refactor: format

This commit is contained in:
edde746
2025-12-12 17:05:26 +01:00
parent b0ee43d8cd
commit 11461eefe5
47 changed files with 518 additions and 121 deletions
+3 -5
View File
@@ -191,11 +191,9 @@ class AppDatabase extends _$AppDatabase {
/// Get all downloaded media items (for syncing watch states)
Future<List<DownloadedMediaItem>> getAllDownloadedMetadata() {
return (select(downloadedMedia)
..where(
(t) => t.status.equals(DownloadStatus.completed.index),
))
.get();
return (select(
downloadedMedia,
)..where((t) => t.status.equals(DownloadStatus.completed.index))).get();
}
}
+5 -5
View File
@@ -905,7 +905,8 @@ class DownloadProvider extends ChangeNotifier {
// Ensure show artwork is downloaded even if metadata already existed
final thumbPath = showWithServer.thumb;
final hasPoster = thumbPath != null &&
final hasPoster =
thumbPath != null &&
await storageService.artworkExists(serverId, thumbPath);
if (!hasPoster) {
await _downloadManager.downloadArtworkForMetadata(
@@ -916,9 +917,7 @@ class DownloadProvider extends ChangeNotifier {
}
// Store artwork reference in provider's map for offline display
_artworkPaths[showGlobalKey] = DownloadedArtwork(
thumbPath: thumbPath,
);
_artworkPaths[showGlobalKey] = DownloadedArtwork(thumbPath: thumbPath);
}
}
@@ -948,7 +947,8 @@ class DownloadProvider extends ChangeNotifier {
// Ensure season artwork is downloaded even if metadata already existed
final thumbPath = seasonWithServer.thumb;
final hasPoster = thumbPath != null &&
final hasPoster =
thumbPath != null &&
await storageService.artworkExists(serverId, thumbPath);
if (!hasPoster) {
await _downloadManager.downloadArtworkForMetadata(
@@ -133,7 +133,12 @@ abstract class BaseMediaListDetailScreen<T extends StatefulWidget>
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const AppIcon(Symbols.error_outline_rounded, fill: 1, size: 48, color: Colors.red),
const AppIcon(
Symbols.error_outline_rounded,
fill: 1,
size: 48,
color: Colors.red,
),
const SizedBox(height: 16),
Text(errorMessage!),
const SizedBox(height: 16),
+33 -5
View File
@@ -845,7 +845,11 @@ class _DiscoverScreenState extends State<DiscoverScreen>
size: 32,
showIndicators: false,
)
: const AppIcon(Symbols.account_circle_rounded, fill: 1, size: 32),
: const AppIcon(
Symbols.account_circle_rounded,
fill: 1,
size: 32,
),
onSelected: (value) {
if (value == 'switch_profile') {
_handleSwitchProfile(context);
@@ -894,7 +898,12 @@ class _DiscoverScreenState extends State<DiscoverScreen>
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const AppIcon(Symbols.error_outline_rounded, fill: 1, size: 48, color: Colors.red),
const AppIcon(
Symbols.error_outline_rounded,
fill: 1,
size: 48,
color: Colors.red,
),
const SizedBox(height: 16),
Text(_errorMessage!),
const SizedBox(height: 16),
@@ -1008,7 +1017,12 @@ class _DiscoverScreenState extends State<DiscoverScreen>
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AppIcon(Symbols.movie_rounded, fill: 1, size: 64, color: Colors.grey),
AppIcon(
Symbols.movie_rounded,
fill: 1,
size: 64,
color: Colors.grey,
),
SizedBox(height: 16),
Text(t.discover.noContentAvailable),
SizedBox(height: 8),
@@ -1072,7 +1086,16 @@ class _DiscoverScreenState extends State<DiscoverScreen>
_pauseAutoScroll();
}
},
child: AppIcon(_isAutoScrollPaused ? Symbols.play_arrow_rounded : Symbols.pause_rounded, fill: 1, color: Colors.white, size: 18, semanticLabel: '${_isAutoScrollPaused ? t.discover.play : t.discover.pause} auto-scroll'),
child: AppIcon(
_isAutoScrollPaused
? Symbols.play_arrow_rounded
: Symbols.pause_rounded,
fill: 1,
color: Colors.white,
size: 18,
semanticLabel:
'${_isAutoScrollPaused ? t.discover.play : t.discover.pause} auto-scroll',
),
),
// Spacer to separate indicators from button
const SizedBox(width: 8),
@@ -1525,7 +1548,12 @@ class _DiscoverScreenState extends State<DiscoverScreen>
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const AppIcon(Symbols.play_arrow_rounded, fill: 1, size: 20, color: Colors.black),
const AppIcon(
Symbols.play_arrow_rounded,
fill: 1,
size: 20,
color: Colors.black,
),
const SizedBox(width: 8),
if (hasProgress) ...[
// Progress bar
+17 -4
View File
@@ -240,7 +240,9 @@ class DownloadsScreenState extends State<DownloadsScreen>
// Helper to get client from globalKey (serverId:ratingKey)
getClient(String globalKey) {
final serverId = globalKey.split(':').first;
return serverProvider.serverManager.getClient(serverId);
return serverProvider.serverManager.getClient(
serverId,
);
}
return DownloadTreeView(
@@ -250,13 +252,19 @@ class DownloadsScreenState extends State<DownloadsScreen>
onResume: (globalKey) {
final client = getClient(globalKey);
if (client != null) {
downloadProvider.resumeDownload(globalKey, client);
downloadProvider.resumeDownload(
globalKey,
client,
);
}
},
onRetry: (globalKey) {
final client = getClient(globalKey);
if (client != null) {
downloadProvider.retryDownload(globalKey, client);
downloadProvider.retryDownload(
globalKey,
client,
);
}
},
onCancel: downloadProvider.cancelDownload,
@@ -339,7 +347,12 @@ class _DownloadsGridContent extends StatelessWidget {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AppIcon(Symbols.download_rounded, fill: 1, size: 80, color: Theme.of(context).colorScheme.outline),
AppIcon(
Symbols.download_rounded,
fill: 1,
size: 80,
color: Theme.of(context).colorScheme.outline,
),
const SizedBox(height: 24),
Text(
t.downloads.noDownloads,
+11 -2
View File
@@ -245,7 +245,11 @@ class _HubDetailScreenState extends State<HubDetailScreen> with Refreshable {
title: Text(widget.hub.title),
actions: [
IconButton(
icon: AppIcon(Symbols.swap_vert_rounded, fill: 1, semanticLabel: t.libraries.sort),
icon: AppIcon(
Symbols.swap_vert_rounded,
fill: 1,
semanticLabel: t.libraries.sort,
),
onPressed: _showSortBottomSheet,
),
],
@@ -256,7 +260,12 @@ class _HubDetailScreenState extends State<HubDetailScreen> with Refreshable {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const AppIcon(Symbols.error_outline_rounded, fill: 1, size: 48, color: Colors.red),
const AppIcon(
Symbols.error_outline_rounded,
fill: 1,
size: 48,
color: Colors.red,
),
const SizedBox(height: 16),
Text(_errorMessage!),
const SizedBox(height: 16),
+17 -2
View File
@@ -81,7 +81,13 @@ class FolderTreeItem extends StatelessWidget {
height: 16,
child: CircularProgressIndicator(strokeWidth: 2),
)
: AppIcon(isExpanded ? Symbols.keyboard_arrow_down_rounded : Symbols.keyboard_arrow_right_rounded, fill: 1, size: 20),
: AppIcon(
isExpanded
? Symbols.keyboard_arrow_down_rounded
: Symbols.keyboard_arrow_right_rounded,
fill: 1,
size: 20,
),
)
else
const SizedBox(width: 24),
@@ -89,7 +95,16 @@ class FolderTreeItem extends StatelessWidget {
const SizedBox(width: 8),
// File/folder icon
AppIcon(_getIcon(), fill: 1, size: 20, color: isFolder ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.7)),
AppIcon(
_getIcon(),
fill: 1,
size: 20,
color: isFolder
? Theme.of(context).colorScheme.primary
: Theme.of(
context,
).colorScheme.onSurface.withValues(alpha: 0.7),
),
const SizedBox(width: 12),
+33 -5
View File
@@ -963,7 +963,12 @@ class _LibrariesScreenState extends State<LibrariesScreen>
value: library.globalKey,
child: Row(
children: [
AppIcon(_getLibraryIcon(library.type), fill: 1, size: 20, color: isSelected ? Theme.of(context).colorScheme.primary : null),
AppIcon(
_getLibraryIcon(library.type),
fill: 1,
size: 20,
color: isSelected ? Theme.of(context).colorScheme.primary : null,
),
const SizedBox(width: 12),
Expanded(
child: Column(
@@ -1170,7 +1175,12 @@ class _LibrariesScreenState extends State<LibrariesScreen>
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const AppIcon(Symbols.error_outline_rounded, fill: 1, size: 48, color: Colors.red),
const AppIcon(
Symbols.error_outline_rounded,
fill: 1,
size: 48,
color: Colors.red,
),
const SizedBox(height: 16),
Text(_errorMessage!),
const SizedBox(height: 16),
@@ -1188,7 +1198,12 @@ class _LibrariesScreenState extends State<LibrariesScreen>
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const AppIcon(Symbols.video_library_rounded, fill: 1, size: 64, color: Colors.grey),
const AppIcon(
Symbols.video_library_rounded,
fill: 1,
size: 64,
color: Colors.grey,
),
const SizedBox(height: 16),
Text(t.libraries.noLibrariesFound),
],
@@ -1684,7 +1699,15 @@ class _LibraryManagementSheetState extends State<_LibraryManagementSheet> {
children: [
ReorderableDragStartListener(
index: index,
child: AppIcon(isMoving ? Symbols.swap_vert_rounded : Symbols.drag_indicator_rounded, fill: 1, color: isMoving ? colorScheme.primary : IconTheme.of(context).color?.withValues(alpha: 0.5)),
child: AppIcon(
isMoving
? Symbols.swap_vert_rounded
: Symbols.drag_indicator_rounded,
fill: 1,
color: isMoving
? colorScheme.primary
: IconTheme.of(context).color?.withValues(alpha: 0.5),
),
),
const SizedBox(width: 8),
AppIcon(_getLibraryIcon(library.type), fill: 1),
@@ -1713,7 +1736,12 @@ class _LibraryManagementSheetState extends State<_LibraryManagementSheet> {
)
: null,
child: IconButton(
icon: AppIcon(isHidden ? Symbols.visibility_off_rounded : Symbols.visibility_rounded, fill: 1),
icon: AppIcon(
isHidden
? Symbols.visibility_off_rounded
: Symbols.visibility_rounded,
fill: 1,
),
tooltip: isHidden
? t.libraries.showLibrary
: t.libraries.hideLibrary,
+10 -2
View File
@@ -110,11 +110,19 @@ class _SortBottomSheetState extends State<SortBottomSheet> {
segments: const [
ButtonSegment(
value: false,
icon: AppIcon(Symbols.arrow_upward_rounded, fill: 1, size: 16),
icon: AppIcon(
Symbols.arrow_upward_rounded,
fill: 1,
size: 16,
),
),
ButtonSegment(
value: true,
icon: AppIcon(Symbols.arrow_downward_rounded, fill: 1, size: 16),
icon: AppIcon(
Symbols.arrow_downward_rounded,
fill: 1,
size: 16,
),
),
],
selected: {_currentDescending},
@@ -46,11 +46,16 @@ class StateMessageWidget extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (icon != null) ...[
AppIcon(icon, fill: 1, size: 64, color:
AppIcon(
icon,
fill: 1,
size: 64,
color:
iconColor ??
Theme.of(
context,
).colorScheme.onSurface.withValues(alpha: 0.4)),
).colorScheme.onSurface.withValues(alpha: 0.4),
),
const SizedBox(height: 16),
],
Text(
+13 -9
View File
@@ -183,16 +183,14 @@ class _MainScreenState extends State<MainScreen> with RouteAware {
}
void _handleOfflineStatusChanged() {
final newOffline =
_offlineModeProvider?.isOffline ?? widget.isOfflineMode;
final newOffline = _offlineModeProvider?.isOffline ?? widget.isOfflineMode;
if (newOffline == _isOffline) return;
setState(() {
_isOffline = newOffline;
_screens = _buildScreens(_isOffline);
_selectedLibraryGlobalKey =
_isOffline ? null : _selectedLibraryGlobalKey;
_selectedLibraryGlobalKey = _isOffline ? null : _selectedLibraryGlobalKey;
_currentIndex = _normalizeIndexForMode(_currentIndex, _isOffline);
});
@@ -205,9 +203,7 @@ class _MainScreenState extends State<MainScreen> with RouteAware {
if (!_isOffline) {
final userProfileProvider = context.userProfile;
userProfileProvider.initialize().then((_) {
userProfileProvider.setDataInvalidationCallback(
_invalidateAllScreens,
);
userProfileProvider.setDataInvalidationCallback(_invalidateAllScreens);
});
}
}
@@ -467,7 +463,10 @@ class _MainScreenState extends State<MainScreen> with RouteAware {
),
NavigationDestination(
icon: const AppIcon(Symbols.video_library_rounded, fill: 1),
selectedIcon: const AppIcon(Symbols.video_library_rounded, fill: 1),
selectedIcon: const AppIcon(
Symbols.video_library_rounded,
fill: 1,
),
label: t.navigation.libraries,
),
NavigationDestination(
@@ -510,7 +509,12 @@ class _OfflinePlaceholder extends StatelessWidget {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AppIcon(Symbols.cloud_off_rounded, fill: 1, size: 64, color: Theme.of(context).colorScheme.onSurfaceVariant),
AppIcon(
Symbols.cloud_off_rounded,
fill: 1,
size: 64,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
const SizedBox(height: 16),
Text(
t.messages.youAreOffline,
@@ -233,7 +233,12 @@ class _PlaylistDetailScreenState
Row(
mainAxisSize: MainAxisSize.min,
children: [
AppIcon(Symbols.auto_awesome_rounded, fill: 1, size: 12, color: Colors.blue[300]),
AppIcon(
Symbols.auto_awesome_rounded,
fill: 1,
size: 12,
color: Colors.blue[300],
),
const SizedBox(width: 4),
Text(
t.playlists.smartPlaylist,
+11 -2
View File
@@ -58,7 +58,11 @@ class _PlaylistItemCardState extends State<PlaylistItemCard> {
index: widget.index,
child: const Padding(
padding: EdgeInsets.only(right: 12),
child: AppIcon(Symbols.drag_indicator_rounded, fill: 1, color: Colors.grey),
child: AppIcon(
Symbols.drag_indicator_rounded,
fill: 1,
color: Colors.grey,
),
),
),
@@ -166,7 +170,12 @@ class _PlaylistItemCardState extends State<PlaylistItemCard> {
color: Colors.grey[850],
borderRadius: BorderRadius.circular(6),
),
child: const AppIcon(Symbols.movie_rounded, fill: 1, color: Colors.grey, size: 24),
child: const AppIcon(
Symbols.movie_rounded,
fill: 1,
color: Colors.grey,
size: 24,
),
);
}
+13 -2
View File
@@ -88,7 +88,12 @@ class _PinEntryDialogState extends State<PinEntryDialog>
child: AlertDialog(
title: Row(
children: [
AppIcon(Symbols.lock_outline_rounded, fill: 1, size: 24, color: theme.colorScheme.primary),
AppIcon(
Symbols.lock_outline_rounded,
fill: 1,
size: 24,
color: theme.colorScheme.primary,
),
const SizedBox(width: 12),
Expanded(
child: Text(widget.userName, overflow: TextOverflow.ellipsis),
@@ -114,7 +119,13 @@ class _PinEntryDialogState extends State<PinEntryDialog>
errorText: widget.errorMessage,
errorMaxLines: 2,
suffixIcon: IconButton(
icon: AppIcon(_obscureText ? Symbols.visibility_off_rounded : Symbols.visibility_rounded, fill: 1, size: 20),
icon: AppIcon(
_obscureText
? Symbols.visibility_off_rounded
: Symbols.visibility_rounded,
fill: 1,
size: 20,
),
onPressed: () {
setState(() {
_obscureText = !_obscureText;
+3 -1
View File
@@ -48,7 +48,9 @@ class ProfileListTile extends StatelessWidget {
),
),
)
: (showTrailingIcon ? const AppIcon(Symbols.chevron_right_rounded, fill: 1) : null),
: (showTrailingIcon
? const AppIcon(Symbols.chevron_right_rounded, fill: 1)
: null),
onTap: isCurrentUser ? null : onTap,
enabled: !isCurrentUser,
);
@@ -56,7 +56,12 @@ class ProfileSwitchScreen extends StatelessWidget {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AppIcon(Symbols.person_off_rounded, fill: 1, size: 64, color: theme.colorScheme.onSurfaceVariant),
AppIcon(
Symbols.person_off_rounded,
fill: 1,
size: 64,
color: theme.colorScheme.onSurfaceVariant,
),
const SizedBox(height: 16),
Text(
'No profiles available',
+6 -1
View File
@@ -29,7 +29,12 @@ class UserAvatarWidget extends StatelessWidget {
color: theme.colorScheme.surfaceContainerHighest,
shape: BoxShape.circle,
),
child: AppIcon(Symbols.person_rounded, fill: 1, size: size * 0.6, color: theme.colorScheme.onSurfaceVariant),
child: AppIcon(
Symbols.person_rounded,
fill: 1,
size: size * 0.6,
color: theme.colorScheme.onSurfaceVariant,
),
);
}
+12 -2
View File
@@ -217,7 +217,12 @@ class _SearchScreenState extends State<SearchScreen> with Refreshable {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AppIcon(Symbols.search_rounded, fill: 1, size: 80, color: Colors.grey.shade400),
AppIcon(
Symbols.search_rounded,
fill: 1,
size: 80,
color: Colors.grey.shade400,
),
const SizedBox(height: 16),
Text(
t.search.searchYourMedia,
@@ -240,7 +245,12 @@ class _SearchScreenState extends State<SearchScreen> with Refreshable {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AppIcon(Symbols.search_off_rounded, fill: 1, size: 80, color: Colors.grey.shade400),
AppIcon(
Symbols.search_off_rounded,
fill: 1,
size: 80,
color: Colors.grey.shade400,
),
const SizedBox(height: 16),
Text(
t.messages.noResultsFound,
+57 -10
View File
@@ -149,7 +149,12 @@ class _SeasonDetailScreenState extends State<SeasonDetailScreen>
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AppIcon(Symbols.movie_rounded, fill: 1, size: 64, color: tokens(context).textMuted),
AppIcon(
Symbols.movie_rounded,
fill: 1,
size: 64,
color: tokens(context).textMuted,
),
const SizedBox(height: 16),
Text(
t.messages.noEpisodesFoundGeneral,
@@ -315,7 +320,11 @@ class _EpisodeCard extends StatelessWidget {
color: Theme.of(
context,
).colorScheme.surfaceContainerHighest,
child: const AppIcon(Symbols.movie_rounded, fill: 1, size: 32),
child: const AppIcon(
Symbols.movie_rounded,
fill: 1,
size: 32,
),
),
)
: episode.thumb != null
@@ -333,14 +342,22 @@ class _EpisodeCard extends StatelessWidget {
color: Theme.of(
context,
).colorScheme.surfaceContainerHighest,
child: const AppIcon(Symbols.movie_rounded, fill: 1, size: 32),
child: const AppIcon(
Symbols.movie_rounded,
fill: 1,
size: 32,
),
),
)
: Container(
color: Theme.of(
context,
).colorScheme.surfaceContainerHighest,
child: const AppIcon(Symbols.movie_rounded, fill: 1, size: 32),
child: const AppIcon(
Symbols.movie_rounded,
fill: 1,
size: 32,
),
),
),
),
@@ -366,7 +383,12 @@ class _EpisodeCard extends StatelessWidget {
color: Colors.black.withValues(alpha: 0.6),
shape: BoxShape.circle,
),
child: const AppIcon(Symbols.play_arrow_rounded, fill: 1, color: Colors.white, size: 20),
child: const AppIcon(
Symbols.play_arrow_rounded,
fill: 1,
color: Colors.white,
size: 20,
),
),
),
),
@@ -440,7 +462,12 @@ class _EpisodeCard extends StatelessWidget {
} else if (progress?.status ==
DownloadStatus.queued) {
// Queued state - waiting to download
downloadStatusIcon = AppIcon(Symbols.schedule_rounded, fill: 1, size: 12, color: getMutedColor(Colors.orange));
downloadStatusIcon = AppIcon(
Symbols.schedule_rounded,
fill: 1,
size: 12,
color: getMutedColor(Colors.orange),
);
} else if (progress?.status ==
DownloadStatus.downloading) {
// Downloading state - active download with radial progress
@@ -474,19 +501,39 @@ class _EpisodeCard extends StatelessWidget {
} else if (progress?.status ==
DownloadStatus.paused) {
// Paused state - download paused
downloadStatusIcon = AppIcon(Symbols.pause_circle_outline_rounded, fill: 1, size: 12, color: getMutedColor(Colors.amber));
downloadStatusIcon = AppIcon(
Symbols.pause_circle_outline_rounded,
fill: 1,
size: 12,
color: getMutedColor(Colors.amber),
);
} else if (progress?.status ==
DownloadStatus.failed) {
// Failed state - download failed
downloadStatusIcon = AppIcon(Symbols.error_outline_rounded, fill: 1, size: 12, color: getMutedColor(Colors.red));
downloadStatusIcon = AppIcon(
Symbols.error_outline_rounded,
fill: 1,
size: 12,
color: getMutedColor(Colors.red),
);
} else if (progress?.status ==
DownloadStatus.cancelled) {
// Cancelled state - download cancelled
downloadStatusIcon = AppIcon(Symbols.cancel_rounded, fill: 1, size: 12, color: getMutedColor(Colors.grey));
downloadStatusIcon = AppIcon(
Symbols.cancel_rounded,
fill: 1,
size: 12,
color: getMutedColor(Colors.grey),
);
} else if (progress?.status ==
DownloadStatus.completed) {
// Completed state - download complete
downloadStatusIcon = AppIcon(Symbols.file_download_done_rounded, fill: 1, size: 12, color: getMutedColor(Colors.green));
downloadStatusIcon = AppIcon(
Symbols.file_download_done_rounded,
fill: 1,
size: 12,
color: getMutedColor(Colors.green),
);
}
// Note: No icon shown if not downloaded (null)
}
+4 -1
View File
@@ -80,7 +80,10 @@ class _AboutScreenState extends State<AboutScreen> {
leading: const AppIcon(Symbols.description_rounded, fill: 1),
title: Text(t.about.openSourceLicenses),
subtitle: Text(t.about.viewLicensesDescription),
trailing: const AppIcon(Symbols.chevron_right_rounded, fill: 1),
trailing: const AppIcon(
Symbols.chevron_right_rounded,
fill: 1,
),
onTap: () {
Navigator.push(
context,
@@ -73,7 +73,11 @@ class _HotKeyRecorderWidgetState extends State<HotKeyRecorderWidget> {
),
if (_recordedHotKey != null)
IconButton(
icon: const AppIcon(Symbols.backspace_rounded, fill: 1, size: 18),
icon: const AppIcon(
Symbols.backspace_rounded,
fill: 1,
size: 18,
),
onPressed: () {
setState(() {
_recordedHotKey = null;
+4 -1
View File
@@ -106,7 +106,10 @@ class _LicensesScreenState extends State<LicensesScreen> {
),
)
: null,
trailing: const AppIcon(Symbols.chevron_right_rounded, fill: 1),
trailing: const AppIcon(
Symbols.chevron_right_rounded,
fill: 1,
),
onTap: () => _showLicenseDetail(mergedLicense),
),
);
+14 -3
View File
@@ -196,7 +196,12 @@ class _LogEntryCardState extends State<_LogEntryCard> {
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AppIcon(widget.levelIcon, fill: 1, color: widget.levelColor, size: 20),
AppIcon(
widget.levelIcon,
fill: 1,
color: widget.levelColor,
size: 20,
),
const SizedBox(width: 8),
Expanded(
child: Column(
@@ -235,9 +240,15 @@ class _LogEntryCardState extends State<_LogEntryCard> {
),
),
if (hasErrorOrStackTrace)
AppIcon(_isExpanded ? Symbols.expand_less_rounded : Symbols.expand_more_rounded, fill: 1, color: Theme.of(
AppIcon(
_isExpanded
? Symbols.expand_less_rounded
: Symbols.expand_more_rounded,
fill: 1,
color: Theme.of(
context,
).iconTheme.color?.withValues(alpha: 0.6)),
).iconTheme.color?.withValues(alpha: 0.6),
),
],
),
if (_isExpanded && hasErrorOrStackTrace) ...[
+6 -3
View File
@@ -73,8 +73,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
_autoSkipCredits = _settingsService.getAutoSkipCredits();
_autoSkipDelay = _settingsService.getAutoSkipDelay();
_downloadOnWifiOnly = _settingsService.getDownloadOnWifiOnly();
_videoPlayerNavigationEnabled =
_settingsService.getVideoPlayerNavigationEnabled();
_videoPlayerNavigationEnabled = _settingsService
.getVideoPlayerNavigationEnabled();
_isLoading = false;
});
}
@@ -386,7 +386,10 @@ class _SettingsScreenState extends State<SettingsScreen> {
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
trailing: const AppIcon(Symbols.chevron_right_rounded, fill: 1),
trailing: const AppIcon(
Symbols.chevron_right_rounded,
fill: 1,
),
onTap: () => _showDownloadLocationDialog(),
);
},
+12 -2
View File
@@ -1375,7 +1375,12 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen>
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const AppIcon(Symbols.play_circle_rounded, fill: 1, size: 64, color: Colors.white),
const AppIcon(
Symbols.play_circle_rounded,
fill: 1,
size: 64,
color: Colors.white,
),
const SizedBox(height: 24),
Consumer<PlaybackStateProvider>(
builder: (context, playbackState, child) {
@@ -1394,7 +1399,12 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen>
),
if (isShuffleActive) ...[
const SizedBox(width: 8),
const AppIcon(Symbols.shuffle_rounded, fill: 1, size: 20, color: Colors.white70),
const AppIcon(
Symbols.shuffle_rounded,
fill: 1,
size: 20,
color: Colors.white70,
),
],
],
);
+8 -5
View File
@@ -153,11 +153,14 @@ extension DownloadDatabaseOperations on AppDatabase {
/// Clear download error and reset retry count (for retry)
Future<void> clearDownloadError(String globalKey) async {
await (update(downloadedMedia)..where((t) => t.globalKey.equals(globalKey)))
.write(const DownloadedMediaCompanion(
errorMessage: Value(null),
retryCount: Value(0),
));
await (update(
downloadedMedia,
)..where((t) => t.globalKey.equals(globalKey))).write(
const DownloadedMediaCompanion(
errorMessage: Value(null),
retryCount: Value(0),
),
);
}
/// Remove item from queue
+1 -3
View File
@@ -76,9 +76,7 @@ class OfflineWatchSyncService extends ChangeNotifier {
/// Push always happens immediately. Pull respects [minSyncInterval] unless [force] is true.
Future<void> _performBidirectionalSync({bool force = false}) async {
if (_serverManager.onlineClients.isEmpty) {
appLogger.d(
'Skipping watch sync - no connected servers available yet',
);
appLogger.d('Skipping watch sync - no connected servers available yet');
return;
}
+6 -1
View File
@@ -154,7 +154,12 @@ class _AppBarBackButtonState extends State<AppBarBackButton>
color: currentColor,
shape: BoxShape.circle,
),
child: AppIcon(Symbols.arrow_back_rounded, fill: 1, color: effectiveColor, size: 20),
child: AppIcon(
Symbols.arrow_back_rounded,
fill: 1,
color: effectiveColor,
size: 20,
),
);
},
),
+7 -1
View File
@@ -121,7 +121,13 @@ class DownloadTreeItem extends StatelessWidget {
Widget _buildExpandIcon() {
return Padding(
padding: const EdgeInsets.only(right: 8.0),
child: AppIcon(isExpanded ? Symbols.expand_more_rounded : Symbols.chevron_right_rounded, fill: 1, size: 24),
child: AppIcon(
isExpanded
? Symbols.expand_more_rounded
: Symbols.chevron_right_rounded,
fill: 1,
size: 24,
),
);
}
+22 -4
View File
@@ -364,7 +364,13 @@ class _DownloadTreeViewState extends State<DownloadTreeView> {
children: [
// Expand/collapse icon
if (canExpand)
AppIcon(isExpanded ? Symbols.expand_more_rounded : Symbols.chevron_right_rounded, fill: 1, size: 20)
AppIcon(
isExpanded
? Symbols.expand_more_rounded
: Symbols.chevron_right_rounded,
fill: 1,
size: 20,
)
else
const SizedBox(width: 20),
@@ -498,7 +504,11 @@ class _DownloadTreeViewState extends State<DownloadTreeView> {
// Resume button for paused items
if (node.status == DownloadStatus.paused && widget.onResume != null)
IconButton(
icon: const AppIcon(Symbols.play_arrow_rounded, fill: 1, size: 20),
icon: const AppIcon(
Symbols.play_arrow_rounded,
fill: 1,
size: 20,
),
onPressed: () => widget.onResume!(globalKey),
tooltip: 'Resume',
),
@@ -548,7 +558,11 @@ class _DownloadTreeViewState extends State<DownloadTreeView> {
// Resume all button - show if container is paused
if (node.status == DownloadStatus.paused && widget.onResume != null)
IconButton(
icon: const AppIcon(Symbols.play_arrow_rounded, fill: 1, size: 20),
icon: const AppIcon(
Symbols.play_arrow_rounded,
fill: 1,
size: 20,
),
onPressed: () => _resumeAllChildren(node),
tooltip: 'Resume all',
),
@@ -556,7 +570,11 @@ class _DownloadTreeViewState extends State<DownloadTreeView> {
// Delete all button
if (widget.onDelete != null)
IconButton(
icon: const AppIcon(Symbols.delete_sweep_rounded, fill: 1, size: 20),
icon: const AppIcon(
Symbols.delete_sweep_rounded,
fill: 1,
size: 20,
),
onPressed: () => _deleteAllChildren(node),
tooltip: 'Delete all',
),
+11 -2
View File
@@ -58,7 +58,12 @@ class _FileInfoBottomSheetState extends State<FileInfoBottomSheet> {
padding: const EdgeInsets.all(16),
child: Row(
children: [
const AppIcon(Symbols.info_rounded, fill: 1, color: Colors.white, size: 24),
const AppIcon(
Symbols.info_rounded,
fill: 1,
color: Colors.white,
size: 24,
),
const SizedBox(width: 12),
Expanded(
child: Text(
@@ -72,7 +77,11 @@ class _FileInfoBottomSheetState extends State<FileInfoBottomSheet> {
),
IconButton(
focusNode: _initialFocusNode,
icon: const AppIcon(Symbols.close_rounded, fill: 1, color: Colors.white),
icon: const AppIcon(
Symbols.close_rounded,
fill: 1,
color: Colors.white,
),
onPressed: () => Navigator.pop(context),
),
],
+5 -1
View File
@@ -287,7 +287,11 @@ class HubSectionState extends State<HubSection> {
),
if (widget.hub.more) ...[
const SizedBox(width: 4),
const AppIcon(Symbols.chevron_right_rounded, fill: 1, size: 20),
const AppIcon(
Symbols.chevron_right_rounded,
fill: 1,
size: 20,
),
],
],
),
+9 -2
View File
@@ -717,7 +717,9 @@ Widget _buildPosterImage(
}
return SkeletonLoader(
child: Center(child: AppIcon(fallbackIcon, fill: 1, size: 40, color: Colors.white54)),
child: Center(
child: AppIcon(fallbackIcon, fill: 1, size: 40, color: Colors.white54),
),
);
}
@@ -840,7 +842,12 @@ class _MediaCardHelpers {
),
],
),
child: AppIcon(Symbols.check_rounded, fill: 1, color: tokens(context).bg, size: 16),
child: AppIcon(
Symbols.check_rounded,
fill: 1,
color: tokens(context).bg,
size: 16,
),
),
),
// Progress bar for partially watched content
+5 -1
View File
@@ -309,7 +309,11 @@ class MediaContextMenuState extends State<MediaContextMenu> {
itemType == 'show' ||
itemType == 'season') {
menuActions.add(
_MenuAction(value: 'add_to', icon: Symbols.add_rounded, label: t.common.addTo),
_MenuAction(
value: 'add_to',
icon: Symbols.add_rounded,
label: t.common.addTo,
),
);
}
} // End of regular menu items else block
+20 -3
View File
@@ -336,7 +336,14 @@ class PlexOptimizedImage extends StatelessWidget {
Widget _buildPlaceholder(BuildContext context) {
return SkeletonLoader(
child: fallbackIcon != null
? Center(child: AppIcon(fallbackIcon!, fill: 1, size: 40, color: Colors.white54))
? Center(
child: AppIcon(
fallbackIcon!,
fill: 1,
size: 40,
color: Colors.white54,
),
)
: null,
);
}
@@ -345,7 +352,12 @@ class PlexOptimizedImage extends StatelessWidget {
return Container(
color: Theme.of(context).colorScheme.surfaceContainerHighest,
child: Center(
child: AppIcon(fallbackIcon ?? Symbols.broken_image_rounded, fill: 1, size: 40, color: Theme.of(context).colorScheme.onSurfaceVariant),
child: AppIcon(
fallbackIcon ?? Symbols.broken_image_rounded,
fill: 1,
size: 40,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
);
}
@@ -356,7 +368,12 @@ class PlexOptimizedImage extends StatelessWidget {
height: height,
color: Theme.of(context).colorScheme.surfaceContainerHighest,
child: Center(
child: AppIcon(fallbackIcon ?? Symbols.image_not_supported_rounded, fill: 1, size: 40, color: Theme.of(context).colorScheme.onSurfaceVariant),
child: AppIcon(
fallbackIcon ?? Symbols.image_not_supported_rounded,
fill: 1,
size: 40,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
);
}
+22 -3
View File
@@ -80,7 +80,12 @@ class NavigationRailItem extends StatelessWidget {
),
child: Row(
children: [
AppIcon(isSelected && selectedIcon != null ? selectedIcon! : icon, fill: 1, size: iconSize, color: isSelected ? t.text : t.textMuted),
AppIcon(
isSelected && selectedIcon != null ? selectedIcon! : icon,
fill: 1,
size: iconSize,
color: isSelected ? t.text : t.textMuted,
),
const SizedBox(width: 12),
Expanded(child: label),
],
@@ -523,7 +528,14 @@ class SideNavigationRailState extends State<SideNavigationRail> {
),
child: Row(
children: [
AppIcon(widget.selectedIndex == 1 ? Symbols.video_library_rounded : Symbols.video_library_rounded, fill: 1, size: 22, color: widget.selectedIndex == 1 ? t.text : t.textMuted),
AppIcon(
widget.selectedIndex == 1
? Symbols.video_library_rounded
: Symbols.video_library_rounded,
fill: 1,
size: 22,
color: widget.selectedIndex == 1 ? t.text : t.textMuted,
),
const SizedBox(width: 12),
Expanded(
child: Text(
@@ -539,7 +551,14 @@ class SideNavigationRailState extends State<SideNavigationRail> {
),
),
),
AppIcon(_librariesExpanded ? Symbols.expand_less_rounded : Symbols.expand_more_rounded, fill: 1, size: 20, color: t.textMuted),
AppIcon(
_librariesExpanded
? Symbols.expand_less_rounded
: Symbols.expand_more_rounded,
fill: 1,
size: 20,
color: t.textMuted,
),
],
),
),
@@ -422,7 +422,9 @@ class DesktopVideoControlsState extends State<DesktopVideoControls> {
return _buildFocusableButton(
focusNode: _playPauseFocusNode,
index: 2,
icon: isPlaying ? Symbols.pause_rounded : Symbols.play_arrow_rounded,
icon: isPlaying
? Symbols.pause_rounded
: Symbols.play_arrow_rounded,
iconSize: 32,
onPressed: () {
if (isPlaying) {
@@ -87,7 +87,9 @@ class TrackSelectionHelper {
label,
style: TextStyle(color: isSelected ? Colors.blue : Colors.white),
),
trailing: isSelected ? const AppIcon(Symbols.check_rounded, fill: 1, color: Colors.blue) : null,
trailing: isSelected
? const AppIcon(Symbols.check_rounded, fill: 1, color: Colors.blue)
: null,
onTap: onTap,
);
}
@@ -103,7 +103,9 @@ class MobileVideoControls extends StatelessWidget {
semanticLabel: isPlaying
? t.videoControls.pauseButton
: t.videoControls.playButton,
icon: isPlaying ? Symbols.pause_rounded : Symbols.play_arrow_rounded,
icon: isPlaying
? Symbols.pause_rounded
: Symbols.play_arrow_rounded,
iconSize: 72,
onPressed: () {
if (isPlaying) {
@@ -149,7 +149,12 @@ class _ChapterSheetState extends State<ChapterSheet> {
height: 34,
fit: BoxFit.cover,
errorWidget: (context, url, error) =>
const AppIcon(Symbols.image_rounded, fill: 1, color: Colors.white54, size: 34),
const AppIcon(
Symbols.image_rounded,
fill: 1,
color: Colors.white54,
size: 34,
),
),
),
if (isCurrentChapter)
@@ -186,7 +191,11 @@ class _ChapterSheetState extends State<ChapterSheet> {
),
),
trailing: isCurrentChapter
? const AppIcon(Symbols.play_circle_rounded, fill: 1, color: Colors.blue)
? const AppIcon(
Symbols.play_circle_rounded,
fill: 1,
color: Colors.blue,
)
: null,
onTap: () {
widget.player.seek(chapter.startTime);
@@ -81,7 +81,11 @@ class _VersionSheetState extends State<VersionSheet> {
),
),
trailing: isSelected
? const AppIcon(Symbols.check_rounded, fill: 1, color: Colors.blue)
? const AppIcon(
Symbols.check_rounded,
fill: 1,
color: Colors.blue,
)
: null,
onTap: () {
Navigator.pop(context);
@@ -51,14 +51,22 @@ class _SettingsMenuItem extends StatelessWidget {
return FocusableListTile(
focusNode: focusNode,
leading: AppIcon(icon, fill: 1, color: isHighlighted ? Colors.amber : Colors.white70),
leading: AppIcon(
icon,
fill: 1,
color: isHighlighted ? Colors.amber : Colors.white70,
),
title: Text(title, style: const TextStyle(color: Colors.white)),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (allowValueOverflow) Flexible(child: valueWidget) else valueWidget,
const SizedBox(width: 8),
const AppIcon(Symbols.chevron_right_rounded, fill: 1, color: Colors.white70),
const AppIcon(
Symbols.chevron_right_rounded,
fill: 1,
color: Colors.white70,
),
],
),
onTap: onTap,
@@ -229,7 +237,9 @@ class _VideoSettingsSheetState extends State<VideoSettingsSheet> {
builder: (context, _) {
final isActive = sleepTimer.isActive;
return _SettingsMenuItem(
icon: isActive ? Symbols.bedtime_rounded : Symbols.bedtime_rounded,
icon: isActive
? Symbols.bedtime_rounded
: Symbols.bedtime_rounded,
title: 'Sleep Timer',
valueText: _formatSleepTimer(sleepTimer),
isHighlighted: isActive,
@@ -259,7 +269,11 @@ class _VideoSettingsSheetState extends State<VideoSettingsSheet> {
// HDR Toggle (iOS, macOS, and Windows)
if (Platform.isIOS || Platform.isMacOS || Platform.isWindows)
ListTile(
leading: AppIcon(Symbols.hdr_strong_rounded, fill: 1, color: _enableHDR ? Colors.amber : Colors.white70),
leading: AppIcon(
Symbols.hdr_strong_rounded,
fill: 1,
color: _enableHDR ? Colors.amber : Colors.white70,
),
title: const Text('HDR', style: TextStyle(color: Colors.white)),
trailing: Switch(
value: _enableHDR,
@@ -319,7 +333,11 @@ class _VideoSettingsSheetState extends State<VideoSettingsSheet> {
),
),
trailing: isSelected
? const AppIcon(Symbols.check_rounded, fill: 1, color: Colors.blue)
? const AppIcon(
Symbols.check_rounded,
fill: 1,
color: Colors.blue,
)
: null,
onTap: () {
widget.player.setRate(speed);
@@ -405,7 +423,11 @@ class _VideoSettingsSheetState extends State<VideoSettingsSheet> {
),
),
trailing: isSelected
? const AppIcon(Symbols.check_rounded, fill: 1, color: Colors.blue)
? const AppIcon(
Symbols.check_rounded,
fill: 1,
color: Colors.blue,
)
: null,
onTap: () {
widget.player.setAudioDevice(device);
@@ -30,7 +30,11 @@ class VideoSheetHeader extends StatelessWidget {
// Back button or icon
if (onBack != null)
IconButton(
icon: const AppIcon(Symbols.arrow_back_rounded, fill: 1, color: Colors.white),
icon: const AppIcon(
Symbols.arrow_back_rounded,
fill: 1,
color: Colors.white,
),
onPressed: onBack,
)
else if (icon != null)
@@ -46,7 +50,11 @@ class VideoSheetHeader extends StatelessWidget {
),
const Spacer(),
IconButton(
icon: const AppIcon(Symbols.close_rounded, fill: 1, color: Colors.white),
icon: const AppIcon(
Symbols.close_rounded,
fill: 1,
color: Colors.white,
),
onPressed: onClose ?? () => Navigator.pop(context),
),
],
+12 -5
View File
@@ -334,8 +334,8 @@ class _PlexVideoControlsState extends State<PlexVideoControls>
_autoSkipIntro = settingsService.getAutoSkipIntro();
_autoSkipCredits = settingsService.getAutoSkipCredits();
_autoSkipDelay = settingsService.getAutoSkipDelay();
_videoPlayerNavigationEnabled =
settingsService.getVideoPlayerNavigationEnabled();
_videoPlayerNavigationEnabled = settingsService
.getVideoPlayerNavigationEnabled();
});
// Apply rotation lock setting
@@ -801,9 +801,14 @@ class _PlexVideoControlsState extends State<PlexVideoControls>
color: Colors.black.withValues(alpha: 0.6),
shape: BoxShape.circle,
),
child: AppIcon(_lastDoubleTapWasForward
child: AppIcon(
_lastDoubleTapWasForward
? getForwardIcon(_seekTimeSmall)
: getReplayIcon(_seekTimeSmall), fill: 1, color: Colors.white, size: 48),
: getReplayIcon(_seekTimeSmall),
fill: 1,
color: Colors.white,
size: 48,
),
),
);
}
@@ -947,7 +952,9 @@ class _PlexVideoControlsState extends State<PlexVideoControls>
// On desktop, show controls and focus play/pause on directional input
// Only handle navigation if video player navigation is enabled
if (!isMobile && _isDirectionalKey(key) && _videoPlayerNavigationEnabled) {
if (!isMobile &&
_isDirectionalKey(key) &&
_videoPlayerNavigationEnabled) {
// If controls are hidden, show them and focus play/pause
if (!_showControls) {
_showControlsWithFocus();
@@ -39,7 +39,11 @@ class SleepTimerDurationList extends StatelessWidget {
);
return ListTile(
leading: const AppIcon(Symbols.timer_rounded, fill: 1, color: Colors.white70),
leading: const AppIcon(
Symbols.timer_rounded,
fill: 1,
color: Colors.white70,
),
title: Text(
label,
style: const TextStyle(
@@ -364,7 +364,9 @@ class TrackChapterControls extends StatelessWidget {
final currentIndex = buttonIndex;
buttons.add(
VideoControlButton(
icon: isFullscreen ? Symbols.fullscreen_exit_rounded : Symbols.fullscreen_rounded,
icon: isFullscreen
? Symbols.fullscreen_exit_rounded
: Symbols.fullscreen_rounded,
semanticLabel: isFullscreen
? t.videoControls.exitFullscreenButton
: t.videoControls.fullscreenButton,
@@ -149,7 +149,11 @@ class _VolumeControlState extends State<VolumeControl> {
button: true,
excludeSemantics: true,
child: IconButton(
icon: AppIcon(isMuted ? Symbols.volume_off_rounded : Symbols.volume_up_rounded, fill: 1, color: Colors.white),
icon: AppIcon(
isMuted ? Symbols.volume_off_rounded : Symbols.volume_up_rounded,
fill: 1,
color: Colors.white,
),
onPressed: () async {
final newVolume = isMuted ? 100.0 : 0.0;
widget.player.setVolume(newVolume);