mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-04-20 03:06:59 +08:00
Compare commits
6 Commits
51163dd985
...
6341660788
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6341660788 | ||
|
|
a1dbcae93e | ||
|
|
1526137a64 | ||
|
|
3097b56816 | ||
|
|
db74eccf77 | ||
|
|
14890d342a |
@@ -1,5 +1,6 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.piliplus">
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@@ -16,8 +17,7 @@
|
||||
</queries>
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name=
|
||||
"android.support.customtabs.action.CustomTabsService" />
|
||||
<action android:name="android.support.customtabs.action.CustomTabsService" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
@@ -35,56 +35,62 @@
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<application
|
||||
android:label="@string/app_name"
|
||||
<application xmlns:tools="http://schemas.android.com/tools"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:enableOnBackInvokedCallback="false"
|
||||
android:allowBackup="false"
|
||||
android:enableOnBackInvokedCallback="false"
|
||||
android:fullBackupContent="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
tools:replace="android:allowBackup">
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.EnableImpeller"
|
||||
android:value="false" />
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:exported="true"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:supportsPictureInPicture="true"
|
||||
android:launchMode="singleTask"
|
||||
android:resizeableActivity="true"
|
||||
>
|
||||
android:supportsPictureInPicture="true"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
|
||||
<meta-data android:name="flutter_deeplinking_enabled" android:value="false" />
|
||||
<meta-data
|
||||
android:name="android.app.shortcuts"
|
||||
android:resource="@xml/shortcuts" />
|
||||
|
||||
<meta-data
|
||||
android:name="flutter_deeplinking_enabled"
|
||||
android:value="false" />
|
||||
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
to determine the Window background behind the Flutter UI. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme" />
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter android:label="PiliPlus">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="http"/>
|
||||
<data android:scheme="https"/>
|
||||
<data android:host="*.bilibili.com"/>
|
||||
<data android:host="*.bilibili.cn"/>
|
||||
<data android:host="*.bilibili.tv"/>
|
||||
<data android:host="bilibili.com"/>
|
||||
<data android:host="bilibili.cn"/>
|
||||
<data android:host="bilibili.tv"/>
|
||||
|
||||
<data android:scheme="http" />
|
||||
<data android:scheme="https" />
|
||||
<data android:host="*.bilibili.com" />
|
||||
<data android:host="*.bilibili.cn" />
|
||||
<data android:host="*.bilibili.tv" />
|
||||
<data android:host="bilibili.com" />
|
||||
<data android:host="bilibili.cn" />
|
||||
<data android:host="bilibili.tv" />
|
||||
<data android:host="b23.tv" />
|
||||
<!--<data android:host="live.bilibili.com"/>-->
|
||||
<!--<data android:host="www.bilibili.com"/>-->
|
||||
@@ -100,36 +106,56 @@
|
||||
<intent-filter android:label="PiliPlus">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<action android:name="android.intent.action.SEARCH" />
|
||||
<action android:name="com.example.piliplus.SHORTCUT" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="bilibili"/>
|
||||
|
||||
<data android:scheme="bilibili" />
|
||||
<data android:host="download" />
|
||||
<data android:host="forward" />
|
||||
<data android:host="comment"
|
||||
<data
|
||||
android:host="comment"
|
||||
android:pathPattern="/detail/.*/.*/.*" />
|
||||
<data android:host="uper" />
|
||||
<data android:host="article"
|
||||
<data
|
||||
android:host="article"
|
||||
android:pathPattern="/readlist" />
|
||||
<data android:host="opus" />
|
||||
<data android:host="advertise" android:path="/home" />
|
||||
<data
|
||||
android:host="advertise"
|
||||
android:path="/home" />
|
||||
<data android:host="clip" />
|
||||
<data android:host="search" android:pathPattern=".*" />
|
||||
<data
|
||||
android:host="search"
|
||||
android:pathPattern=".*" />
|
||||
<data android:host="stardust-search" />
|
||||
<data android:host="music" />
|
||||
<data android:host="cheese" />
|
||||
<data android:host="bangumi"
|
||||
<data
|
||||
android:host="bangumi"
|
||||
android:pathPattern="/season.*" />
|
||||
<data android:host="bangumi" android:pathPattern="/.*" />
|
||||
<data android:host="pictureshow"
|
||||
<data
|
||||
android:host="bangumi"
|
||||
android:pathPattern="/.*" />
|
||||
<data
|
||||
android:host="pictureshow"
|
||||
android:pathPrefix="/creative_center" />
|
||||
<data android:host="cliparea" />
|
||||
<data android:host="im" />
|
||||
<data android:host="im" android:path="/notifications" />
|
||||
<data
|
||||
android:host="im"
|
||||
android:path="/notifications" />
|
||||
<data android:host="following" />
|
||||
<data android:host="following"
|
||||
<data
|
||||
android:host="following"
|
||||
android:pathPattern="/detail/.*" />
|
||||
<data android:host="following"
|
||||
<data
|
||||
android:host="following"
|
||||
android:path="/publishInfo/" />
|
||||
<data android:host="laser" android:pathPattern="/.*" />
|
||||
<data
|
||||
android:host="laser"
|
||||
android:pathPattern="/.*" />
|
||||
<data android:host="livearea" />
|
||||
<data android:host="live" />
|
||||
<data android:host="catalog" />
|
||||
@@ -147,28 +173,44 @@
|
||||
<data android:host="video" />
|
||||
<data android:host="story" />
|
||||
<data android:host="podcast" />
|
||||
<data android:host="main" android:path="/favorite" />
|
||||
<data android:host="pgc" android:path="/theater/match" />
|
||||
<data android:host="pgc" android:path="/theater/square" />
|
||||
<data android:host="m.bilibili.com"
|
||||
<data
|
||||
android:host="main"
|
||||
android:path="/favorite" />
|
||||
<data
|
||||
android:host="pgc"
|
||||
android:path="/theater/match" />
|
||||
<data
|
||||
android:host="pgc"
|
||||
android:path="/theater/square" />
|
||||
<data
|
||||
android:host="m.bilibili.com"
|
||||
android:path="/topic-detail" />
|
||||
<data android:host="article" />
|
||||
<data android:host="pegasus"
|
||||
<data
|
||||
android:host="pegasus"
|
||||
android:pathPattern="/channel/v2/.*" />
|
||||
<data android:host="feed" android:pathPattern="/channel" />
|
||||
<data
|
||||
android:host="feed"
|
||||
android:pathPattern="/channel" />
|
||||
<data android:host="vip" />
|
||||
<data android:host="user_center" android:path="/vip" />
|
||||
<data
|
||||
android:host="user_center"
|
||||
android:path="/vip" />
|
||||
<data android:host="history" />
|
||||
<data android:host="charge" android:path="/rank" />
|
||||
<data
|
||||
android:host="charge"
|
||||
android:path="/rank" />
|
||||
<data android:host="assistant" />
|
||||
<data android:host="feedback" />
|
||||
<data android:host="auth" android:path="/launch" />
|
||||
<data
|
||||
android:host="auth"
|
||||
android:path="/launch" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<service
|
||||
<service
|
||||
android:name="com.ryanheise.audioservice.AudioService"
|
||||
android:exported="true"
|
||||
android:foregroundServiceType="mediaPlayback"
|
||||
android:exported="true"
|
||||
tools:ignore="Instantiatable">
|
||||
<intent-filter>
|
||||
<action android:name="android.media.browse.MediaBrowserService" />
|
||||
@@ -177,32 +219,37 @@
|
||||
|
||||
<activity
|
||||
android:name="com.yalantis.ucrop.UCropActivity"
|
||||
android:theme="@style/Ucrop.CropTheme"/>
|
||||
android:theme="@style/Ucrop.CropTheme" />
|
||||
|
||||
<receiver
|
||||
<receiver
|
||||
android:name="com.ryanheise.audioservice.MediaButtonReceiver"
|
||||
android:exported="true"
|
||||
android:exported="true"
|
||||
tools:ignore="Instantiatable">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MEDIA_BUTTON" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</receiver>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
</application>
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/>
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
<uses-permission
|
||||
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="32" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="28" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<!--
|
||||
Media access permissions.
|
||||
Android 13 or higher.
|
||||
@@ -210,5 +257,5 @@
|
||||
-->
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||
</manifest>
|
||||
|
||||
10
android/app/src/main/res/drawable/download.xml
Normal file
10
android/app/src/main/res/drawable/download.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#515151"
|
||||
android:pathData="M16.59 9H15V4c0-.55-.45-1-1-1h-4c-.55 0-1 .45-1 1v5H7.41c-.89 0-1.34 1.08-.71 1.71l4.59 4.59c.39.39 1.02.39 1.41 0l4.59-4.59c.63-.63.19-1.71-.7-1.71zM5 19c0 .55.45 1 1 1h12c.55 0 1-.45 1-1s-.45-1-1-1H6c-.55 0-1 .45-1 1z" />
|
||||
</vector>
|
||||
10
android/app/src/main/res/drawable/search.xml
Normal file
10
android/app/src/main/res/drawable/search.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#515151"
|
||||
android:pathData="M15.5 14h-.79l-.28-.27c1.2-1.4 1.82-3.31 1.48-5.34-.47-2.78-2.79-5-5.59-5.34-4.23-.52-7.79 3.04-7.27 7.27.34 2.8 2.56 5.12 5.34 5.59 2.03.34 3.94-.28 5.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" />
|
||||
</vector>
|
||||
@@ -1,3 +1,5 @@
|
||||
<resources>
|
||||
<string name="app_name">PiliPlus</string>
|
||||
<string name="search">搜索</string>
|
||||
<string name="offline_video">离线视频</string>
|
||||
</resources>
|
||||
20
android/app/src/main/res/xml-v25/shortcuts.xml
Normal file
20
android/app/src/main/res/xml-v25/shortcuts.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<shortcut
|
||||
android:icon="@drawable/search"
|
||||
android:shortcutId="search"
|
||||
android:shortcutLongLabel="@string/search"
|
||||
android:shortcutShortLabel="@string/search">
|
||||
<intent
|
||||
android:action="com.example.piliplus.SHORTCUT"
|
||||
android:data="bilibili://search" />
|
||||
</shortcut>
|
||||
<shortcut
|
||||
android:icon="@drawable/download"
|
||||
android:shortcutId="offline_video"
|
||||
android:shortcutLongLabel="@string/offline_video"
|
||||
android:shortcutShortLabel="@string/offline_video">
|
||||
<intent
|
||||
android:action="com.example.piliplus.SHORTCUT"
|
||||
android:data="bilibili://download" />
|
||||
</shortcut>
|
||||
</shortcuts>
|
||||
@@ -6,8 +6,6 @@ PODS:
|
||||
- FlutterMacOS
|
||||
- audio_session (0.0.1):
|
||||
- Flutter
|
||||
- auto_orientation (0.0.1):
|
||||
- Flutter
|
||||
- battery_plus (1.0.0):
|
||||
- Flutter
|
||||
- chat_bottom_container (0.0.1):
|
||||
@@ -83,6 +81,8 @@ PODS:
|
||||
- Flutter
|
||||
- media_kit_video (0.0.1):
|
||||
- Flutter
|
||||
- native_device_orientation (0.0.1):
|
||||
- Flutter
|
||||
- OrderedSet (6.0.3)
|
||||
- package_info_plus (0.4.5):
|
||||
- Flutter
|
||||
@@ -114,7 +114,6 @@ DEPENDENCIES:
|
||||
- app_links (from `.symlinks/plugins/app_links/ios`)
|
||||
- audio_service (from `.symlinks/plugins/audio_service/darwin`)
|
||||
- audio_session (from `.symlinks/plugins/audio_session/ios`)
|
||||
- auto_orientation (from `.symlinks/plugins/auto_orientation/ios`)
|
||||
- battery_plus (from `.symlinks/plugins/battery_plus/ios`)
|
||||
- chat_bottom_container (from `.symlinks/plugins/chat_bottom_container/ios`)
|
||||
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
||||
@@ -133,6 +132,7 @@ DEPENDENCIES:
|
||||
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
|
||||
- media_kit_native_event_loop (from `.symlinks/plugins/media_kit_native_event_loop/ios`)
|
||||
- media_kit_video (from `.symlinks/plugins/media_kit_video/ios`)
|
||||
- native_device_orientation (from `.symlinks/plugins/native_device_orientation/ios`)
|
||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||
- saver_gallery (from `.symlinks/plugins/saver_gallery/ios`)
|
||||
@@ -160,8 +160,6 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/audio_service/darwin"
|
||||
audio_session:
|
||||
:path: ".symlinks/plugins/audio_session/ios"
|
||||
auto_orientation:
|
||||
:path: ".symlinks/plugins/auto_orientation/ios"
|
||||
battery_plus:
|
||||
:path: ".symlinks/plugins/battery_plus/ios"
|
||||
chat_bottom_container:
|
||||
@@ -198,6 +196,8 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/media_kit_native_event_loop/ios"
|
||||
media_kit_video:
|
||||
:path: ".symlinks/plugins/media_kit_video/ios"
|
||||
native_device_orientation:
|
||||
:path: ".symlinks/plugins/native_device_orientation/ios"
|
||||
package_info_plus:
|
||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||
permission_handler_apple:
|
||||
@@ -221,7 +221,6 @@ SPEC CHECKSUMS:
|
||||
app_links: a754cbec3c255bd4bbb4d236ecc06f28cd9a7ce8
|
||||
audio_service: aa99a6ba2ae7565996015322b0bb024e1d25c6fd
|
||||
audio_session: 9bb7f6c970f21241b19f5a3658097ae459681ba0
|
||||
auto_orientation: a1600c9ed72e6e96982fb4e1214463343342432a
|
||||
battery_plus: b42253f6d2dde71712f8c36fef456d99121c5977
|
||||
chat_bottom_container: f1eb8323db77a87db50f361142c679f11e892d1b
|
||||
connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
|
||||
@@ -243,6 +242,7 @@ SPEC CHECKSUMS:
|
||||
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
|
||||
media_kit_native_event_loop: 5fba1a849a6c87a34985f1e178a0de5bd444a0cf
|
||||
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
|
||||
native_device_orientation: e3580675687d5034770da198f6839ebf2122ef94
|
||||
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
||||
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
|
||||
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
|
||||
|
||||
@@ -9,6 +9,7 @@ import 'package:PiliPlus/common/widgets/scale_app.dart';
|
||||
import 'package:PiliPlus/common/widgets/scroll_behavior.dart';
|
||||
import 'package:PiliPlus/http/init.dart';
|
||||
import 'package:PiliPlus/models/common/theme/theme_color_type.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart';
|
||||
import 'package:PiliPlus/router/app_pages.dart';
|
||||
import 'package:PiliPlus/services/account_service.dart';
|
||||
import 'package:PiliPlus/services/download/download_service.dart';
|
||||
@@ -28,6 +29,7 @@ import 'package:PiliPlus/utils/storage_pref.dart';
|
||||
import 'package:PiliPlus/utils/theme_utils.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:catcher_2/catcher_2.dart';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -82,6 +84,10 @@ Future<void> _initAppPath() async {
|
||||
appSupportDirPath = (await getApplicationSupportDirectory()).path;
|
||||
}
|
||||
|
||||
Future<void> _initSdkInt() async {
|
||||
Utils.sdkInt = (await DeviceInfoPlugin().androidInfo).version.sdkInt;
|
||||
}
|
||||
|
||||
void main() async {
|
||||
ScaledWidgetsFlutterBinding.ensureInitialized();
|
||||
MediaKit.ensureInitialized();
|
||||
@@ -104,15 +110,8 @@ void main() async {
|
||||
|
||||
if (PlatformUtils.isMobile) {
|
||||
await Future.wait([
|
||||
SystemChrome.setPreferredOrientations(
|
||||
[
|
||||
DeviceOrientation.portraitUp,
|
||||
if (Pref.horizontalScreen) ...[
|
||||
DeviceOrientation.landscapeLeft,
|
||||
DeviceOrientation.landscapeRight,
|
||||
],
|
||||
],
|
||||
),
|
||||
if (Platform.isAndroid) _initSdkInt(),
|
||||
if (Pref.horizontalScreen) ?fullMode() else ?portraitUpMode(),
|
||||
setupServiceLocator(),
|
||||
]);
|
||||
} else if (Platform.isWindows) {
|
||||
@@ -131,12 +130,10 @@ void main() async {
|
||||
Request.setCookie();
|
||||
RequestUtils.syncHistoryStatus();
|
||||
|
||||
SmartDialog.config.toast = SmartConfigToast(
|
||||
displayType: SmartToastType.onlyRefresh,
|
||||
);
|
||||
SmartDialog.config.toast = SmartConfigToast(displayType: .onlyRefresh);
|
||||
|
||||
if (PlatformUtils.isMobile) {
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
|
||||
SystemChrome.setEnabledSystemUIMode(.edgeToEdge);
|
||||
SystemChrome.setSystemUIOverlayStyle(
|
||||
const SystemUiOverlayStyle(
|
||||
systemNavigationBarColor: Colors.transparent,
|
||||
|
||||
@@ -30,7 +30,6 @@ import 'package:PiliPlus/pages/video/widgets/player_focus.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/controller.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/play_status.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/utils/danmaku_options.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/view/view.dart';
|
||||
import 'package:PiliPlus/services/service_locator.dart';
|
||||
import 'package:PiliPlus/utils/extension/num_ext.dart';
|
||||
@@ -92,6 +91,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
maxWidth = size.width;
|
||||
maxHeight = size.height;
|
||||
isPortrait = size.isPortrait;
|
||||
plPlayerController.screenRatio = maxHeight / maxWidth;
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -169,19 +169,12 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
if (state == AppLifecycleState.resumed) {
|
||||
if (plPlayerController.visible = state == .resumed) {
|
||||
if (!plPlayerController.showDanmaku) {
|
||||
_liveRoomController.startLiveTimer();
|
||||
plPlayerController.showDanmaku = true;
|
||||
if (isFullScreen && Platform.isIOS) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (!_liveRoomController.isPortrait.value) {
|
||||
landscape();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (state == AppLifecycleState.paused) {
|
||||
} else if (state == .paused) {
|
||||
_liveRoomController.cancelLiveTimer();
|
||||
plPlayerController
|
||||
..showDanmaku = false
|
||||
@@ -353,7 +346,8 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
}
|
||||
return popScope(
|
||||
canPop: !isFullScreen && !plPlayerController.isDesktopPip,
|
||||
onPopInvokedWithResult: plPlayerController.onPopInvokedWithResult,
|
||||
onPopInvokedWithResult: (didPop, result) =>
|
||||
plPlayerController.onPopInvokedWithResult(didPop, result, isPortrait),
|
||||
child: player,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ import 'package:PiliPlus/utils/page_utils.dart';
|
||||
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
|
||||
import 'package:flutter/foundation.dart' show kDebugMode;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
@@ -383,7 +382,7 @@ class _MemberPageState extends State<MemberPage> {
|
||||
],
|
||||
),
|
||||
),
|
||||
if (kDebugMode || PlatformUtils.isMobile)
|
||||
if (PlatformUtils.isMobile)
|
||||
PopupMenuItem(
|
||||
onTap: _createShortcut,
|
||||
child: const Row(
|
||||
|
||||
@@ -880,11 +880,17 @@ class UserInfoCard extends StatelessWidget {
|
||||
),
|
||||
];
|
||||
if (children.isNotEmpty) {
|
||||
Widget child;
|
||||
if (children.length == 1) {
|
||||
child = children.first;
|
||||
} else {
|
||||
child = isPortrait
|
||||
? Row(mainAxisAlignment: .spaceBetween, children: children)
|
||||
: Wrap(spacing: 10, runSpacing: 6, children: children);
|
||||
}
|
||||
return Padding(
|
||||
padding: const .only(left: 20, right: 20, top: 6),
|
||||
child: isPortrait
|
||||
? Row(mainAxisAlignment: .spaceBetween, children: children)
|
||||
: Wrap(spacing: 10, runSpacing: 6, children: children),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -33,6 +33,8 @@ class MemberGuardController
|
||||
tops = list.take(3).toList();
|
||||
if (list.length > 3) {
|
||||
list.removeRange(0, 3);
|
||||
} else {
|
||||
list.clear();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -9,8 +9,6 @@ import 'package:PiliPlus/pages/setting/widgets/select_dialog.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/bottom_progress_behavior.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/fullscreen_mode.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/play_repeat.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart'
|
||||
show allowRotateScreen;
|
||||
import 'package:PiliPlus/services/service_locator.dart';
|
||||
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
@@ -175,14 +173,6 @@ List<SettingsModel> get playSettings => [
|
||||
setKey: SettingBoxKey.enableLongShowControl,
|
||||
defaultVal: false,
|
||||
),
|
||||
SwitchModel(
|
||||
title: '全向旋转',
|
||||
subtitle: '小屏可受重力转为临时全屏,若系统锁定旋转仍触发请关闭,关闭会影响横屏适配',
|
||||
leading: const Icon(Icons.screen_rotation_alt_outlined),
|
||||
setKey: SettingBoxKey.allowRotateScreen,
|
||||
defaultVal: true,
|
||||
onChanged: (value) => allowRotateScreen = value,
|
||||
),
|
||||
if (PlatformUtils.isMobile)
|
||||
const SwitchModel(
|
||||
title: '后台播放',
|
||||
|
||||
@@ -35,7 +35,6 @@ import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
import 'package:PiliPlus/utils/storage_key.dart';
|
||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||
import 'package:auto_orientation/auto_orientation.dart';
|
||||
import 'package:flutter/material.dart' hide StatefulBuilder;
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
@@ -69,9 +68,9 @@ List<SettingsModel> get styleSettings => [
|
||||
defaultVal: Pref.horizontalScreen,
|
||||
onChanged: (value) {
|
||||
if (value) {
|
||||
autoScreen();
|
||||
fullMode();
|
||||
} else {
|
||||
AutoOrientation.portraitUpMode();
|
||||
portraitUpMode();
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
@@ -61,7 +61,6 @@ import 'package:PiliPlus/utils/page_utils.dart';
|
||||
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
import 'package:PiliPlus/utils/storage_key.dart';
|
||||
import 'package:auto_orientation/auto_orientation.dart';
|
||||
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
|
||||
import 'package:floating/floating.dart';
|
||||
import 'package:flutter/foundation.dart' show kDebugMode;
|
||||
@@ -162,7 +161,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
}
|
||||
|
||||
videoSourceInit();
|
||||
autoScreen();
|
||||
|
||||
addObserverMobile(this);
|
||||
}
|
||||
@@ -184,29 +182,14 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
late final ctr = videoDetailController.plPlayerController;
|
||||
if (state == AppLifecycleState.resumed) {
|
||||
final isResume = state == .resumed;
|
||||
final ctr = videoDetailController.plPlayerController..visible = isResume;
|
||||
if (isResume) {
|
||||
if (!ctr.showDanmaku) {
|
||||
introController.startTimer();
|
||||
ctr.showDanmaku = true;
|
||||
|
||||
// 修复从后台恢复时全屏状态下屏幕方向错误的问题
|
||||
if (isFullScreen && Platform.isIOS) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// 根据视频方向重新设置屏幕方向
|
||||
final isVertical = videoDetailController.isVertical.value;
|
||||
final mode = ctr.mode;
|
||||
|
||||
if (!(mode == FullScreenMode.vertical ||
|
||||
(mode == FullScreenMode.auto && isVertical) ||
|
||||
(mode == FullScreenMode.ratio &&
|
||||
(isVertical || maxHeight / maxWidth < kScreenRatio)))) {
|
||||
landscape();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (state == AppLifecycleState.paused) {
|
||||
} else if (state == .paused) {
|
||||
introController.cancelTimer();
|
||||
ctr.showDanmaku = false;
|
||||
}
|
||||
@@ -362,9 +345,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
pgcIntroController.cancelTimer();
|
||||
}
|
||||
}
|
||||
if (!videoDetailController.horizontalScreen) {
|
||||
AutoOrientation.portraitUpMode();
|
||||
}
|
||||
|
||||
if (!videoDetailController.plPlayerController.isCloseAll) {
|
||||
videoPlayerServiceHandler?.onVideoDetailDispose(heroTag);
|
||||
if (plPlayerController != null) {
|
||||
@@ -414,7 +395,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
void didPopNext() {
|
||||
super.didPopNext();
|
||||
|
||||
if (plPlayerController?.isCloseAll ?? false) {
|
||||
if (videoDetailController.plPlayerController.isCloseAll) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -472,6 +453,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
final size = MediaQuery.sizeOf(context);
|
||||
maxWidth = size.width;
|
||||
maxHeight = size.height;
|
||||
videoDetailController.plPlayerController.screenRatio = maxHeight / maxWidth;
|
||||
|
||||
final shortestSide = size.shortestSide;
|
||||
final minVideoHeight = shortestSide / Style.aspectRatio16x9;
|
||||
@@ -528,34 +510,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
videoDetailController.animationController
|
||||
..removeListener(animListener)
|
||||
..addListener(animListener);
|
||||
if (PlatformUtils.isMobile && mounted && isShowing && !isFullScreen) {
|
||||
if (isPortrait) {
|
||||
showStatusBar();
|
||||
} else if (!videoDetailController.horizontalScreen) {
|
||||
hideStatusBar();
|
||||
}
|
||||
}
|
||||
if (PlatformUtils.isMobile) {
|
||||
if (!isPortrait &&
|
||||
!isFullScreen &&
|
||||
plPlayerController != null &&
|
||||
videoDetailController.autoPlay) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
plPlayerController!.triggerFullScreen(
|
||||
status: true,
|
||||
isManualFS: false,
|
||||
mode: FullScreenMode.gravity,
|
||||
);
|
||||
});
|
||||
} else if (isPortrait &&
|
||||
isFullScreen &&
|
||||
plPlayerController?.isManualFS == false &&
|
||||
plPlayerController?.controlsLock.value == false) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
plPlayerController!.triggerFullScreen(status: false);
|
||||
});
|
||||
}
|
||||
}
|
||||
return Obx(
|
||||
() {
|
||||
final isFullScreen = this.isFullScreen;
|
||||
@@ -701,15 +655,9 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
.colorScheme
|
||||
.onSurface,
|
||||
),
|
||||
onPressed: () {
|
||||
videoDetailController
|
||||
.plPlayerController
|
||||
..isCloseAll = true
|
||||
..dispose();
|
||||
Get.until(
|
||||
(route) => route.isFirst,
|
||||
);
|
||||
},
|
||||
onPressed: videoDetailController
|
||||
.plPlayerController
|
||||
.onCloseAll,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1239,12 +1187,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
videoDetailController.plPlayerController
|
||||
..isCloseAll = true
|
||||
..dispose();
|
||||
Get.until((route) => route.isFirst);
|
||||
},
|
||||
onPressed:
|
||||
videoDetailController.plPlayerController.onCloseAll,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -2174,14 +2118,11 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
}
|
||||
|
||||
void _onPopInvokedWithResult(bool didPop, result) {
|
||||
if (plPlayerController?.onPopInvokedWithResult(didPop, result) ?? false) {
|
||||
return;
|
||||
}
|
||||
if (PlatformUtils.isMobile &&
|
||||
!videoDetailController.horizontalScreen &&
|
||||
!isPortrait) {
|
||||
verticalScreenForTwoSeconds();
|
||||
}
|
||||
videoDetailController.plPlayerController.onPopInvokedWithResult(
|
||||
didPop,
|
||||
result,
|
||||
isPortrait,
|
||||
);
|
||||
}
|
||||
|
||||
void onShowMemberPage(int? mid) {
|
||||
|
||||
@@ -35,7 +35,6 @@ import 'package:PiliPlus/pages/video/widgets/header_mixin.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/controller.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/data_source.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/play_repeat.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart';
|
||||
import 'package:PiliPlus/services/service_locator.dart';
|
||||
import 'package:PiliPlus/services/shutdown_timer_service.dart'
|
||||
show shutdownTimerService;
|
||||
@@ -1757,21 +1756,11 @@ class HeaderControlState extends State<HeaderControl>
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
onPressed: () {
|
||||
if (plPlayerController.onPopInvokedWithResult(
|
||||
false,
|
||||
null,
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
if (PlatformUtils.isMobile &&
|
||||
!horizontalScreen &&
|
||||
!isPortrait) {
|
||||
verticalScreenForTwoSeconds();
|
||||
} else {
|
||||
Get.back();
|
||||
}
|
||||
},
|
||||
onPressed: () => plPlayerController.onPopInvokedWithResult(
|
||||
false,
|
||||
null,
|
||||
videoDetailCtr.isPortrait,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (!plPlayerController.isDesktopPip &&
|
||||
@@ -1787,12 +1776,7 @@ class HeaderControlState extends State<HeaderControl>
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
onPressed: () {
|
||||
videoDetailCtr.plPlayerController
|
||||
..isCloseAll = true
|
||||
..dispose();
|
||||
Get.until((route) => route.isFirst);
|
||||
},
|
||||
onPressed: plPlayerController.onCloseAll,
|
||||
),
|
||||
),
|
||||
title,
|
||||
|
||||
@@ -56,6 +56,7 @@ import 'package:get/get.dart';
|
||||
import 'package:hive_ce/hive.dart';
|
||||
import 'package:media_kit/media_kit.dart';
|
||||
import 'package:media_kit_video/media_kit_video.dart';
|
||||
import 'package:native_device_orientation/native_device_orientation.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:wakelock_plus/wakelock_plus.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
@@ -513,26 +514,68 @@ class PlPlayerController with BlockConfigMixin {
|
||||
|
||||
Box video = GStorage.video;
|
||||
|
||||
bool visible = true;
|
||||
|
||||
StreamSubscription<NativeDeviceOrientation>? _orientationListener;
|
||||
|
||||
void _stopOrientationListener() {
|
||||
_orientationListener?.cancel();
|
||||
_orientationListener = null;
|
||||
}
|
||||
|
||||
void _onOrientationChanged(NativeDeviceOrientation value) {
|
||||
if (!visible) return;
|
||||
switch (value) {
|
||||
case .portraitUp:
|
||||
if (!_isVertical && controlsLock.value) return;
|
||||
if (!horizontalScreen && !_isVertical && isFullScreen.value) {
|
||||
triggerFullScreen(status: false, orientation: value);
|
||||
} else {
|
||||
portraitUpMode();
|
||||
}
|
||||
case .landscapeLeft:
|
||||
if (!horizontalScreen && !isFullScreen.value) {
|
||||
triggerFullScreen(orientation: value);
|
||||
} else {
|
||||
landscapeLeftMode();
|
||||
}
|
||||
case .landscapeRight:
|
||||
if (!horizontalScreen && !isFullScreen.value) {
|
||||
triggerFullScreen(orientation: value);
|
||||
} else {
|
||||
landscapeRightMode();
|
||||
}
|
||||
case _:
|
||||
}
|
||||
}
|
||||
|
||||
// 添加一个私有构造函数
|
||||
PlPlayerController._() {
|
||||
if (PlatformUtils.isMobile) {
|
||||
_orientationListener = NativeDeviceOrientationPlatform.instance
|
||||
.onOrientationChanged(
|
||||
useSensor: Platform.isAndroid,
|
||||
checkIsAutoRotate: mode != .gravity,
|
||||
)
|
||||
.listen(_onOrientationChanged);
|
||||
}
|
||||
|
||||
if (!Accounts.heartbeat.isLogin || Pref.historyPause) {
|
||||
enableHeart = false;
|
||||
}
|
||||
|
||||
if (Platform.isAndroid && autoPiP) {
|
||||
Utils.sdkInt.then((sdkInt) {
|
||||
if (sdkInt < 36) {
|
||||
Utils.channel.setMethodCallHandler((call) async {
|
||||
if (call.method == 'onUserLeaveHint') {
|
||||
if (playerStatus.isPlaying && _isCurrVideoPage) {
|
||||
enterPip();
|
||||
}
|
||||
if (Utils.sdkInt < 36) {
|
||||
Utils.channel.setMethodCallHandler((call) async {
|
||||
if (call.method == 'onUserLeaveHint') {
|
||||
if (playerStatus.isPlaying && _isCurrVideoPage) {
|
||||
enterPip();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_shouldSetPip = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_shouldSetPip = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1360,69 +1403,71 @@ class PlPlayerController with BlockConfigMixin {
|
||||
updateSubtitleStyle();
|
||||
}
|
||||
|
||||
late bool isManualFS = true;
|
||||
double screenRatio = 0.0;
|
||||
late final FullScreenMode mode = Pref.fullScreenMode;
|
||||
late final horizontalScreen = Pref.horizontalScreen;
|
||||
|
||||
// 全屏
|
||||
bool fsProcessing = false;
|
||||
bool _fsProcessing = false;
|
||||
Future<void> triggerFullScreen({
|
||||
bool status = true,
|
||||
bool inAppFullScreen = false,
|
||||
bool isManualFS = true,
|
||||
FullScreenMode? mode,
|
||||
NativeDeviceOrientation? orientation,
|
||||
}) async {
|
||||
if (isDesktopPip) return;
|
||||
if (isFullScreen.value == status) return;
|
||||
|
||||
if (fsProcessing) {
|
||||
return;
|
||||
}
|
||||
fsProcessing = true;
|
||||
if (_fsProcessing) return;
|
||||
_fsProcessing = true;
|
||||
toggleFullScreen(status);
|
||||
try {
|
||||
mode ??= this.mode;
|
||||
this.isManualFS = isManualFS;
|
||||
|
||||
if (status) {
|
||||
if (PlatformUtils.isMobile) {
|
||||
hideStatusBar();
|
||||
if (mode == FullScreenMode.none) {
|
||||
if (orientation == null && mode == .none) {
|
||||
return;
|
||||
}
|
||||
if (mode == FullScreenMode.gravity) {
|
||||
await fullAutoModeForceSensor();
|
||||
return;
|
||||
}
|
||||
late final size = MediaQuery.sizeOf(Get.context!);
|
||||
if ((mode == FullScreenMode.vertical ||
|
||||
(mode == FullScreenMode.auto && isVertical) ||
|
||||
(mode == FullScreenMode.ratio &&
|
||||
(isVertical || size.height / size.width < kScreenRatio)))) {
|
||||
await verticalScreenForTwoSeconds();
|
||||
if (orientation == null &&
|
||||
(mode == .vertical ||
|
||||
(mode == .auto && isVertical) ||
|
||||
(mode == .ratio &&
|
||||
(isVertical || screenRatio < kScreenRatio)))) {
|
||||
await portraitUpMode();
|
||||
} else {
|
||||
await landscape();
|
||||
// https://github.com/flutter/flutter/issues/73651
|
||||
// https://github.com/flutter/flutter/issues/183708
|
||||
if (Platform.isAndroid) {
|
||||
if (orientation == .landscapeRight) {
|
||||
await landscapeRightMode();
|
||||
} else {
|
||||
await landscapeLeftMode();
|
||||
}
|
||||
} else {
|
||||
if (orientation == .landscapeLeft) {
|
||||
await landscapeLeftMode();
|
||||
} else {
|
||||
await landscapeRightMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
await enterDesktopFullscreen(inAppFullScreen: inAppFullScreen);
|
||||
await enterDesktopFullScreen(inAppFullScreen: inAppFullScreen);
|
||||
}
|
||||
} else {
|
||||
if (PlatformUtils.isMobile) {
|
||||
showStatusBar();
|
||||
if (mode == FullScreenMode.none) {
|
||||
if (orientation == null && mode == .none) {
|
||||
return;
|
||||
}
|
||||
if (!horizontalScreen) {
|
||||
await verticalScreenForTwoSeconds();
|
||||
} else {
|
||||
await autoScreen();
|
||||
await portraitUpMode();
|
||||
}
|
||||
} else {
|
||||
await exitDesktopFullscreen();
|
||||
await exitDesktopFullScreen();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
fsProcessing = false;
|
||||
_fsProcessing = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1520,12 +1565,29 @@ class PlPlayerController with BlockConfigMixin {
|
||||
});
|
||||
}
|
||||
|
||||
bool isCloseAll = false;
|
||||
bool _isCloseAll = false;
|
||||
bool get isCloseAll => _isCloseAll;
|
||||
|
||||
void resetScreenRotation() {
|
||||
if (horizontalScreen) {
|
||||
fullMode();
|
||||
} else {
|
||||
portraitUpMode();
|
||||
}
|
||||
}
|
||||
|
||||
void onCloseAll() {
|
||||
_isCloseAll = true;
|
||||
dispose();
|
||||
Get.until((route) => route.isFirst);
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
// 每次减1,最后销毁
|
||||
resetScreenRotation();
|
||||
cancelLongPressTimer();
|
||||
_cancelSubForSeek();
|
||||
if (!isCloseAll && _playerCount > 1) {
|
||||
if (!_isCloseAll && _playerCount > 1) {
|
||||
_playerCount -= 1;
|
||||
_heartDuration = 0;
|
||||
if (!_isPreviousVideoPage) {
|
||||
@@ -1536,6 +1598,7 @@ class PlPlayerController with BlockConfigMixin {
|
||||
|
||||
_playerCount = 0;
|
||||
danmakuController = null;
|
||||
_stopOrientationListener();
|
||||
_disableAutoEnterPip();
|
||||
setPlayCallBack(null);
|
||||
dmState.clear();
|
||||
@@ -1683,25 +1746,27 @@ class PlPlayerController with BlockConfigMixin {
|
||||
});
|
||||
}
|
||||
|
||||
bool onPopInvokedWithResult(bool didPop, Object? result) {
|
||||
void onPopInvokedWithResult(bool didPop, Object? result, bool isPortrait) {
|
||||
if (didPop) {
|
||||
if (Platform.isAndroid) {
|
||||
_disableAutoEnterPipIfNeeded();
|
||||
}
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
if (controlsLock.value) {
|
||||
onLockControl(false);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
if (isDesktopPip) {
|
||||
exitDesktopPip();
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
if (isFullScreen.value) {
|
||||
triggerFullScreen(status: false);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
if (!horizontalScreen && !isPortrait) {
|
||||
Get.back();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:auto_orientation/auto_orientation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/services.dart'
|
||||
show SystemChrome, MethodChannel, SystemUiOverlay, DeviceOrientation;
|
||||
|
||||
bool _isDesktopFullScreen = false;
|
||||
|
||||
@pragma('vm:notify-debugger-on-exception')
|
||||
Future<void> enterDesktopFullscreen({bool inAppFullScreen = false}) async {
|
||||
Future<void> enterDesktopFullScreen({bool inAppFullScreen = false}) async {
|
||||
if (!inAppFullScreen && !_isDesktopFullScreen) {
|
||||
_isDesktopFullScreen = true;
|
||||
try {
|
||||
@@ -22,7 +20,7 @@ Future<void> enterDesktopFullscreen({bool inAppFullScreen = false}) async {
|
||||
}
|
||||
|
||||
@pragma('vm:notify-debugger-on-exception')
|
||||
Future<void> exitDesktopFullscreen() async {
|
||||
Future<void> exitDesktopFullScreen() async {
|
||||
if (_isDesktopFullScreen) {
|
||||
_isDesktopFullScreen = false;
|
||||
try {
|
||||
@@ -33,60 +31,50 @@ Future<void> exitDesktopFullscreen() async {
|
||||
}
|
||||
}
|
||||
|
||||
//横屏
|
||||
@pragma('vm:notify-debugger-on-exception')
|
||||
Future<void> landscape() async {
|
||||
try {
|
||||
await AutoOrientation.landscapeAutoMode(forceSensor: true);
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
//竖屏
|
||||
Future<void> verticalScreenForTwoSeconds() async {
|
||||
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||
await autoScreen();
|
||||
}
|
||||
|
||||
//全向
|
||||
bool allowRotateScreen = Pref.allowRotateScreen;
|
||||
Future<void> autoScreen() async {
|
||||
if (PlatformUtils.isMobile && allowRotateScreen) {
|
||||
await SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.portraitUp,
|
||||
// DeviceOrientation.portraitDown,
|
||||
DeviceOrientation.landscapeLeft,
|
||||
DeviceOrientation.landscapeRight,
|
||||
]);
|
||||
List<DeviceOrientation>? _lastOrientation;
|
||||
Future<void>? _setPreferredOrientations(List<DeviceOrientation> orientations) {
|
||||
if (_lastOrientation == orientations) {
|
||||
return null;
|
||||
}
|
||||
_lastOrientation = orientations;
|
||||
return SystemChrome.setPreferredOrientations(orientations);
|
||||
}
|
||||
|
||||
Future<void> fullAutoModeForceSensor() {
|
||||
return AutoOrientation.fullAutoMode(forceSensor: true);
|
||||
Future<void>? portraitUpMode() {
|
||||
return _setPreferredOrientations(const [.portraitUp]);
|
||||
}
|
||||
|
||||
Future<void>? landscapeLeftMode() {
|
||||
return _setPreferredOrientations(const [.landscapeLeft]);
|
||||
}
|
||||
|
||||
Future<void>? landscapeRightMode() {
|
||||
return _setPreferredOrientations(const [.landscapeRight]);
|
||||
}
|
||||
|
||||
Future<void>? fullMode() {
|
||||
return _setPreferredOrientations(
|
||||
const [.portraitUp, .landscapeLeft, .landscapeRight],
|
||||
);
|
||||
}
|
||||
|
||||
bool _showStatusBar = true;
|
||||
Future<void> hideStatusBar() async {
|
||||
Future<void>? hideStatusBar() {
|
||||
if (!_showStatusBar) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
_showStatusBar = false;
|
||||
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
|
||||
return SystemChrome.setEnabledSystemUIMode(.immersiveSticky);
|
||||
}
|
||||
|
||||
//退出全屏显示
|
||||
Future<void> showStatusBar() async {
|
||||
Future<void>? showStatusBar() {
|
||||
if (_showStatusBar) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
_showStatusBar = true;
|
||||
SystemUiMode mode;
|
||||
if (Platform.isAndroid && (await Utils.sdkInt < 29)) {
|
||||
mode = SystemUiMode.manual;
|
||||
} else {
|
||||
mode = SystemUiMode.edgeToEdge;
|
||||
}
|
||||
await SystemChrome.setEnabledSystemUIMode(
|
||||
mode,
|
||||
return SystemChrome.setEnabledSystemUIMode(
|
||||
Platform.isAndroid && Utils.sdkInt < 29 ? .manual : .edgeToEdge,
|
||||
overlays: SystemUiOverlay.values,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -300,10 +300,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
if (!plPlayerController.continuePlayInBackground.value) {
|
||||
late final player = plPlayerController.videoPlayerController;
|
||||
if (const [
|
||||
AppLifecycleState.paused,
|
||||
AppLifecycleState.detached,
|
||||
].contains(state)) {
|
||||
if (const <AppLifecycleState>[.paused, .detached].contains(state)) {
|
||||
if (player != null && player.state.playing) {
|
||||
_pauseDueToPauseUponEnteringBackgroundMode = true;
|
||||
player.pause();
|
||||
|
||||
@@ -397,6 +397,9 @@ abstract final class PiliScheme {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case 'download':
|
||||
Get.toNamed('/download');
|
||||
return true;
|
||||
default:
|
||||
if (!selfHandle) {
|
||||
// if (kDebugMode) debugPrint('$uri');
|
||||
|
||||
@@ -35,11 +35,11 @@ abstract final class AppSign {
|
||||
assert(value != null, 'remove null value');
|
||||
result.write(separator);
|
||||
separator = '&';
|
||||
result.write(Uri.encodeQueryComponent(key));
|
||||
result.write(Uri.encodeComponent(key));
|
||||
if (value != null && value.isNotEmpty) {
|
||||
result
|
||||
..write('=')
|
||||
..write(Uri.encodeQueryComponent(value));
|
||||
..write(Uri.encodeComponent(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,12 +78,12 @@ abstract final class ImageUtils {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> checkPermissionDependOnSdkInt() async {
|
||||
static Future<bool> checkPermissionDependOnSdkInt() {
|
||||
if (Platform.isAndroid) {
|
||||
if (await Utils.sdkInt < 29) {
|
||||
if (Utils.sdkInt < 29) {
|
||||
return requestPer();
|
||||
} else {
|
||||
return true;
|
||||
return Future.syncValue(true);
|
||||
}
|
||||
}
|
||||
return requestPer();
|
||||
|
||||
@@ -32,7 +32,6 @@ abstract final class SettingBoxKey {
|
||||
static const String enableVerticalExpand = 'enableVerticalExpand',
|
||||
feedBackEnable = 'feedBackEnable',
|
||||
enableLongShowControl = 'enableLongShowControl',
|
||||
allowRotateScreen = 'allowRotateScreen',
|
||||
horizontalScreen = 'horizontalScreen',
|
||||
CDNService = 'CDNService',
|
||||
disableAudioCDN = 'disableAudioCDN',
|
||||
|
||||
@@ -193,7 +193,9 @@ abstract final class Pref {
|
||||
static FullScreenMode get fullScreenMode =>
|
||||
FullScreenMode.values[_setting.get(
|
||||
SettingBoxKey.fullScreenMode,
|
||||
defaultValue: FullScreenMode.auto.index,
|
||||
defaultValue: horizontalScreen
|
||||
? FullScreenMode.none.index
|
||||
: FullScreenMode.auto.index,
|
||||
)];
|
||||
|
||||
static BtmProgressBehavior get btmProgressBehavior =>
|
||||
@@ -636,9 +638,6 @@ abstract final class Pref {
|
||||
static bool get enableBackgroundPlay =>
|
||||
_setting.get(SettingBoxKey.enableBackgroundPlay, defaultValue: true);
|
||||
|
||||
static bool get allowRotateScreen =>
|
||||
_setting.get(SettingBoxKey.allowRotateScreen, defaultValue: true);
|
||||
|
||||
static bool get disableLikeMsg =>
|
||||
_setting.get(SettingBoxKey.disableLikeMsg, defaultValue: false);
|
||||
|
||||
|
||||
@@ -87,10 +87,7 @@ abstract final class Utils {
|
||||
int.parse('${color.substring(7)}${color.substring(1, 7)}', radix: 16),
|
||||
);
|
||||
|
||||
static int? _sdkInt;
|
||||
static Future<int> get sdkInt async {
|
||||
return _sdkInt ??= (await DeviceInfoPlugin().androidInfo).version.sdkInt;
|
||||
}
|
||||
static late int sdkInt;
|
||||
|
||||
static bool? _isIpad;
|
||||
static Future<bool> get isIpad async {
|
||||
|
||||
32
pubspec.lock
32
pubspec.lock
@@ -121,15 +121,6 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.3"
|
||||
auto_orientation:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: master
|
||||
resolved-ref: ca2bb137bd0e4b221df3bc5ba1492d2902c78624
|
||||
url: "https://github.com/bggRGjQaUbCoE/auto_orientation.git"
|
||||
source: git
|
||||
version: "2.3.1"
|
||||
battery_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -530,10 +521,10 @@ packages:
|
||||
description:
|
||||
path: "."
|
||||
ref: mod
|
||||
resolved-ref: aba199942d9b92b5c08cf3559d8a8f06594f0480
|
||||
resolved-ref: d1dde80df07a6ec46d9291cfeba6c01de53b5305
|
||||
url: "https://github.com/bggRGjQaUbCoE/flutter_file_picker.git"
|
||||
source: git
|
||||
version: "11.0.1"
|
||||
version: "11.0.2"
|
||||
file_selector_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -906,10 +897,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: image_cropper
|
||||
sha256: d2555be1ec4b7b12fc502ede481c846ad44578fbb0748debd4c648b25ca07cad
|
||||
sha256: e2c8da14ecb4c6ead02b8e1265f966ce72b43ff930da66eef3833e622185dec7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "12.1.1"
|
||||
version: "12.2.0"
|
||||
image_cropper_for_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1239,6 +1230,15 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
native_device_orientation:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: master
|
||||
resolved-ref: "42454199133e83a9a31f0fb0107d14af1f96f959"
|
||||
url: "https://github.com/bggRGjQaUbCoE/flutter_native_device_orientation.git"
|
||||
source: git
|
||||
version: "2.0.5"
|
||||
native_toolchain_c:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1320,7 +1320,7 @@ packages:
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: path_provider_android
|
||||
sha256: "149441ca6e4f38193b2e004c0ca6376a3d11f51fa5a77552d8bd4d2b0c0912ba"
|
||||
@@ -1571,10 +1571,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sentry
|
||||
sha256: "288aee3d35f252ac0dc3a4b0accbbe7212fa2867604027f2cc5bc65334afd743"
|
||||
sha256: "682360642a7b14b36daef3b5574b7269164e7763512ac92cdafd55b695bd2183"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.16.0"
|
||||
version: "9.16.1"
|
||||
share_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
||||
13
pubspec.yaml
13
pubspec.yaml
@@ -17,7 +17,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
# update when release
|
||||
version: 2.0.2+1
|
||||
version: 2.0.3+1
|
||||
|
||||
environment:
|
||||
sdk: ">=3.10.0"
|
||||
@@ -126,9 +126,13 @@ dependencies:
|
||||
flutter_volume_controller: ^1.3.3
|
||||
wakelock_plus: ^1.2.8
|
||||
# universal_platform: ^1.1.0
|
||||
auto_orientation:
|
||||
# auto_orientation:
|
||||
# git:
|
||||
# url: https://github.com/bggRGjQaUbCoE/auto_orientation.git
|
||||
# ref: master
|
||||
native_device_orientation:
|
||||
git:
|
||||
url: https://github.com/bggRGjQaUbCoE/auto_orientation.git
|
||||
url: https://github.com/bggRGjQaUbCoE/flutter_native_device_orientation.git
|
||||
ref: master
|
||||
protobuf: ^6.0.0
|
||||
# animations: ^2.0.11
|
||||
@@ -292,6 +296,9 @@ dependency_overrides:
|
||||
path: libs/macos/media_kit_libs_macos_video
|
||||
ref: dev
|
||||
font_awesome_flutter: 10.9.0
|
||||
# TODO: remove
|
||||
# https://github.com/flutter/flutter/issues/184750
|
||||
path_provider_android: 2.2.23
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
Reference in New Issue
Block a user