poem_publish.dart 11.5 KB
import 'package:Parlando/models/upload_entity.dart';
import 'package:Parlando/net/dio_utils.dart';
import 'package:Parlando/net/http_api.dart';
import 'package:Parlando/util/toast_utils.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:Parlando/poem/provider/lang_sort_provider.dart';
import 'package:Parlando/poem/widgets/lang_sort_bottom_sheet.dart';
import 'package:Parlando/res/resources.dart';
import 'package:Parlando/routers/fluro_navigator.dart';
import 'package:Parlando/routers/routers.dart';
import 'package:Parlando/widgets/my_app_bar.dart';

import 'package:Parlando/extension/int_extension.dart';
import 'package:getwidget/getwidget.dart';
import 'package:path_provider/path_provider.dart';

import '../poem_router.dart';

class PoemPublish extends StatefulWidget {
  const PoemPublish({
    Key? key,
    required this.data,
    required this.id,
    required this.type,
  }) : super(key: key);

  final int id;
  final int type;
  final String data;

  @override
  PoemPublishState createState() => PoemPublishState();
}

class PoemPublishState extends State<PoemPublish> {
  bool isPublishing = false;
  bool isUploading = false;
  String _langSortName = "普通话";
  int _langSortId = 1; //TODO 传入服务器的口音ID
  String _address = '我在此地';
  String _longitude = "";
  String _latitude = "";
  final LangSortProvider _provider = LangSortProvider();
  final ValueNotifier<double> _counter = ValueNotifier<double>(0.0);
  final TextEditingController _msgController = TextEditingController();

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    _counter.dispose();
    _provider.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: _isExit,
      child: Scaffold(
        appBar: MyAppBar(
          homeMenuHeader: Container(
            alignment: Alignment.center,
            width: double.infinity,
            child: const Text(
              "发布临境",
              style: TextStyle(
                color: Colors.white,
              ),
            ),
          ),
        ),
        body: Stack(
          children: [
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.all(
                    10.0,
                  ),
                  child: ConstrainedBox(
                    constraints: const BoxConstraints(
                      maxHeight: 200,
                      maxWidth: double.infinity,
                    ),
                    child: TextField(
                      controller: _msgController,
                      maxLines: 10,
                      decoration: InputDecoration(
                        contentPadding: const EdgeInsets.all(10.0),
                        hintText: '读此一言,仿佛身临其境',
                        border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(5),
                            borderSide: BorderSide.none),
                        filled: true,
                        fillColor: Colors.grey.shade100,
                      ),
                    ),
                  ),
                ),
                InkWell(
                  onTap: () {
                    NavigatorUtils.pushResult(
                        context, PoemRouter.addressSelectPage, (result) {
                      setState(() {
                        // final BMFSuggestionInfo model =
                        //     result as BMFSuggestionInfo;
                        // _longitude = model.location!.longitude.toString();
                        // _latitude = model.location!.latitude.toString();
                        // _address =
                        //     '${model.city!} ${model.district!} ${model.address!}';
                      });
                    });
                  },
                  child: Container(
                    padding: EdgeInsets.all(10.px),
                    alignment: Alignment.centerLeft,
                    width: double.infinity,
                    height: 36.px,
                    child: Wrap(
                      children: [
                        Icon(
                          Icons.room_outlined,
                          size: 15.px,
                        ),
                        Gaps.hGap5,
                        Text(
                          _address,
                          style: const TextStyle(color: Colors.black45),
                        ),
                      ],
                    ),
                  ),
                ),
                InkWell(
                  onTap: () {
                    showModalBottomSheet<void>(
                      context: context,
                      isScrollControlled: true,
                      builder: (BuildContext context) {
                        return LangSortBottomSheet(
                          provider: _provider,
                          onSelected: (id, name) {
                            setState(() {
                              _langSortId = int.parse(id);
                              _langSortName = name;
                            });
                          },
                        );
                      },
                    );
                  },
                  child: Container(
                    padding: EdgeInsets.all(10.px),
                    alignment: Alignment.centerLeft,
                    width: double.infinity,
                    height: 36.px,
                    child: Wrap(
                      children: [
                        Icon(
                          Icons.record_voice_over_outlined,
                          size: 15.px,
                        ),
                        Gaps.hGap5,
                        Text(
                          "所用口音 $_langSortName",
                          style: const TextStyle(color: Colors.black45),
                        ),
                      ],
                    ),
                  ),
                ),
                const Spacer(),
                Expanded(
                  child: Center(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Text(
                          "发布临境,让更多人身临其境",
                          style: TextStyle(fontSize: 14.px),
                        ),
                        Gaps.vGap10,
                        TextButton(
                          style: ButtonStyle(
                            side: MaterialStateProperty.all(
                              BorderSide(
                                color: Colors.black54,
                                width: 1.px,
                              ),
                            ),
                          ),
                          onPressed: () {
                            publishPoem(context);
                          },
                          child: Text(
                            "发布",
                            style: TextStyle(
                                color: Colors.black54, fontSize: 15.px),
                          ),
                        ),
                        Gaps.vGap10,
                        isUploading
                            ? Padding(
                                padding: const EdgeInsets.all(20),
                                child: ValueListenableBuilder<double>(
                                  builder: _buildWithValue,
                                  valueListenable: _counter,
                                ),
                              )
                            : Container(),
                      ],
                    ),
                  ),
                ),
              ],
            ),
            isPublishing
                ? const Center(
                    child: CupertinoActivityIndicator(
                      radius: 16.0,
                    ),
                  )
                : Container(),
          ],
        ),
      ),
    );
  }

  Widget _buildWithValue(BuildContext context, double value, Widget? child) {
    return GFProgressBar(
      percentage: value,
      lineHeight: 10,
      alignment: MainAxisAlignment.spaceBetween,
      backgroundColor: Colors.black26,
      progressBarColor: GFColors.INFO,
      child: Text(
        "${(value * 100).toStringAsFixed(1)}%",
        textAlign: TextAlign.end,
        style: const TextStyle(fontSize: 8, color: Colors.white),
      ),
    );
  }

  Future<dynamic> _getUploadVideo() async {
    final directory = await getApplicationDocumentsDirectory();
    dynamic video = await MultipartFile.fromFile(
        "${directory.path}/${widget.data}",
        filename: "video.mp4");
    return video;
  }

  Future<void> publishPoem(BuildContext context) async {
    String msg = _msgController.text;
    if (msg.isEmpty) {
      msg = "读此一言,仿佛身临其境";
    }

    isPublishing = true;
    isUploading = true;
    setState(() {});

    _getUploadVideo().then((value) {
      Map<String, dynamic> map = <String, dynamic>{
        "video": value,
      };
      FormData formData = FormData.fromMap(map);
      DioUtils.instance.asyncUploadFile<UploadEntity>(
        Method.post,
        HttpApi.uploadVideo,
        params: formData,
        progressCallback: (int count, int data) {
          _counter.value = count / data;
        },
        onSuccess: (data) {
          String path = data!.data!.relativePath!;
          String videoId = '${widget.id}';
          isUploading = false;
          Map<String, String> params = <String, String>{
            "item_id": videoId,
            "item_url": path,
            "content": msg,
            "type": '${widget.type}',
            "longitude": _longitude,
            "latitude": _latitude,
            "location": _address,
          };
          DioUtils.instance.asyncRequestNetwork(
            Method.post,
            HttpApi.immersive,
            params: params,
            onSuccess: (data) {
              isPublishing = false;
              NavigatorUtils.push(
                context,
                '${PoemRouter.poemCompletePage}?id=100',
              );
            },
            onError: (code, msg) {
              Toast.show(msg.toString());
              isPublishing = false;
              setState(() {});
            },
          );
        },
        onError: (code, msg) {
          Toast.show(msg.toString());
          isPublishing = false;
          setState(() {});
        },
      );
    });
  }

  Future<bool> _isExit() async {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text("温馨提示"),
          content: Container(
            padding: EdgeInsets.all(1.px),
            //可滑动布局
            child: const Text("确认放弃此次作品吗?"),
          ),
          actions: [
            TextButton(
              child: const Text("再想想"),
              onPressed: () {
                Navigator.of(context).pop(true);
              },
            ),
            TextButton(
              child: const Text("残忍放弃"),
              onPressed: () {
                NavigatorUtils.push(context, Routes.navBarPage,
                    clearStack: true);
              },
            ),
          ],
        );
      },
    );
    return Future.value(false);
  }
}