add a force landscapre mode on mobile

This commit is contained in:
686udjie 2026-01-01 19:48:57 +02:00
parent 53cd2101f4
commit 79ee4b4fc8
14 changed files with 502 additions and 326 deletions

View file

@ -1,7 +1,5 @@
PODS:
- app_links (6.4.1):
- Flutter
- audio_session (0.0.1):
- app_links (7.0.0):
- Flutter
- connectivity_plus (0.0.1):
- Flutter
@ -57,9 +55,8 @@ PODS:
- Flutter
- isar_community_flutter_libs (1.0.0):
- Flutter
- just_audio (0.0.1):
- m_extension_server (0.0.1):
- Flutter
- FlutterMacOS
- media_kit_libs_ios_video (1.0.4):
- Flutter
- media_kit_video (0.0.1):
@ -81,26 +78,16 @@ PODS:
- SDWebImage/Core (5.17.0)
- share_plus (0.0.1):
- Flutter
- sqflite_darwin (0.0.4):
- Flutter
- FlutterMacOS
- SwiftyGif (5.4.4)
- url_launcher_ios (0.0.1):
- Flutter
- video_player_avfoundation (0.0.1):
- Flutter
- FlutterMacOS
- volume_controller (0.0.1):
- Flutter
- wakelock_plus (0.0.1):
- Flutter
- webview_flutter_wkwebview (0.0.1):
- Flutter
- FlutterMacOS
DEPENDENCIES:
- app_links (from `.symlinks/plugins/app_links/ios`)
- audio_session (from `.symlinks/plugins/audio_session/ios`)
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
@ -110,7 +97,7 @@ DEPENDENCIES:
- flutter_qjs (from `.symlinks/plugins/flutter_qjs/ios`)
- flutter_web_auth_2 (from `.symlinks/plugins/flutter_web_auth_2/ios`)
- isar_community_flutter_libs (from `.symlinks/plugins/isar_community_flutter_libs/ios`)
- just_audio (from `.symlinks/plugins/just_audio/darwin`)
- m_extension_server (from `.symlinks/plugins/m_extension_server/ios`)
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
- media_kit_video (from `.symlinks/plugins/media_kit_video/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
@ -119,12 +106,9 @@ DEPENDENCIES:
- rust_lib_mangayomi (from `.symlinks/plugins/rust_lib_mangayomi/ios`)
- screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`)
- share_plus (from `.symlinks/plugins/share_plus/ios`)
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
- volume_controller (from `.symlinks/plugins/volume_controller/ios`)
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`)
SPEC REPOS:
trunk:
@ -137,8 +121,6 @@ SPEC REPOS:
EXTERNAL SOURCES:
app_links:
:path: ".symlinks/plugins/app_links/ios"
audio_session:
:path: ".symlinks/plugins/audio_session/ios"
connectivity_plus:
:path: ".symlinks/plugins/connectivity_plus/ios"
device_info_plus:
@ -157,8 +139,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_web_auth_2/ios"
isar_community_flutter_libs:
:path: ".symlinks/plugins/isar_community_flutter_libs/ios"
just_audio:
:path: ".symlinks/plugins/just_audio/darwin"
m_extension_server:
:path: ".symlinks/plugins/m_extension_server/ios"
media_kit_libs_ios_video:
:path: ".symlinks/plugins/media_kit_libs_ios_video/ios"
media_kit_video:
@ -175,22 +157,15 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/screen_brightness_ios/ios"
share_plus:
:path: ".symlinks/plugins/share_plus/ios"
sqflite_darwin:
:path: ".symlinks/plugins/sqflite_darwin/darwin"
url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios"
video_player_avfoundation:
:path: ".symlinks/plugins/video_player_avfoundation/darwin"
volume_controller:
:path: ".symlinks/plugins/volume_controller/ios"
wakelock_plus:
:path: ".symlinks/plugins/wakelock_plus/ios"
webview_flutter_wkwebview:
:path: ".symlinks/plugins/webview_flutter_wkwebview/darwin"
SPEC CHECKSUMS:
app_links: 3dbc685f76b1693c66a6d9dd1e9ab6f73d97dc0a
audio_session: 9bb7f6c970f21241b19f5a3658097ae459681ba0
app_links: a754cbec3c255bd4bbb4d236ecc06f28cd9a7ce8
connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
@ -202,24 +177,21 @@ SPEC CHECKSUMS:
flutter_qjs: 1d5918f42171154e88dd545dd45f126c0291976f
flutter_web_auth_2: 3464a7c16dc6480b6194fc89913bae6e82f28405
isar_community_flutter_libs: bede843185a61a05ff364a05c9b23209523f7e0d
just_audio: 4e391f57b79cad2b0674030a00453ca5ce817eed
m_extension_server: 6946ec189542b271dbd15629b9498595f1036761
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
path_provider_foundation: bb55f6dbba17d0dccd6737fe6f7f34fbd0376880
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
rust_lib_mangayomi: 360a904274b47351a0f7c26d3ce5aa6392bb8db3
screen_brightness_ios: 9953fd7da5bd480f1a93990daeec2eb42d4f3b52
SDWebImage: 750adf017a315a280c60fde706ab1e552a3ae4e9
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b
url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b
volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
webview_flutter_wkwebview: 8ebf4fded22593026f7dbff1fbff31ea98573c8d
PODFILE CHECKSUM: a57f30d18f102dd3ce366b1d62a55ecbef2158e5

View file

@ -561,5 +561,7 @@
"show_scroll_percentage": "Show Scroll Percentage",
"remove_extra_paragraph_spacing": "Remove Extra Paragraph Spacing",
"select_label_color": "Select {label} Color",
"default_user_agent": "Defaul user agent"
"default_user_agent": "Defaul user agent",
"forceLandscapeMode": "Force landscape mode",
"forceLandscapeModeSubtitle": "Force the player to use landscape orientation."
}

View file

@ -563,5 +563,8 @@
"line_height": "行高",
"show_scroll_percentage": "显示滚动百分比",
"remove_extra_paragraph_spacing": "删除额外的段落间距",
"select_label_color": "选择 {label} 颜色"
}
"select_label_color": "选择 {label} 颜色",
"default_user_agent": "默认用户代理",
"forceLandscapeMode": "强制横屏模式",
"forceLandscapeModeSubtitle": "强制播放器使用横屏方向。"
}

View file

@ -3442,6 +3442,18 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'Defaul user agent'**
String get default_user_agent;
/// No description provided for @forceLandscapeMode.
///
/// In en, this message translates to:
/// **'Force landscape mode'**
String get forceLandscapeMode;
/// No description provided for @forceLandscapeModeSubtitle.
///
/// In en, this message translates to:
/// **'Force the player to use landscape orientation.'**
String get forceLandscapeModeSubtitle;
}
class _AppLocalizationsDelegate

View file

@ -1781,4 +1781,11 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get default_user_agent => 'Defaul user agent';
@override
String get forceLandscapeMode => 'Force landscape mode';
@override
String get forceLandscapeModeSubtitle =>
'Force the player to use landscape orientation.';
}

View file

@ -1738,5 +1738,11 @@ class AppLocalizationsZh extends AppLocalizations {
}
@override
String get default_user_agent => 'Defaul user agent';
String get default_user_agent => '默认用户代理';
@override
String get forceLandscapeMode => '强制横屏模式';
@override
String get forceLandscapeModeSubtitle => '强制播放器使用横屏方向。';
}

View file

@ -163,6 +163,8 @@ class Settings {
bool? fullScreenPlayer;
bool? forceLandscapePlayer;
bool? updateProgressAfterReading;
bool? enableAniSkip;
@ -375,6 +377,7 @@ class Settings {
this.defaultDoubleTapToSkipLength = 10,
this.defaultPlayBackSpeed = 1.0,
this.fullScreenPlayer = false,
this.forceLandscapePlayer = false,
this.updateProgressAfterReading = true,
this.enableAniSkip,
this.enableAutoSkip,
@ -581,6 +584,7 @@ class Settings {
? json['defaultPlayBackSpeed']
: (json['defaultPlayBackSpeed'] as int).toDouble();
fullScreenPlayer = json['fullScreenPlayer'];
forceLandscapePlayer = json['forceLandscapePlayer'];
updateProgressAfterReading = json['updateProgressAfterReading'];
enableAniSkip = json['enableAniSkip'];
enableAutoSkip = json['enableAutoSkip'];
@ -787,6 +791,7 @@ class Settings {
'defaultDoubleTapToSkipLength': defaultDoubleTapToSkipLength,
'defaultPlayBackSpeed': defaultPlayBackSpeed,
'fullScreenPlayer': fullScreenPlayer,
'forceLandscapePlayer': forceLandscapePlayer,
'updateProgressAfterReading': updateProgressAfterReading,
'enableAniSkip': enableAniSkip,
'enableAutoSkip': enableAutoSkip,

File diff suppressed because it is too large Load diff

View file

@ -882,6 +882,12 @@ mp.register_script_message('call_button_${button.id}_long', button${button.id}lo
});
_firstTime = false;
}
if (!_isDesktop) {
final forceLandscape = ref.read(forceLandscapePlayerStateProvider);
if (forceLandscape) {
_setLandscapeMode(true);
}
}
_currentPositionSub = _player.stream.position.listen(
_unifiedPositionHandler,
);

View file

@ -136,7 +136,7 @@ final class DownloadChapterProvider
}
}
String _$downloadChapterHash() => r'b64c5de46eafb0e7322eb599e49de3b09f027c04';
String _$downloadChapterHash() => r'c503cef46aa7083316b023400f0aa470ae3a3bc4';
final class DownloadChapterFamily extends $Family
with

View file

@ -43,7 +43,7 @@ final class TotalChapterCacheSizeStateProvider
}
String _$totalChapterCacheSizeStateHash() =>
r'6e92eec01cc21fbea3996d220c0b2edaadec3786';
r'fdecfd853bcd1355217fcef9590d6c69fbd92ce4';
abstract class _$TotalChapterCacheSizeState extends $Notifier<String> {
String build();

View file

@ -33,6 +33,7 @@ class _PlayerScreenState extends ConsumerState<PlayerScreen> {
final useLibass = ref.watch(useLibassStateProvider);
final fullScreenPlayer = ref.watch(fullScreenPlayerStateProvider);
final forceLandscapePlayer = ref.watch(forceLandscapePlayerStateProvider);
return Scaffold(
appBar: AppBar(title: Text(context.l10n.internal_player)),
body: SingleChildScrollView(
@ -487,6 +488,17 @@ class _PlayerScreenState extends ConsumerState<PlayerScreen> {
ref.read(fullScreenPlayerStateProvider.notifier).set(value);
},
),
SwitchListTile(
value: forceLandscapePlayer,
title: Text(context.l10n.forceLandscapeMode),
subtitle: Text(
context.l10n.forceLandscapeModeSubtitle,
style: TextStyle(fontSize: 11, color: context.secondaryColor),
),
onChanged: (value) {
ref.read(forceLandscapePlayerStateProvider.notifier).set(value);
},
),
],
),
),

View file

@ -232,3 +232,23 @@ class UseMpvConfigState extends _$UseMpvConfigState {
);
}
}
@riverpod
class ForceLandscapePlayerState extends _$ForceLandscapePlayerState {
@override
bool build() {
return isar.settings.getSync(227)!.forceLandscapePlayer ?? false;
}
void set(bool value) {
final settings = isar.settings.getSync(227);
state = value;
isar.writeTxnSync(
() => isar.settings.putSync(
settings!
..forceLandscapePlayer = value
..updatedAt = DateTime.now().millisecondsSinceEpoch,
),
);
}
}

View file

@ -605,3 +605,56 @@ abstract class _$UseMpvConfigState extends $Notifier<bool> {
element.handleValue(ref, created);
}
}
@ProviderFor(ForceLandscapePlayerState)
const forceLandscapePlayerStateProvider = ForceLandscapePlayerStateProvider._();
final class ForceLandscapePlayerStateProvider
extends $NotifierProvider<ForceLandscapePlayerState, bool> {
const ForceLandscapePlayerStateProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'forceLandscapePlayerStateProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$forceLandscapePlayerStateHash();
@$internal
@override
ForceLandscapePlayerState create() => ForceLandscapePlayerState();
Override overrideWithValue(bool value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<bool>(value),
);
}
}
String _$forceLandscapePlayerStateHash() =>
r'65d3e0b91d7b6d38e9f70893a8c71f13029715b5';
abstract class _$ForceLandscapePlayerState extends $Notifier<bool> {
bool build();
@$mustCallSuper
@override
void runBuild() {
final created = build();
final ref = this.ref as $Ref<bool, bool>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<bool, bool>,
bool,
Object?,
Object?
>;
element.handleValue(ref, created);
}
}