poem_page.dart 8.57 KB
import 'dart:async';

import 'package:Parlando/events/trans_event.dart';
import 'package:Parlando/home/models/home_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:flutter/material.dart';
import 'package:Parlando/category/category_router.dart';
import 'package:Parlando/poem/poem_router.dart';
import 'package:Parlando/routers/fluro_navigator.dart';
import 'package:Parlando/tiktok/controller/tiktok_video_list_controller.dart';
import 'package:Parlando/tiktok/mock/video.dart';
import 'package:Parlando/tiktok/pages/search_page.dart';
import 'package:Parlando/tiktok/style/physics.dart';
import 'package:Parlando/tiktok/widgets/tiktok_scaffold.dart';
import 'package:Parlando/tiktok/widgets/tiktok_top_info.dart';
import 'package:Parlando/tiktok/widgets/tiktok_video.dart';
import 'package:Parlando/tiktok/widgets/tiktok_video_button_column.dart';
import 'package:Parlando/tiktok/widgets/tiktok_video_poem.dart';
import 'package:Parlando/widgets/bars/home_types_bar.dart';
import 'package:Parlando/widgets/my_app_bar.dart';
import 'package:getwidget/getwidget.dart';
import 'package:video_player/video_player.dart';

import 'poem_detail.dart';

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

class PoemPage extends StatefulWidget {
  const PoemPage({Key? key}) : super(key: key);

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

class _PoemPageState extends State<PoemPage> with WidgetsBindingObserver {
  TikTokScaffoldController tkController = TikTokScaffoldController();
  final PageController _pageController = PageController();
  final TikTokVideoListController _videoListController =
      TikTokVideoListController();
  List<UserVideo> videoDataList = [];
  late StreamSubscription bus;
  bool isLoading = false;

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) async {
    if (state != AppLifecycleState.resumed) {
      _videoListController.currentPlayer.pause();
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _videoListController.currentPlayer.pause();
    bus.cancel();
    super.dispose();
  }

  @override
  void initState() {
    WidgetsBinding.instance.addObserver(this);
    isLoading = true;
    DioUtils.instance.asyncRequestNetwork<HomeEntity>(
      Method.get,
      HttpApi.home,
      params: [],
      onSuccess: (data) {
        isLoading = false;
        setState(() {});
        List<UserVideo> videoDataList = <UserVideo>[];
        for (HomeDataData data in data!.data!.data!) {
          videoDataList.add(
            UserVideo(
              image: '',
              url: data.url!,
              desc: data.content,
            ),
          );
        }
        _videoListController.init(
          pageController: _pageController,
          initialList: videoDataList
              .map(
                (e) => VPVideoController(
                  videoInfo: e,
                  builder: () => VideoPlayerController.network(e.url),
                ),
              )
              .toList(),
          videoProvider: (int index, List<VPVideoController> list) async {
            return videoDataList
                .map(
                  (e) => VPVideoController(
                    videoInfo: e,
                    builder: () => VideoPlayerController.network(e.url),
                  ),
                )
                .toList();
          },
        );

        _videoListController.addListener(() {
          setState(() {});
        });
        tkController.addListener(
          () {
            if (tkController.value == TikTokPagePosition.middle) {
              _videoListController.currentPlayer.play();
            } else {
              _videoListController.currentPlayer.pause();
            }
          },
        );

        bus = eventBus.on<TransEvent>().listen((event) {
          _videoListController.currentPlayer.pause();
        });
      },
      onError: (code, msg) {
        Toast.show("获取数据失败,请稍候再试...");
        isLoading = false;
      },
    );
    super.initState();
  }

  @override
  void setState(fn) {
    if (mounted) {
      super.setState(fn);
    }
  }

  @override
  Widget build(BuildContext context) {
    Widget? currentPage;
    double a = MediaQuery.of(context).size.aspectRatio;
    bool hasBottomPadding = a < 0.55;

    var detailPage = PoemDetailPage(
      onPop: () {
        tkController.animateToMiddle();
      },
      poemId: 1,
      poemPanelHeight: 60.px,
    );
    var searchPage = SearchPage(
      onPop: tkController.animateToMiddle,
    );

    // 组合
    return isLoading
        ? const GFLoader()
        : TikTokScaffold(
            controller: tkController,
            header: MyAppBar(
              isBack: false,
              isTransparent: true,
              homeMenuHeader: HomeTypesHeader(
                funcCenter: () {
                  _videoListController.currentPlayer.pause();
                  NavigatorUtils.push(
                    context,
                    CategoryRouter.categoryPage,
                  );
                },
              ),
              homeActionWidgets: IconButton(
                icon: const Icon(
                  Icons.search,
                  color: Colors.white,
                ),
                onPressed: () {
                  NavigatorUtils.push(context, PoemRouter.poemSearchPage);
                  _videoListController.currentPlayer.pause();
                },
              ),
            ),
            leftPage: searchPage,
            rightPage: detailPage,
            enableGesture: true,
            page: Stack(
              children: <Widget>[
                PageView.builder(
                  key: const Key('home'),
                  physics: const QuickerScrollPhysics(),
                  controller: _pageController,
                  scrollDirection: Axis.vertical,
                  itemCount: _videoListController.videoCount,
                  itemBuilder: (context, i) {
                    // 拼一个视频组件出来
                    var player = _videoListController.playerOfIndex(i)!;
                    var data = player.videoInfo!;
                    // 右侧按钮列
                    Widget buttons = TikTokButtonColumn(
                      isFavorite: false,
                      onAvatar: () {
                        tkController.animateToPage(TikTokPagePosition.right);
                      },
                      onFavorite: () {},
                      onShare: () {},
                    );
                    Widget poem = TikTokVidePoem(
                      title: "每日一言",
                      poem:
                          "清晨入古寺,初日照高林。\n曲径通幽处,禅房花木深。\n山光悦鸟性,潭影空人心。\n万籁此都寂,但余钟磬音。\n",
                      author: "----《题破山寺后禅院》常建",
                      onShowDetail: () {
                        tkController.animateToPage(TikTokPagePosition.right);
                      },
                    );
                    Widget topInfo = const TikTokTopInfoColumn(info: "早安");
                    // video
                    Widget currentVideo = Center(
                      child: AspectRatio(
                        aspectRatio: player.controller.value.aspectRatio,
                        child: VideoPlayer(player.controller),
                      ),
                    );

                    currentVideo = TikTokVideoPage(
                      // 手势播放与自然播放都会产生暂停按钮状态变化,待处理
                      hidePauseIcon: !player.showPauseIcon.value,
                      aspectRatio: 9 / 16.0,
                      key: Key('${data.url}$i'),
                      tag: data.url,
                      bottomPadding: hasBottomPadding ? 16.px : 16.px,
                      onSingleTap: () async {
                        if (player.controller.value.isPlaying) {
                          await player.pause();
                        } else {
                          await player.play();
                        }
                        setState(() {});
                      },
                      onAddFavorite: () {},
                      rightButtonColumn: buttons,
                      // leftPoemArea: poem,
                      // topInfo: topInfo,
                      video: currentVideo,
                    );
                    return currentVideo;
                  },
                ),
                currentPage ?? Container(),
              ],
            ),
          );
  }
}