feat(ui): M3E restyle for settings, auth, and profile screens
This commit is contained in:
@@ -144,18 +144,18 @@ class _SettingsScreenState extends State<SettingsScreen> with FocusableTab, Moun
|
||||
ExcludeFocus(child: CustomAppBar(title: Text(t.settings.title), pinned: true)),
|
||||
SliverList(
|
||||
delegate: SliverChildListDelegate([
|
||||
if (DonationService.isEnabled) _buildDonateTile(),
|
||||
|
||||
_buildAppearanceTile(),
|
||||
|
||||
_buildPlaybackTile(),
|
||||
|
||||
_buildTrackersTile(),
|
||||
const SizedBox(height: 8),
|
||||
SettingsGroup(
|
||||
children: [
|
||||
if (DonationService.isEnabled) _buildDonateTile(),
|
||||
_buildAppearanceTile(),
|
||||
_buildPlaybackTile(),
|
||||
_buildTrackersTile(),
|
||||
],
|
||||
),
|
||||
|
||||
_buildConnectionsSection(),
|
||||
|
||||
_buildProfilesSection(),
|
||||
|
||||
if (!PlatformDetector.isAppleTV()) _buildDownloadsSection(),
|
||||
|
||||
if (_keyboardShortcutsSupported) ...[_buildKeyboardShortcutsSection()],
|
||||
@@ -166,12 +166,17 @@ class _SettingsScreenState extends State<SettingsScreen> with FocusableTab, Moun
|
||||
|
||||
if (!PlatformDetector.isTV()) _buildBackupSection(),
|
||||
|
||||
SettingNavigationTile(
|
||||
focusNode: _focusTracker.get(_kAbout),
|
||||
icon: Symbols.info_rounded,
|
||||
title: t.settings.about,
|
||||
subtitle: t.settings.aboutDescription,
|
||||
destinationBuilder: (context) => const AboutScreen(),
|
||||
const SizedBox(height: 24),
|
||||
SettingsGroup(
|
||||
children: [
|
||||
SettingNavigationTile(
|
||||
focusNode: _focusTracker.get(_kAbout),
|
||||
icon: Symbols.info_rounded,
|
||||
title: t.settings.about,
|
||||
subtitle: t.settings.aboutDescription,
|
||||
destinationBuilder: (context) => const AboutScreen(),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
]),
|
||||
@@ -253,10 +258,9 @@ class _SettingsScreenState extends State<SettingsScreen> with FocusableTab, Moun
|
||||
? t.connections.addConnectionSubtitleNoProfile
|
||||
: t.connections.addConnectionSubtitleScoped(displayName: active.displayName);
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: .start,
|
||||
return SettingsGroup(
|
||||
title: t.connections.sectionTitle,
|
||||
children: [
|
||||
SettingsSectionHeader(t.connections.sectionTitle),
|
||||
// Connections are managed per-profile (via the Profiles section
|
||||
// and each profile's detail screen). The shortcut here just opens
|
||||
// the picker scoped to the active profile so users can add a Plex
|
||||
@@ -270,11 +274,12 @@ class _SettingsScreenState extends State<SettingsScreen> with FocusableTab, Moun
|
||||
Navigator.push(context, MaterialPageRoute(builder: (_) => AddConnectionScreen(targetProfile: active)));
|
||||
},
|
||||
),
|
||||
_buildProfilesTile(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildProfilesSection() {
|
||||
Widget _buildProfilesTile() {
|
||||
// ActiveProfileProvider already merges local rows with virtual Plex
|
||||
// Home profiles — counting only the local DB rows made every Plex Home
|
||||
// household read as a single profile here. `context.select` keeps
|
||||
@@ -302,10 +307,9 @@ class _SettingsScreenState extends State<SettingsScreen> with FocusableTab, Moun
|
||||
final storageService = DownloadStorageService.instance;
|
||||
final isCustom = storageService.isUsingCustomPath();
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: .start,
|
||||
return SettingsGroup(
|
||||
title: t.settings.downloads,
|
||||
children: [
|
||||
SettingsSectionHeader(t.settings.downloads),
|
||||
if (!Platform.isIOS)
|
||||
FutureBuilder<String>(
|
||||
future: storageService.getCurrentDownloadPathDisplay(),
|
||||
@@ -342,10 +346,9 @@ class _SettingsScreenState extends State<SettingsScreen> with FocusableTab, Moun
|
||||
Widget _buildKeyboardShortcutsSection() {
|
||||
if (_keyboardService == null) return const SizedBox.shrink();
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: .start,
|
||||
return SettingsGroup(
|
||||
title: t.settings.keyboardShortcuts,
|
||||
children: [
|
||||
SettingsSectionHeader(t.settings.keyboardShortcuts),
|
||||
SettingNavigationTile(
|
||||
focusNode: _focusTracker.get(_kVideoPlayerControls),
|
||||
icon: Symbols.keyboard_rounded,
|
||||
@@ -370,10 +373,9 @@ class _SettingsScreenState extends State<SettingsScreen> with FocusableTab, Moun
|
||||
}
|
||||
|
||||
Widget _buildAdvancedSection() {
|
||||
return Column(
|
||||
crossAxisAlignment: .start,
|
||||
return SettingsGroup(
|
||||
title: t.settings.advanced,
|
||||
children: [
|
||||
SettingsSectionHeader(t.settings.advanced),
|
||||
ListTile(
|
||||
focusNode: _focusTracker.get(_kWatchTogetherRelay),
|
||||
leading: const AppIcon(Symbols.dns_rounded, fill: 1),
|
||||
@@ -446,10 +448,9 @@ class _SettingsScreenState extends State<SettingsScreen> with FocusableTab, Moun
|
||||
}
|
||||
|
||||
Widget _buildBackupSection() {
|
||||
return Column(
|
||||
crossAxisAlignment: .start,
|
||||
return SettingsGroup(
|
||||
title: t.settings.backup,
|
||||
children: [
|
||||
SettingsSectionHeader(t.settings.backup),
|
||||
ListTile(
|
||||
focusNode: _focusTracker.get(_kExportSettings),
|
||||
leading: const AppIcon(Symbols.upload_rounded, fill: 1),
|
||||
@@ -480,10 +481,9 @@ class _SettingsScreenState extends State<SettingsScreen> with FocusableTab, Moun
|
||||
|
||||
Widget _buildUpdateSection() {
|
||||
if (UpdateService.useNativeUpdater) {
|
||||
return Column(
|
||||
crossAxisAlignment: .start,
|
||||
return SettingsGroup(
|
||||
title: t.settings.updates,
|
||||
children: [
|
||||
SettingsSectionHeader(t.settings.updates),
|
||||
ListTile(
|
||||
focusNode: _focusTracker.get(_kCheckForUpdates),
|
||||
leading: const AppIcon(Symbols.system_update_rounded, fill: 1),
|
||||
@@ -498,10 +498,9 @@ class _SettingsScreenState extends State<SettingsScreen> with FocusableTab, Moun
|
||||
|
||||
final hasUpdate = _updateInfo != null && _updateInfo!['hasUpdate'] == true;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: .start,
|
||||
return SettingsGroup(
|
||||
title: t.settings.updates,
|
||||
children: [
|
||||
SettingsSectionHeader(t.settings.updates),
|
||||
ListTile(
|
||||
focusNode: _focusTracker.get(_kCheckForUpdates),
|
||||
leading: AppIcon(
|
||||
|
||||
Reference in New Issue
Block a user