diff --git a/android/app/build.gradle b/android/app/build.gradle index 3dc4f82a..0e6ecb11 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -1,3 +1,9 @@ +plugins { + id "com.android.application" + id "kotlin-android" + id "dev.flutter.flutter-gradle-plugin" +} + def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { @@ -6,10 +12,6 @@ if (localPropertiesFile.exists()) { } } -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { @@ -21,9 +23,6 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" def keystorePropertiesFile = rootProject.file('key.properties') def keystoreProperties = new Properties() @@ -37,8 +36,9 @@ def _keyAlias = System.getenv("KEY_ALIAS") ?: keystoreProperties["keyAlias"] def _keyPassword = System.getenv("KEY_PASSWORD") ?: keystoreProperties["keyPassword"] android { + namespace "com.guozhigq.pilipala" compileSdkVersion flutter.compileSdkVersion - ndkVersion flutter.ndkVersion + ndkVersion "27.0.12077973" compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -91,9 +91,6 @@ flutter { source '../..' } -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} ext.abiCodes = ["x86_64": 1, "armeabi-v7a": 2, "arm64-v8a": 3] import com.android.build.OutputFile diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro new file mode 100644 index 00000000..2bcd166d --- /dev/null +++ b/android/app/proguard-rules.pro @@ -0,0 +1,4 @@ +# missing R8 error +-dontwarn javax.annotation.Nullable +-dontwarn org.conscrypt.Conscrypt +-dontwarn org.conscrypt.OpenSSLProvider \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle index 674e96f4..a7b975c2 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,15 +1,3 @@ -buildscript { - ext.kotlin_version = '1.9.0' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.2.0' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} allprojects { repositories { @@ -20,6 +8,15 @@ allprojects { rootProject.buildDir = '../build' subprojects { + afterEvaluate { project -> + if (project.hasProperty('android')) { + project.android { + if (namespace == null) { + namespace project.group + } + } + } + } project.buildDir = "${rootProject.buildDir}/${project.name}" } subprojects { diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 3c472b99..afa1e8eb 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip diff --git a/android/settings.gradle b/android/settings.gradle index 44e62bcf..f2420f21 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,11 +1,25 @@ -include ':app' +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "8.7.2" apply false + id "org.jetbrains.kotlin.android" version "1.9.0" apply false +} + +include ":app" \ No newline at end of file diff --git a/lib/common/pages_bottom_sheet.dart b/lib/common/pages_bottom_sheet.dart index 49300949..64ed40e8 100644 --- a/lib/common/pages_bottom_sheet.dart +++ b/lib/common/pages_bottom_sheet.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:pilipala/common/constants.dart'; @@ -183,7 +182,7 @@ class _PagesBottomSheetState extends State isFixedHeight: true, ); } else { - _listObserverControllerList![widget.currentEpisodeIndex!] + _listObserverControllerList![widget.currentEpisodeIndex ?? 0] .initialIndexModel = ObserverIndexPositionModel( index: currentIndex, isFixedHeight: true, diff --git a/lib/common/widgets/html_render.dart b/lib/common/widgets/html_render.dart index b2aa75ff..e4e3ef77 100644 --- a/lib/common/widgets/html_render.dart +++ b/lib/common/widgets/html_render.dart @@ -5,6 +5,8 @@ import 'package:pilipala/plugin/pl_gallery/hero_dialog_route.dart'; import 'package:pilipala/plugin/pl_gallery/interactiveviewer_gallery.dart'; import 'package:pilipala/utils/highlight.dart'; +import '../../utils/global_data_cache.dart'; + // ignore: must_be_immutable class HtmlRender extends StatelessWidget { const HtmlRender({ @@ -41,6 +43,8 @@ class HtmlRender extends StatelessWidget { TagExtension( tagsToExtend: {'img'}, builder: (ExtensionContext extensionContext) { + int defaultImgQuality = 10; + defaultImgQuality = GlobalDataCache.imgQuality; try { final Map attributes = extensionContext.attributes; @@ -99,13 +103,13 @@ class HtmlRender extends StatelessWidget { ), ); }, - child: CachedNetworkImage(imageUrl: imgUrl), + child: ClipRRect( + borderRadius: BorderRadius.circular(12), + child: CachedNetworkImage( + imageUrl: '$imgUrl@${defaultImgQuality}q.webp', + ), + ), ); - // return NetworkImgLayer( - // width: isEmote ? 22 : Get.size.width - 24, - // height: isEmote ? 22 : 200, - // src: imgUrl, - // ); } catch (err) { return const SizedBox(); } @@ -138,6 +142,14 @@ class HtmlRender extends StatelessWidget { textAlign: TextAlign.justify, ), 'img': Style(margin: Margins.only(top: 4, bottom: 4)), + 'figcaption': Style( + textAlign: TextAlign.center, + margin: Margins.only(top: 8, bottom: 20), + color: Theme.of(context).colorScheme.secondary, + ), + 'figure': Style( + margin: Margins.zero, + ), }, ); } diff --git a/lib/pages/dynamics/detail/view.dart b/lib/pages/dynamics/detail/view.dart index 186a9e9a..5c8f85e3 100644 --- a/lib/pages/dynamics/detail/view.dart +++ b/lib/pages/dynamics/detail/view.dart @@ -103,7 +103,7 @@ class _DynamicDetailPageState extends State if (!isOpusId) { _dynamicDetailController = Get.put(DynamicDetailController(oid, replyType), tag: oid.toString()); - _futureBuilderFuture ??= _dynamicDetailController.queryReplyList(); + _futureBuilderFuture = _dynamicDetailController.queryReplyList(); } } diff --git a/lib/pages/later/controller.dart b/lib/pages/later/controller.dart index 6cb8a3c0..cf408d97 100644 --- a/lib/pages/later/controller.dart +++ b/lib/pages/later/controller.dart @@ -122,6 +122,7 @@ class LaterController extends GetxController { 'heroTag': heroTag, 'sourceType': 'watchLater', 'count': laterList.length, + 'mediaId': userInfo!.mid, }, ); } diff --git a/lib/pages/opus/view.dart b/lib/pages/opus/view.dart index 42c0c419..971bb678 100644 --- a/lib/pages/opus/view.dart +++ b/lib/pages/opus/view.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; import 'package:pilipala/models/read/opus.dart'; + import 'controller.dart'; import 'text_helper.dart'; @@ -26,16 +27,18 @@ class _OpusPageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: _buildAppBar(), - body: SingleChildScrollView( + body: CustomScrollView( controller: controller.scrollController, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildTitle(), - _buildFutureContent(), - ], - ), + slivers: [ + SliverList( + delegate: SliverChildListDelegate( + [ + _buildTitle(), + _buildFutureContent(), + ], + ), + ), + ], ), ); } diff --git a/lib/pages/read/view.dart b/lib/pages/read/view.dart index 710934eb..4bc93326 100644 --- a/lib/pages/read/view.dart +++ b/lib/pages/read/view.dart @@ -6,6 +6,7 @@ import 'package:pilipala/models/read/opus.dart'; import 'package:pilipala/models/read/read.dart'; import 'package:pilipala/pages/opus/text_helper.dart'; import 'package:pilipala/utils/utils.dart'; + import 'controller.dart'; class ReadPage extends StatefulWidget { @@ -38,16 +39,18 @@ class _ReadPageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: _buildAppBar(), - body: SingleChildScrollView( + body: CustomScrollView( controller: controller.scrollController, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildTitle(), - _buildFutureContent(), - ], - ), + slivers: [ + SliverList( + delegate: SliverChildListDelegate( + [ + _buildTitle(), + _buildFutureContent(), + ], + ), + ), + ], ), ); } diff --git a/lib/pages/video/detail/controller.dart b/lib/pages/video/detail/controller.dart index 4fdf8420..ad5cce70 100644 --- a/lib/pages/video/detail/controller.dart +++ b/lib/pages/video/detail/controller.dart @@ -624,10 +624,8 @@ class VideoDetailController extends GetxController } void toggeleWatchLaterVisible(bool val) { - if (sourceType.value == 'watchLater' || - sourceType.value == 'fav' || - sourceType.value == 'up_archive') { - isWatchLaterVisible.value = !isWatchLaterVisible.value; + if (['watchLater', 'fav', 'up_archive'].contains(sourceType.value)) { + isWatchLaterVisible.value = val; } } diff --git a/lib/pages/video/detail/introduction/controller.dart b/lib/pages/video/detail/introduction/controller.dart index bc8fe81a..d16d85a8 100644 --- a/lib/pages/video/detail/introduction/controller.dart +++ b/lib/pages/video/detail/introduction/controller.dart @@ -523,7 +523,7 @@ class VideoIntroController extends GetxController { Get.find(tag: heroTag); /// 优先稍后再看、收藏夹 - if (videoDetailCtr.isWatchLaterVisible.value) { + if (videoDetailCtr.sourceType.value != 'normal') { episodes.addAll(videoDetailCtr.mediaList); } else if (videoDetail.value.ugcSeason != null) { final UgcSeason ugcSeason = videoDetail.value.ugcSeason!; @@ -617,6 +617,7 @@ class VideoIntroController extends GetxController { // 播放器底栏 选集 回调 void showEposideHandler() { late List episodes; + int currentEpisodeIndex = 0; VideoEpidoesType dataType = VideoEpidoesType.videoEpisode; if (videoDetail.value.ugcSeason != null) { dataType = VideoEpidoesType.videoEpisode; @@ -625,6 +626,7 @@ class VideoIntroController extends GetxController { final List episodesList = sections[i].episodes!; for (int j = 0; j < episodesList.length; j++) { if (episodesList[j].cid == lastPlayCid.value) { + currentEpisodeIndex = i; episodes = episodesList; continue; } @@ -644,6 +646,7 @@ class VideoIntroController extends GetxController { sheetHeight: Get.size.height, isFullScreen: true, ugcSeason: ugcSeason, + currentEpisodeIndex: currentEpisodeIndex, changeFucCall: (item, index) { if (dataType == VideoEpidoesType.videoEpisode) { changeSeasonOrbangu( diff --git a/lib/pages/video/detail/introduction/widgets/season_panel.dart b/lib/pages/video/detail/introduction/widgets/season_panel.dart index acc5f115..05f67631 100644 --- a/lib/pages/video/detail/introduction/widgets/season_panel.dart +++ b/lib/pages/video/detail/introduction/widgets/season_panel.dart @@ -42,23 +42,14 @@ class _SeasonPanelState extends State { _videoDetailController = Get.find(tag: heroTag); /// 根据 cid 找到对应集,找到对应 episodes - final List sections = widget.ugcSeason.sections!; - for (int i = 0; i < sections.length; i++) { - final List episodesList = sections[i].episodes!; - for (int j = 0; j < episodesList.length; j++) { - if (episodesList[j].cid == cid) { - currentEpisodeIndex = i; - episodes = episodesList; - continue; - } - } - } + getCurrentEpisodeIndex(); /// 取对应 season_id 的 episodes getCurrentIndex(); _videoDetailController.cid.listen((int p0) { cid = p0; getCurrentIndex(); + getCurrentEpisodeIndex(); }); } @@ -94,6 +85,21 @@ class _SeasonPanelState extends State { } } + // 获取currentEpisodeIndex + void getCurrentEpisodeIndex() { + final List sections = widget.ugcSeason.sections!; + for (int i = 0; i < sections.length; i++) { + final List episodesList = sections[i].episodes!; + for (int j = 0; j < episodesList.length; j++) { + if (episodesList[j].cid == cid) { + currentEpisodeIndex = i; + episodes = episodesList; + continue; + } + } + } + } + Widget buildEpisodeListItem( EpisodeItem episode, int index, diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index c7896480..0ec777c4 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -206,12 +206,12 @@ class _VideoDetailPageState extends State vdCtr.bottomList.insert(3, BottomControlType.episode); } } + vdCtr.toggeleWatchLaterVisible(false); } else { if (vdCtr.bottomList.contains(BottomControlType.episode)) { vdCtr.bottomList.removeAt(3); } } - vdCtr.toggeleWatchLaterVisible(!isFullScreen); }); } @@ -554,6 +554,11 @@ class _VideoDetailPageState extends State playerController: plPlayerController!, ), bottomList: vdCtr.bottomList, + fullScreenCb: (bool status) { + if (vdCtr.videoDirection.value == 'vertical') { + videoHeight.value = status ? Get.size.height : verticalHeight; + } + }, showEposideCb: () => vdCtr.videoType == SearchType.video ? videoIntroController.showEposideHandler() : bangumiIntroController.showEposideHandler(), @@ -825,9 +830,8 @@ class _VideoDetailPageState extends State /// 稍后再看列表 Obx( () => Visibility( - visible: vdCtr.sourceType.value == 'watchLater' || - vdCtr.sourceType.value == 'fav' || - vdCtr.sourceType.value == 'up_archive', + visible: ['watchLater', 'fav', 'up_archive'] + .contains(vdCtr.sourceType.value), child: AnimatedPositioned( duration: const Duration(milliseconds: 400), curve: Curves.easeInOut, diff --git a/lib/pages/video/detail/widgets/watch_later_list.dart b/lib/pages/video/detail/widgets/watch_later_list.dart index 93326ec3..6d675dd8 100644 --- a/lib/pages/video/detail/widgets/watch_later_list.dart +++ b/lib/pages/video/detail/widgets/watch_later_list.dart @@ -85,9 +85,12 @@ class _MediaListPanelState extends State { AppBar( toolbarHeight: 45, automaticallyImplyLeading: false, - title: Text( - widget.panelTitle ?? '稍后再看', - style: Theme.of(context).textTheme.titleSmall, + title: Padding( + padding: const EdgeInsets.only(left: 12), + child: Text( + widget.panelTitle ?? '稍后再看', + style: Theme.of(context).textTheme.titleSmall, + ), ), actions: [ IconButton( diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index dab32b5c..e95fe647 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -81,7 +81,7 @@ class PlPlayerController { final Rx _subTitleOpen = false.obs; final Rx _subTitleCode = (-1).obs; // 默认投稿视频格式 - static Rx _videoType = 'archive'.obs; + static String _videoType = 'archive'; final Rx _direction = 'horizontal'.obs; @@ -127,7 +127,6 @@ class PlPlayerController { PreferredSizeWidget? bottomControl; Widget? danmuWidget; RxList subtitles = [].obs; - String videoType = 'archive'; /// 数据加载监听 Stream get onDataStatusChanged => dataStatus.status.stream; @@ -225,7 +224,7 @@ class PlPlayerController { Rx get playerCount => _playerCount; /// - // Rx get videoType => _videoType; + String get videoType => _videoType; /// 弹幕开关 Rx isOpenDanmu = false.obs; @@ -279,7 +278,7 @@ class PlPlayerController { } // 添加一个私有构造函数 - PlPlayerController._internal(this.videoType) { + PlPlayerController._internal() { isOpenDanmu.value = GlobalDataCache.isOpenDanmu; blockTypes = GlobalDataCache.blockTypes; showArea = GlobalDataCache.showArea; @@ -306,11 +305,11 @@ class PlPlayerController { String videoType = 'archive', }) { // 如果实例尚未创建,则创建一个新实例 - _instance ??= PlPlayerController._internal(videoType); + _instance ??= PlPlayerController._internal(); if (videoType != 'none') { _instance!._playerCount.value += 1; - _videoType.value = videoType; } + _videoType = videoType; return _instance!; } diff --git a/pubspec.lock b/pubspec.lock index 715b23a5..d29eb4f3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -85,10 +85,10 @@ packages: dependency: "direct main" description: name: audio_service - sha256: "4547c312a94f9cb2c48b60823fb190767cbd63454a83c73049384d5d3cba4650" + sha256: "9dd5ba7e77567b290c35908b1950d61485b4dfdd3a0ac398e98cfeec04651b75" url: "https://pub.flutter-io.cn" source: hosted - version: "0.18.13" + version: "0.18.15" audio_service_platform_interface: dependency: transitive description: @@ -101,18 +101,18 @@ packages: dependency: transitive description: name: audio_service_web - sha256: "9d7d5ae5f98a5727f2580fad73062f2484f400eef6cef42919413268e62a363e" + sha256: "4cdc2127cd4562b957fb49227dc58e3303fafb09bde2573bc8241b938cf759d9" url: "https://pub.flutter-io.cn" source: hosted - version: "0.1.2" + version: "0.1.3" audio_session: dependency: "direct main" description: name: audio_session - sha256: "6fdf255ed3af86535c96452c33ecff1245990bb25a605bfb1958661ccc3d467f" + sha256: "343e83bc7809fbda2591a49e525d6b63213ade10c76f15813be9aed6657b3261" url: "https://pub.flutter-io.cn" source: hosted - version: "0.1.18" + version: "0.1.21" audio_video_progress_bar: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 80a8b067..6ee98cc3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -89,8 +89,8 @@ dependencies: media_kit_libs_video: ^1.0.4 # 媒体通知 - audio_service: ^0.18.13 - audio_session: ^0.1.18 + audio_service: ^0.18.15 + audio_session: ^0.1.21 # 音量、亮度、屏幕控制 flutter_volume_controller: ^1.3.2