Compare commits

...

6 Commits

Author SHA1 Message Date
dom
6341660788 Release 2.0.3
Signed-off-by: dom <githubaccount56556@proton.me>
2026-04-08 13:05:08 +08:00
dom
a1dbcae93e upgrade deps
Signed-off-by: dom <githubaccount56556@proton.me>
2026-04-08 12:50:22 +08:00
dom
1526137a64 fix AppSign
Signed-off-by: dom <githubaccount56556@proton.me>
2026-04-07 17:24:44 +08:00
dom
3097b56816 refactor device orientation
Signed-off-by: dom <githubaccount56556@proton.me>
2026-04-07 12:56:29 +08:00
dom
db74eccf77 android shortcut
Signed-off-by: dom <githubaccount56556@proton.me>
2026-04-06 15:34:07 +08:00
dom
14890d342a tweaks
Signed-off-by: dom <githubaccount56556@proton.me>
2026-04-06 00:13:35 +08:00
26 changed files with 397 additions and 341 deletions

View File

@@ -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>

View 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>

View 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>

View File

@@ -1,3 +1,5 @@
<resources>
<string name="app_name">PiliPlus</string>
<string name="search">搜索</string>
<string name="offline_video">离线视频</string>
</resources>

View 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>

View File

@@ -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

View File

@@ -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,

View File

@@ -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,
);
}

View File

@@ -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(

View File

@@ -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;

View File

@@ -33,6 +33,8 @@ class MemberGuardController
tops = list.take(3).toList();
if (list.length > 3) {
list.removeRange(0, 3);
} else {
list.clear();
}
}
return false;

View File

@@ -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: '后台播放',

View File

@@ -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();
}
},
),

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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;
}
}

View File

@@ -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,
);
}

View File

@@ -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();

View File

@@ -397,6 +397,9 @@ abstract final class PiliScheme {
}
}
return false;
case 'download':
Get.toNamed('/download');
return true;
default:
if (!selfHandle) {
// if (kDebugMode) debugPrint('$uri');

View File

@@ -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));
}
}

View File

@@ -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();

View File

@@ -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',

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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:

View File

@@ -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: