From 6f628374953ff9d032e6f980f6497ca343b86026 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Fri, 2 Feb 2024 23:12:04 +0800 Subject: [PATCH 01/36] =?UTF-8?q?mod:=20media=5Fkit=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pubspec.lock | 27 +++++++++++++++------------ pubspec.yaml | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index d9b6a01d..e98d7443 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -848,10 +848,11 @@ packages: media_kit: dependency: "direct main" description: - name: media_kit - sha256: "3289062540e3b8b9746e5c50d95bd78a9289826b7227e253dff806d002b9e67a" - url: "https://pub.flutter-io.cn" - source: hosted + path: media_kit + ref: main + resolved-ref: "63c6ebe8366db7ecfbd13ab9ce76b11dd86dae48" + url: "https://github.com/media-kit/media-kit.git" + source: git version: "1.1.10+1" media_kit_libs_android_video: dependency: transitive @@ -888,10 +889,11 @@ packages: media_kit_libs_video: dependency: "direct main" description: - name: media_kit_libs_video - sha256: "3688e0c31482074578652bf038ce6301a5d21e1eda6b54fc3117ffeb4bdba067" - url: "https://pub.flutter-io.cn" - source: hosted + path: "libs/universal/media_kit_libs_video" + ref: main + resolved-ref: "63c6ebe8366db7ecfbd13ab9ce76b11dd86dae48" + url: "https://github.com/media-kit/media-kit.git" + source: git version: "1.0.4" media_kit_libs_windows_video: dependency: transitive @@ -912,10 +914,11 @@ packages: media_kit_video: dependency: "direct main" description: - name: media_kit_video - sha256: c048d11a19e379aebbe810647636e3fc6d18374637e2ae12def4ff8a4b99a882 - url: "https://pub.flutter-io.cn" - source: hosted + path: media_kit_video + ref: main + resolved-ref: "63c6ebe8366db7ecfbd13ab9ce76b11dd86dae48" + url: "https://github.com/media-kit/media-kit.git" + source: git version: "1.2.4" meta: dependency: transitive diff --git a/pubspec.yaml b/pubspec.yaml index f4b8fe61..41cc829d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -85,9 +85,21 @@ dependencies: encrypt: ^5.0.3 # 视频播放器 - media_kit: ^1.1.10 # Primary package. - media_kit_video: ^1.2.4 # For video rendering. - media_kit_libs_video: ^1.0.4 + media_kit: + git: + url: https://github.com/media-kit/media-kit.git + ref: main + path: ./media_kit + media_kit_video: + git: + url: https://github.com/media-kit/media-kit.git + ref: main + path: ./media_kit_video + media_kit_libs_video: + git: + url: https://github.com/media-kit/media-kit.git + ref: main + path: ./libs/universal/media_kit_libs_video # 媒体通知 audio_service: ^0.18.12 @@ -156,6 +168,23 @@ dev_dependencies: hive_generator: ^2.0.0 build_runner: ^2.3.3 +dependency_overrides: + media_kit: + git: + url: https://github.com/media-kit/media-kit.git + ref: main + path: ./media_kit + media_kit_video: + git: + url: https://github.com/media-kit/media-kit.git + ref: main + path: ./media_kit_video + media_kit_libs_video: + git: + url: https://github.com/media-kit/media-kit.git + ref: main + path: ./libs/universal/media_kit_libs_video + flutter_launcher_icons: android: true ios: true From 2dbef3fee24ff5e9320b2c28f4e2e1835aa38416 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Tue, 19 Mar 2024 23:23:14 +0800 Subject: [PATCH 02/36] =?UTF-8?q?mod:=20media=5Fkit=E5=BC=95=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pubspec.lock | 12 ++++++------ pubspec.yaml | 27 ++++++--------------------- 2 files changed, 12 insertions(+), 27 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index a42bd421..fc479e1a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -858,8 +858,8 @@ packages: dependency: "direct main" description: path: media_kit - ref: main - resolved-ref: "63c6ebe8366db7ecfbd13ab9ce76b11dd86dae48" + ref: HEAD + resolved-ref: "77a130b1d7ce733b47d2133b57563716090450d0" url: "https://github.com/media-kit/media-kit.git" source: git version: "1.1.10+1" @@ -899,8 +899,8 @@ packages: dependency: "direct main" description: path: "libs/universal/media_kit_libs_video" - ref: main - resolved-ref: "63c6ebe8366db7ecfbd13ab9ce76b11dd86dae48" + ref: HEAD + resolved-ref: "77a130b1d7ce733b47d2133b57563716090450d0" url: "https://github.com/media-kit/media-kit.git" source: git version: "1.0.4" @@ -924,8 +924,8 @@ packages: dependency: "direct main" description: path: media_kit_video - ref: main - resolved-ref: "63c6ebe8366db7ecfbd13ab9ce76b11dd86dae48" + ref: HEAD + resolved-ref: "77a130b1d7ce733b47d2133b57563716090450d0" url: "https://github.com/media-kit/media-kit.git" source: git version: "1.2.4" diff --git a/pubspec.yaml b/pubspec.yaml index 23cc509f..e6690a37 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -85,21 +85,9 @@ dependencies: encrypt: ^5.0.3 # 视频播放器 - media_kit: - git: - url: https://github.com/media-kit/media-kit.git - ref: main - path: ./media_kit - media_kit_video: - git: - url: https://github.com/media-kit/media-kit.git - ref: main - path: ./media_kit_video - media_kit_libs_video: - git: - url: https://github.com/media-kit/media-kit.git - ref: main - path: ./libs/universal/media_kit_libs_video + media_kit: ^1.1.10 # Primary package. + media_kit_video: ^1.2.4 # For video rendering. + media_kit_libs_video: ^1.0.4 # 媒体通知 audio_service: ^0.18.12 @@ -177,18 +165,15 @@ dependency_overrides: media_kit: git: url: https://github.com/media-kit/media-kit.git - ref: main - path: ./media_kit + path: media_kit media_kit_video: git: url: https://github.com/media-kit/media-kit.git - ref: main - path: ./media_kit_video + path: media_kit_video media_kit_libs_video: git: url: https://github.com/media-kit/media-kit.git - ref: main - path: ./libs/universal/media_kit_libs_video + path: libs/universal/media_kit_libs_video flutter_launcher_icons: android: true From 76784ee6647893098512226f39e41c57c22b2dc9 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Tue, 19 Mar 2024 23:33:32 +0800 Subject: [PATCH 03/36] mod: seekTo --- lib/plugin/pl_player/controller.dart | 30 +++++++++++++--------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index aaded67d..465b3003 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -375,7 +375,13 @@ class PlPlayerController { } // 配置Player 音轨、字幕等等 _videoPlayerController = await _createVideoController( - dataSource, _looping, enableHA, width, height); + dataSource, + _looping, + enableHA, + width, + height, + seekTo, + ); // 获取视频时长 00:00 _duration.value = duration ?? _videoPlayerController!.state.duration; updateDurationSecond(); @@ -386,7 +392,7 @@ class PlPlayerController { if (!_listenersInitialized) { startListeners(); } - await _initializePlayer(seekTo: seekTo, duration: _duration.value); + await _initializePlayer(duration: _duration.value); bool autoEnterFullcreen = setting.get(SettingBoxKey.enableAutoEnter, defaultValue: false); if (autoEnterFullcreen && _isFirstTime) { @@ -406,6 +412,7 @@ class PlPlayerController { bool enableHA, double? width, double? height, + Duration? seekTo, ) async { // 每次配置时先移除监听 removeListeners(); @@ -488,7 +495,11 @@ class PlPlayerController { ); } player.open( - Media(dataSource.videoSource!, httpHeaders: dataSource.httpHeaders), + Media( + dataSource.videoSource!, + httpHeaders: dataSource.httpHeaders, + start: seekTo ?? Duration.zero, + ), play: false, ); // 音轨 @@ -501,7 +512,6 @@ class PlPlayerController { // 开始播放 Future _initializePlayer({ - Duration seekTo = Duration.zero, Duration? duration, }) async { // 设置倍速 @@ -519,11 +529,6 @@ class PlPlayerController { // await setLooping(_looping); // } - // 跳转播放 - if (seekTo != Duration.zero) { - await this.seekTo(seekTo); - } - // 自动播放 if (_autoPlay) { await play(duration: duration); @@ -637,21 +642,14 @@ class PlPlayerController { await _videoPlayerController?.stream.buffer.first; } await _videoPlayerController?.seek(position); - // if (playerStatus.stopped) { - // play(); - // } } else { print('seek duration else'); _timerForSeek?.cancel(); _timerForSeek = Timer.periodic(const Duration(milliseconds: 200), (Timer t) async { - //_timerForSeek = null; if (duration.value.inSeconds != 0) { await _videoPlayerController!.stream.buffer.first; await _videoPlayerController?.seek(position); - // if (playerStatus.status.value == PlayerStatus.paused) { - // play(); - // } t.cancel(); _timerForSeek = null; } From b8e3764345aaf66e2cbad0c73f8d5d2ce2e1f8d0 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Fri, 10 May 2024 23:45:51 +0800 Subject: [PATCH 04/36] fix: login Box has already been closed --- lib/pages/webview/controller.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/pages/webview/controller.dart b/lib/pages/webview/controller.dart index 40f84ff6..bdacc652 100644 --- a/lib/pages/webview/controller.dart +++ b/lib/pages/webview/controller.dart @@ -110,6 +110,9 @@ class WebviewController extends GetxController { SmartDialog.showToast('登录成功'); try { Box userInfoCache = GStrorage.userInfo; + if (!userInfoCache.isOpen) { + userInfoCache = await Hive.openBox('userInfo'); + } await userInfoCache.put('userInfoCache', result['data']); final HomeController homeCtr = Get.find(); From 14b7ac438f25d97711a70301eb5ded8ad455da5a Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sat, 11 May 2024 23:50:41 +0800 Subject: [PATCH 05/36] =?UTF-8?q?fix:=20=E7=9B=B4=E6=92=AD=E5=85=A8?= =?UTF-8?q?=E5=B1=8F=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/live_room/widgets/bottom_control.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pages/live_room/widgets/bottom_control.dart b/lib/pages/live_room/widgets/bottom_control.dart index e5a9d6c9..4dd7c538 100644 --- a/lib/pages/live_room/widgets/bottom_control.dart +++ b/lib/pages/live_room/widgets/bottom_control.dart @@ -153,7 +153,8 @@ class _BottomControlState extends State { size: 20, color: Colors.white, ), - fuc: () => widget.controller!.triggerFullScreen(), + fuc: () => widget.controller!.triggerFullScreen( + status: !(widget.controller!.isFullScreen.value)), ), ], ), From 79bde1b7ff03158a36d18fd8885bc3fa080fd3b2 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Mon, 13 May 2024 23:16:25 +0800 Subject: [PATCH 06/36] =?UTF-8?q?mod:=20=E5=8E=86=E5=8F=B2=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E9=95=BF=E6=8C=89=E5=9C=86=E8=A7=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/history/widgets/item.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pages/history/widgets/item.dart b/lib/pages/history/widgets/item.dart index ba5f6b5c..00ebd511 100644 --- a/lib/pages/history/widgets/item.dart +++ b/lib/pages/history/widgets/item.dart @@ -198,7 +198,8 @@ class HistoryItem extends StatelessWidget { duration: const Duration(milliseconds: 200), child: Container( decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), + borderRadius: BorderRadius.circular( + StyleString.imgRadius.x), color: Colors.black.withOpacity( ctr!.enableMultiple.value && videoItem.checked From 31e8ee8d34023b6d541088836432eba556123853 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Mon, 13 May 2024 23:55:17 +0800 Subject: [PATCH 07/36] =?UTF-8?q?fix:=20=E7=95=AA=E5=89=A7=E6=97=A0?= =?UTF-8?q?=E8=AF=84=E5=88=86=E5=AF=BC=E8=87=B4=E7=9A=84=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/bangumi/introduction/view.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pages/bangumi/introduction/view.dart b/lib/pages/bangumi/introduction/view.dart index 6876da79..95d4d898 100644 --- a/lib/pages/bangumi/introduction/view.dart +++ b/lib/pages/bangumi/introduction/view.dart @@ -194,7 +194,8 @@ class _BangumiInfoState extends State { src: widget.bangumiDetail!.cover!, ), PBadge( - text: '评分 ${widget.bangumiDetail!.rating!['score']!}', + text: + '评分 ${widget.bangumiDetail?.rating?['score']! ?? '暂无'}', top: null, right: 6, bottom: 6, From 44f2a168ce79b62c315f5706152240c3396a1562 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Wed, 15 May 2024 23:55:04 +0800 Subject: [PATCH 08/36] =?UTF-8?q?opt:=20=E6=92=AD=E6=94=BE=E5=99=A8?= =?UTF-8?q?=E5=8D=95=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/live_room/controller.dart | 3 +-- lib/pages/video/detail/controller.dart | 2 +- lib/plugin/pl_player/controller.dart | 19 +++++++++---------- lib/plugin/pl_player/view.dart | 10 +++++----- lib/services/audio_handler.dart | 2 +- lib/services/audio_session.dart | 4 ++-- lib/services/shutdown_timer_service.dart | 4 ++-- 7 files changed, 21 insertions(+), 23 deletions(-) diff --git a/lib/pages/live_room/controller.dart b/lib/pages/live_room/controller.dart index 5c2a9800..4e67fa2c 100644 --- a/lib/pages/live_room/controller.dart +++ b/lib/pages/live_room/controller.dart @@ -17,8 +17,7 @@ class LiveRoomController extends GetxController { double volume = 0.0; // 静音状态 RxBool volumeOff = false.obs; - PlPlayerController plPlayerController = - PlPlayerController.getInstance(videoType: 'live'); + PlPlayerController plPlayerController = PlPlayerController(videoType: 'live'); Rx roomInfoH5 = RoomInfoH5Model().obs; late bool enableCDN; late int currentQn; diff --git a/lib/pages/video/detail/controller.dart b/lib/pages/video/detail/controller.dart index f7f9e848..722af317 100644 --- a/lib/pages/video/detail/controller.dart +++ b/lib/pages/video/detail/controller.dart @@ -74,7 +74,7 @@ class VideoDetailController extends GetxController final scaffoldKey = GlobalKey(); RxString bgCover = ''.obs; RxString cover = ''.obs; - PlPlayerController plPlayerController = PlPlayerController.getInstance(); + PlPlayerController plPlayerController = PlPlayerController(); late VideoItem firstVideo; late AudioItem firstAudio; diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index 93d67703..03c2efbe 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -123,6 +123,7 @@ class PlPlayerController { PreferredSizeWidget? bottomControl; Widget? danmuWidget; late RxList subtitles; + String videoType = 'archive'; /// 数据加载监听 Stream get onDataStatusChanged => dataStatus.status.stream; @@ -220,7 +221,7 @@ class PlPlayerController { Rx get playerCount => _playerCount; /// - Rx get videoType => _videoType; + // Rx get videoType => _videoType; /// 弹幕开关 Rx isOpenDanmu = false.obs; @@ -274,8 +275,7 @@ class PlPlayerController { } // 添加一个私有构造函数 - PlPlayerController._() { - _videoType = videoType; + PlPlayerController._internal(this.videoType) { isOpenDanmu.value = setting.get(SettingBoxKey.enableShowDanmaku, defaultValue: false); blockTypes = @@ -330,11 +330,11 @@ class PlPlayerController { } // 获取实例 传参 - static PlPlayerController getInstance({ + factory PlPlayerController({ String videoType = 'archive', }) { // 如果实例尚未创建,则创建一个新实例 - _instance ??= PlPlayerController._(); + _instance ??= PlPlayerController._internal(videoType); if (videoType != 'none') { _instance!._playerCount.value += 1; _videoType.value = videoType; @@ -443,7 +443,7 @@ class PlPlayerController { configuration: PlayerConfiguration( // 默认缓存 5M 大小 bufferSize: - videoType.value == 'live' ? 32 * 1024 * 1024 : 5 * 1024 * 1024, + videoType == 'live' ? 32 * 1024 * 1024 : 5 * 1024 * 1024, ), ); @@ -541,7 +541,7 @@ class PlPlayerController { } /// 设置倍速 - if (videoType.value == 'live') { + if (videoType == 'live') { await setPlaybackSpeed(1.0); } else { if (_playbackSpeed.value != 1.0) { @@ -933,7 +933,7 @@ class PlPlayerController { /// 设置长按倍速状态 live模式下禁用 void setDoubleSpeedStatus(bool val) { - if (videoType.value == 'live') { + if (videoType == 'live') { return; } if (controlsLock.value) { @@ -1015,7 +1015,7 @@ class PlPlayerController { if (!_enableHeart) { return false; } - if (videoType.value == 'live') { + if (videoType == 'live') { return; } // 播放状态变化时,更新 @@ -1114,7 +1114,6 @@ class PlPlayerController { // _buffered.close(); // _showControls.close(); // _controlsLock.close(); - // playerStatus.status.close(); // dataStatus.status.close(); diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index d359391e..cff4611a 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -652,7 +652,7 @@ class _PLVideoPlayerState extends State }, onDoubleTapDown: (TapDownDetails details) { // live模式下禁用 锁定时🔒禁用 - if (_.videoType.value == 'live' || _.controlsLock.value) { + if (_.videoType == 'live' || _.controlsLock.value) { return; } final double totalWidth = MediaQuery.sizeOf(context).width; @@ -679,7 +679,7 @@ class _PLVideoPlayerState extends State /// 水平位置 快进 live模式下禁用 onHorizontalDragUpdate: (DragUpdateDetails details) { // live模式下禁用 锁定时🔒禁用 - if (_.videoType.value == 'live' || _.controlsLock.value) { + if (_.videoType == 'live' || _.controlsLock.value) { return; } // final double tapPosition = details.localPosition.dx; @@ -695,7 +695,7 @@ class _PLVideoPlayerState extends State _.onChangedSliderStart(); }, onHorizontalDragEnd: (DragEndDetails details) { - if (_.videoType.value == 'live' || _.controlsLock.value) { + if (_.videoType == 'live' || _.controlsLock.value) { return; } _.onChangedSliderEnd(); @@ -826,7 +826,7 @@ class _PLVideoPlayerState extends State return const SizedBox(); } - if (_.videoType.value == 'live') { + if (_.videoType == 'live') { return const SizedBox(); } if (value > max || max <= 0) { @@ -879,7 +879,7 @@ class _PLVideoPlayerState extends State // 锁 Obx( () => Visibility( - visible: _.videoType.value != 'live' && _.isFullScreen.value, + visible: _.videoType != 'live' && _.isFullScreen.value, child: Align( alignment: Alignment.centerLeft, child: FractionalTranslation( diff --git a/lib/services/audio_handler.dart b/lib/services/audio_handler.dart index bf98298b..853c58d0 100644 --- a/lib/services/audio_handler.dart +++ b/lib/services/audio_handler.dart @@ -26,7 +26,7 @@ class VideoPlayerServiceHandler extends BaseAudioHandler with SeekHandler { static final List _item = []; Box setting = GStrorage.setting; bool enableBackgroundPlay = false; - PlPlayerController player = PlPlayerController.getInstance(); + PlPlayerController player = PlPlayerController(); VideoPlayerServiceHandler() { revalidateSetting(); diff --git a/lib/services/audio_session.dart b/lib/services/audio_session.dart index 53b497ae..d1d2a466 100644 --- a/lib/services/audio_session.dart +++ b/lib/services/audio_session.dart @@ -18,7 +18,7 @@ class AudioSessionHandler { session.configure(const AudioSessionConfiguration.music()); session.interruptionEventStream.listen((event) { - final player = PlPlayerController.getInstance(videoType: 'none'); + final player = PlPlayerController(videoType: 'none'); if (event.begin) { if (!player.playerStatus.playing) return; switch (event.type) { @@ -51,7 +51,7 @@ class AudioSessionHandler { // 耳机拔出暂停 session.becomingNoisyEventStream.listen((_) { - final player = PlPlayerController.getInstance(videoType: 'none'); + final player = PlPlayerController(videoType: 'none'); if (player.playerStatus.playing) { player.pause(); } diff --git a/lib/services/shutdown_timer_service.dart b/lib/services/shutdown_timer_service.dart index 156b63c8..06993f62 100644 --- a/lib/services/shutdown_timer_service.dart +++ b/lib/services/shutdown_timer_service.dart @@ -89,7 +89,7 @@ class ShutdownTimerService { return; } PlPlayerController plPlayerController = - PlPlayerController.getInstance(videoType: 'none'); + PlPlayerController(videoType: 'none'); if (!exitApp && !waitForPlayingCompleted) { if (!plPlayerController.playerStatus.playing) { //仅提示用户 @@ -124,7 +124,7 @@ class ShutdownTimerService { } else { //暂停播放 PlPlayerController plPlayerController = - PlPlayerController.getInstance(videoType: 'none'); + PlPlayerController(videoType: 'none'); if (plPlayerController.playerStatus.playing) { plPlayerController.pause(); waitForPlayingCompleted = true; From f23a21f6dce39cffc0fb2879a321d3f3b514ba05 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Thu, 16 May 2024 23:04:47 +0800 Subject: [PATCH 09/36] =?UTF-8?q?feat:=20=E5=8A=A8=E6=80=81=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/models/dynamics/result.dart | 3 + lib/pages/dynamics/widgets/forward_panel.dart | 55 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/lib/models/dynamics/result.dart b/lib/models/dynamics/result.dart index bc7105d1..64a6e5b1 100644 --- a/lib/models/dynamics/result.dart +++ b/lib/models/dynamics/result.dart @@ -415,6 +415,7 @@ class DynamicMajorModel { this.type, this.courses, this.common, + this.music, }); DynamicArchiveModel? archive; @@ -431,6 +432,7 @@ class DynamicMajorModel { String? type; Map? courses; Map? common; + Map? music; DynamicMajorModel.fromJson(Map json) { archive = json['archive'] != null @@ -455,6 +457,7 @@ class DynamicMajorModel { type = json['type']; courses = json['courses'] ?? {}; common = json['common'] ?? {}; + music = json['music'] ?? {}; } } diff --git a/lib/pages/dynamics/widgets/forward_panel.dart b/lib/pages/dynamics/widgets/forward_panel.dart index 76c7b24e..f8b90a81 100644 --- a/lib/pages/dynamics/widgets/forward_panel.dart +++ b/lib/pages/dynamics/widgets/forward_panel.dart @@ -238,6 +238,61 @@ Widget forWard(item, context, ctr, source, {floor = 1}) { ), ), ); + case 'DYNAMIC_TYPE_MUSIC': + final Map music = item.modules.moduleDynamic.major.music; + return Padding( + padding: const EdgeInsets.only(top: 8), + child: InkWell( + onTap: () { + Get.toNamed('/webview', parameters: { + 'url': "https:${music['jump_url']}", + 'type': 'url', + 'pageTitle': music['title'] + }); + }, + child: Container( + width: double.infinity, + padding: + const EdgeInsets.only(left: 12, top: 10, right: 12, bottom: 10), + color: Theme.of(context).dividerColor.withOpacity(0.08), + child: Row( + children: [ + NetworkImgLayer( + width: 45, + height: 45, + src: music['cover'], + ), + const SizedBox(width: 10), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + music['title'], + style: TextStyle( + color: Theme.of(context).colorScheme.primary, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + const SizedBox(height: 2), + Text( + music['label'], + style: TextStyle( + color: Theme.of(context).colorScheme.outline, + fontSize: + Theme.of(context).textTheme.labelMedium!.fontSize, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], + ) + ], + ), + // TextButton(onPressed: () {}, child: Text('123')) + ), + ), + ); default: return const SizedBox( width: double.infinity, From eae39c480c9f99887695f1755fd6acb36f5720bc Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sat, 18 May 2024 19:29:57 +0800 Subject: [PATCH 10/36] =?UTF-8?q?mod:=20playInit=20autoplay=20=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/video/detail/controller.dart | 4 ++-- lib/pages/video/detail/view.dart | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/pages/video/detail/controller.dart b/lib/pages/video/detail/controller.dart index 722af317..38c62d7e 100644 --- a/lib/pages/video/detail/controller.dart +++ b/lib/pages/video/detail/controller.dart @@ -233,7 +233,7 @@ class VideoDetailController extends GetxController audio, seekToTime, duration, - bool autoplay = true, + bool? autoplay, }) async { /// 设置/恢复 屏幕亮度 if (brightness != null) { @@ -266,7 +266,7 @@ class VideoDetailController extends GetxController cid: cid.value, enableHeart: enableHeart, isFirstTime: isFirstTime, - autoplay: autoplay, + autoplay: autoplay ?? autoPlay.value, ); /// 开启自动全屏时,在player初始化完成后立即传入headerControl diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index 2c35858f..6f751e52 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -176,7 +176,7 @@ class _VideoDetailPageState extends State /// 未开启自动播放时触发播放 Future handlePlay() async { - await vdCtr.playerInit(); + await vdCtr.playerInit(autoplay: true); plPlayerController = vdCtr.plPlayerController; plPlayerController!.addStatusLister(playerListener); vdCtr.autoPlay.value = true; @@ -266,7 +266,7 @@ class _VideoDetailPageState extends State } vdCtr.isFirstTime = false; final bool autoplay = autoPlayEnable; - vdCtr.playerInit(autoplay: autoplay); + vdCtr.playerInit(); /// 未开启自动播放时,未播放跳转下一页返回/播放后跳转下一页返回 vdCtr.autoPlay.value = !vdCtr.isShowCover.value; From ed28e98bbae2d38971ae2ae16c15871e2f8c5c84 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Mon, 20 May 2024 23:45:38 +0800 Subject: [PATCH 11/36] =?UTF-8?q?opt:=20=E6=8E=A8=E8=8D=90=E8=A7=86?= =?UTF-8?q?=E9=A2=91=E6=8B=89=E9=BB=91=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/common/widgets/video_card_v.dart | 37 ++++++++++++++++++++++------ lib/http/video.dart | 10 ++++++-- lib/pages/rcmd/controller.dart | 7 ++++++ lib/pages/rcmd/view.dart | 1 + 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/lib/common/widgets/video_card_v.dart b/lib/common/widgets/video_card_v.dart index 7b56152f..14476cdf 100644 --- a/lib/common/widgets/video_card_v.dart +++ b/lib/common/widgets/video_card_v.dart @@ -20,11 +20,13 @@ import 'network_img_layer.dart'; class VideoCardV extends StatelessWidget { final dynamic videoItem; final int crossAxisCount; + final Function? blockUserCb; const VideoCardV({ Key? key, required this.videoItem, required this.crossAxisCount, + this.blockUserCb, }) : super(key: key); bool isStringNumeric(String str) { @@ -157,7 +159,11 @@ class VideoCardV extends StatelessWidget { ); }), ), - VideoContent(videoItem: videoItem, crossAxisCount: crossAxisCount) + VideoContent( + videoItem: videoItem, + crossAxisCount: crossAxisCount, + blockUserCb: blockUserCb, + ) ], ), ); @@ -167,9 +173,14 @@ class VideoCardV extends StatelessWidget { class VideoContent extends StatelessWidget { final dynamic videoItem; final int crossAxisCount; - const VideoContent( - {Key? key, required this.videoItem, required this.crossAxisCount}) - : super(key: key); + final Function? blockUserCb; + + const VideoContent({ + Key? key, + required this.videoItem, + required this.crossAxisCount, + this.blockUserCb, + }) : super(key: key); Widget _buildBadge(String text, String type, [double fs = 12]) { return PBadge( @@ -241,7 +252,10 @@ class VideoContent extends StatelessWidget { useRootNavigator: true, isScrollControlled: true, builder: (context) { - return MorePanel(videoItem: videoItem); + return MorePanel( + videoItem: videoItem, + blockUserCb: blockUserCb, + ); }, ); }, @@ -297,11 +311,17 @@ class VideoStat extends StatelessWidget { class MorePanel extends StatelessWidget { final dynamic videoItem; - const MorePanel({super.key, required this.videoItem}); + final Function? blockUserCb; + const MorePanel({ + super.key, + required this.videoItem, + this.blockUserCb, + }); Future menuActionHandler(String type) async { switch (type) { case 'block': + Get.back(); blockUser(); break; case 'watchLater': @@ -338,7 +358,10 @@ class MorePanel extends StatelessWidget { reSrc: 11, ); SmartDialog.dismiss(); - SmartDialog.showToast(res['msg'] ?? '成功'); + if (res['status']) { + blockUserCb?.call(videoItem.owner.mid); + } + SmartDialog.showToast(res['msg']); }, child: const Text('确认'), ) diff --git a/lib/http/video.dart b/lib/http/video.dart index bf5921d6..7c1d9ba6 100644 --- a/lib/http/video.dart +++ b/lib/http/video.dart @@ -387,9 +387,15 @@ class VideoHttp { 'csrf': await Request.getCsrf(), }); if (res.data['code'] == 0) { - return {'status': true, 'data': res.data['data']}; + if (act == 5) { + List blackMidsList = + setting.get(SettingBoxKey.blackMidsList, defaultValue: [-1]); + blackMidsList.add(mid); + setting.put(SettingBoxKey.blackMidsList, blackMidsList); + } + return {'status': true, 'data': res.data['data'], 'msg': '成功'}; } else { - return {'status': false, 'data': []}; + return {'status': false, 'data': [], 'msg': res.data['message']}; } } diff --git a/lib/pages/rcmd/controller.dart b/lib/pages/rcmd/controller.dart index 28ff055b..2d606b12 100644 --- a/lib/pages/rcmd/controller.dart +++ b/lib/pages/rcmd/controller.dart @@ -1,4 +1,5 @@ import 'package:flutter/cupertino.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:hive/hive.dart'; import 'package:pilipala/http/video.dart'; @@ -106,4 +107,10 @@ class RcmdController extends GetxController { duration: const Duration(milliseconds: 500), curve: Curves.easeInOut); } } + + void blockUserCb(mid) { + videoList.removeWhere((e) => e.owner.mid == mid); + videoList.refresh(); + SmartDialog.showToast('已移除相关视频'); + } } diff --git a/lib/pages/rcmd/view.dart b/lib/pages/rcmd/view.dart index 67567870..29a8d469 100644 --- a/lib/pages/rcmd/view.dart +++ b/lib/pages/rcmd/view.dart @@ -146,6 +146,7 @@ class _RcmdPageState extends State ? VideoCardV( videoItem: videoList[index], crossAxisCount: crossAxisCount, + blockUserCb: (mid) => ctr.blockUserCb(mid), ) : const VideoCardVSkeleton(); }, From 2dfd2d4dc16d42ffbf42d6ed9c112066c8177e2e Mon Sep 17 00:00:00 2001 From: guozhigq Date: Thu, 23 May 2024 00:32:59 +0800 Subject: [PATCH 12/36] =?UTF-8?q?opt:=20=E8=A7=86=E9=A2=91=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E6=A0=8F=E5=AE=89=E5=85=A8=E5=8C=BA=E5=9F=9F=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/plugin/pl_player/view.dart | 46 +++++++++---------- lib/plugin/pl_player/widgets/app_bar_ani.dart | 4 ++ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index cff4611a..ff0888be 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -768,37 +768,33 @@ class _PLVideoPlayerState extends State ), // 头部、底部控制条 - SafeArea( - top: false, - bottom: false, - child: Obx( - () => Column( - children: [ - if (widget.headerControl != null || _.headerControl != null) - ClipRect( - child: AppBarAni( - controller: animationController, - visible: !_.controlsLock.value && _.showControls.value, - position: 'top', - child: widget.headerControl ?? _.headerControl!, - ), - ), - const Spacer(), + Obx( + () => Column( + children: [ + if (widget.headerControl != null || _.headerControl != null) ClipRect( child: AppBarAni( controller: animationController, visible: !_.controlsLock.value && _.showControls.value, - position: 'bottom', - child: widget.bottomControl ?? - BottomControl( - controller: widget.controller, - triggerFullScreen: _.triggerFullScreen, - buildBottomControl: buildBottomControl(), - ), + position: 'top', + child: widget.headerControl ?? _.headerControl!, ), ), - ], - ), + const Spacer(), + ClipRect( + child: AppBarAni( + controller: animationController, + visible: !_.controlsLock.value && _.showControls.value, + position: 'bottom', + child: widget.bottomControl ?? + BottomControl( + controller: widget.controller, + triggerFullScreen: _.triggerFullScreen, + buildBottomControl: buildBottomControl(), + ), + ), + ), + ], ), ), diff --git a/lib/plugin/pl_player/widgets/app_bar_ani.dart b/lib/plugin/pl_player/widgets/app_bar_ani.dart index 53eaad16..a1db5807 100644 --- a/lib/plugin/pl_player/widgets/app_bar_ani.dart +++ b/lib/plugin/pl_player/widgets/app_bar_ani.dart @@ -29,6 +29,10 @@ class AppBarAni extends StatelessWidget implements PreferredSizeWidget { curve: Curves.linear, )), child: Container( + padding: EdgeInsets.only( + left: MediaQuery.of(context).padding.left, + right: MediaQuery.of(context).padding.right, + ), decoration: BoxDecoration( gradient: position! == 'top' ? const LinearGradient( From c387cb83e7809c36456c85a82ccb1fa930d2a19f Mon Sep 17 00:00:00 2001 From: guozhigq Date: Fri, 24 May 2024 23:54:25 +0800 Subject: [PATCH 13/36] =?UTF-8?q?mod:=20=E6=94=B6=E8=97=8F=E5=A4=B9?= =?UTF-8?q?=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/media/view.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/media/view.dart b/lib/pages/media/view.dart index 6541680a..cc413e59 100644 --- a/lib/pages/media/view.dart +++ b/lib/pages/media/view.dart @@ -105,7 +105,7 @@ class _MediaPageState extends State color: Theme.of(context).dividerColor.withOpacity(0.1), ), ListTile( - onTap: () {}, + onTap: () => Get.toNamed('/fav'), leading: null, dense: true, title: Padding( From 732beb38a71a20cb2980d3c40d473b4b64b68fd1 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sat, 25 May 2024 15:31:00 +0800 Subject: [PATCH 14/36] =?UTF-8?q?opt:=20=E8=AF=84=E8=AE=BA=E5=8C=BA?= =?UTF-8?q?=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/reply/widgets/reply_item.dart | 41 ++++++------------- lib/utils/app_scheme.dart | 24 +++++++++-- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/lib/pages/video/detail/reply/widgets/reply_item.dart b/lib/pages/video/detail/reply/widgets/reply_item.dart index 4ff13065..55c16f7d 100644 --- a/lib/pages/video/detail/reply/widgets/reply_item.dart +++ b/lib/pages/video/detail/reply/widgets/reply_item.dart @@ -1,3 +1,4 @@ +import 'package:appscheme/appscheme.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -11,6 +12,7 @@ import 'package:pilipala/models/video/reply/item.dart'; import 'package:pilipala/pages/preview/index.dart'; import 'package:pilipala/pages/video/detail/index.dart'; import 'package:pilipala/pages/video/detail/reply_new/index.dart'; +import 'package:pilipala/utils/app_scheme.dart'; import 'package:pilipala/utils/feed_back.dart'; import 'package:pilipala/utils/id_utils.dart'; import 'package:pilipala/utils/storage.dart'; @@ -643,34 +645,17 @@ InlineSpan buildContent( '', ); } else { - final String pathSegment = Uri.parse(matchStr).path; - Map matchRes = IdUtils.matchAvorBv(input: pathSegment); - List matchKeys = matchRes.keys.toList(); - if (matchKeys.isNotEmpty) { - UrlUtils.matchUrlPush( - matchRes.containsKey('AV') - ? matchRes['AV']! as int - : matchRes['BV'], - title, - matchStr, - ); - } else { - final String redirectUrl = - await UrlUtils.parseRedirectUrl(matchStr); - // if (redirectUrl == matchStr) { - // Clipboard.setData(ClipboardData(text: matchStr)); - // SmartDialog.showToast('地址可能有误'); - // return; - // } - Get.toNamed( - '/webview', - parameters: { - 'url': redirectUrl, - 'type': 'url', - 'pageTitle': title - }, - ); - } + Uri uri = Uri.parse(matchStr); + SchemeEntity scheme = SchemeEntity( + scheme: uri.scheme, + host: uri.host, + port: uri.port, + path: uri.path, + query: uri.queryParameters, + source: '', + dataString: matchStr, + ); + PiliSchame.fullPathPush(scheme); } } else { if (appUrlSchema.startsWith('bilibili://search')) { diff --git a/lib/utils/app_scheme.dart b/lib/utils/app_scheme.dart index 8502dc7f..a83b7809 100644 --- a/lib/utils/app_scheme.dart +++ b/lib/utils/app_scheme.dart @@ -95,7 +95,7 @@ class PiliSchame { } } if (scheme == 'https') { - _fullPathPush(value); + fullPathPush(value); } } @@ -126,7 +126,7 @@ class PiliSchame { } } - static Future _fullPathPush(SchemeEntity value) async { + static Future fullPathPush(SchemeEntity value) async { // https://m.bilibili.com/bangumi/play/ss39708 // https | m.bilibili.com | /bangumi/play/ss39708 // final String scheme = value.scheme!; @@ -135,8 +135,6 @@ class PiliSchame { Map? query = value.query; RegExp regExp = RegExp(r'^((www\.)|(m\.))?bilibili\.com$'); if (regExp.hasMatch(host)) { - print('bilibili.com host: $host'); - print('bilibili.com path: $path'); final String lastPathSegment = path!.split('/').last; if (path.startsWith('/video')) { Map matchRes = IdUtils.matchAvorBv(input: path); @@ -236,6 +234,24 @@ class PiliSchame { print('个人空间'); Get.toNamed('/member?mid=$area', arguments: {'face': ''}); break; + default: + final Map map = + IdUtils.matchAvorBv(input: area.split('?').first); + if (map.containsKey('AV')) { + _videoPush(map['AV']! as int, null); + } else if (map.containsKey('BV')) { + _videoPush(null, map['BV'] as String); + } else { + Get.toNamed( + '/webview', + parameters: { + 'url': value.dataString ?? "", + 'type': 'url', + 'pageTitle': '' + }, + ); + } + break; } } } From 95685c4fdf04e8e0c725c7257755b641d7ca169f Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sat, 25 May 2024 16:16:23 +0800 Subject: [PATCH 15/36] =?UTF-8?q?mod:=20=E5=8E=86=E5=8F=B2=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=90=9C=E7=B4=A2=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/history/widgets/item.dart | 2 +- lib/pages/history_search/controller.dart | 12 +- lib/pages/history_search/view.dart | 150 ++++++++--------------- 3 files changed, 59 insertions(+), 105 deletions(-) diff --git a/lib/pages/history/widgets/item.dart b/lib/pages/history/widgets/item.dart index 00ebd511..baebfedb 100644 --- a/lib/pages/history/widgets/item.dart +++ b/lib/pages/history/widgets/item.dart @@ -244,7 +244,7 @@ class HistoryItem extends StatelessWidget { ), ), ), - videoItem.progress != 0 + videoItem.progress != 0 && videoItem.duration != 0 ? Positioned( left: 3, right: 3, diff --git a/lib/pages/history_search/controller.dart b/lib/pages/history_search/controller.dart index 90ac7a02..a6c79e6a 100644 --- a/lib/pages/history_search/controller.dart +++ b/lib/pages/history_search/controller.dart @@ -10,9 +10,8 @@ class HistorySearchController extends GetxController { final FocusNode searchFocusNode = FocusNode(); RxString searchKeyWord = ''.obs; String hintText = '搜索'; - RxString loadingStatus = 'init'.obs; + RxBool loadingStatus = false.obs; RxString loadingText = '加载中...'.obs; - bool hasRequest = false; late int mid; RxString uname = ''.obs; int pn = 1; @@ -36,8 +35,7 @@ class HistorySearchController extends GetxController { // 提交搜索内容 void submit() { - loadingStatus.value = 'loading'; - if (hasRequest) { + if (!loadingStatus.value) { pn = 1; searchHistories(); } @@ -48,6 +46,7 @@ class HistorySearchController extends GetxController { if (type == 'onLoad' && loadingText.value == '没有更多了') { return; } + loadingStatus.value = true; var res = await UserHttp.searchHistory( pn: pn, keyword: controller.value.text, @@ -63,9 +62,8 @@ class HistorySearchController extends GetxController { loadingText.value = '没有更多了'; } pn += 1; - hasRequest = true; } - loadingStatus.value = 'finish'; + loadingStatus.value = false; return res; } @@ -86,6 +84,6 @@ class HistorySearchController extends GetxController { historyList.removeWhere((e) => e.kid == kid); SmartDialog.showToast(res['msg']); } - loadingStatus.value = 'finish'; + // loadingStatus.value = fasle; } } diff --git a/lib/pages/history_search/view.dart b/lib/pages/history_search/view.dart index 5bde691d..f5bcae64 100644 --- a/lib/pages/history_search/view.dart +++ b/lib/pages/history_search/view.dart @@ -2,7 +2,6 @@ import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:pilipala/common/skeleton/video_card_h.dart'; -import 'package:pilipala/common/widgets/http_error.dart'; import 'package:pilipala/common/widgets/no_data.dart'; import 'package:pilipala/pages/history/widgets/item.dart'; @@ -16,20 +15,19 @@ class HistorySearchPage extends StatefulWidget { } class _HistorySearchPageState extends State { - final HistorySearchController _historySearchCtr = - Get.put(HistorySearchController()); + final HistorySearchController _hisCtr = Get.put(HistorySearchController()); late ScrollController scrollController; @override void initState() { super.initState(); - scrollController = _historySearchCtr.scrollController; + scrollController = _hisCtr.scrollController; scrollController.addListener( () { if (scrollController.position.pixels >= scrollController.position.maxScrollExtent - 300) { EasyThrottle.throttle('history', const Duration(seconds: 1), () { - _historySearchCtr.onLoad(); + _hisCtr.onLoad(); }); } }, @@ -50,19 +48,19 @@ class _HistorySearchPageState extends State { titleSpacing: 0, actions: [ IconButton( - onPressed: () => _historySearchCtr.submit(), + onPressed: () => _hisCtr.submit(), icon: const Icon(Icons.search_outlined, size: 22)), const SizedBox(width: 10) ], title: Obx( () => TextField( autofocus: true, - focusNode: _historySearchCtr.searchFocusNode, - controller: _historySearchCtr.controller.value, + focusNode: _hisCtr.searchFocusNode, + controller: _hisCtr.controller.value, textInputAction: TextInputAction.search, - onChanged: (value) => _historySearchCtr.onChange(value), + onChanged: (value) => _hisCtr.onChange(value), decoration: InputDecoration( - hintText: _historySearchCtr.hintText, + hintText: _hisCtr.hintText, border: InputBorder.none, suffixIcon: IconButton( icon: Icon( @@ -70,103 +68,61 @@ class _HistorySearchPageState extends State { size: 22, color: Theme.of(context).colorScheme.outline, ), - onPressed: () => _historySearchCtr.onClear(), + onPressed: () => _hisCtr.onClear(), ), ), - onSubmitted: (String value) => _historySearchCtr.submit(), + onSubmitted: (String value) => _hisCtr.submit(), ), ), ), body: Obx( - () => Column( - children: _historySearchCtr.loadingStatus.value == 'init' - ? [const SizedBox()] - : [ - Expanded( - child: FutureBuilder( - future: _historySearchCtr.searchHistories(), - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - Map data = snapshot.data as Map; - if (data['status']) { - return Obx( - () => _historySearchCtr.historyList.isNotEmpty - ? ListView.builder( - controller: scrollController, - itemCount: - _historySearchCtr.historyList.length + - 1, - itemBuilder: (context, index) { - if (index == - _historySearchCtr - .historyList.length) { - return Container( - height: MediaQuery.of(context) - .padding - .bottom + - 60, - padding: EdgeInsets.only( - bottom: MediaQuery.of(context) - .padding - .bottom), - child: Center( - child: Obx( - () => Text( - _historySearchCtr - .loadingText.value, - style: TextStyle( - color: Theme.of(context) - .colorScheme - .outline, - fontSize: 13), - ), - ), - ), - ); - } else { - return HistoryItem( - videoItem: _historySearchCtr - .historyList[index], - ctr: _historySearchCtr, - onChoose: null, - onUpdateMultiple: () => null, - ); - } - }, - ) - : _historySearchCtr.loadingStatus.value == - 'loading' - ? const SizedBox(child: Text('加载中...')) - : const CustomScrollView( - slivers: [ - NoData(), - ], - ), - ); - } else { - return CustomScrollView( - slivers: [ - HttpError( - errMsg: data['msg'], - fn: () => setState(() {}), - ) - ], - ); - } + () { + return _hisCtr.loadingStatus.value && _hisCtr.historyList.isEmpty + ? ListView.builder( + itemCount: 10, + itemBuilder: (context, index) { + return const VideoCardHSkeleton(); + }, + ) + : _hisCtr.historyList.isNotEmpty + ? ListView.builder( + controller: scrollController, + itemCount: _hisCtr.historyList.length + 1, + itemBuilder: (context, index) { + if (index == _hisCtr.historyList.length) { + return Container( + height: MediaQuery.of(context).padding.bottom + 60, + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).padding.bottom), + child: Center( + child: Obx( + () => Text( + _hisCtr.loadingText.value, + style: TextStyle( + color: + Theme.of(context).colorScheme.outline, + fontSize: 13, + ), + ), + ), + ), + ); } else { - // 骨架屏 - return ListView.builder( - itemCount: 10, - itemBuilder: (context, index) { - return const VideoCardHSkeleton(); - }, + return HistoryItem( + videoItem: _hisCtr.historyList[index], + ctr: _hisCtr, + onChoose: null, + onUpdateMultiple: () => null, ); } }, - ), - ), - ], - ), + ) + : const CustomScrollView( + slivers: [ + NoData(), + ], + ); + }, ), ); } From 1cefdb68b7692833acbe561865a8793af21294c0 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sat, 25 May 2024 16:38:16 +0800 Subject: [PATCH 16/36] =?UTF-8?q?opt:=20=E9=AA=A8=E6=9E=B6=E5=B1=8F?= =?UTF-8?q?=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/fav/view.dart | 8 +++++++- lib/pages/subscription/view.dart | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/pages/fav/view.dart b/lib/pages/fav/view.dart index b8d37f50..4f48213e 100644 --- a/lib/pages/fav/view.dart +++ b/lib/pages/fav/view.dart @@ -1,6 +1,7 @@ import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:pilipala/common/skeleton/video_card_h.dart'; import 'package:pilipala/common/widgets/http_error.dart'; import 'package:pilipala/pages/fav/index.dart'; import 'package:pilipala/pages/fav/widgets/item.dart'; @@ -93,7 +94,12 @@ class _FavPageState extends State { } } else { // 骨架屏 - return const Text('请求中'); + return ListView.builder( + itemBuilder: (context, index) { + return const VideoCardHSkeleton(); + }, + itemCount: 10, + ); } }, ), diff --git a/lib/pages/subscription/view.dart b/lib/pages/subscription/view.dart index 5e6e4664..bcc03cc3 100644 --- a/lib/pages/subscription/view.dart +++ b/lib/pages/subscription/view.dart @@ -1,6 +1,7 @@ import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:pilipala/common/skeleton/video_card_h.dart'; import 'package:pilipala/common/widgets/http_error.dart'; import 'package:pilipala/utils/route_push.dart'; import 'controller.dart'; @@ -87,7 +88,12 @@ class _SubPageState extends State { } } else { // 骨架屏 - return const Text('请求中'); + return ListView.builder( + itemBuilder: (context, index) { + return const VideoCardHSkeleton(); + }, + itemCount: 10, + ); } }, ), From d6e24096e0197e389122f463eaf31f075306272b Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sun, 26 May 2024 15:48:28 +0800 Subject: [PATCH 17/36] =?UTF-8?q?opt:=20=E8=A7=86=E9=A2=91=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E9=A1=B5Hero=E5=8A=A8=E7=94=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/video/detail/view.dart | 167 +++++++++++++++---------------- 1 file changed, 78 insertions(+), 89 deletions(-) diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index 6f751e52..bf156c71 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -525,11 +525,10 @@ class _VideoDetailPageState extends State Scaffold( resizeToAvoidBottomInset: false, key: vdCtr.scaffoldKey, - backgroundColor: Colors.black, appBar: PreferredSize( preferredSize: const Size.fromHeight(0), child: AppBar( - backgroundColor: Colors.transparent, + backgroundColor: Colors.black, elevation: 0, ), ), @@ -559,8 +558,7 @@ class _VideoDetailPageState extends State } return SliverAppBar( automaticallyImplyLeading: false, - // 假装使用一个非空变量,避免Obx检测不到而罢工 - pinned: vdCtr.autoPlay.value, + pinned: true, elevation: 0, scrolledUnderElevation: 0, forceElevated: innerBoxIsScrolled, @@ -568,47 +566,42 @@ class _VideoDetailPageState extends State backgroundColor: Colors.black, flexibleSpace: FlexibleSpaceBar( background: PopScope( - canPop: plPlayerController?.isFullScreen.value != - true, - onPopInvoked: (bool didPop) { - if (plPlayerController?.isFullScreen.value == - true) { - plPlayerController! - .triggerFullScreen(status: false); - } - if (MediaQuery.of(context).orientation == - Orientation.landscape) { - verticalScreen(); - } - }, - child: LayoutBuilder( - builder: (BuildContext context, - BoxConstraints boxConstraints) { - return Stack( - children: [ - if (isShowing) - Padding( - padding: EdgeInsets.only(top: 0), - child: videoPlayerPanel, - ), + canPop: + plPlayerController?.isFullScreen.value != true, + onPopInvoked: (bool didPop) { + if (plPlayerController?.isFullScreen.value == + true) { + plPlayerController! + .triggerFullScreen(status: false); + } + if (MediaQuery.of(context).orientation == + Orientation.landscape) { + verticalScreen(); + } + }, + child: Hero( + tag: heroTag, + child: Stack( + children: [ + if (isShowing) videoPlayerPanel, - /// 关闭自动播放时 手动播放 - Obx( - () => Visibility( - visible: !vdCtr.autoPlay.value && - vdCtr.isShowCover.value, - child: Positioned( - top: 0, - left: 0, - right: 0, - child: handlePlayPanel(), - ), - ), + /// 关闭自动播放时 手动播放 + Obx( + () => Visibility( + visible: !vdCtr.autoPlay.value && + vdCtr.isShowCover.value, + child: Positioned( + top: 0, + left: 0, + right: 0, + child: handlePlayPanel(), ), - ], - ); - }, - )), + ), + ), + ], + ), + ), + ), ), ); }, @@ -627,55 +620,51 @@ class _VideoDetailPageState extends State : pinnedHeaderHeight; }, onlyOneScrollInBody: true, - body: ColoredBox( - key: Key(heroTag), - color: Theme.of(context).colorScheme.background, - child: Column( - children: [ - tabbarBuild(), - Expanded( - child: TabBarView( - controller: vdCtr.tabCtr, - children: [ - Builder( - builder: (BuildContext context) { - return CustomScrollView( - key: const PageStorageKey('简介'), - slivers: [ - if (vdCtr.videoType == SearchType.video) ...[ - VideoIntroPanel(bvid: vdCtr.bvid), - ] else if (vdCtr.videoType == - SearchType.media_bangumi) ...[ - Obx(() => BangumiIntroPanel( - cid: vdCtr.cid.value)), - ], - SliverToBoxAdapter( - child: Divider( - indent: 12, - endIndent: 12, - color: Theme.of(context) - .dividerColor - .withOpacity(0.06), - ), - ), - if (vdCtr.videoType == SearchType.video && - vdCtr.enableRelatedVideo) - const RelatedVideoPanel(), + body: Column( + children: [ + tabbarBuild(), + Expanded( + child: TabBarView( + controller: vdCtr.tabCtr, + children: [ + Builder( + builder: (BuildContext context) { + return CustomScrollView( + key: const PageStorageKey('简介'), + slivers: [ + if (vdCtr.videoType == SearchType.video) ...[ + VideoIntroPanel(bvid: vdCtr.bvid), + ] else if (vdCtr.videoType == + SearchType.media_bangumi) ...[ + Obx(() => + BangumiIntroPanel(cid: vdCtr.cid.value)), ], - ); - }, + SliverToBoxAdapter( + child: Divider( + indent: 12, + endIndent: 12, + color: Theme.of(context) + .dividerColor + .withOpacity(0.06), + ), + ), + if (vdCtr.videoType == SearchType.video && + vdCtr.enableRelatedVideo) + const RelatedVideoPanel(), + ], + ); + }, + ), + Obx( + () => VideoReplyPanel( + bvid: vdCtr.bvid, + oid: vdCtr.oid.value, ), - Obx( - () => VideoReplyPanel( - bvid: vdCtr.bvid, - oid: vdCtr.oid.value, - ), - ) - ], - ), + ) + ], ), - ], - ), + ), + ], ), ), ), From 5c0edf873b8c1e959041e563c0598bac8c8afa0f Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sun, 26 May 2024 16:26:39 +0800 Subject: [PATCH 18/36] =?UTF-8?q?fix:=20=E5=A4=96=E9=93=BE=E8=B7=B3?= =?UTF-8?q?=E8=BD=AC=20pic=20null?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/utils/url_utils.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/utils/url_utils.dart b/lib/utils/url_utils.dart index 99886e09..573f9f9d 100644 --- a/lib/utils/url_utils.dart +++ b/lib/utils/url_utils.dart @@ -44,7 +44,7 @@ class UrlUtils { final String bv = matchRes['BV']; final Map res = await SearchHttp.ab2cWithPic(bvid: bv); final int cid = res['cid']; - final String pic = res['pic']; + final String? pic = res['pic']; final String heroTag = Utils.makeHeroTag(bv); await Get.toNamed( '/video?bvid=$bv&cid=$cid', From 63d5752d3e797f53b1db7c327952bc94ab9ca06d Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sun, 26 May 2024 17:30:42 +0800 Subject: [PATCH 19/36] =?UTF-8?q?fix:=20=E8=BF=9E=E7=BB=AD=E5=BF=AB?= =?UTF-8?q?=E8=BF=9B=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/plugin/pl_player/view.dart | 4 ++-- lib/plugin/pl_player/widgets/backward_seek.dart | 7 +++++++ lib/plugin/pl_player/widgets/forward_seek.dart | 7 +++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index ff0888be..df68da2f 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -935,7 +935,7 @@ class _PLVideoPlayerState extends State begin: 0.0, end: _hideSeekBackwardButton.value ? 0.0 : 1.0, ), - duration: const Duration(milliseconds: 500), + duration: const Duration(milliseconds: 200), builder: (BuildContext context, double value, Widget? child) => Opacity( @@ -978,7 +978,7 @@ class _PLVideoPlayerState extends State begin: 0.0, end: _hideSeekForwardButton.value ? 0.0 : 1.0, ), - duration: const Duration(milliseconds: 500), + duration: const Duration(milliseconds: 200), builder: (BuildContext context, double value, Widget? child) => Opacity( diff --git a/lib/plugin/pl_player/widgets/backward_seek.dart b/lib/plugin/pl_player/widgets/backward_seek.dart index 35de0ae6..8fddf80a 100644 --- a/lib/plugin/pl_player/widgets/backward_seek.dart +++ b/lib/plugin/pl_player/widgets/backward_seek.dart @@ -20,6 +20,13 @@ class BackwardSeekIndicatorState extends State { Timer? timer; + @override + void setState(VoidCallback fn) { + if (mounted) { + super.setState(fn); + } + } + @override void initState() { super.initState(); diff --git a/lib/plugin/pl_player/widgets/forward_seek.dart b/lib/plugin/pl_player/widgets/forward_seek.dart index 43ddd322..7e3886ce 100644 --- a/lib/plugin/pl_player/widgets/forward_seek.dart +++ b/lib/plugin/pl_player/widgets/forward_seek.dart @@ -20,6 +20,13 @@ class ForwardSeekIndicatorState extends State { Timer? timer; + @override + void setState(VoidCallback fn) { + if (mounted) { + super.setState(fn); + } + } + @override void initState() { super.initState(); From 4aa47f4a7bd31cd3085f9200b692884685bb9b41 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sun, 26 May 2024 23:18:37 +0800 Subject: [PATCH 20/36] =?UTF-8?q?fix:=20pip=E8=BF=9B=E5=85=A5=20=E8=AF=84?= =?UTF-8?q?=E8=AE=BA=E5=8C=BA=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/video/detail/reply/controller.dart | 2 -- lib/pages/video/detail/reply/view.dart | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/pages/video/detail/reply/controller.dart b/lib/pages/video/detail/reply/controller.dart index b718c840..c1929434 100644 --- a/lib/pages/video/detail/reply/controller.dart +++ b/lib/pages/video/detail/reply/controller.dart @@ -1,5 +1,4 @@ import 'package:easy_debounce/easy_throttle.dart'; -import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:hive/hive.dart'; import 'package:pilipala/http/reply.dart'; @@ -15,7 +14,6 @@ class VideoReplyController extends GetxController { this.rpid, this.replyLevel, ); - final ScrollController scrollController = ScrollController(); // 视频aid 请求时使用的oid int? aid; // 层级 2为楼中楼 diff --git a/lib/pages/video/detail/reply/view.dart b/lib/pages/video/detail/reply/view.dart index 4c533647..653fe7e0 100644 --- a/lib/pages/video/detail/reply/view.dart +++ b/lib/pages/video/detail/reply/view.dart @@ -67,13 +67,12 @@ class _VideoReplyPanelState extends State vsync: this, duration: const Duration(milliseconds: 300)); _futureBuilderFuture = _videoReplyController.queryReplyList(); - + scrollController = ScrollController(); fabAnimationCtr.forward(); scrollListener(); } void scrollListener() { - scrollController = _videoReplyController.scrollController; scrollController.addListener( () { if (scrollController.position.pixels >= @@ -185,7 +184,8 @@ class _VideoReplyPanelState extends State builder: (BuildContext context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { var data = snapshot.data; - if (data['status']) { + if (_videoReplyController.replyList.isNotEmpty || + (data && data['status'])) { // 请求成功 return Obx( () => _videoReplyController.isLoadingMore && From 1c6047a3268ab1d01a4a0059912c2b5604aeb267 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Mon, 27 May 2024 23:54:33 +0800 Subject: [PATCH 21/36] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 470e9a35..228d17bb 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ QQ频道: https://pd.qq.com/s/365esodk3 - [x] 音质选择(视视频而定) - [x] 解码格式选择(视视频而定) - [x] 弹幕 - - [ ] 字幕 + - [x] 字幕 - [x] 记忆播放 - [x] 视频比例:高度/宽度适应、填充、包含等 From 6b4d24f59566ee12142408b9720809adc23cc86b Mon Sep 17 00:00:00 2001 From: guozhigq Date: Tue, 28 May 2024 22:58:51 +0800 Subject: [PATCH 22/36] =?UTF-8?q?opt:=20=E5=8A=A8=E6=80=81=E9=A1=B5up?= =?UTF-8?q?=E4=B8=BB=E7=82=B9=E5=87=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/dynamics/widgets/up_panel.dart | 54 +++++++++++++----------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/lib/pages/dynamics/widgets/up_panel.dart b/lib/pages/dynamics/widgets/up_panel.dart index fd0ae642..ee522cbb 100644 --- a/lib/pages/dynamics/widgets/up_panel.dart +++ b/lib/pages/dynamics/widgets/up_panel.dart @@ -1,3 +1,4 @@ +import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; @@ -30,6 +31,31 @@ class _UpPanelState extends State { liveList = widget.upData.liveList!; } + void onClickUp(data, i) { + currentMid = data.mid; + Get.find().mid.value = data.mid; + Get.find().upInfo.value = data; + Get.find().onSelectUp(data.mid); + int liveLen = liveList.length; + int upLen = upList.length; + double itemWidth = contentWidth + itemPadding.horizontal; + double screenWidth = MediaQuery.sizeOf(context).width; + double moveDistance = 0.0; + if (itemWidth * (upList.length + liveList.length) <= screenWidth) { + } else if ((upLen - i - 0.5) * itemWidth > screenWidth / 2) { + moveDistance = (i + liveLen + 0.5) * itemWidth + 46 - screenWidth / 2; + } else { + moveDistance = (upLen + liveLen) * itemWidth + 46 - screenWidth; + } + data.hasUpdate = false; + scrollController.animateTo( + moveDistance, + duration: const Duration(milliseconds: 200), + curve: Curves.linear, + ); + setState(() {}); + } + @override Widget build(BuildContext context) { listFormat(); @@ -120,30 +146,10 @@ class _UpPanelState extends State { onTap: () { feedBack(); if (data.type == 'up') { - currentMid = data.mid; - Get.find().mid.value = data.mid; - Get.find().upInfo.value = data; - Get.find().onSelectUp(data.mid); - int liveLen = liveList.length; - int upLen = upList.length; - double itemWidth = contentWidth + itemPadding.horizontal; - double screenWidth = MediaQuery.sizeOf(context).width; - double moveDistance = 0.0; - if (itemWidth * (upList.length + liveList.length) <= screenWidth) { - } else if ((upLen - i - 0.5) * itemWidth > screenWidth / 2) { - moveDistance = - (i + liveLen + 0.5) * itemWidth + 46 - screenWidth / 2; - } else { - moveDistance = (upLen + liveLen) * itemWidth + 46 - screenWidth; - } - data.hasUpdate = false; - scrollController.animateTo( - moveDistance, - duration: const Duration(milliseconds: 500), - curve: Curves.easeInOut, - ); - - setState(() {}); + EasyThrottle.throttle('follow', const Duration(milliseconds: 300), + () { + onClickUp(data, i); + }); } else if (data.type == 'live') { LiveItemModel liveItem = LiveItemModel.fromJson({ 'title': data.title, From eef9e3ae9eb3713a14b55fd04f0880132d623beb Mon Sep 17 00:00:00 2001 From: guozhigq Date: Thu, 30 May 2024 23:58:42 +0800 Subject: [PATCH 23/36] opt: loading Ani --- assets/loading.json | 1 + assets/trail_loading.json | 1 + lib/pages/video/detail/introduction/view.dart | 12 ++++++------ lib/plugin/pl_player/view.dart | 7 ++++--- pubspec.lock | 8 ++++++++ pubspec.yaml | 8 +++++--- 6 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 assets/loading.json create mode 100644 assets/trail_loading.json diff --git a/assets/loading.json b/assets/loading.json new file mode 100644 index 00000000..38bccbed --- /dev/null +++ b/assets/loading.json @@ -0,0 +1 @@ +{"v":"5.7.11","fr":60,"ip":0,"op":81,"w":1920,"h":1080,"nm":"Loading Dots","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Dot4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":25,"s":[25]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":39,"s":[100]},{"t":55,"s":[25]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":25,"s":[1142,540,0],"to":[0,-6.667,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":39,"s":[1142,500,0],"to":[0,0,0],"ti":[0,-6.667,0]},{"t":55,"s":[1142,540,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-284,92,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":25,"s":[50,50,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":39,"s":[75,75,100]},{"t":55,"s":[50,50,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[120,120],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.0039,0.6157,0.5686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-284,92],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Dot3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":17,"s":[25]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":31,"s":[100]},{"t":47,"s":[25]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":17,"s":[1022,540,0],"to":[0,-6.667,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":31,"s":[1022,500,0],"to":[0,0,0],"ti":[0,-6.667,0]},{"t":47,"s":[1022,540,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-284,92,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":17,"s":[50,50,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":31,"s":[75,75,100]},{"t":47,"s":[50,50,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[120,120],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.0039,0.6157,0.5686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-284,92],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Dot2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":9,"s":[25]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":23,"s":[100]},{"t":39,"s":[25]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":9,"s":[902,540,0],"to":[0,-6.667,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":23,"s":[902,500,0],"to":[0,0,0],"ti":[0,0,0]},{"t":39,"s":[902,540,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-284,92,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":9,"s":[50,50,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":23,"s":[75,75,100]},{"t":39,"s":[50,50,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[120,120],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.0039,0.6157,0.5686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-284,92],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Dot1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[25]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":14,"s":[100]},{"t":30,"s":[25]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[782,540,0],"to":[0,-6.667,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":14,"s":[782,500,0],"to":[0,0,0],"ti":[0,-6.667,0]},{"t":30,"s":[782,540,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-284,92,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[50,50,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":14,"s":[75,75,100]},{"t":30,"s":[50,50,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[120,120],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.0039,0.6157,0.5686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-284,92],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/assets/trail_loading.json b/assets/trail_loading.json new file mode 100644 index 00000000..9fb39ea6 --- /dev/null +++ b/assets/trail_loading.json @@ -0,0 +1 @@ +{"v":"4.6.8","fr":60,"ip":0,"op":106,"w":500,"h":500,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 5","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":20,"s":[0],"e":[360]},{"t":110}]},"p":{"a":0,"k":[251,250,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[10,10]},"p":{"a":0,"k":[0,-100]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0,0,0,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"a":0,"k":[0,0.7294118,1,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":20,"op":620,"st":20,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 4","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":15,"s":[0],"e":[360]},{"t":105}]},"p":{"a":0,"k":[251,250,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[20,20]},"p":{"a":0,"k":[0,-100]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0,0,0,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"a":0,"k":[0,0.7294118,1,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":15,"op":615,"st":15,"bm":0,"sr":1},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 3","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[0],"e":[360]},{"t":100}]},"p":{"a":0,"k":[251,250,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[30,30]},"p":{"a":0,"k":[0,-100]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0,0,0,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"a":0,"k":[0,0.7294118,1,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":10,"op":610,"st":10,"bm":0,"sr":1},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 2","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":5,"s":[0],"e":[360]},{"t":95}]},"p":{"a":0,"k":[251,250,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[40,40]},"p":{"a":0,"k":[0,-100]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0,0,0,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"a":0,"k":[0,0.7294118,1,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":5,"op":605,"st":5,"bm":0,"sr":1},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 1","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[0],"e":[360]},{"t":90}]},"p":{"a":0,"k":[250,250,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":0,"s":[50,50],"e":[40,40]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":84,"s":[40,40],"e":[50,50]},{"t":100}]},"p":{"a":0,"k":[0,-100]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0,0,0,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"a":0,"k":[0,0.7294118,1,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":600,"st":0,"bm":0,"sr":1}]} \ No newline at end of file diff --git a/lib/pages/video/detail/introduction/view.dart b/lib/pages/video/detail/introduction/view.dart index 9103c130..06a026aa 100644 --- a/lib/pages/video/detail/introduction/view.dart +++ b/lib/pages/video/detail/introduction/view.dart @@ -5,6 +5,7 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; +import 'package:lottie/lottie.dart'; import 'package:pilipala/common/constants.dart'; import 'package:pilipala/common/widgets/http_error.dart'; import 'package:pilipala/pages/video/detail/index.dart'; @@ -97,11 +98,14 @@ class _VideoIntroPanelState extends State ); } } else { - return const SliverToBoxAdapter( + return SliverToBoxAdapter( child: SizedBox( height: 100, child: Center( - child: CircularProgressIndicator(), + child: Lottie.asset( + 'assets/loading.json', + width: 200, + ), ), ), ); @@ -595,8 +599,4 @@ class _VideoInfoState extends State with TickerProviderStateMixin { ); }); } - - // Widget StaffPanel(BuildContext context, videoIntroController) { - // return - // } } diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index df68da2f..6508b624 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -7,6 +7,7 @@ import 'package:flutter_volume_controller/flutter_volume_controller.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:get/get.dart'; import 'package:hive/hive.dart'; +import 'package:lottie/lottie.dart'; import 'package:media_kit/media_kit.dart'; import 'package:media_kit_video/media_kit_video.dart'; import 'package:pilipala/models/common/gesture_mode.dart'; @@ -909,9 +910,9 @@ class _PLVideoPlayerState extends State colors: [Colors.black26, Colors.transparent], ), ), - child: Image.asset( - 'assets/images/loading.gif', - height: 25, + child: Lottie.asset( + 'assets/loading.json', + width: 200, ), ), ); diff --git a/pubspec.lock b/pubspec.lock index 8f8a5cae..7ff7ef0d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -846,6 +846,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.2.0" + lottie: + dependency: "direct main" + description: + name: lottie + sha256: "6a24ade5d3d918c306bb1c21a6b9a04aab0489d51a2582522eea820b4093b62b" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.1.2" mailer: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index a269cd6f..10a0f065 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -146,6 +146,7 @@ dependencies: expandable: ^5.0.1 # 投屏 dlna_dart: ^0.0.8 + lottie: ^3.1.2 dev_dependencies: flutter_test: @@ -166,15 +167,15 @@ dev_dependencies: build_runner: ^2.4.8 dependency_overrides: - media_kit: + media_kit: git: url: https://github.com/media-kit/media-kit path: media_kit - media_kit_video: + media_kit_video: git: url: https://github.com/media-kit/media-kit path: media_kit_video - media_kit_libs_video: + media_kit_libs_video: git: url: https://github.com/media-kit/media-kit path: libs/universal/media_kit_libs_video @@ -205,6 +206,7 @@ flutter: # To add assets to your application, add an assets section, like this: assets: + - assets/ - assets/images/ - assets/images/lv/ - assets/images/logo/ From e1572c0962b43cf89fb32b02aeb6ceabdb63960f Mon Sep 17 00:00:00 2001 From: guozhigq Date: Fri, 31 May 2024 23:37:27 +0800 Subject: [PATCH 24/36] =?UTF-8?q?fix:=20=E9=94=81=E5=AE=9A=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E4=B8=8B=E9=81=BF=E5=85=8D=E6=89=8B=E5=8A=BF=E9=80=80?= =?UTF-8?q?=E5=87=BA=E5=85=A8=E5=B1=8F=20issues=20#753?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/plugin/pl_player/view.dart | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index df68da2f..a695e752 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -733,14 +733,18 @@ class _PLVideoPlayerState extends State const double threshold = 7.0; // 滑动阈值 final bool flag = fullScreenGestureMode != FullScreenGestureMode.values.last; - if (dy > _distance.value && dy > threshold) { + if (dy > _distance.value && + dy > threshold && + !_.controlsLock.value) { if (_.isFullScreen.value ^ flag) { lastFullScreenToggleTime = DateTime.now(); // 下滑退出全屏 await widget.controller.triggerFullScreen(status: flag); } _distance.value = 0.0; - } else if (dy < _distance.value && dy < -threshold) { + } else if (dy < _distance.value && + dy < -threshold && + !_.controlsLock.value) { if (!_.isFullScreen.value ^ flag) { lastFullScreenToggleTime = DateTime.now(); // 上滑进入全屏 From 2358ba42e1867b1aa52c7278e10e2fe811455a33 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sat, 1 Jun 2024 00:21:04 +0800 Subject: [PATCH 25/36] opt: pip issues #752 --- lib/pages/video/detail/view.dart | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index bf156c71..fa531684 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -99,7 +99,6 @@ class _VideoDetailPageState extends State fullScreenStatusListener(); if (Platform.isAndroid) { floating = vdCtr.floating!; - autoEnterPip(); } WidgetsBinding.instance.addObserver(this); lifecycleListener(); @@ -128,8 +127,9 @@ class _VideoDetailPageState extends State } // 播放器状态监听 - void playerListener(PlayerStatus? status) async { - playerStatus.value = status!; + void playerListener(PlayerStatus status) async { + playerStatus.value = status; + autoEnterPip(status: status); if (status == PlayerStatus.completed) { // 结束播放退出全屏 if (autoExitFullcreen) { @@ -181,6 +181,7 @@ class _VideoDetailPageState extends State plPlayerController!.addStatusLister(playerListener); vdCtr.autoPlay.value = true; vdCtr.isShowCover.value = false; + autoEnterPip(status: PlayerStatus.playing); } void fullScreenStatusListener() { @@ -287,10 +288,12 @@ class _VideoDetailPageState extends State .subscribe(this, ModalRoute.of(context)! as PageRoute); } - void autoEnterPip() { + void autoEnterPip({PlayerStatus? status}) { final String routePath = Get.currentRoute; if (autoPiP && routePath.startsWith('/video')) { - floating.toggleAutoPip(autoEnter: autoPiP); + floating.toggleAutoPip( + autoEnter: autoPiP && status == PlayerStatus.playing, + ); } } @@ -314,6 +317,15 @@ class _VideoDetailPageState extends State case 'show' || 'restart': plPlayerController?.danmakuController?.clear(); break; + case 'pause': + vdCtr.hiddenReplyReplyPanel(); + if (vdCtr.videoType == SearchType.video) { + videoIntroController.hiddenEpisodeBottomSheet(); + } + if (vdCtr.videoType == SearchType.media_bangumi) { + bangumiIntroController.hiddenEpisodeBottomSheet(); + } + break; } } From bde44af9a0afd283c247c6fac7bcd6eb740eb730 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sat, 1 Jun 2024 22:43:27 +0800 Subject: [PATCH 26/36] opt: main.daat code --- lib/main.dart | 314 ++++++++++++++++++++++++++++---------------------- 1 file changed, 177 insertions(+), 137 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 066bb599..1a2ce989 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -23,7 +23,7 @@ import 'package:pilipala/utils/app_scheme.dart'; import 'package:pilipala/utils/data.dart'; import 'package:pilipala/utils/global_data.dart'; import 'package:pilipala/utils/storage.dart'; -import 'package:media_kit/media_kit.dart'; // Provides [Player], [Media], [Playlist] etc. +import 'package:media_kit/media_kit.dart'; import 'package:pilipala/utils/recommend_filter.dart'; import 'package:catcher_2/catcher_2.dart'; import './services/loggeer.dart'; @@ -31,59 +31,42 @@ import './services/loggeer.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); MediaKit.ensureInitialized(); - SystemChrome.setPreferredOrientations( - [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]) - .then((_) async { - await GStrorage.init(); - await setupServiceLocator(); - clearLogs(); - Request(); - await Request.setCookie(); - RecommendFilter(); + await SystemChrome.setPreferredOrientations( + [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); + await GStrorage.init(); + await setupServiceLocator(); + clearLogs(); + Request(); + await Request.setCookie(); - // 异常捕获 logo记录 - final Catcher2Options debugConfig = Catcher2Options( - SilentReportMode(), - [ - FileHandler(await getLogsPath()), - ConsoleHandler( - enableDeviceParameters: false, - enableApplicationParameters: false, - ) - ], - ); + // 异常捕获 logo记录 + final Catcher2Options releaseConfig = Catcher2Options( + SilentReportMode(), + [FileHandler(await getLogsPath())], + ); - final Catcher2Options releaseConfig = Catcher2Options( - SilentReportMode(), - [FileHandler(await getLogsPath())], - ); + Catcher2( + releaseConfig: releaseConfig, + runAppFunction: () { + runApp(const MyApp()); + }, + ); - Catcher2( - debugConfig: debugConfig, - releaseConfig: releaseConfig, - runAppFunction: () { - runApp(const MyApp()); - }, - ); - - // 小白条、导航栏沉浸 - if (Platform.isAndroid) { - final androidInfo = await DeviceInfoPlugin().androidInfo; - if (androidInfo.version.sdkInt >= 29) { - SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); - } - SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( - systemNavigationBarColor: Colors.transparent, - systemNavigationBarDividerColor: Colors.transparent, - statusBarColor: Colors.transparent, - )); + // 小白条、导航栏沉浸 + if (Platform.isAndroid) { + final androidInfo = await DeviceInfoPlugin().androidInfo; + if (androidInfo.version.sdkInt >= 29) { + SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); } + SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( + systemNavigationBarColor: Colors.transparent, + systemNavigationBarDividerColor: Colors.transparent, + statusBarColor: Colors.transparent, + )); + } - Data.init(); - GlobalData(); - PiliSchame.init(); - DisableBatteryOpt(); - }); + PiliSchame.init(); + DisableBatteryOpt(); } class MyApp extends StatelessWidget { @@ -124,6 +107,39 @@ class MyApp extends StatelessWidget { } catch (_) {} } + if (Platform.isAndroid) { + return AndroidApp( + brandColor: brandColor, + isDynamicColor: isDynamicColor, + currentThemeValue: currentThemeValue, + textScale: textScale, + ); + } else { + return OtherApp( + brandColor: brandColor, + currentThemeValue: currentThemeValue, + textScale: textScale, + ); + } + } +} + +class AndroidApp extends StatelessWidget { + const AndroidApp({ + super.key, + required this.brandColor, + required this.isDynamicColor, + required this.currentThemeValue, + required this.textScale, + }); + + final Color brandColor; + final bool isDynamicColor; + final ThemeType currentThemeValue; + final double textScale; + + @override + Widget build(BuildContext context) { return DynamicColorBuilder( builder: ((ColorScheme? lightDynamic, ColorScheme? darkDynamic) { ColorScheme? lightColorScheme; @@ -143,96 +159,120 @@ class MyApp extends StatelessWidget { brightness: Brightness.dark, ); } - - // ThemeData themeData = ThemeData( - // colorScheme: currentThemeValue == ThemeType.dark - // ? darkColorScheme - // : lightColorScheme, - // ); - - // // 小白条、导航栏沉浸 - // if (Platform.isAndroid) { - // List versionParts = Platform.version.split('.'); - // int androidVersion = int.parse(versionParts[0]); - // if (androidVersion >= 29) { - // SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); - // } - // SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( - // systemNavigationBarColor: GlobalData().enableMYBar - // ? const Color(0x00010000) - // : themeData.canvasColor, - // systemNavigationBarDividerColor: GlobalData().enableMYBar - // ? const Color(0x00010000) - // : themeData.canvasColor, - // systemNavigationBarIconBrightness: - // currentThemeValue == ThemeType.dark - // ? Brightness.light - // : Brightness.dark, - // statusBarColor: Colors.transparent, - // )); - // } - - // 图片缓存 - // PaintingBinding.instance.imageCache.maximumSizeBytes = 1000 << 20; - return GetMaterialApp( - title: 'PiliPala', - theme: ThemeData( - colorScheme: currentThemeValue == ThemeType.dark - ? darkColorScheme - : lightColorScheme, - snackBarTheme: SnackBarThemeData( - actionTextColor: lightColorScheme.primary, - backgroundColor: lightColorScheme.secondaryContainer, - closeIconColor: lightColorScheme.secondary, - contentTextStyle: TextStyle(color: lightColorScheme.secondary), - elevation: 20, - ), - pageTransitionsTheme: const PageTransitionsTheme( - builders: { - TargetPlatform.android: ZoomPageTransitionsBuilder( - allowEnterRouteSnapshotting: false, - ), - }, - ), - ), - darkTheme: ThemeData( - colorScheme: currentThemeValue == ThemeType.light - ? lightColorScheme - : darkColorScheme, - snackBarTheme: SnackBarThemeData( - actionTextColor: darkColorScheme.primary, - backgroundColor: darkColorScheme.secondaryContainer, - closeIconColor: darkColorScheme.secondary, - contentTextStyle: TextStyle(color: darkColorScheme.secondary), - elevation: 20, - ), - ), - localizationsDelegates: const [ - GlobalCupertinoLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - ], - locale: const Locale("zh", "CN"), - supportedLocales: const [Locale("zh", "CN"), Locale("en", "US")], - fallbackLocale: const Locale("zh", "CN"), - getPages: Routes.getPages, - home: const MainApp(), - builder: (BuildContext context, Widget? child) { - return FlutterSmartDialog( - toastBuilder: (String msg) => CustomToast(msg: msg), - child: MediaQuery( - data: MediaQuery.of(context) - .copyWith(textScaler: TextScaler.linear(textScale)), - child: child!, - ), - ); - }, - navigatorObservers: [ - VideoDetailPage.routeObserver, - SearchPage.routeObserver, - ], + return BuildMainApp( + lightColorScheme: lightColorScheme, + darkColorScheme: darkColorScheme, + currentThemeValue: currentThemeValue, + textScale: textScale, ); }), ); } } + +class OtherApp extends StatelessWidget { + const OtherApp({ + super.key, + required this.brandColor, + required this.currentThemeValue, + required this.textScale, + }); + + final Color brandColor; + final ThemeType currentThemeValue; + final double textScale; + + @override + Widget build(BuildContext context) { + return BuildMainApp( + lightColorScheme: ColorScheme.fromSeed( + seedColor: brandColor, + brightness: Brightness.light, + ), + darkColorScheme: ColorScheme.fromSeed( + seedColor: brandColor, + brightness: Brightness.dark, + ), + currentThemeValue: currentThemeValue, + textScale: textScale, + ); + } +} + +class BuildMainApp extends StatelessWidget { + const BuildMainApp({ + super.key, + required this.lightColorScheme, + required this.darkColorScheme, + required this.currentThemeValue, + required this.textScale, + }); + + final ColorScheme lightColorScheme; + final ColorScheme darkColorScheme; + final ThemeType currentThemeValue; + final double textScale; + + @override + Widget build(BuildContext context) { + final SnackBarThemeData snackBarTheme = SnackBarThemeData( + actionTextColor: lightColorScheme.primary, + backgroundColor: lightColorScheme.secondaryContainer, + closeIconColor: lightColorScheme.secondary, + contentTextStyle: TextStyle(color: lightColorScheme.secondary), + elevation: 20, + ); + + return GetMaterialApp( + title: 'PiliPala', + theme: ThemeData( + colorScheme: currentThemeValue == ThemeType.dark + ? darkColorScheme + : lightColorScheme, + snackBarTheme: snackBarTheme, + pageTransitionsTheme: const PageTransitionsTheme( + builders: { + TargetPlatform.android: ZoomPageTransitionsBuilder( + allowEnterRouteSnapshotting: false, + ), + }, + ), + ), + darkTheme: ThemeData( + colorScheme: currentThemeValue == ThemeType.light + ? lightColorScheme + : darkColorScheme, + snackBarTheme: snackBarTheme, + ), + localizationsDelegates: const [ + GlobalCupertinoLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ], + locale: const Locale("zh", "CN"), + supportedLocales: const [Locale("zh", "CN"), Locale("en", "US")], + fallbackLocale: const Locale("zh", "CN"), + getPages: Routes.getPages, + home: const MainApp(), + builder: (BuildContext context, Widget? child) { + return FlutterSmartDialog( + toastBuilder: (String msg) => CustomToast(msg: msg), + child: MediaQuery( + data: MediaQuery.of(context) + .copyWith(textScaler: TextScaler.linear(textScale)), + child: child!, + ), + ); + }, + navigatorObservers: [ + VideoDetailPage.routeObserver, + SearchPage.routeObserver, + ], + onInit: () { + RecommendFilter(); + Data.init(); + GlobalData(); + }, + ); + } +} From 8f26884164a5a114529b02efc1875c5387e32bfc Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sun, 2 Jun 2024 01:04:51 +0800 Subject: [PATCH 27/36] =?UTF-8?q?upgrade:=20=E4=BE=9D=E8=B5=96=E5=8D=87?= =?UTF-8?q?=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/build.gradle | 2 +- ios/Flutter/AppFrameworkInfo.plist | 2 +- ios/Podfile.lock | 14 +- ios/Runner.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- lib/pages/bangumi/view.dart | 7 +- .../pl_player/widgets/bottom_control.dart | 3 +- pubspec.lock | 160 ++++++++++-------- pubspec.yaml | 32 ++-- 9 files changed, 116 insertions(+), 108 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 713d7f6e..674e96f4 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.7.10' + ext.kotlin_version = '1.9.0' repositories { google() mavenCentral() diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index 9625e105..7c569640 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 11.0 + 12.0 diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 2c1a635b..04fe6670 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -10,7 +10,6 @@ PODS: - connectivity_plus (0.0.1): - Flutter - FlutterMacOS - - ReachabilitySwift - device_info_plus (0.0.1): - Flutter - Flutter (1.0.0) @@ -41,7 +40,6 @@ PODS: - FlutterMacOS - permission_handler_apple (9.3.0): - Flutter - - ReachabilitySwift (5.0.0) - saver_gallery (0.0.1): - Flutter - screen_brightness_ios (0.1.0): @@ -101,7 +99,6 @@ SPEC REPOS: trunk: - FMDB - GT3Captcha-iOS - - ReachabilitySwift - Toast EXTERNAL SOURCES: @@ -167,9 +164,9 @@ SPEC CHECKSUMS: audio_service: f509d65da41b9521a61f1c404dd58651f265a567 audio_session: 4f3e461722055d21515cf3261b64c973c062f345 auto_orientation: 102ed811a5938d52c86520ddd7ecd3a126b5d39d - connectivity_plus: e2dad488011aeb593e219360e804c43cc1af5770 + connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6 - Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_mailer: 2ef5a67087bc8c6c4cefd04a178bf1ae2c94cd83 flutter_volume_controller: e4d5832f08008180f76e30faf671ffd5a425e529 fluttertoast: 31b00dabfa7fb7bacd9e7dbee580d7a2ff4bf265 @@ -182,7 +179,6 @@ SPEC CHECKSUMS: package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85 path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2 - ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 saver_gallery: 2b4e584106fde2407ab51560f3851564963e6b78 screen_brightness_ios: 715ca807df953bf676d339f11464e438143ee625 share_plus: c3fef564749587fc939ef86ffb283ceac0baf9f5 @@ -190,11 +186,11 @@ SPEC CHECKSUMS: status_bar_control: 7c84146799e6a076315cc1550f78ef53aae3e446 system_proxy: bec1a5c5af67dd3e3ebf43979400a8756c04cc44 Toast: ec33c32b8688982cecc6348adeae667c1b9938da - url_launcher_ios: bf5ce03e0e2088bad9cc378ea97fa0ed5b49673b + url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe volume_controller: 531ddf792994285c9b17f9d8a7e4dcdd29b3eae9 - wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47 + wakelock_plus: 78ec7c5b202cab7761af8e2b2b3d0671be6c4ae1 webview_cookie_manager: eaf920722b493bd0f7611b5484771ca53fed03f7 - webview_flutter_wkwebview: 4f3e50f7273d31e5500066ed267e3ae4309c5ae4 + webview_flutter_wkwebview: be0f0d33777f1bfd0c9fdcb594786704dbf65f36 PODFILE CHECKSUM: 637cd290bed23275b5f5ffcc7eb1e73d0a5fb2be diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index bac856d2..55565d40 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -156,7 +156,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index a6b826db..5e31d3d3 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ ), ); } else { - return nil; + return const SizedBox(); } } else { - return nil; + return const SizedBox(); } }, ), @@ -216,7 +215,7 @@ class _BangumiPageState extends State (BuildContext context, int index) { return bangumiList!.isNotEmpty ? BangumiCardV(bangumiItem: bangumiList[index]) - : nil; + : const SizedBox(); }, childCount: bangumiList!.isNotEmpty ? bangumiList!.length : 10, ), diff --git a/lib/plugin/pl_player/widgets/bottom_control.dart b/lib/plugin/pl_player/widgets/bottom_control.dart index 35e7792a..b3ff37db 100644 --- a/lib/plugin/pl_player/widgets/bottom_control.dart +++ b/lib/plugin/pl_player/widgets/bottom_control.dart @@ -1,7 +1,6 @@ import 'package:audio_video_progress_bar/audio_video_progress_bar.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:nil/nil.dart'; import 'package:pilipala/plugin/pl_player/index.dart'; import 'package:pilipala/utils/feed_back.dart'; @@ -36,7 +35,7 @@ class BottomControl extends StatelessWidget implements PreferredSizeWidget { final int max = _.durationSeconds.value; final int buffer = _.bufferedSeconds.value; if (value > max || max <= 0) { - return nil; + return const SizedBox(); } return Padding( padding: const EdgeInsets.only(left: 7, right: 7, bottom: 6), diff --git a/pubspec.lock b/pubspec.lock index 8f8a5cae..de434f2e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -17,14 +17,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "6.2.0" - animations: - dependency: "direct main" - description: - name: animations - sha256: d3d6dcfb218225bbe68e87ccf6378bbb2e32a94900722c5f81611dad089911cb - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.0.11" appscheme: dependency: "direct main" description: @@ -101,10 +93,10 @@ packages: dependency: "direct main" description: name: audio_video_progress_bar - sha256: ccc7d7b83d2a16c52d4a7fb332faabd1baa053fb0e4c16815aefd3945ab33b81 + sha256: "552b1f73c56c4c88407999e0a8507176f60c56de3e6d63bc20a0eab48467d4c9" url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.2" + version: "2.0.3" auto_orientation: dependency: "direct main" description: @@ -213,10 +205,10 @@ packages: dependency: "direct main" description: name: catcher_2 - sha256: "9cf33d2befd10058374e5fc6177577fdd938d73d9c06810de81cf91311a7ce98" + sha256: "2c2c6f8cf8c817730cd1dbb010d55292396930e7a3d42c04c3039e3fd411a2f8" url: "https://pub.flutter-io.cn" source: hosted - version: "1.2.3" + version: "1.2.6" characters: dependency: transitive description: @@ -269,10 +261,10 @@ packages: dependency: "direct main" description: name: connectivity_plus - sha256: e9feae83b1849f61bad9f6f33ee00646e3410d54ce0821e02f262f9901dad3c9 + sha256: db7a4e143dc72cc3cb2044ef9b052a7ebfe729513e6a82943bc3526f784365b8 url: "https://pub.flutter-io.cn" source: hosted - version: "6.0.1" + version: "6.0.3" connectivity_plus_platform_interface: dependency: transitive description: @@ -301,10 +293,10 @@ packages: dependency: transitive description: name: cross_file - sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e + sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32" url: "https://pub.flutter-io.cn" source: hosted - version: "0.3.3+8" + version: "0.3.4+1" crypto: dependency: "direct main" description: @@ -333,10 +325,10 @@ packages: dependency: "direct main" description: name: custom_sliding_segmented_control - sha256: "05b73fa48d57218bfdf806bad68a859812b216cd81fe81c6cbefde89f39eb257" + sha256: "53c3e931c3ae1f696085d1ec70ac8e934da836595a9b7d9b88fdd0fcbf2a5574" url: "https://pub.flutter-io.cn" source: hosted - version: "1.8.1" + version: "1.8.3" dart_style: dependency: transitive description: @@ -461,10 +453,10 @@ packages: dependency: transitive description: name: extended_image_library - sha256: "9b55fc5ebc65fad984de66b8f177a1bef2a84d79203c9c213f75ff83c2c29edd" + sha256: c9caee8fe9b6547bd41c960c4f2d1ef8e34321804de6a1777f1d614a24247ad6 url: "https://pub.flutter-io.cn" source: hosted - version: "4.0.1" + version: "4.0.4" extended_list: dependency: transitive description: @@ -621,10 +613,10 @@ packages: dependency: "direct main" description: name: flutter_volume_controller - sha256: "0f10cc759499cb6c3e152a8f6ff8e5ce385b99db7e1f586d1a29d8e6c11f4082" + sha256: fa4c36dfe7ef7f423704f34ab8e64e00b4a30a90aa6e56f251e9dba649efcd7f url: "https://pub.flutter-io.cn" source: hosted - version: "1.3.1" + version: "1.3.2" flutter_web_plugins: dependency: transitive description: flutter @@ -722,10 +714,10 @@ packages: dependency: transitive description: name: http - sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139 + sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.2" + version: "1.2.1" http2: dependency: transitive description: @@ -770,10 +762,10 @@ packages: dependency: transitive description: name: intl - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.flutter-io.cn" source: hosted - version: "0.18.1" + version: "0.19.0" io: dependency: transitive description: @@ -798,6 +790,30 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "4.8.1" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + url: "https://pub.flutter-io.cn" + source: hosted + version: "10.0.4" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.3" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.1" lints: dependency: transitive description: @@ -834,10 +850,10 @@ packages: dependency: "direct main" description: name: logger - sha256: "6bbb9d6f7056729537a4309bda2e74e18e5d9f14302489cc1e93f33b3fe32cac" + sha256: af05cc8714f356fd1f3888fb6741cbe9fbe25cdb6eedbab80e1a6db21047d4a4 url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.2+1" + version: "2.3.0" logging: dependency: transitive description: @@ -850,26 +866,26 @@ packages: dependency: transitive description: name: mailer - sha256: "57f6dd1496699999a7bfd0aa6be0645384f477f4823e16d4321c40a434346382" + sha256: d25d89555c1031abacb448f07b801d7c01b4c21d4558e944b12b64394c84a3cb url: "https://pub.flutter-io.cn" source: hosted - version: "6.0.1" + version: "6.1.0" matcher: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.flutter-io.cn" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.flutter-io.cn" source: hosted - version: "0.5.0" + version: "0.8.0" media_kit: dependency: "direct main" description: @@ -949,10 +965,10 @@ packages: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" url: "https://pub.flutter-io.cn" source: hosted - version: "1.10.0" + version: "1.12.0" mime: dependency: transitive description: @@ -961,14 +977,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.0.4" - nil: - dependency: "direct main" - description: - name: nil - sha256: ef05770c48942876d843bf6a4822d35e5da0ff893a61f1d5ad96d15c4a659136 - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.1.1" nm: dependency: transitive description: @@ -1022,10 +1030,10 @@ packages: dependency: "direct main" description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.flutter-io.cn" source: hosted - version: "1.8.3" + version: "1.9.0" path_parsing: dependency: transitive description: @@ -1435,10 +1443,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" url: "https://pub.flutter-io.cn" source: hosted - version: "0.6.1" + version: "0.7.0" timing: dependency: transitive description: @@ -1467,10 +1475,10 @@ packages: dependency: "direct main" description: name: universal_platform - sha256: d315be0f6641898b280ffa34e2ddb14f3d12b1a37882557869646e0cc363d0cc + sha256: "64e16458a0ea9b99260ceb5467a214c1f298d647c659af1bff6d3bf82536b1ec" url: "https://pub.flutter-io.cn" source: hosted - version: "1.0.0+1" + version: "1.1.0" uri_parser: dependency: transitive description: @@ -1483,10 +1491,10 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: e9aa5ea75c84cf46b3db4eea212523591211c3cf2e13099ee4ec147f54201c86 + sha256: "6ce1e04375be4eed30548f10a315826fd933c1e493206eab82eed01f438c8d2e" url: "https://pub.flutter-io.cn" source: hosted - version: "6.2.2" + version: "6.2.6" url_launcher_android: dependency: transitive description: @@ -1499,10 +1507,10 @@ packages: dependency: transitive description: name: url_launcher_ios - sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3 + sha256: "7068716403343f6ba4969b4173cbf3b84fc768042124bc2c011e5d782b24fe89" url: "https://pub.flutter-io.cn" source: hosted - version: "6.2.1" + version: "6.3.0" url_launcher_linux: dependency: transitive description: @@ -1531,10 +1539,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "7286aec002c8feecc338cc33269e96b73955ab227456e9fb2a91f7fab8a358e9" + sha256: "8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a" url: "https://pub.flutter-io.cn" source: hosted - version: "2.2.2" + version: "2.3.1" url_launcher_windows: dependency: transitive description: @@ -1591,6 +1599,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "0.4.0+2" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + url: "https://pub.flutter-io.cn" + source: hosted + version: "14.2.1" volume_controller: dependency: transitive description: @@ -1603,18 +1619,18 @@ packages: dependency: "direct main" description: name: wakelock_plus - sha256: f268ca2116db22e57577fb99d52515a24bdc1d570f12ac18bb762361d43b043d + sha256: "104d94837bb28c735894dcd592877e990149c380e6358b00c04398ca1426eed4" url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.4" + version: "1.2.1" wakelock_plus_platform_interface: dependency: transitive description: name: wakelock_plus_platform_interface - sha256: "40fabed5da06caff0796dc638e1f07ee395fb18801fbff3255a2372db2d80385" + sha256: "582f2f7aecc7376332d961a0dd1efa9378ce117657e0ade55d9ff72699a55e82" url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.0" + version: "1.2.0" watcher: dependency: transitive description: @@ -1635,10 +1651,10 @@ packages: dependency: transitive description: name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" url: "https://pub.flutter-io.cn" source: hosted - version: "0.3.0" + version: "0.5.1" web_socket_channel: dependency: transitive description: @@ -1659,34 +1675,34 @@ packages: dependency: "direct main" description: name: webview_flutter - sha256: d81b68e88cc353e546afb93fb38958e3717282c5ac6e5d3be4a4aef9fc3c1413 + sha256: "6869c8786d179f929144b4a1f86e09ac0eddfe475984951ea6c634774c16b522" url: "https://pub.flutter-io.cn" source: hosted - version: "4.5.0" + version: "4.8.0" webview_flutter_android: dependency: transitive description: name: webview_flutter_android - sha256: e313dcdf45d4c95bcb8960351ef2389b7f0687b90bc92483f7f7983ae5758456 + sha256: f42447ca49523f11d8f70abea55ea211b3cafe172dd7a0e7ac007bb35dd356dc url: "https://pub.flutter-io.cn" source: hosted - version: "3.13.0" + version: "3.16.4" webview_flutter_platform_interface: dependency: transitive description: name: webview_flutter_platform_interface - sha256: "68e86162aa8fc646ae859e1585995c096c95fc2476881fa0c4a8d10f56013a5a" + sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d url: "https://pub.flutter-io.cn" source: hosted - version: "2.8.0" + version: "2.10.0" webview_flutter_wkwebview: dependency: transitive description: name: webview_flutter_wkwebview - sha256: "4d062ad505390ecef1c4bfb6001cd857a51e00912cc9dfb66edb1886a9ebd80c" + sha256: "7affdf9d680c015b11587181171d3cad8093e449db1f7d9f0f08f4f33d24f9a0" url: "https://pub.flutter-io.cn" source: hosted - version: "3.10.2" + version: "3.13.1" win32: dependency: transitive description: @@ -1728,5 +1744,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.2.0 <4.0.0" - flutter: ">=3.16.0" + dart: ">=3.4.0 <4.0.0" + flutter: ">=3.22.0" diff --git a/pubspec.yaml b/pubspec.yaml index a269cd6f..b9390dd9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -44,7 +44,7 @@ dependencies: dio: ^5.4.1 cookie_jar: ^4.0.8 dio_cookie_manager: ^3.1.1 - connectivity_plus: ^6.0.1 + connectivity_plus: ^6.0.3 dio_http2_adapter: ^2.3.1+1 # 图片 @@ -66,7 +66,7 @@ dependencies: # cookie 管理 webview_cookie_manager: ^2.0.6 # 浏览器 - webview_flutter: ^4.5.0 + webview_flutter: ^4.8.0 # 解决sliver滑动不同步 extended_nested_scroll_view: ^6.2.1 # 上拉加载 @@ -79,7 +79,7 @@ dependencies: flutter_smart_dialog: ^4.9.4 # 下滑关闭 dismissible_page: ^1.0.2 - custom_sliding_segmented_control: ^1.7.5 + custom_sliding_segmented_control: ^1.8.3 # 加密 crypto: ^3.0.3 encrypt: ^5.0.3 @@ -94,19 +94,18 @@ dependencies: audio_session: ^0.1.18 # 音量、亮度、屏幕控制 - flutter_volume_controller: ^1.3.1 + flutter_volume_controller: ^1.3.2 screen_brightness: ^0.2.2+1 - wakelock_plus: ^1.1.1 - universal_platform: ^1.0.0+1 + wakelock_plus: ^1.1.6 + universal_platform: ^1.1.0 # 进度条 - audio_video_progress_bar: ^2.0.2 + audio_video_progress_bar: ^2.0.3 auto_orientation: ^2.3.1 protobuf: ^3.0.0 - animations: ^2.0.11 # 获取appx信息 - package_info_plus: ^4.1.0 - url_launcher: ^6.1.14 + package_info_plus: ^4.2.0 + url_launcher: ^6.2.6 flutter_svg: ^2.0.10+1 # 防抖节流 easy_debounce: ^2.0.3 @@ -136,10 +135,9 @@ dependencies: gt3_flutter_plugin: ^0.0.8 uuid: ^3.0.7 scrollable_positioned_list: ^0.3.8 - nil: ^1.1.1 - catcher_2: ^1.2.3 - logger: ^2.0.2+1 - path: 1.8.3 + catcher_2: ^1.2.6 + logger: ^2.3.0 + path: ^1.9.0 # 电池优化 disable_battery_optimization: ^1.1.1 # 展开/收起 @@ -166,15 +164,15 @@ dev_dependencies: build_runner: ^2.4.8 dependency_overrides: - media_kit: + media_kit: git: url: https://github.com/media-kit/media-kit path: media_kit - media_kit_video: + media_kit_video: git: url: https://github.com/media-kit/media-kit path: media_kit_video - media_kit_libs_video: + media_kit_libs_video: git: url: https://github.com/media-kit/media-kit path: libs/universal/media_kit_libs_video From 3b1ad133db0a9e8bdec5d47ec44e030dc4ee8367 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sun, 2 Jun 2024 22:32:00 +0800 Subject: [PATCH 28/36] mod: logs replace# --- lib/pages/setting/pages/logs.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/pages/setting/pages/logs.dart b/lib/pages/setting/pages/logs.dart index 0958edb8..f497aee5 100644 --- a/lib/pages/setting/pages/logs.dart +++ b/lib/pages/setting/pages/logs.dart @@ -41,7 +41,8 @@ class _LogsPageState extends State { .replaceAll('DEVICE INFO', '设备信息') .replaceAll('APP INFO', '应用信息') .replaceAll('ERROR', '错误信息') - .replaceAll('STACK TRACE', '错误堆栈'); + .replaceAll('STACK TRACE', '错误堆栈') + .replaceAll('#', 'Line'); }).toList(); List> result = []; for (String i in contentList) { @@ -50,7 +51,7 @@ class _LogsPageState extends State { .split("\n") .map((l) { if (l.startsWith("Crash occurred on")) { - date = DateTime.parse( + date = DateTime.tryParse( l.split("Crash occurred on")[1].trim().split('.')[0], ); return ""; From e0e1c6b08af706f79856074ba4b3ea5a53806fc4 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Tue, 4 Jun 2024 23:59:23 +0800 Subject: [PATCH 29/36] upgrade: color --- lib/common/pages_bottom_sheet.dart | 2 +- lib/common/skeleton/skeleton.dart | 4 ++-- lib/common/widgets/stat/danmu.dart | 2 +- lib/common/widgets/stat/view.dart | 2 +- .../introduction/widgets/intro_detail.dart | 4 ++-- lib/pages/dynamics/view.dart | 5 ++--- lib/pages/dynamics/widgets/additional_panel.dart | 2 +- lib/pages/dynamics/widgets/author_panel.dart | 2 +- lib/pages/dynamics/widgets/up_panel.dart | 4 ++-- lib/pages/search/widgets/search_text.dart | 5 ++++- lib/pages/setting/pages/font_size_select.dart | 2 +- .../detail/introduction/widgets/fav_panel.dart | 2 +- .../detail/introduction/widgets/group_panel.dart | 2 +- .../detail/introduction/widgets/menu_row.dart | 4 ++-- lib/pages/video/detail/reply_new/view.dart | 2 +- lib/pages/video/detail/reply_reply/view.dart | 2 +- lib/pages/video/detail/widgets/ai_detail.dart | 2 +- lib/pages/video/detail/widgets/app_bar.dart | 2 +- .../video/detail/widgets/header_control.dart | 16 ++++++++-------- lib/utils/image_save.dart | 2 +- 20 files changed, 35 insertions(+), 33 deletions(-) diff --git a/lib/common/pages_bottom_sheet.dart b/lib/common/pages_bottom_sheet.dart index 2a56eb41..49e9b4d8 100644 --- a/lib/common/pages_bottom_sheet.dart +++ b/lib/common/pages_bottom_sheet.dart @@ -124,7 +124,7 @@ class EpisodeBottomSheet { }); return Container( height: sheetHeight, - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, child: Column( children: [ buildTitle(), diff --git a/lib/common/skeleton/skeleton.dart b/lib/common/skeleton/skeleton.dart index 34e87f55..b17a55fc 100644 --- a/lib/common/skeleton/skeleton.dart +++ b/lib/common/skeleton/skeleton.dart @@ -13,8 +13,8 @@ class Skeleton extends StatelessWidget { var shimmerGradient = LinearGradient( colors: [ Colors.transparent, - Theme.of(context).colorScheme.background.withAlpha(10), - Theme.of(context).colorScheme.background.withAlpha(10), + Theme.of(context).colorScheme.surface.withAlpha(10), + Theme.of(context).colorScheme.surface.withAlpha(10), Colors.transparent, ], stops: const [ diff --git a/lib/common/widgets/stat/danmu.dart b/lib/common/widgets/stat/danmu.dart index c1c439db..511839a0 100644 --- a/lib/common/widgets/stat/danmu.dart +++ b/lib/common/widgets/stat/danmu.dart @@ -14,7 +14,7 @@ class StatDanMu extends StatelessWidget { Map colorObject = { 'white': Colors.white, 'gray': Theme.of(context).colorScheme.outline, - 'black': Theme.of(context).colorScheme.onBackground.withOpacity(0.8), + 'black': Theme.of(context).colorScheme.onSurface.withOpacity(0.8), }; Color color = colorObject[theme]!; return Row( diff --git a/lib/common/widgets/stat/view.dart b/lib/common/widgets/stat/view.dart index 2665e2d4..5359c979 100644 --- a/lib/common/widgets/stat/view.dart +++ b/lib/common/widgets/stat/view.dart @@ -14,7 +14,7 @@ class StatView extends StatelessWidget { Map colorObject = { 'white': Colors.white, 'gray': Theme.of(context).colorScheme.outline, - 'black': Theme.of(context).colorScheme.onBackground.withOpacity(0.8), + 'black': Theme.of(context).colorScheme.onSurface.withOpacity(0.8), }; Color color = colorObject[theme]!; return Row( diff --git a/lib/pages/bangumi/introduction/widgets/intro_detail.dart b/lib/pages/bangumi/introduction/widgets/intro_detail.dart index c5bbd566..07684a86 100644 --- a/lib/pages/bangumi/introduction/widgets/intro_detail.dart +++ b/lib/pages/bangumi/introduction/widgets/intro_detail.dart @@ -20,10 +20,10 @@ class IntroDetail extends StatelessWidget { sheetHeight = localCache.get('sheetHeight'); TextStyle smallTitle = TextStyle( fontSize: 12, - color: Theme.of(context).colorScheme.onBackground, + color: Theme.of(context).colorScheme.onSurface, ); return Container( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, padding: const EdgeInsets.only(left: 14, right: 14), height: sheetHeight, child: Column( diff --git a/lib/pages/dynamics/view.dart b/lib/pages/dynamics/view.dart index da15239d..258ad531 100644 --- a/lib/pages/dynamics/view.dart +++ b/lib/pages/dynamics/view.dart @@ -162,13 +162,12 @@ class _DynamicsPageState extends State decoration: BoxDecoration( color: Theme.of(context) .colorScheme - .surfaceVariant + .surfaceContainerHighest .withOpacity(0.7), borderRadius: BorderRadius.circular(20), ), thumbDecoration: BoxDecoration( - color: - Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(20), ), duration: const Duration(milliseconds: 300), diff --git a/lib/pages/dynamics/widgets/additional_panel.dart b/lib/pages/dynamics/widgets/additional_panel.dart index fa11f217..50e1b6d3 100644 --- a/lib/pages/dynamics/widgets/additional_panel.dart +++ b/lib/pages/dynamics/widgets/additional_panel.dart @@ -19,7 +19,7 @@ Widget addWidget(item, context, type, {floor = 1}) { }; Color bgColor = floor == 1 ? Theme.of(context).dividerColor.withOpacity(0.08) - : Theme.of(context).colorScheme.background; + : Theme.of(context).colorScheme.surface; switch (type) { case 'ADDITIONAL_TYPE_UGC': // 转发的投稿 diff --git a/lib/pages/dynamics/widgets/author_panel.dart b/lib/pages/dynamics/widgets/author_panel.dart index 0d3baecd..8acdc26a 100644 --- a/lib/pages/dynamics/widgets/author_panel.dart +++ b/lib/pages/dynamics/widgets/author_panel.dart @@ -52,7 +52,7 @@ class AuthorPanel extends StatelessWidget { color: item.modules.moduleAuthor!.vip != null && item.modules.moduleAuthor!.vip['status'] > 0 ? const Color.fromARGB(255, 251, 100, 163) - : Theme.of(context).colorScheme.onBackground, + : Theme.of(context).colorScheme.onSurface, fontSize: Theme.of(context).textTheme.titleSmall!.fontSize, ), ), diff --git a/lib/pages/dynamics/widgets/up_panel.dart b/lib/pages/dynamics/widgets/up_panel.dart index ee522cbb..f8c973a0 100644 --- a/lib/pages/dynamics/widgets/up_panel.dart +++ b/lib/pages/dynamics/widgets/up_panel.dart @@ -69,7 +69,7 @@ class _UpPanelState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, padding: const EdgeInsets.only(left: 16, right: 16), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -95,7 +95,7 @@ class _UpPanelState extends State { ), Container( height: 90, - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, child: Row( children: [ Flexible( diff --git a/lib/pages/search/widgets/search_text.dart b/lib/pages/search/widgets/search_text.dart index 039a851b..1b96d412 100644 --- a/lib/pages/search/widgets/search_text.dart +++ b/lib/pages/search/widgets/search_text.dart @@ -16,7 +16,10 @@ class SearchText extends StatelessWidget { @override Widget build(BuildContext context) { return Material( - color: Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.5), + color: Theme.of(context) + .colorScheme + .surfaceContainerHighest + .withOpacity(0.5), borderRadius: BorderRadius.circular(6), child: Padding( padding: EdgeInsets.zero, diff --git a/lib/pages/setting/pages/font_size_select.dart b/lib/pages/setting/pages/font_size_select.dart index 4985c83f..f5ca6be3 100644 --- a/lib/pages/setting/pages/font_size_select.dart +++ b/lib/pages/setting/pages/font_size_select.dart @@ -66,7 +66,7 @@ class _FontSizeSelectPageState extends State { .colorScheme .primary .withOpacity(0.3))), - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, ), child: Row( children: [ diff --git a/lib/pages/video/detail/introduction/widgets/fav_panel.dart b/lib/pages/video/detail/introduction/widgets/fav_panel.dart index 517caeaa..5ef78967 100644 --- a/lib/pages/video/detail/introduction/widgets/fav_panel.dart +++ b/lib/pages/video/detail/introduction/widgets/fav_panel.dart @@ -29,7 +29,7 @@ class _FavPanelState extends State { Widget build(BuildContext context) { return Container( height: sheetHeight, - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, child: Column( children: [ AppBar( diff --git a/lib/pages/video/detail/introduction/widgets/group_panel.dart b/lib/pages/video/detail/introduction/widgets/group_panel.dart index 64ff913d..dcdaf9c5 100644 --- a/lib/pages/video/detail/introduction/widgets/group_panel.dart +++ b/lib/pages/video/detail/introduction/widgets/group_panel.dart @@ -57,7 +57,7 @@ class _GroupPanelState extends State { Widget build(BuildContext context) { return Container( height: sheetHeight, - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, child: Column( children: [ AppBar( diff --git a/lib/pages/video/detail/introduction/widgets/menu_row.dart b/lib/pages/video/detail/introduction/widgets/menu_row.dart index c175aff1..a26c86f0 100644 --- a/lib/pages/video/detail/introduction/widgets/menu_row.dart +++ b/lib/pages/video/detail/introduction/widgets/menu_row.dart @@ -12,7 +12,7 @@ class MenuRow extends StatelessWidget { Widget build(BuildContext context) { return Container( width: double.infinity, - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, padding: const EdgeInsets.only(top: 9, bottom: 9, left: 12), child: SingleChildScrollView( scrollDirection: Axis.horizontal, @@ -84,7 +84,7 @@ class MenuRow extends StatelessWidget { style: TextStyle( fontSize: 13, color: selectStatus - ? Theme.of(context).colorScheme.onBackground + ? Theme.of(context).colorScheme.onSurface : Theme.of(context).colorScheme.outline), ), ), diff --git a/lib/pages/video/detail/reply_new/view.dart b/lib/pages/video/detail/reply_new/view.dart index 3da15f64..d7355d81 100644 --- a/lib/pages/video/detail/reply_new/view.dart +++ b/lib/pages/video/detail/reply_new/view.dart @@ -170,7 +170,7 @@ class _VideoReplyNewDialogState extends State topLeft: Radius.circular(12), topRight: Radius.circular(12), ), - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, ), child: Column( mainAxisSize: MainAxisSize.min, diff --git a/lib/pages/video/detail/reply_reply/view.dart b/lib/pages/video/detail/reply_reply/view.dart index 3fe84c71..6dda9512 100644 --- a/lib/pages/video/detail/reply_reply/view.dart +++ b/lib/pages/video/detail/reply_reply/view.dart @@ -78,7 +78,7 @@ class _VideoReplyReplyPanelState extends State { Widget build(BuildContext context) { return Container( height: widget.source == 'videoDetail' ? widget.sheetHeight : null, - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, child: Column( children: [ if (widget.source == 'videoDetail') diff --git a/lib/pages/video/detail/widgets/ai_detail.dart b/lib/pages/video/detail/widgets/ai_detail.dart index 882a9a8b..197d6124 100644 --- a/lib/pages/video/detail/widgets/ai_detail.dart +++ b/lib/pages/video/detail/widgets/ai_detail.dart @@ -23,7 +23,7 @@ class AiDetail extends StatelessWidget { Widget build(BuildContext context) { sheetHeight = localCache.get('sheetHeight'); return Container( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, padding: const EdgeInsets.only(left: 14, right: 14), height: sheetHeight, child: Column( diff --git a/lib/pages/video/detail/widgets/app_bar.dart b/lib/pages/video/detail/widgets/app_bar.dart index efc0b593..b16623ad 100644 --- a/lib/pages/video/detail/widgets/app_bar.dart +++ b/lib/pages/video/detail/widgets/app_bar.dart @@ -29,7 +29,7 @@ class ScrollAppBar extends StatelessWidget { opacity: scrollDistance / (videoHeight - kToolbarHeight), child: Container( height: statusBarHeight + kToolbarHeight, - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, padding: EdgeInsets.only(top: statusBarHeight), child: AppBar( primary: false, diff --git a/lib/pages/video/detail/widgets/header_control.dart b/lib/pages/video/detail/widgets/header_control.dart index 544d93e0..3ff74b44 100644 --- a/lib/pages/video/detail/widgets/header_control.dart +++ b/lib/pages/video/detail/widgets/header_control.dart @@ -93,7 +93,7 @@ class _HeaderControlState extends State { height: 460, clipBehavior: Clip.hardEdge, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.all(Radius.circular(12)), ), margin: const EdgeInsets.all(12), @@ -317,7 +317,7 @@ class _HeaderControlState extends State { height: 500, clipBehavior: Clip.hardEdge, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.all(Radius.circular(12)), ), margin: const EdgeInsets.all(12), @@ -377,7 +377,7 @@ class _HeaderControlState extends State { inactiveThumbColor: Theme.of(context).colorScheme.primaryContainer, inactiveTrackColor: - Theme.of(context).colorScheme.background, + Theme.of(context).colorScheme.surface, splashRadius: 10.0, // boolean variable value value: shutdownTimerService.waitForPlayingCompleted, @@ -570,7 +570,7 @@ class _HeaderControlState extends State { height: 310, clipBehavior: Clip.hardEdge, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.all(Radius.circular(12)), ), margin: const EdgeInsets.all(12), @@ -660,7 +660,7 @@ class _HeaderControlState extends State { height: 250, clipBehavior: Clip.hardEdge, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.all(Radius.circular(12)), ), margin: const EdgeInsets.all(12), @@ -734,7 +734,7 @@ class _HeaderControlState extends State { height: 250, clipBehavior: Clip.hardEdge, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.all(Radius.circular(12)), ), margin: const EdgeInsets.all(12), @@ -828,7 +828,7 @@ class _HeaderControlState extends State { height: 580, clipBehavior: Clip.hardEdge, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.all(Radius.circular(12)), ), margin: const EdgeInsets.all(12), @@ -1084,7 +1084,7 @@ class _HeaderControlState extends State { height: 250, clipBehavior: Clip.hardEdge, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.all(Radius.circular(12)), ), margin: const EdgeInsets.all(12), diff --git a/lib/utils/image_save.dart b/lib/utils/image_save.dart index 0cd6915c..0b77b7cc 100644 --- a/lib/utils/image_save.dart +++ b/lib/utils/image_save.dart @@ -12,7 +12,7 @@ Future imageSaveDialog(context, videoItem, closeFn) { builder: (context) => Container( margin: const EdgeInsets.symmetric(horizontal: StyleString.safeSpace), decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(10.0), ), child: Column( From 7fc4f3fd4145acacdf116a82ff04ce8aa68002f3 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Thu, 6 Jun 2024 00:28:46 +0800 Subject: [PATCH 30/36] =?UTF-8?q?fix:=20=E9=A6=96=E9=A1=B5app=E6=8E=A8?= =?UTF-8?q?=E8=8D=90=E5=85=B3=E6=B3=A8=E7=8A=B6=E6=80=81=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/models/home/rcmd/result.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/models/home/rcmd/result.dart b/lib/models/home/rcmd/result.dart index 78747d1a..0098fe95 100644 --- a/lib/models/home/rcmd/result.dart +++ b/lib/models/home/rcmd/result.dart @@ -69,9 +69,10 @@ class RecVideoItemAppModel { : null; // 由于app端api并不会直接返回与owner的关注状态 // 所以借用推荐原因是否为“已关注”、“新关注”等判别关注状态,从而与web端接口等效 + RegExp regex = RegExp(r'已关注|新关注'); isFollowed = rcmdReason != null && rcmdReason!.content != null && - rcmdReason!.content!.contains('关注') + regex.hasMatch(rcmdReason!.content!) ? 1 : 0; // 如果是,就无需再显示推荐原因,交由view统一处理即可 From f8897f74bfae9b2d86d8d30625f3816ab9797462 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Fri, 7 Jun 2024 23:48:48 +0800 Subject: [PATCH 31/36] =?UTF-8?q?feat:=20web=E7=AB=AF=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E7=A0=81=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/http/api.dart | 4 +- lib/http/login.dart | 99 ++++++++++++++++++++++--------- lib/pages/login/controller.dart | 80 ++++++++++++++++++++++--- lib/pages/login/view.dart | 37 +++++++----- lib/pages/mine/controller.dart | 5 +- lib/pages/webview/controller.dart | 52 +--------------- lib/pages/webview/view.dart | 4 +- lib/utils/login.dart | 58 ++++++++++++++++++ 8 files changed, 231 insertions(+), 108 deletions(-) diff --git a/lib/http/api.dart b/lib/http/api.dart index 42fc03b8..8a72479b 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -400,10 +400,12 @@ class Api { '${HttpString.passBaseUrl}/x/passport-login/captcha?source=main_web'; // web端短信验证码 - static const String smsCode = + static const String webSmsCode = '${HttpString.passBaseUrl}/x/passport-login/web/sms/send'; // web端验证码登录 + static const String webSmsLogin = + "${HttpString.passBaseUrl}/x/passport-login/web/login/sms"; // web端密码登录 diff --git a/lib/http/login.dart b/lib/http/login.dart index ff3fee23..13236623 100644 --- a/lib/http/login.dart +++ b/lib/http/login.dart @@ -3,6 +3,7 @@ import 'dart:math'; import 'package:crypto/crypto.dart'; import 'package:dio/dio.dart'; import 'package:encrypt/encrypt.dart'; +import 'package:pilipala/http/constants.dart'; import 'package:uuid/uuid.dart'; import '../models/login/index.dart'; import '../utils/login.dart'; @@ -21,32 +22,32 @@ class LoginHttp { } } - static Future sendSmsCode({ - int? cid, - required int tel, - required String token, - required String challenge, - required String validate, - required String seccode, - }) async { - var res = await Request().post( - Api.appSmsCode, - data: { - 'cid': cid, - 'tel': tel, - "source": "main_web", - 'token': token, - 'challenge': challenge, - 'validate': validate, - 'seccode': seccode, - }, - options: Options( - contentType: Headers.formUrlEncodedContentType, - // headers: {'user-agent': ApiConstants.userAgent} - ), - ); - print(res); - } + // static Future sendSmsCode({ + // int? cid, + // required int tel, + // required String token, + // required String challenge, + // required String validate, + // required String seccode, + // }) async { + // var res = await Request().post( + // Api.appSmsCode, + // data: { + // 'cid': cid, + // 'tel': tel, + // "source": "main_web", + // 'token': token, + // 'challenge': challenge, + // 'validate': validate, + // 'seccode': seccode, + // }, + // options: Options( + // contentType: Headers.formUrlEncodedContentType, + // // headers: {'user-agent': ApiConstants.userAgent} + // ), + // ); + // print(res); + // } // web端验证码 static Future sendWebSmsCode({ @@ -60,6 +61,7 @@ class LoginHttp { Map data = { 'cid': cid, 'tel': tel, + "source": "main_web", 'token': token, 'challenge': challenge, 'validate': validate, @@ -67,17 +69,56 @@ class LoginHttp { }; FormData formData = FormData.fromMap({...data}); var res = await Request().post( - Api.smsCode, + Api.webSmsCode, data: formData, options: Options( contentType: Headers.formUrlEncodedContentType, ), ); - print(res); + if (res.data['code'] == 0) { + return { + 'status': true, + 'data': res.data['data'], + }; + } else { + return {'status': false, 'data': [], 'msg': res.data['message']}; + } } // web端验证码登录 - static Future loginInByWebSmsCode() async {} + static Future loginInByWebSmsCode({ + int? cid, + required int tel, + required int code, + required String captchaKey, + }) async { + // webSmsLogin + Map data = { + "cid": cid, + "tel": tel, + "code": code, + "source": "main_mini", + "keep": 0, + "captcha_key": captchaKey, + "go_url": HttpString.baseUrl + }; + FormData formData = FormData.fromMap({...data}); + var res = await Request().post( + Api.webSmsLogin, + data: formData, + options: Options( + contentType: Headers.formUrlEncodedContentType, + ), + ); + if (res.data['code'] == 0) { + return { + 'status': true, + 'data': res.data['data'], + }; + } else { + return {'status': false, 'data': [], 'msg': res.data['message']}; + } + } // web端密码登录 static Future liginInByWebPwd() async {} diff --git a/lib/pages/login/controller.dart b/lib/pages/login/controller.dart index c002fdf9..e47653e2 100644 --- a/lib/pages/login/controller.dart +++ b/lib/pages/login/controller.dart @@ -1,11 +1,16 @@ +import 'dart:async'; +import 'dart:developer'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; +import 'package:get/get_rx/get_rx.dart'; import 'package:pilipala/http/login.dart'; import 'package:gt3_flutter_plugin/gt3_flutter_plugin.dart'; import 'package:pilipala/models/login/index.dart'; +import 'package:pilipala/pages/webview/index.dart'; +import 'package:pilipala/utils/login.dart'; class LoginPageController extends GetxController { final GlobalKey mobFormKey = GlobalKey(); @@ -26,9 +31,19 @@ class LoginPageController extends GetxController { final Gt3FlutterPlugin captcha = Gt3FlutterPlugin(); + // 倒计时60s + RxInt seconds = 60.obs; + late Timer timer; + RxBool smsCodeSendStatus = false.obs; + // 默认密码登录 RxInt loginType = 0.obs; + late String captchaLey; + + late int tel; + late int webSmsCode; + // 监听pageView切换 void onPageChange(int index) { currentIndex.value = index; @@ -43,6 +58,7 @@ class LoginPageController extends GetxController { curve: Curves.easeInOut, ); passwordTextFieldNode.requestFocus(); + (mobFormKey.currentState as FormState).save(); } } @@ -86,18 +102,32 @@ class LoginPageController extends GetxController { } } - // 验证码登录 - void loginInByCode() { - if ((msgCodeFormKey.currentState as FormState).validate()) {} + // web端验证码登录 + void loginInByCode() async { + if ((msgCodeFormKey.currentState as FormState).validate()) { + (msgCodeFormKey.currentState as FormState).save(); + var res = await LoginHttp.loginInByWebSmsCode( + cid: 86, + tel: tel, + code: webSmsCode, + captchaKey: captchaLey, + ); + if (res['status']) { + log(res.toString()); + LoginUtils.confirmLogin('', null); + } else { + SmartDialog.showToast(res['msg']); + } + } } - // app端验证码 - void getMsgCode() async { + // 获取app端验证码 + void getAppMsgCode() async { getCaptcha((data) async { CaptchaDataModel captchaData = data; var res = await LoginHttp.sendAppSmsCode( cid: 86, - tel: 13734077064, + tel: tel, token: captchaData.token!, challenge: captchaData.geetest!.challenge!, validate: captchaData.validate!, @@ -121,7 +151,7 @@ class LoginPageController extends GetxController { captcha.addEventHandler(onShow: (Map message) async { SmartDialog.dismiss(); }, onClose: (Map message) async { - SmartDialog.showToast('关闭验证'); + SmartDialog.showToast('取消验证'); }, onResult: (Map message) async { debugPrint("Captcha result: $message"); String code = message["code"]; @@ -201,4 +231,40 @@ class LoginPageController extends GetxController { captcha.startCaptcha(registerData); } else {} } + + // 获取web端验证码 + void getWebMsgCode() async { + getCaptcha((data) async { + CaptchaDataModel captchaData = data; + var res = await LoginHttp.sendWebSmsCode( + cid: 86, + tel: tel, + token: captchaData.token!, + challenge: captchaData.geetest!.challenge!, + validate: captchaData.validate!, + seccode: captchaData.seccode!, + ); + if (res['status']) { + captchaLey = res['data']['captcha_key']; + SmartDialog.showToast('验证码已发送'); + // 倒计时60s + smsCodeSendStatus.value = true; + startTimer(); + } else { + SmartDialog.showToast(res['msg']); + } + }); + } + + void startTimer() { + timer = Timer.periodic(const Duration(seconds: 1), (timer) { + if (seconds.value > 0) { + seconds.value--; + } else { + seconds.value = 60; + smsCodeSendStatus.value = false; + timer.cancel(); + } + }); + } } diff --git a/lib/pages/login/view.dart b/lib/pages/login/view.dart index 6521e9d9..ae0a60b9 100644 --- a/lib/pages/login/view.dart +++ b/lib/pages/login/view.dart @@ -93,9 +93,7 @@ class _LoginPageState extends State { validator: (v) { return v!.trim().isNotEmpty ? null : "手机号码不能为空"; }, - onSaved: (val) { - print(val); - }, + onSaved: (val) => _loginPageCtr.tel = int.parse(val!), onEditingComplete: () { _loginPageCtr.nextStep(); }, @@ -308,21 +306,28 @@ class _LoginPageState extends State { ? null : "验证码不能为空"; }, - onSaved: (val) { - print(val); - }, + onSaved: (val) => _loginPageCtr.webSmsCode = + int.parse(val!), ), - Positioned( - right: 8, - top: 4, - child: Center( - child: TextButton( - onPressed: () => - _loginPageCtr.getMsgCode(), - child: const Text('获取验证码'), + Obx(() { + return Positioned( + right: 8, + top: 0, + child: Center( + child: TextButton( + onPressed: _loginPageCtr + .smsCodeSendStatus.value + ? null + : () => + _loginPageCtr.getWebMsgCode(), + child: _loginPageCtr + .smsCodeSendStatus.value + ? Text( + '重新获取(${_loginPageCtr.seconds.value}s)') + : const Text('获取验证码')), ), - ), - ), + ); + }) ], ), ), diff --git a/lib/pages/mine/controller.dart b/lib/pages/mine/controller.dart index a61bb820..153a7162 100644 --- a/lib/pages/mine/controller.dart +++ b/lib/pages/mine/controller.dart @@ -6,7 +6,6 @@ import 'package:pilipala/http/user.dart'; import 'package:pilipala/models/common/theme_type.dart'; import 'package:pilipala/models/user/info.dart'; import 'package:pilipala/models/user/stat.dart'; -import 'package:pilipala/utils/route_push.dart'; import 'package:pilipala/utils/storage.dart'; class MineController extends GetxController { @@ -34,8 +33,8 @@ class MineController extends GetxController { onLogin() async { if (!userLogin.value) { - RoutePush.loginPush(); - // Get.toNamed('/loginPage'); + // RoutePush.loginPush(); + Get.toNamed('/loginPage'); } else { int mid = userInfo.value.mid!; String face = userInfo.value.face!; diff --git a/lib/pages/webview/controller.dart b/lib/pages/webview/controller.dart index bdacc652..e0ff113c 100644 --- a/lib/pages/webview/controller.dart +++ b/lib/pages/webview/controller.dart @@ -76,7 +76,7 @@ class WebviewController extends GetxController { (url.startsWith( 'https://passport.bilibili.com/web/sso/exchange_cookie') || url.startsWith('https://m.bilibili.com/'))) { - confirmLogin(url); + LoginUtils.confirmLogin(url, controller); } }, onWebResourceError: (WebResourceError error) {}, @@ -97,54 +97,4 @@ class WebviewController extends GetxController { ) ..loadRequest(Uri.parse(url)); } - - confirmLogin(url) async { - var content = ''; - if (url != null) { - content = '${content + url}; \n'; - } - try { - await SetCookie.onSet(); - final result = await UserHttp.userInfo(); - if (result['status'] && result['data'].isLogin) { - SmartDialog.showToast('登录成功'); - try { - Box userInfoCache = GStrorage.userInfo; - if (!userInfoCache.isOpen) { - userInfoCache = await Hive.openBox('userInfo'); - } - await userInfoCache.put('userInfoCache', result['data']); - - final HomeController homeCtr = Get.find(); - homeCtr.updateLoginStatus(true); - homeCtr.userFace.value = result['data'].face; - final MediaController mediaCtr = Get.find(); - mediaCtr.mid = result['data'].mid; - await LoginUtils.refreshLoginStatus(true); - } catch (err) { - SmartDialog.show(builder: (BuildContext context) { - return AlertDialog( - title: const Text('登录遇到问题'), - content: Text(err.toString()), - actions: [ - TextButton( - onPressed: () => controller.reload(), - child: const Text('确认'), - ) - ], - ); - }); - } - Get.back(); - } else { - // 获取用户信息失败 - SmartDialog.showToast(result['msg']); - Clipboard.setData(ClipboardData(text: result['msg'])); - } - } catch (e) { - SmartDialog.showNotify(msg: e.toString(), notifyType: NotifyType.warning); - content = content + e.toString(); - Clipboard.setData(ClipboardData(text: content)); - } - } } diff --git a/lib/pages/webview/view.dart b/lib/pages/webview/view.dart index 8edd2189..cba40ad1 100644 --- a/lib/pages/webview/view.dart +++ b/lib/pages/webview/view.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:pilipala/utils/login.dart'; import 'package:url_launcher/url_launcher.dart'; import 'controller.dart'; import 'package:webview_flutter/webview_flutter.dart'; @@ -43,7 +44,8 @@ class _WebviewPageState extends State { Obx( () => _webviewController.type.value == 'login' ? TextButton( - onPressed: () => _webviewController.confirmLogin(null), + onPressed: () => + LoginUtils.confirmLogin(null, _webviewController), child: const Text('刷新登录状态'), ) : const SizedBox(), diff --git a/lib/utils/login.dart b/lib/utils/login.dart index 59c53027..2687a8c2 100644 --- a/lib/utils/login.dart +++ b/lib/utils/login.dart @@ -2,12 +2,18 @@ import 'dart:convert'; import 'dart:math'; import 'package:crypto/crypto.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; +import 'package:hive/hive.dart'; +import 'package:pilipala/http/user.dart'; import 'package:pilipala/pages/dynamics/index.dart'; import 'package:pilipala/pages/home/index.dart'; import 'package:pilipala/pages/media/index.dart'; import 'package:pilipala/pages/mine/index.dart'; +import 'package:pilipala/utils/cookie.dart'; +import 'package:pilipala/utils/storage.dart'; import 'package:uuid/uuid.dart'; class LoginUtils { @@ -57,4 +63,56 @@ class LoginUtils { String uuid = getUUID() + getUUID(); return 'XY${uuid.substring(0, 35).toUpperCase()}'; } + + static confirmLogin(url, controller) async { + var content = ''; + if (url != null) { + content = '${content + url}; \n'; + } + try { + await SetCookie.onSet(); + final result = await UserHttp.userInfo(); + if (result['status'] && result['data'].isLogin) { + SmartDialog.showToast('登录成功'); + try { + Box userInfoCache = GStrorage.userInfo; + if (!userInfoCache.isOpen) { + userInfoCache = await Hive.openBox('userInfo'); + } + await userInfoCache.put('userInfoCache', result['data']); + + final HomeController homeCtr = Get.find(); + homeCtr.updateLoginStatus(true); + homeCtr.userFace.value = result['data'].face; + final MediaController mediaCtr = Get.find(); + mediaCtr.mid = result['data'].mid; + await LoginUtils.refreshLoginStatus(true); + } catch (err) { + SmartDialog.show(builder: (BuildContext context) { + return AlertDialog( + title: const Text('登录遇到问题'), + content: Text(err.toString()), + actions: [ + TextButton( + onPressed: controller != null + ? () => controller.reload() + : SmartDialog.dismiss, + child: const Text('确认'), + ) + ], + ); + }); + } + Get.back(); + } else { + // 获取用户信息失败 + SmartDialog.showToast(result['msg']); + Clipboard.setData(ClipboardData(text: result['msg'])); + } + } catch (e) { + SmartDialog.showNotify(msg: e.toString(), notifyType: NotifyType.warning); + content = content + e.toString(); + Clipboard.setData(ClipboardData(text: content)); + } + } } From 9888aba62e93b87c75832c543697302930c588e5 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sat, 8 Jun 2024 00:26:08 +0800 Subject: [PATCH 32/36] =?UTF-8?q?feat:=20web=E7=AB=AF=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/http/api.dart | 2 ++ lib/http/login.dart | 38 ++++++++++++++++++++++++++ lib/pages/login/controller.dart | 47 +++++++++++++++++++++++++++------ lib/pages/login/view.dart | 2 +- 4 files changed, 80 insertions(+), 9 deletions(-) diff --git a/lib/http/api.dart b/lib/http/api.dart index 8a72479b..e0b92c02 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -408,6 +408,8 @@ class Api { "${HttpString.passBaseUrl}/x/passport-login/web/login/sms"; // web端密码登录 + static const String loginInByWebPwd = + "${HttpString.passBaseUrl}/x/passport-login/web/login"; // app端短信验证码 static const String appSmsCode = diff --git a/lib/http/login.dart b/lib/http/login.dart index 13236623..a97360c7 100644 --- a/lib/http/login.dart +++ b/lib/http/login.dart @@ -214,4 +214,42 @@ class LoginHttp { ); print(res); } + + // web端密码登录 + static Future loginInByWebPwd({ + required int username, + required String password, + required String token, + required String challenge, + required String validate, + required String seccode, + }) async { + Map data = { + 'username': username, + 'password': password, + 'keep': 0, + 'token': token, + 'challenge': challenge, + 'validate': validate, + 'seccode': seccode, + 'source': 'main-fe-header', + "go_url": HttpString.baseUrl + }; + FormData formData = FormData.fromMap({...data}); + var res = await Request().post( + Api.loginInByWebPwd, + data: formData, + options: Options( + contentType: Headers.formUrlEncodedContentType, + ), + ); + if (res.data['code'] == 0) { + return { + 'status': true, + 'data': res.data['data'], + }; + } else { + return {'status': false, 'data': [], 'msg': res.data['message']}; + } + } } diff --git a/lib/pages/login/controller.dart b/lib/pages/login/controller.dart index e47653e2..354076f9 100644 --- a/lib/pages/login/controller.dart +++ b/lib/pages/login/controller.dart @@ -1,15 +1,13 @@ import 'dart:async'; -import 'dart:developer'; import 'dart:io'; +import 'package:encrypt/encrypt.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; -import 'package:get/get_rx/get_rx.dart'; import 'package:pilipala/http/login.dart'; import 'package:gt3_flutter_plugin/gt3_flutter_plugin.dart'; import 'package:pilipala/models/login/index.dart'; -import 'package:pilipala/pages/webview/index.dart'; import 'package:pilipala/utils/login.dart'; class LoginPageController extends GetxController { @@ -39,7 +37,7 @@ class LoginPageController extends GetxController { // 默认密码登录 RxInt loginType = 0.obs; - late String captchaLey; + late String captchaKey; late int tel; late int webSmsCode; @@ -102,6 +100,39 @@ class LoginPageController extends GetxController { } } + // web端密码登录 + void loginInByWebPassword() async { + if ((passwordFormKey.currentState as FormState).validate()) { + getCaptcha((data) async { + CaptchaDataModel captchaData = data; + var webKeyRes = await LoginHttp.getWebKey(); + if (webKeyRes['status']) { + String rhash = webKeyRes['data']['hash']; + String key = webKeyRes['data']['key']; + dynamic publicKey = RSAKeyParser().parse(key); + String passwordEncryptyed = Encrypter(RSA(publicKey: publicKey)) + .encrypt(rhash + passwordTextController.text) + .base64; + var res = await LoginHttp.loginInByWebPwd( + username: tel, + password: passwordEncryptyed, + token: captchaData.token!, + challenge: captchaData.geetest!.challenge!, + validate: captchaData.validate!, + seccode: captchaData.seccode!, + ); + if (res['status']) { + await LoginUtils.confirmLogin('', null); + } else { + SmartDialog.showToast(res['msg']); + } + } else { + SmartDialog.showToast(webKeyRes['msg']); + } + }); + } + } + // web端验证码登录 void loginInByCode() async { if ((msgCodeFormKey.currentState as FormState).validate()) { @@ -110,11 +141,10 @@ class LoginPageController extends GetxController { cid: 86, tel: tel, code: webSmsCode, - captchaKey: captchaLey, + captchaKey: captchaKey, ); if (res['status']) { - log(res.toString()); - LoginUtils.confirmLogin('', null); + await LoginUtils.confirmLogin('', null); } else { SmartDialog.showToast(res['msg']); } @@ -245,7 +275,7 @@ class LoginPageController extends GetxController { seccode: captchaData.seccode!, ); if (res['status']) { - captchaLey = res['data']['captcha_key']; + captchaKey = res['data']['captcha_key']; SmartDialog.showToast('验证码已发送'); // 倒计时60s smsCodeSendStatus.value = true; @@ -256,6 +286,7 @@ class LoginPageController extends GetxController { }); } + // 验证码倒计时 void startTimer() { timer = Timer.periodic(const Duration(seconds: 1), (timer) { if (seconds.value > 0) { diff --git a/lib/pages/login/view.dart b/lib/pages/login/view.dart index ae0a60b9..2f406706 100644 --- a/lib/pages/login/view.dart +++ b/lib/pages/login/view.dart @@ -234,7 +234,7 @@ class _LoginPageState extends State { .primary, // 设置按钮背景色 ), onPressed: () => - _loginPageCtr.loginInByAppPassword(), + _loginPageCtr.loginInByWebPassword(), child: const Text('确认登录'), ) ], From 4fe8366c2fe6013f8f9f941ebc6b33437709975e Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sat, 8 Jun 2024 00:42:45 +0800 Subject: [PATCH 33/36] upgrade: gt3 plugin --- pubspec.lock | 20 ++++++++++---------- pubspec.yaml | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index fdcd517c..406fbca4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -674,10 +674,10 @@ packages: dependency: "direct main" description: name: gt3_flutter_plugin - sha256: f12bff2bfbcf27467833f8d564dcc24ee2f1b3254a7c7cf5eb2c4590baf11cc1 + sha256: "08f35692e937770ad6b3e2017eb8ef81839a82b8a63f5acf3abab14b688fc36c" url: "https://pub.flutter-io.cn" source: hosted - version: "0.0.8" + version: "0.1.0" hive: dependency: "direct main" description: @@ -981,10 +981,10 @@ packages: dependency: transitive description: name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" url: "https://pub.flutter-io.cn" source: hosted - version: "1.0.4" + version: "1.0.5" nm: dependency: transitive description: @@ -1054,10 +1054,10 @@ packages: dependency: "direct main" description: name: path_provider - sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161 url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.1" + version: "2.1.3" path_provider_android: dependency: transitive description: @@ -1070,10 +1070,10 @@ packages: dependency: transitive description: name: path_provider_foundation - sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 url: "https://pub.flutter-io.cn" source: hosted - version: "2.3.1" + version: "2.4.0" path_provider_linux: dependency: transitive description: @@ -1238,10 +1238,10 @@ packages: dependency: "direct main" description: name: saver_gallery - sha256: "2657953427ebe5a3b2d08157d41587c01923ccce3f1a616d55082be7470f8530" + sha256: "0f740608072053a0da3b19cc5812a87e36f5c3c0b959d2475c4eb3d697f4a782" url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.1" + version: "3.0.3" screen_brightness: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index f758d308..f02c2ead 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -132,7 +132,7 @@ dependencies: # html渲染 flutter_html: ^3.0.0-beta.2 # 极验 - gt3_flutter_plugin: ^0.0.8 + gt3_flutter_plugin: ^0.1.0 uuid: ^3.0.7 scrollable_positioned_list: ^0.3.8 catcher_2: ^1.2.6 From 3a94281310ecf86ccdd0a5d21853b9ed38dceff6 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sat, 8 Jun 2024 03:14:37 +0800 Subject: [PATCH 34/36] =?UTF-8?q?feat:=20web=E7=AB=AF=E6=89=AB=E7=A0=81?= =?UTF-8?q?=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/http/api.dart | 12 +++- lib/http/login.dart | 27 +++++++ lib/pages/login/controller.dart | 35 +++++++++ lib/pages/login/view.dart | 121 ++++++++++++++++++++++++++------ pubspec.lock | 16 +++++ pubspec.yaml | 2 + 6 files changed, 190 insertions(+), 23 deletions(-) diff --git a/lib/http/api.dart b/lib/http/api.dart index e0b92c02..b0fc0556 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -405,11 +405,19 @@ class Api { // web端验证码登录 static const String webSmsLogin = - "${HttpString.passBaseUrl}/x/passport-login/web/login/sms"; + '${HttpString.passBaseUrl}/x/passport-login/web/login/sms'; // web端密码登录 static const String loginInByWebPwd = - "${HttpString.passBaseUrl}/x/passport-login/web/login"; + '${HttpString.passBaseUrl}/x/passport-login/web/login'; + + // web端二维码 + static const String qrCodeApi = + '${HttpString.passBaseUrl}/x/passport-login/web/qrcode/generate'; + + // 扫码登录 + static const String loginInByQrcode = + '${HttpString.passBaseUrl}/x/passport-login/web/qrcode/poll'; // app端短信验证码 static const String appSmsCode = diff --git a/lib/http/login.dart b/lib/http/login.dart index a97360c7..2437b72a 100644 --- a/lib/http/login.dart +++ b/lib/http/login.dart @@ -252,4 +252,31 @@ class LoginHttp { return {'status': false, 'data': [], 'msg': res.data['message']}; } } + + // web端登录二维码 + static Future getWebQrcode() async { + var res = await Request().get(Api.qrCodeApi); + if (res.data['code'] == 0) { + return { + 'status': true, + 'data': res.data['data'], + }; + } else { + return {'status': false, 'data': [], 'msg': res.data['message']}; + } + } + + // web端二维码轮询登录状态 + static Future queryWebQrcodeStatus(String qrcodeKey) async { + var res = await Request() + .get(Api.loginInByQrcode, data: {'qrcode_key': qrcodeKey}); + if (res.data['data']['code'] == 0) { + return { + 'status': true, + 'data': res.data['data'], + }; + } else { + return {'status': false, 'data': [], 'msg': res.data['message']}; + } + } } diff --git a/lib/pages/login/controller.dart b/lib/pages/login/controller.dart index 354076f9..b5ddba16 100644 --- a/lib/pages/login/controller.dart +++ b/lib/pages/login/controller.dart @@ -42,6 +42,10 @@ class LoginPageController extends GetxController { late int tel; late int webSmsCode; + RxInt validSeconds = 180.obs; + late Timer validTimer; + late String qrcodeKey; + // 监听pageView切换 void onPageChange(int index) { currentIndex.value = index; @@ -298,4 +302,35 @@ class LoginPageController extends GetxController { } }); } + + // 获取登录二维码 + Future getWebQrcode() async { + var res = await LoginHttp.getWebQrcode(); + validSeconds.value = 180; + if (res['status']) { + qrcodeKey = res['data']['qrcode_key']; + validTimer = Timer.periodic(const Duration(seconds: 1), (validTimer) { + if (validSeconds.value > 0) { + validSeconds.value--; + queryWebQrcodeStatus(); + } else { + getWebQrcode(); + validTimer.cancel(); + } + }); + return res; + } else { + SmartDialog.showToast(res['msg']); + } + } + + // 轮询二维码登录状态 + Future queryWebQrcodeStatus() async { + var res = await LoginHttp.queryWebQrcodeStatus(qrcodeKey); + if (res['status']) { + await LoginUtils.confirmLogin('', null); + validTimer.cancel(); + Get.back(); + } + } } diff --git a/lib/pages/login/view.dart b/lib/pages/login/view.dart index 2f406706..cd91ea26 100644 --- a/lib/pages/login/view.dart +++ b/lib/pages/login/view.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:qr_flutter/qr_flutter.dart'; import 'controller.dart'; @@ -37,6 +38,105 @@ class _LoginPageState extends State { icon: const Icon(Icons.arrow_back), ), ), + actions: [ + IconButton( + tooltip: '浏览器打开', + onPressed: () { + Get.offNamed( + '/webview', + parameters: { + 'url': 'https://passport.bilibili.com/h5-app/passport/login', + 'type': 'login', + 'pageTitle': '登录bilibili', + }, + ); + }, + icon: const Icon(Icons.language), + ), + IconButton( + tooltip: '二维码登录', + onPressed: () { + showDialog( + context: context, + builder: (context) { + return StatefulBuilder( + builder: (context, StateSetter setState) { + return AlertDialog( + title: Row( + children: [ + const Text('扫码登录'), + IconButton( + onPressed: () { + setState(() {}); + }, + icon: const Icon(Icons.refresh), + ), + ], + ), + contentPadding: const EdgeInsets.fromLTRB(0, 0, 0, 4), + content: AspectRatio( + aspectRatio: 1, + child: Container( + width: 200, + padding: const EdgeInsets.all(12), + child: FutureBuilder( + future: _loginPageCtr.getWebQrcode(), + builder: (context, snapshot) { + if (snapshot.connectionState == + ConnectionState.done) { + if (snapshot.data == null) { + return const SizedBox(); + } + Map data = snapshot.data as Map; + return QrImageView( + data: data['data']['url'], + backgroundColor: Colors.transparent, + ); + } else { + return const Center( + child: SizedBox( + width: 40, + height: 40, + child: CircularProgressIndicator(), + ), + ); + } + }, + ), + ), + ), + actions: [ + TextButton( + onPressed: () {}, + child: Obx(() { + return Text( + '有效期: ${_loginPageCtr.validSeconds.value}s', + style: Theme.of(context).textTheme.titleMedium, + ); + }), + ), + TextButton( + onPressed: () {}, + child: Text( + '检查登录状态', + style: TextStyle( + fontSize: Theme.of(context) + .textTheme + .titleMedium! + .fontSize, + ), + ), + ) + ], + ); + }); + }, + ); + }, + icon: const Icon(Icons.qr_code), + ), + const SizedBox(width: 22), + ], ), body: PageView( physics: const NeverScrollableScrollPhysics(), @@ -99,27 +199,6 @@ class _LoginPageState extends State { }, ), ), - GestureDetector( - onTap: () { - Get.offNamed( - '/webview', - parameters: { - 'url': - 'https://passport.bilibili.com/h5-app/passport/login', - 'type': 'login', - 'pageTitle': '登录bilibili', - }, - ); - }, - child: Padding( - padding: const EdgeInsets.only(left: 2), - child: Text( - '使用网页端登录', - style: TextStyle( - color: Theme.of(context).colorScheme.primary), - ), - ), - ), const Spacer(), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, diff --git a/pubspec.lock b/pubspec.lock index 406fbca4..5c6f2b43 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1218,6 +1218,22 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "3.1.0" + qr: + dependency: transitive + description: + name: qr + sha256: "64957a3930367bf97cc211a5af99551d630f2f4625e38af10edd6b19131b64b3" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.1" + qr_flutter: + dependency: "direct main" + description: + name: qr_flutter + sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.1.0" rxdart: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index f02c2ead..66187abf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -145,6 +145,8 @@ dependencies: # 投屏 dlna_dart: ^0.0.8 lottie: ^3.1.2 + # 二维码 + qr_flutter: ^4.1.0 dev_dependencies: flutter_test: From aee52b02470f91db723b24a9ce2b9a6dbc573c10 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sat, 8 Jun 2024 04:09:00 +0800 Subject: [PATCH 35/36] =?UTF-8?q?opt:=20=E6=B6=88=E6=81=AF=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E5=A2=9E=E5=8A=A0=E9=AA=A8=E6=9E=B6=E5=B1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/whisper/view.dart | 270 +++++++++++++++++++----------------- 1 file changed, 142 insertions(+), 128 deletions(-) diff --git a/lib/pages/whisper/view.dart b/lib/pages/whisper/view.dart index fa7ad60b..fa95463b 100644 --- a/lib/pages/whisper/view.dart +++ b/lib/pages/whisper/view.dart @@ -1,6 +1,7 @@ import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:pilipala/common/skeleton/skeleton.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; import 'package:pilipala/utils/utils.dart'; @@ -102,134 +103,83 @@ class _WhisperPageState extends State { }, child: SingleChildScrollView( controller: _scrollController, - child: Column( - children: [ - FutureBuilder( - future: _futureBuilderFuture, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - Map? data = snapshot.data; - if (data != null && data['status']) { - RxList sessionList = _whisperController.sessionList; - return Obx( - () => sessionList.isEmpty - ? const SizedBox() - : ListView.separated( - itemCount: sessionList.length, - shrinkWrap: true, - physics: - const NeverScrollableScrollPhysics(), - itemBuilder: (_, int i) { - return ListTile( - onTap: () { - sessionList[i].unreadCount = 0; - sessionList.refresh(); - Get.toNamed( - '/whisperDetail', - parameters: { - 'talkerId': sessionList[i] - .talkerId - .toString(), - 'name': sessionList[i] - .accountInfo - .name, - 'face': sessionList[i] - .accountInfo - .face, - 'mid': sessionList[i] - .accountInfo - .mid - .toString(), - }, - ); - }, - leading: Badge( - isLabelVisible: - sessionList[i].unreadCount > 0, - label: Text(sessionList[i] - .unreadCount - .toString()), - alignment: Alignment.topRight, - child: NetworkImgLayer( - width: 45, - height: 45, - type: 'avatar', - src: sessionList[i] - .accountInfo - .face, - ), - ), - title: Text( - sessionList[i].accountInfo.name), - subtitle: Text( - sessionList[i].lastMsg.content != - null && - sessionList[i] - .lastMsg - .content != - '' - ? (sessionList[i] - .lastMsg - .content['text'] ?? - sessionList[i] - .lastMsg - .content['content'] ?? - sessionList[i] - .lastMsg - .content['title'] ?? - sessionList[i] - .lastMsg - .content[ - 'reply_content'] ?? - '不支持的消息类型') - : '不支持的消息类型', - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: Theme.of(context) - .textTheme - .labelMedium! - .copyWith( - color: Theme.of(context) - .colorScheme - .outline)), - trailing: Text( - Utils.dateFormat(sessionList[i] - .lastMsg - .timestamp), - style: Theme.of(context) - .textTheme - .labelSmall! - .copyWith( - color: Theme.of(context) - .colorScheme - .outline), - ), - ); - }, - separatorBuilder: - (BuildContext context, int index) { - return Divider( - indent: 72, - endIndent: 20, - height: 6, - color: Colors.grey.withOpacity(0.1), - ); - }, - ), - ); - } else { - // 请求错误 - return Center( - child: Text(data?['msg'] ?? '请求异常'), - ); - } - } else { - // 骨架屏 - return const SizedBox(); - } - }, - ) - ], + child: FutureBuilder( + future: _futureBuilderFuture, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + Map? data = snapshot.data; + if (data != null && data['status']) { + RxList sessionList = _whisperController.sessionList; + return Obx( + () => sessionList.isEmpty + ? const SizedBox() + : ListView.separated( + itemCount: sessionList.length, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (_, int i) { + return SessionItem( + sessionItem: sessionList[i], + changeFucCall: () => + sessionList.refresh(), + ); + }, + separatorBuilder: + (BuildContext context, int index) { + return Divider( + indent: 72, + endIndent: 20, + height: 6, + color: Colors.grey.withOpacity(0.1), + ); + }, + ), + ); + } else { + // 请求错误 + return Center( + child: Text(data?['msg'] ?? '请求异常'), + ); + } + } else { + // 骨架屏 + return ListView.builder( + itemCount: 15, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, int i) { + return Skeleton( + child: ListTile( + leading: Container( + width: 45, + height: 45, + decoration: BoxDecoration( + color: Theme.of(context) + .colorScheme + .onInverseSurface, + borderRadius: BorderRadius.circular(25), + ), + ), + title: Container( + width: 100, + height: 14, + color: Theme.of(context) + .colorScheme + .onInverseSurface, + ), + subtitle: Container( + width: 80, + height: 14, + color: Theme.of(context) + .colorScheme + .onInverseSurface, + ), + ), + ); + }, + ); + } + }, ), ), ), @@ -239,3 +189,67 @@ class _WhisperPageState extends State { ); } } + +class SessionItem extends StatelessWidget { + final dynamic sessionItem; + final Function changeFucCall; + + const SessionItem({ + super.key, + required this.sessionItem, + required this.changeFucCall, + }); + + @override + Widget build(BuildContext context) { + final content = sessionItem.lastMsg.content; + return ListTile( + onTap: () { + sessionItem.unreadCount = 0; + changeFucCall.call(); + Get.toNamed( + '/whisperDetail', + parameters: { + 'talkerId': sessionItem.talkerId.toString(), + 'name': sessionItem.accountInfo.name, + 'face': sessionItem.accountInfo.face, + 'mid': sessionItem.accountInfo.mid.toString(), + }, + ); + }, + leading: Badge( + isLabelVisible: sessionItem.unreadCount > 0, + label: Text(sessionItem.unreadCount.toString()), + alignment: Alignment.topRight, + child: NetworkImgLayer( + width: 45, + height: 45, + type: 'avatar', + src: sessionItem.accountInfo.face, + ), + ), + title: Text(sessionItem.accountInfo.name), + subtitle: Text( + content != null && content != '' + ? (content['text'] ?? + content['content'] ?? + content['title'] ?? + content['reply_content'] ?? + '不支持的消息类型') + : '不支持的消息类型', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: Theme.of(context) + .textTheme + .labelMedium! + .copyWith(color: Theme.of(context).colorScheme.outline)), + trailing: Text( + Utils.dateFormat(sessionItem.lastMsg.timestamp), + style: Theme.of(context) + .textTheme + .labelSmall! + .copyWith(color: Theme.of(context).colorScheme.outline), + ), + ); + } +} From 897551bf237c65ec364507aa1c3d1cff865c6851 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sat, 8 Jun 2024 15:35:45 +0800 Subject: [PATCH 36/36] =?UTF-8?q?fix:=20=E7=A7=81=E4=BF=A1=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E7=B1=BB=E5=9E=8B=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../whisper_detail/widget/chat_item.dart | 203 +++++++++--------- 1 file changed, 101 insertions(+), 102 deletions(-) diff --git a/lib/pages/whisper_detail/widget/chat_item.dart b/lib/pages/whisper_detail/widget/chat_item.dart index ad11e4c3..0d37e8b3 100644 --- a/lib/pages/whisper_detail/widget/chat_item.dart +++ b/lib/pages/whisper_detail/widget/chat_item.dart @@ -259,115 +259,114 @@ class ChatItem extends StatelessWidget { ); case MsgType.auto_reply_push: return Container( - constraints: const BoxConstraints( - maxWidth: 300.0, // 设置最大宽度为200.0 + constraints: const BoxConstraints( + maxWidth: 300.0, // 设置最大宽度为200.0 + ), + decoration: BoxDecoration( + color: Theme.of(context) + .colorScheme + .secondaryContainer + .withOpacity(0.4), + borderRadius: const BorderRadius.all( + Radius.circular(16), ), - decoration: BoxDecoration( - color: Theme.of(context) - .colorScheme - .secondaryContainer - .withOpacity(0.4), - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(16), - topRight: Radius.circular(16), - bottomLeft: Radius.circular(6), - bottomRight: Radius.circular(16), - ), - ), - margin: const EdgeInsets.all(12), - padding: const EdgeInsets.all(12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - content['main_title'], - style: TextStyle( - letterSpacing: 0.6, - height: 1.5, - color: textColor(context), - fontWeight: FontWeight.bold, - ), + ), + margin: const EdgeInsets.all(12), + padding: const EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + content['main_title'], + style: TextStyle( + letterSpacing: 0.6, + height: 1.5, + color: textColor(context), + fontWeight: FontWeight.bold, ), - for (var i in content['sub_cards']) ...[ - const SizedBox(height: 6), - GestureDetector( - onTap: () async { - RegExp bvRegex = RegExp(r'BV[0-9A-Za-z]{10}', - caseSensitive: false); - Iterable matches = - bvRegex.allMatches(i['jump_url']); - if (matches.isNotEmpty) { - Match match = matches.first; - String bvid = match.group(0)!; - try { - SmartDialog.showLoading(); - final int cid = await SearchHttp.ab2c(bvid: bvid); - final String heroTag = Utils.makeHeroTag(bvid); - SmartDialog.dismiss().then( - (e) => Get.toNamed( - '/video?bvid=$bvid&cid=$cid', - arguments: { - 'pic': i['cover_url'], - 'heroTag': heroTag, - }), - ); - } catch (err) { - SmartDialog.dismiss(); - SmartDialog.showToast(err.toString()); - } - } else { - SmartDialog.showToast('未匹配到 BV 号'); - Get.toNamed('/webview', - arguments: {'url': i['jump_url']}); - } - }, - child: Row( + ), + for (var i in content['sub_cards']) ...[ + const SizedBox(height: 6), + GestureDetector( + onTap: () async { + RegExp bvRegex = + RegExp(r'BV[0-9A-Za-z]{10}', caseSensitive: false); + Iterable matches = + bvRegex.allMatches(i['jump_url']); + if (matches.isNotEmpty) { + Match match = matches.first; + String bvid = match.group(0)!; + try { + SmartDialog.showLoading(); + final int cid = await SearchHttp.ab2c(bvid: bvid); + final String heroTag = Utils.makeHeroTag(bvid); + SmartDialog.dismiss().then( + (e) => Get.toNamed( + '/video?bvid=$bvid&cid=$cid', + arguments: { + 'pic': i['cover_url'], + 'heroTag': heroTag, + }), + ); + } catch (err) { + SmartDialog.dismiss(); + SmartDialog.showToast(err.toString()); + } + } else { + SmartDialog.showToast('未匹配到 BV 号'); + Get.toNamed('/webview', + arguments: {'url': i['jump_url']}); + } + }, + child: Row( + children: [ + NetworkImgLayer( + width: 130, + height: 130 * 9 / 16, + src: i['cover_url'], + ), + const SizedBox(width: 6), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - NetworkImgLayer( - width: 130, - height: 130 * 9 / 16, - src: i['cover_url'], + Text( + i['field1'], + maxLines: 2, + style: TextStyle( + letterSpacing: 0.6, + height: 1.5, + color: textColor(context), + fontWeight: FontWeight.bold, + ), + ), + Text( + i['field2'], + style: TextStyle( + letterSpacing: 0.6, + height: 1.5, + color: textColor(context).withOpacity(0.6), + fontSize: 12, + ), + ), + Text( + i['field3'], + style: TextStyle( + letterSpacing: 0.6, + height: 1.5, + color: textColor(context).withOpacity(0.6), + fontSize: 12, + ), ), - const SizedBox(width: 6), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - i['field1'], - maxLines: 2, - style: TextStyle( - letterSpacing: 0.6, - height: 1.5, - color: textColor(context), - fontWeight: FontWeight.bold, - ), - ), - Text( - i['field2'], - style: TextStyle( - letterSpacing: 0.6, - height: 1.5, - color: textColor(context).withOpacity(0.6), - fontSize: 12, - ), - ), - Text( - Utils.timeFormat(int.parse(i['field3'])), - style: TextStyle( - letterSpacing: 0.6, - height: 1.5, - color: textColor(context).withOpacity(0.6), - fontSize: 12, - ), - ), - ], - )), ], )), - ], + ], + ), + ), ], - )); + ], + ), + ); default: return Text( content != null && content != ''