123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- import 'dart:async';
- import 'dart:convert';
- import 'dart:io';
- import 'package:async/async.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter_osc/model/api.dart';
- import 'package:flutter_osc/util/DataUtils.dart';
- import 'package:http/http.dart' as http;
- import 'package:image_picker/image_picker.dart';
- class PublishTweetPage extends StatefulWidget {
- @override
- State<StatefulWidget> createState() {
- return PublishTweetPageState();
- }
- }
- class PublishTweetPageState extends State<PublishTweetPage> {
- TextEditingController _controller = TextEditingController();
- List<File> fileList = [];
- Future<XFile?>? _imageFile;
- bool isLoading = false;
- String msg = "";
- Widget getBody() {
- var textField = TextField(
- decoration: InputDecoration(
- hintText: "说点什么吧~",
- hintStyle: TextStyle(color: const Color(0xFF808080)),
- border: OutlineInputBorder(
- borderRadius:
- const BorderRadius.all(const Radius.circular(10.0)))),
- maxLines: 6,
- maxLength: 150,
- controller: _controller,
- );
- var gridView = Builder(
- builder: (ctx) {
- return GridView.count(
- crossAxisCount: 4,
- children: List.generate(fileList.length + 1, (index) {
- var content;
- if (index == 0) {
- // 添加图片按钮
- var addCell = Center(
- child: Image.asset(
- './images/ic_add_pics.png',
- width: 80.0,
- height: 80.0,
- ));
- content = GestureDetector(
- onTap: () {
- // 添加图片
- pickImage(ctx);
- },
- child: addCell,
- );
- } else {
- // 被选中的图片
- content = Center(
- child: Image.file(
- fileList[index - 1],
- width: 80.0,
- height: 80.0,
- fit: BoxFit.cover,
- ));
- }
- return Container(
- margin: const EdgeInsets.all(2.0),
- width: 80.0,
- height: 80.0,
- color: const Color(0xFFECECEC),
- child: content,
- );
- }),
- );
- },
- );
- var children = [
- Text(
- "提示:由于OSC的openapi限制,发布动弹的接口只支持上传一张图片,本项目可添加最多9张图片,但OSC只会接收最后一张图片。",
- style: TextStyle(fontSize: 12.0),
- ),
- textField,
- Container(
- margin: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
- height: 200.0,
- child: gridView)
- ];
- if (isLoading) {
- children.add(Container(
- margin: const EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 0.0),
- child: Center(
- child: CircularProgressIndicator(),
- ),
- ));
- } else {
- children.add(Container(
- margin: const EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 0.0),
- child: Center(
- child: Text(msg),
- )));
- }
- return Container(
- padding: const EdgeInsets.all(5.0),
- child: Column(
- children: children,
- ),
- );
- }
- // 相机拍照或者从图库选择图片
- pickImage(ctx) {
- // 如果已添加了9张图片,则提示不允许添加更多
- num size = fileList.length;
- if (size >= 9) {
- ScaffoldMessenger.of(ctx).showSnackBar(SnackBar(
- content: Text("最多只能添加9张图片!"),
- ));
- return;
- }
- showModalBottomSheet<void>(context: context, builder: _bottomSheetBuilder);
- }
- Widget _bottomSheetBuilder(BuildContext context) {
- return Container(
- height: 182.0,
- child: Padding(
- padding: const EdgeInsets.fromLTRB(0.0, 30.0, 0.0, 30.0),
- child: Column(
- children: [
- _renderBottomMenuItem("相机拍照", ImageSource.camera),
- Divider(
- height: 2.0,
- ),
- _renderBottomMenuItem("图库选择照片", ImageSource.gallery)
- ],
- ),
- ));
- }
- _renderBottomMenuItem(title, ImageSource source) {
- var item = Container(
- height: 60.0,
- child: Center(child: Text(title)),
- );
- return InkWell(
- child: item,
- onTap: () {
- Navigator.of(context).pop();
- setState(() {
- _imageFile = ImagePicker().pickImage(source: source);
- });
- },
- );
- }
- sendTweet(ctx, token) async {
- if (token == null) {
- ScaffoldMessenger.of(ctx).showSnackBar(SnackBar(
- content: Text("未登录!"),
- ));
- return;
- }
- String content = _controller.text;
- if (content == null || content.length == 0 || content.trim().length == 0) {
- ScaffoldMessenger.of(ctx).showSnackBar(SnackBar(
- content: Text("请输入动弹内容!"),
- ));
- }
- try {
- Map<String, String> params = Map();
- params['msg'] = content;
- params['access_token'] = token;
- var request = http.MultipartRequest('POST', Uri.parse(Api.PUB_TWEET));
- request.fields.addAll(params);
- if (fileList != null && fileList.length > 0) {
- for (File f in fileList) {
- var stream = http.ByteStream(DelegatingStream.typed(f.openRead()));
- var length = await f.length();
- var filename = f.path.substring(f.path.lastIndexOf("/") + 1);
- request.files.add(
- http.MultipartFile('img', stream, length, filename: filename));
- }
- }
- setState(() {
- isLoading = true;
- });
- var response = await request.send();
- response.stream.transform(utf8.decoder).listen((value) {
- print(value);
- if (value != null) {
- var obj = json.decode(value);
- var error = obj['error'];
- setState(() {
- if (error != null && error == '200') {
- // 成功
- setState(() {
- isLoading = false;
- msg = "发布成功";
- fileList.clear();
- });
- _controller.clear();
- } else {
- setState(() {
- isLoading = false;
- msg = "发布失败:$error";
- });
- }
- });
- }
- });
- } catch (exception) {
- print(exception);
- }
- }
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text("发布动弹", style: TextStyle(color: Colors.white)),
- iconTheme: IconThemeData(color: Colors.white),
- actions: <Widget>[
- Builder(
- builder: (ctx) {
- return IconButton(
- icon: Icon(Icons.send),
- onPressed: () {
- // 发送动弹
- DataUtils.isLogin().then((isLogin) {
- if (isLogin) {
- return DataUtils.getAccessToken();
- } else {
- return null;
- }
- }).then((token) {
- sendTweet(ctx, token);
- });
- });
- },
- )
- ],
- ),
- body: FutureBuilder(
- future: _imageFile,
- builder: (BuildContext context, AsyncSnapshot<XFile?> snapshot) {
- if (snapshot.connectionState == ConnectionState.done &&
- snapshot.data != null &&
- _imageFile != null) {
- fileList.add(File(snapshot.data!.path));
- _imageFile = null;
- }
- return getBody();
- },
- ),
- );
- }
- }
|