mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-22 18:20:14 +08:00
Compare commits
12 Commits
f52bbe9804
...
2.0.3.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db30aa8041 | ||
|
|
6f95456d20 | ||
|
|
de6e402d97 | ||
|
|
6341660788 | ||
|
|
a1dbcae93e | ||
|
|
1526137a64 | ||
|
|
3097b56816 | ||
|
|
db74eccf77 | ||
|
|
14890d342a | ||
|
|
51163dd985 | ||
|
|
f0d9b3a9a7 | ||
|
|
8f3707fbf1 |
@@ -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>
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
package com.example.piliplus
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.app.PictureInPictureParams
|
||||
import android.app.SearchManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.ShortcutInfo
|
||||
import android.content.pm.ShortcutManager
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.provider.MediaStore
|
||||
@@ -16,6 +21,7 @@ import com.ryanheise.audioservice.AudioServiceActivity
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import kotlin.system.exitProcess
|
||||
import java.io.File
|
||||
|
||||
class MainActivity : AudioServiceActivity() {
|
||||
private lateinit var methodChannel: MethodChannel
|
||||
@@ -133,6 +139,38 @@ class MainActivity : AudioServiceActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
"createShortcut" -> {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
try {
|
||||
val shortcutManager =
|
||||
context.getSystemService(ShortcutManager::class.java)
|
||||
if (shortcutManager.isRequestPinShortcutSupported) {
|
||||
val id = call.argument<String>("id")!!
|
||||
val uri = call.argument<String>("uri")!!
|
||||
val label = call.argument<String>("label")!!
|
||||
val icon = call.argument<String>("icon")!!
|
||||
val bitmap = BitmapFactory.decodeFile(icon)
|
||||
val shortcut =
|
||||
ShortcutInfo.Builder(context, id)
|
||||
.setShortLabel(label)
|
||||
.setIcon(Icon.createWithAdaptiveBitmap(bitmap))
|
||||
.setIntent(Intent(Intent.ACTION_VIEW, uri.toUri()))
|
||||
.build()
|
||||
val pinIntent =
|
||||
shortcutManager.createShortcutResultIntent(shortcut)
|
||||
val pendingIntent = PendingIntent.getBroadcast(
|
||||
context, 0, pinIntent, PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
shortcutManager.requestPinShortcut(
|
||||
shortcut,
|
||||
pendingIntent.intentSender
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> result.notImplemented()
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:PiliPlus/utils/parse_string.dart';
|
||||
|
||||
class ReservationCardItem {
|
||||
int? sid;
|
||||
String? name;
|
||||
@@ -26,7 +28,7 @@ class ReservationCardItem {
|
||||
total: json['total'] ?? 0,
|
||||
isFollow: json['is_follow'] == 1,
|
||||
livePlanStartTime: json['live_plan_start_time'] as int?,
|
||||
descText1: json['desc_text_1']?['text'],
|
||||
descText1: noneNullOrEmptyString(json['desc_text_1']?['text']),
|
||||
dynamicId: json['dynamic_id'] as String?,
|
||||
lotteryPrizeInfo: json['lottery_prize_info'] == null
|
||||
? null
|
||||
|
||||
@@ -433,7 +433,9 @@ class _EpisodePanelState extends State<EpisodePanel>
|
||||
type: MaterialType.transparency,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
if (episode.badge == "会员" && vipStatus != 1) {
|
||||
if (episode.badge == "会员" &&
|
||||
Accounts.mainEqVideo &&
|
||||
vipStatus != 1) {
|
||||
SmartDialog.showToast('需要大会员');
|
||||
// return;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -28,6 +28,7 @@ class MemberController extends CommonDataController<SpaceData, SpaceData?>
|
||||
MemberController({required this.mid});
|
||||
int mid;
|
||||
String? username;
|
||||
String? userAvatar;
|
||||
|
||||
late final account = Accounts.main;
|
||||
|
||||
@@ -71,7 +72,10 @@ class MemberController extends CommonDataController<SpaceData, SpaceData?>
|
||||
final data = response.response;
|
||||
final card = data.card;
|
||||
username = card?.name ?? '';
|
||||
userAvatar = card?.face;
|
||||
|
||||
isFollowed = card?.relation?.isFollowed;
|
||||
|
||||
// charge
|
||||
final elec = data.elec;
|
||||
charges = elec?.list;
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:io' show Platform;
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:PiliPlus/common/style.dart';
|
||||
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
|
||||
import 'package:PiliPlus/common/widgets/dialog/report_member.dart';
|
||||
import 'package:PiliPlus/common/widgets/dynamic_sliver_app_bar/dynamic_sliver_app_bar.dart';
|
||||
import 'package:PiliPlus/common/widgets/gesture/tap_gesture_recognizer.dart';
|
||||
@@ -33,11 +34,14 @@ import 'package:PiliPlus/pages/member_video_web/archive/view.dart';
|
||||
import 'package:PiliPlus/pages/member_video_web/season_series/view.dart';
|
||||
import 'package:PiliPlus/utils/date_utils.dart';
|
||||
import 'package:PiliPlus/utils/extension/context_ext.dart';
|
||||
import 'package:PiliPlus/utils/extension/string_ext.dart';
|
||||
import 'package:PiliPlus/utils/num_utils.dart';
|
||||
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';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -209,6 +213,60 @@ class _MemberPageState extends State<MemberPage> {
|
||||
...list.map((e) {
|
||||
return Builder(
|
||||
builder: (context) {
|
||||
Widget trailing = FilledButton.tonal(
|
||||
onPressed: () async {
|
||||
final isFollow = e.isFollow;
|
||||
final res = await UserHttp.spaceReserve(
|
||||
sid: e.sid!,
|
||||
isFollow: isFollow,
|
||||
);
|
||||
if (res.isSuccess) {
|
||||
e
|
||||
..total += isFollow ? -1 : 1
|
||||
..isFollow = !isFollow;
|
||||
if (!context.mounted) return;
|
||||
(context as Element).markNeedsBuild();
|
||||
} else {
|
||||
res.toast();
|
||||
}
|
||||
},
|
||||
style: FilledButton.styleFrom(
|
||||
backgroundColor: e.isFollow
|
||||
? scheme.onInverseSurface
|
||||
: null,
|
||||
foregroundColor: e.isFollow ? scheme.outline : null,
|
||||
tapTargetSize: .shrinkWrap,
|
||||
minimumSize: const Size(68, 40),
|
||||
padding: const .symmetric(horizontal: 10),
|
||||
visualDensity: const .new(horizontal: -2, vertical: -3),
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: .all(.circular(6)),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
'${e.isFollow ? '已' : ''}预约',
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
);
|
||||
if (e.dynamicId?.isNotEmpty ?? false) {
|
||||
trailing = Row(
|
||||
spacing: 8,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
iconButton(
|
||||
tooltip: '预约动态',
|
||||
size: 32,
|
||||
iconSize: 20,
|
||||
iconColor: scheme.outline,
|
||||
icon: const Icon(Icons.open_in_browser),
|
||||
onPressed: () => PageUtils.pushDynFromId(
|
||||
id: e.dynamicId,
|
||||
),
|
||||
),
|
||||
trailing,
|
||||
],
|
||||
);
|
||||
}
|
||||
return ListTile(
|
||||
dense: true,
|
||||
title: Text(
|
||||
@@ -221,7 +279,11 @@ class _MemberPageState extends State<MemberPage> {
|
||||
style: TextStyle(fontSize: 12, color: scheme.outline),
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(text: '${e.descText1} ${e.total}人预约'),
|
||||
TextSpan(
|
||||
text:
|
||||
'${e.descText1 == null ? '' : '${e.descText1} '}'
|
||||
'${NumUtils.numFormat(e.total)}人预约',
|
||||
),
|
||||
if (e.lotteryPrizeInfo case final lottery?) ...[
|
||||
const TextSpan(text: '\n'),
|
||||
WidgetSpan(
|
||||
@@ -254,44 +316,7 @@ class _MemberPageState extends State<MemberPage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
trailing: FilledButton.tonal(
|
||||
onPressed: () async {
|
||||
final isFollow = e.isFollow;
|
||||
final res = await UserHttp.spaceReserve(
|
||||
sid: e.sid!,
|
||||
isFollow: isFollow,
|
||||
);
|
||||
if (res.isSuccess) {
|
||||
if (!context.mounted) return;
|
||||
e
|
||||
..total += isFollow ? -1 : 1
|
||||
..isFollow = !isFollow;
|
||||
(context as Element).markNeedsBuild();
|
||||
} else {
|
||||
res.toast();
|
||||
}
|
||||
},
|
||||
style: FilledButton.styleFrom(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: .all(.circular(6)),
|
||||
),
|
||||
backgroundColor: e.isFollow
|
||||
? scheme.onInverseSurface
|
||||
: null,
|
||||
foregroundColor: e.isFollow ? scheme.outline : null,
|
||||
visualDensity: const VisualDensity(
|
||||
horizontal: -2,
|
||||
vertical: -3,
|
||||
),
|
||||
tapTargetSize: .shrinkWrap,
|
||||
padding: const .symmetric(horizontal: 10),
|
||||
minimumSize: const Size(68, 40),
|
||||
),
|
||||
child: Text(
|
||||
'${e.isFollow ? '已' : ''}预约',
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
),
|
||||
trailing: trailing,
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -357,11 +382,9 @@ class _MemberPageState extends State<MemberPage> {
|
||||
],
|
||||
),
|
||||
),
|
||||
if (kDebugMode || Platform.isIOS)
|
||||
if (PlatformUtils.isMobile)
|
||||
PopupMenuItem(
|
||||
onTap: () => PageUtils.launchURL(
|
||||
'https://www.bilibili.com/blackboard/disablelink/go-to-up-space.html?mid=$_mid',
|
||||
),
|
||||
onTap: _createShortcut,
|
||||
child: const Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
@@ -665,4 +688,35 @@ class _MemberPageState extends State<MemberPage> {
|
||||
SmartDialog.showToast(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void _createShortcut() {
|
||||
if (Platform.isIOS) {
|
||||
PageUtils.launchURL(
|
||||
'https://www.bilibili.com/blackboard/disablelink/go-to-up-space.html?mid=$_mid',
|
||||
);
|
||||
} else if (Platform.isAndroid) {
|
||||
_createShortcutAndroid();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _createShortcutAndroid() async {
|
||||
try {
|
||||
SmartDialog.showLoading();
|
||||
final file = (await DefaultCacheManager().getSingleFile(
|
||||
'${_userController.userAvatar!}@200w_200h.webp'.http2https,
|
||||
));
|
||||
SmartDialog.dismiss();
|
||||
await Utils.channel.invokeMethod(
|
||||
'createShortcut',
|
||||
<String, String>{
|
||||
'id': _userController.mid.toString(),
|
||||
'uri': 'bilibili://space/${_userController.mid}',
|
||||
'label': _userController.username!,
|
||||
'icon': file.path,
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
SmartDialog.showToast(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
@@ -17,6 +17,7 @@ import 'package:PiliPlus/pages/video/controller.dart';
|
||||
import 'package:PiliPlus/pages/video/introduction/ugc/controller.dart';
|
||||
import 'package:PiliPlus/pages/video/introduction/ugc/widgets/page.dart';
|
||||
import 'package:PiliPlus/services/download/download_service.dart';
|
||||
import 'package:PiliPlus/utils/accounts.dart';
|
||||
import 'package:PiliPlus/utils/date_utils.dart';
|
||||
import 'package:PiliPlus/utils/duration_utils.dart';
|
||||
import 'package:PiliPlus/utils/extension/num_ext.dart';
|
||||
@@ -254,7 +255,7 @@ class _DownloadPanelState extends State<DownloadPanel> {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (kReleaseMode && episode.badge == '会员') {
|
||||
if (kReleaseMode && episode.badge == '会员' && Accounts.mainEqVideo) {
|
||||
if (vipStatus != 1) {
|
||||
if (!isDownloadAll) {
|
||||
SmartDialog.showToast('需要大会员');
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:PiliPlus/models_new/pgc/pgc_info_model/new_ep.dart';
|
||||
import 'package:PiliPlus/models_new/video/video_detail/episode.dart'
|
||||
hide EpisodeItem;
|
||||
import 'package:PiliPlus/pages/video/controller.dart';
|
||||
import 'package:PiliPlus/utils/accounts.dart';
|
||||
import 'package:PiliPlus/utils/extension/num_ext.dart';
|
||||
import 'package:PiliPlus/utils/extension/theme_ext.dart';
|
||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||
@@ -166,7 +167,7 @@ class _PgcPanelState extends State<PgcPanel> {
|
||||
child: InkWell(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(6)),
|
||||
onTap: () {
|
||||
if (item.badge == '会员' && vipStatus) {
|
||||
if (item.badge == '会员' && Accounts.mainEqVideo && vipStatus) {
|
||||
SmartDialog.showToast('需要大会员');
|
||||
}
|
||||
widget.onChangeEpisode(item);
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1338,7 +1282,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
!isFullScreen &&
|
||||
!videoDetailController.plPlayerController.isDesktopPip &&
|
||||
(videoDetailController.horizontalScreen || isPortrait),
|
||||
onPopInvokedWithResult: _onPopInvokedWithResult,
|
||||
onPopInvokedWithResult:
|
||||
videoDetailController.plPlayerController.onPopInvokedWithResult,
|
||||
child: Obx(
|
||||
() =>
|
||||
!videoDetailController.videoState.value ||
|
||||
@@ -2173,17 +2118,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
}
|
||||
}
|
||||
|
||||
void _onPopInvokedWithResult(bool didPop, result) {
|
||||
if (plPlayerController?.onPopInvokedWithResult(didPop, result) ?? false) {
|
||||
return;
|
||||
}
|
||||
if (PlatformUtils.isMobile &&
|
||||
!videoDetailController.horizontalScreen &&
|
||||
!isPortrait) {
|
||||
verticalScreenForTwoSeconds();
|
||||
}
|
||||
}
|
||||
|
||||
void onShowMemberPage(int? mid) {
|
||||
videoDetailController.childKey.currentState?.showBottomSheet(
|
||||
shape: const RoundedRectangleBorder(),
|
||||
|
||||
@@ -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,8 @@ 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),
|
||||
),
|
||||
),
|
||||
if (!plPlayerController.isDesktopPip &&
|
||||
@@ -1787,12 +1773,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,25 @@ class PlPlayerController with BlockConfigMixin {
|
||||
});
|
||||
}
|
||||
|
||||
bool onPopInvokedWithResult(bool didPop, Object? result) {
|
||||
void onPopInvokedWithResult(bool didPop, Object? result) {
|
||||
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;
|
||||
}
|
||||
return false;
|
||||
Get.back();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -11,7 +11,9 @@ abstract final class Accounts {
|
||||
AccountType.values.length,
|
||||
AnonymousAccount(),
|
||||
);
|
||||
static bool get mainEqVideo => main == video;
|
||||
static Account get main => accountMode[AccountType.main.index];
|
||||
static Account get video => accountMode[AccountType.video.index];
|
||||
static Account get heartbeat => accountMode[AccountType.heartbeat.index];
|
||||
static Account get history {
|
||||
final heartbeat = Accounts.heartbeat;
|
||||
|
||||
@@ -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: a3714717dacde780e6dd55c21094112cdf6ee3ba
|
||||
resolved-ref: d1dde80df07a6ec46d9291cfeba6c01de53b5305
|
||||
url: "https://github.com/bggRGjQaUbCoE/flutter_file_picker.git"
|
||||
source: git
|
||||
version: "11.0.0"
|
||||
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