1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-25 10:43:13 +02:00

refactor(mobile): build context extensions (#4923)

* refactor: move all extensions to separate package

* refactor(mobile): add BuildContext extension

* refactor(mobile): use theme getters from context

* refactor(mobile): use media query size from context

* refactor(mobile): use auto router methods from context

* refactor(mobile): use navigator methods from context

---------

Co-authored-by: shalong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
shenlong 2023-11-09 16:19:53 +00:00 committed by GitHub
parent a147dee4b6
commit bffc2cdf60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
106 changed files with 660 additions and 628 deletions

View File

@ -0,0 +1,54 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
extension ContextHelper on BuildContext {
// Returns the current size from MediaQuery
Size get size => MediaQuery.sizeOf(this);
// Returns the current width from MediaQuery
double get width => size.width;
// Returns the current height from MediaQuery
double get height => size.height;
// Returns true if the app is running on a mobile device (!tablets)
bool get isMobile => width < 550;
// Returns the current ThemeData
ThemeData get themeData => Theme.of(this);
// Returns true if the app is using a dark theme
bool get isDarkTheme => themeData.brightness == Brightness.dark;
// Returns the current Primary color of the Theme
Color get primaryColor => themeData.primaryColor;
// Returns the Scaffold background color of the Theme
Color get scaffoldBackgroundColor => themeData.scaffoldBackgroundColor;
// Returns the current TextTheme
TextTheme get textTheme => themeData.textTheme;
// Current ColorScheme used
ColorScheme get colorScheme => themeData.colorScheme;
// Pop-out from the current context with optional result
void pop<T>([T? result]) => Navigator.of(this).pop(result);
// Auto-Push new route from the current context
Future<T?> autoPush<T extends Object?>(PageRouteInfo<dynamic> route) =>
AutoRouter.of(this).push(route);
// Auto-Push navigate route from the current context
Future<dynamic> autoNavigate<T extends Object?>(
PageRouteInfo<dynamic> route,
) =>
AutoRouter.of(this).navigate(route);
// Auto-Push replace route from the current context
Future<T?> autoReplace<T extends Object?>(PageRouteInfo<dynamic> route) =>
AutoRouter.of(this).replace(route);
// Auto-Pop from the current context
Future<bool> autoPop<T>([T? result]) => AutoRouter.of(this).pop(result);
}

View File

@ -2,27 +2,6 @@ import 'dart:typed_data';
import 'package:collection/collection.dart';
extension DurationExtension on String {
Duration? toDuration() {
try {
final parts = split(':')
.map((e) => double.parse(e).toInt())
.toList(growable: false);
return Duration(hours: parts[0], minutes: parts[1], seconds: parts[2]);
} catch (e) {
return null;
}
}
double toDouble() {
return double.parse(this);
}
int toInt() {
return int.parse(this);
}
}
extension ListExtension<E> on List<E> {
List<E> uniqueConsecutive({
int Function(E a, E b)? compare,

View File

@ -0,0 +1,30 @@
extension StringExtension on String {
String capitalize() {
return split(" ")
.map(
(str) => str.isEmpty ? str : str[0].toUpperCase() + str.substring(1),
)
.join(" ");
}
}
extension DurationExtension on String {
Duration? toDuration() {
try {
final parts = split(':')
.map((e) => double.parse(e).toInt())
.toList(growable: false);
return Duration(hours: parts[0], minutes: parts[1], seconds: parts[2]);
} catch (e) {
return null;
}
}
double toDouble() {
return double.parse(this);
}
int toInt() {
return int.parse(this);
}
}

View File

@ -4,13 +4,14 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/activities/models/activity.model.dart';
import 'package:immich_mobile/modules/activities/providers/activity.provider.dart';
import 'package:immich_mobile/shared/models/store.dart';
import 'package:immich_mobile/shared/ui/confirm_dialog.dart';
import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
import 'package:immich_mobile/shared/ui/user_circle_avatar.dart';
import 'package:immich_mobile/utils/datetime_extensions.dart';
import 'package:immich_mobile/extensions/datetime_extensions.dart';
import 'package:immich_mobile/utils/image_url_builder.dart';
class ActivitiesPage extends HookConsumerWidget {
@ -49,12 +50,8 @@ class ActivitiesPage extends HookConsumerWidget {
);
buildTitleWithTimestamp(Activity activity, {bool leftAlign = true}) {
final textColor = Theme.of(context).brightness == Brightness.dark
? Colors.white
: Colors.black;
final textStyle = Theme.of(context)
.textTheme
.bodyMedium
final textColor = context.isDarkTheme ? Colors.white : Colors.black;
final textStyle = context.textTheme.bodyMedium
?.copyWith(color: textColor.withOpacity(0.6));
return Row(
@ -306,7 +303,7 @@ class ActivitiesPage extends HookConsumerWidget {
Align(
alignment: Alignment.bottomCenter,
child: Container(
color: Theme.of(context).scaffoldBackgroundColor,
color: context.scaffoldBackgroundColor,
child: buildTextField(liked?.id),
),
),

View File

@ -1,8 +1,8 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/album/providers/album.provider.dart';
import 'package:immich_mobile/modules/album/providers/album_detail.provider.dart';
import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart';
@ -95,20 +95,19 @@ class AddToAlbumBottomSheet extends HookConsumerWidget {
children: [
Text(
'common_add_to_album'.tr(),
style: Theme.of(context).textTheme.displayMedium,
style: context.textTheme.displayMedium,
),
TextButton.icon(
icon: Icon(
Icons.add,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
label: Text(
'common_create_new_album'.tr(),
style:
TextStyle(color: Theme.of(context).primaryColor),
style: TextStyle(color: context.primaryColor),
),
onPressed: () {
AutoRouter.of(context).push(
context.autoPush(
CreateAlbumRoute(
isSharedAlbum: false,
initialAssets: assets,

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
class AlbumActionOutlinedButton extends StatelessWidget {
final VoidCallback? onPressed;
@ -14,8 +15,6 @@ class AlbumActionOutlinedButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
return Padding(
padding: const EdgeInsets.only(right: 8.0),
child: OutlinedButton.icon(
@ -26,7 +25,7 @@ class AlbumActionOutlinedButton extends StatelessWidget {
),
side: BorderSide(
width: 1,
color: isDarkTheme
color: context.isDarkTheme
? const Color.fromARGB(255, 63, 63, 63)
: const Color.fromARGB(255, 206, 206, 206),
),
@ -34,13 +33,13 @@ class AlbumActionOutlinedButton extends StatelessWidget {
icon: Icon(
iconData,
size: 15,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
label: Text(
labelText,
style: Theme.of(context).textTheme.labelSmall?.copyWith(
fontWeight: FontWeight.bold,
),
style: context.textTheme.labelSmall?.copyWith(
fontWeight: FontWeight.bold,
),
),
onPressed: onPressed,
),

View File

@ -1,5 +1,6 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/shared/models/album.dart';
import 'package:immich_mobile/shared/models/store.dart';
import 'package:immich_mobile/shared/ui/immich_image.dart';
@ -22,7 +23,8 @@ class AlbumThumbnailCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
var isDarkTheme = context.isDarkTheme;
return LayoutBuilder(
builder: (context, constraints) {
var cardSize = constraints.maxWidth;
@ -32,7 +34,7 @@ class AlbumThumbnailCard extends StatelessWidget {
height: cardSize,
width: cardSize,
decoration: BoxDecoration(
color: isDarkMode ? Colors.grey[800] : Colors.grey[200],
color: isDarkTheme ? Colors.grey[800] : Colors.grey[200],
),
child: Center(
child: Icon(
@ -73,14 +75,14 @@ class AlbumThumbnailCard extends StatelessWidget {
style: TextStyle(
fontFamily: 'WorkSans',
fontSize: 12,
color: isDarkMode ? Colors.white : Colors.black,
color: isDarkTheme ? Colors.white : Colors.black,
),
),
if (owner != null) const TextSpan(text: ' · '),
if (owner != null)
TextSpan(
text: owner,
style: Theme.of(context).textTheme.labelSmall,
style: context.textTheme.labelSmall,
),
],
),
@ -114,8 +116,8 @@ class AlbumThumbnailCard extends StatelessWidget {
album.name,
style: TextStyle(
fontWeight: FontWeight.bold,
color: isDarkMode
? Theme.of(context).primaryColor
color: isDarkTheme
? context.primaryColor
: Colors.black,
),
),

View File

@ -1,7 +1,7 @@
import 'package:auto_route/auto_route.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/shared/models/album.dart';
import 'package:immich_mobile/shared/models/store.dart';
@ -21,12 +21,11 @@ class AlbumThumbnailListTile extends StatelessWidget {
@override
Widget build(BuildContext context) {
var cardSize = 68.0;
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
buildEmptyThumbnail() {
return Container(
decoration: BoxDecoration(
color: isDarkMode ? Colors.grey[800] : Colors.grey[200],
color: context.isDarkTheme ? Colors.grey[800] : Colors.grey[200],
),
child: SizedBox(
height: cardSize,
@ -61,7 +60,7 @@ class AlbumThumbnailListTile extends StatelessWidget {
behavior: HitTestBehavior.opaque,
onTap: onTap ??
() {
AutoRouter.of(context).push(AlbumViewerRoute(albumId: album.id));
context.autoPush(AlbumViewerRoute(albumId: album.id));
},
child: Padding(
padding: const EdgeInsets.only(bottom: 12.0),

View File

@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/album/providers/album_title.provider.dart';
class AlbumTitleTextField extends ConsumerWidget {
@ -19,7 +20,7 @@ class AlbumTitleTextField extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
final isDarkTheme = context.isDarkTheme;
return TextField(
onChanged: (v) {
@ -55,7 +56,7 @@ class AlbumTitleTextField extends ConsumerWidget {
},
icon: Icon(
Icons.cancel_rounded,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
splashRadius: 10,
)

View File

@ -1,8 +1,8 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/activities/providers/activity.provider.dart';
import 'package:immich_mobile/modules/album/providers/album.provider.dart';
import 'package:immich_mobile/modules/album/providers/album_detail.provider.dart';
@ -58,12 +58,12 @@ class AlbumViewerAppbar extends HookConsumerWidget
if (album.shared) {
success =
await ref.watch(sharedAlbumProvider.notifier).deleteAlbum(album);
AutoRouter.of(context)
.navigate(const TabControllerRoute(children: [SharingRoute()]));
context
.autoNavigate(const TabControllerRoute(children: [SharingRoute()]));
} else {
success = await ref.watch(albumProvider.notifier).deleteAlbum(album);
AutoRouter.of(context)
.navigate(const TabControllerRoute(children: [LibraryRoute()]));
context
.autoNavigate(const TabControllerRoute(children: [LibraryRoute()]));
}
if (!success) {
ImmichToast.show(
@ -93,7 +93,7 @@ class AlbumViewerAppbar extends HookConsumerWidget
child: Text(
'Cancel',
style: TextStyle(
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontWeight: FontWeight.bold,
),
),
@ -107,9 +107,7 @@ class AlbumViewerAppbar extends HookConsumerWidget
'Confirm',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).brightness == Brightness.light
? Colors.red
: Colors.red[300],
color: !context.isDarkTheme ? Colors.red : Colors.red[300],
),
),
),
@ -130,8 +128,8 @@ class AlbumViewerAppbar extends HookConsumerWidget
await ref.watch(sharedAlbumProvider.notifier).leaveAlbum(album);
if (isSuccess) {
AutoRouter.of(context)
.navigate(const TabControllerRoute(children: [SharingRoute()]));
context
.autoNavigate(const TabControllerRoute(children: [SharingRoute()]));
} else {
Navigator.pop(context);
ImmichToast.show(
@ -190,7 +188,7 @@ class AlbumViewerAppbar extends HookConsumerWidget
gravity: ToastGravity.BOTTOM,
);
}
Navigator.of(buildContext).pop();
context.pop();
},
);
return const ShareDialog();
@ -266,8 +264,7 @@ class AlbumViewerAppbar extends HookConsumerWidget
ListTile(
leading: const Icon(Icons.share_rounded),
onTap: () {
AutoRouter.of(context)
.push(SharedLinkEditRoute(albumId: album.remoteId));
context.autoPush(SharedLinkEditRoute(albumId: album.remoteId));
Navigator.pop(context);
},
title: const Text(
@ -277,8 +274,7 @@ class AlbumViewerAppbar extends HookConsumerWidget
),
ListTile(
leading: const Icon(Icons.settings_rounded),
onTap: () =>
AutoRouter.of(context).navigate(AlbumOptionsRoute(album: album)),
onTap: () => context.autoNavigate(AlbumOptionsRoute(album: album)),
title: const Text(
"translated_text_options",
style: TextStyle(fontWeight: FontWeight.bold),
@ -300,7 +296,7 @@ class AlbumViewerAppbar extends HookConsumerWidget
),
];
showModalBottomSheet(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
backgroundColor: context.scaffoldBackgroundColor,
isScrollControlled: false,
context: context,
builder: (context) {
@ -342,7 +338,7 @@ class AlbumViewerAppbar extends HookConsumerWidget
comments.toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
),
),
@ -381,7 +377,7 @@ class AlbumViewerAppbar extends HookConsumerWidget
);
} else {
return IconButton(
onPressed: () async => await AutoRouter.of(context).pop(),
onPressed: () async => await context.autoPop(),
icon: const Icon(Icons.arrow_back_ios_rounded),
splashRadius: 25,
);

View File

@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/album/providers/album_viewer.provider.dart';
import 'package:immich_mobile/shared/models/album.dart';
@ -17,7 +18,6 @@ class AlbumViewerEditableTitle extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final titleTextEditController = useTextEditingController(text: album.name);
final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
void onFocusModeChange() {
if (!titleFocusNode.hasFocus && titleTextEditController.text.isEmpty) {
@ -65,7 +65,7 @@ class AlbumViewerEditableTitle extends HookConsumerWidget {
},
icon: Icon(
Icons.cancel_rounded,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
splashRadius: 10,
)
@ -79,14 +79,14 @@ class AlbumViewerEditableTitle extends HookConsumerWidget {
borderRadius: BorderRadius.circular(10),
),
focusColor: Colors.grey[300],
fillColor: isDarkTheme
fillColor: context.isDarkTheme
? const Color.fromARGB(255, 32, 33, 35)
: Colors.grey[200],
filled: titleFocusNode.hasFocus,
hintText: 'share_add_title'.tr(),
hintStyle: TextStyle(
fontSize: 28,
color: isDarkTheme ? Colors.grey[300] : Colors.grey[700],
color: context.isDarkTheme ? Colors.grey[300] : Colors.grey[700],
fontWeight: FontWeight.bold,
),
),

View File

@ -1,9 +1,9 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart';
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
import 'package:immich_mobile/routing/router.dart';
@ -44,8 +44,9 @@ class AlbumOptionsPage extends HookConsumerWidget {
await ref.read(sharedAlbumProvider.notifier).leaveAlbum(album);
if (isSuccess) {
AutoRouter.of(context)
.navigate(const TabControllerRoute(children: [SharingRoute()]));
context.autoNavigate(
const TabControllerRoute(children: [SharingRoute()]),
);
} else {
showErrorMessage();
}
@ -97,7 +98,7 @@ class AlbumOptionsPage extends HookConsumerWidget {
}
showModalBottomSheet(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
backgroundColor: context.scaffoldBackgroundColor,
isScrollControlled: false,
context: context,
builder: (context) {
@ -177,7 +178,7 @@ class AlbumOptionsPage extends HookConsumerWidget {
buildSectionTitle(String text) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Text(text, style: Theme.of(context).textTheme.bodySmall),
child: Text(text, style: context.textTheme.bodySmall),
);
}
@ -186,7 +187,7 @@ class AlbumOptionsPage extends HookConsumerWidget {
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios_new_rounded),
onPressed: () {
AutoRouter.of(context).pop(null);
context.autoPop(null);
},
),
centerTitle: true,
@ -208,14 +209,12 @@ class AlbumOptionsPage extends HookConsumerWidget {
}
},
activeColor: activityEnabled.value
? Theme.of(context).primaryColor
: Theme.of(context).disabledColor,
? context.primaryColor
: context.themeData.disabledColor,
dense: true,
title: Text(
"shared_album_activity_setting_title",
style: Theme.of(context)
.textTheme
.labelLarge
style: context.textTheme.labelLarge
?.copyWith(fontWeight: FontWeight.bold),
).tr(),
subtitle:

View File

@ -1,10 +1,10 @@
import 'dart:async';
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/album/models/asset_selection_page_result.model.dart';
import 'package:immich_mobile/modules/album/providers/album_detail.provider.dart';
import 'package:immich_mobile/modules/album/services/album.service.dart';
@ -67,7 +67,7 @@ class AlbumViewerPage extends HookConsumerWidget {
/// If they exist, add to selected asset state to show they are already selected.
void onAddPhotosPressed(Album albumInfo) async {
AssetSelectionPageResult? returnPayload =
await AutoRouter.of(context).push<AssetSelectionPageResult?>(
await context.autoPush<AssetSelectionPageResult?>(
AssetSelectionRoute(
existingAssets: albumInfo.assets,
canDeselect: false,
@ -97,8 +97,7 @@ class AlbumViewerPage extends HookConsumerWidget {
}
void onAddUsersPressed(Album album) async {
List<String>? sharedUserIds =
await AutoRouter.of(context).push<List<String>?>(
List<String>? sharedUserIds = await context.autoPush<List<String>?>(
SelectAdditionalUserForSharingRoute(album: album),
);
@ -203,7 +202,7 @@ class AlbumViewerPage extends HookConsumerWidget {
Widget buildSharedUserIconsRow(Album album) {
return GestureDetector(
onTap: () async {
await AutoRouter.of(context).push(AlbumOptionsRoute(album: album));
await context.autoPush(AlbumOptionsRoute(album: album));
ref.invalidate(albumDetailProvider(album.id));
},
child: SizedBox(
@ -242,7 +241,7 @@ class AlbumViewerPage extends HookConsumerWidget {
onActivitiesPressed(Album album) {
if (album.remoteId != null) {
AutoRouter.of(context).push(
context.autoPush(
ActivitiesRoute(
albumId: album.remoteId!,
appBarTitle: album.name,

View File

@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/album/models/asset_selection_page_result.model.dart';
import 'package:immich_mobile/modules/asset_viewer/providers/render_list.provider.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/asset_grid_data_structure.dart';
@ -78,7 +79,7 @@ class AssetSelectionPage extends HookConsumerWidget {
canDeselect ? "share_done" : "share_add",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
).tr(),
),

View File

@ -1,8 +1,8 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/album/models/asset_selection_page_result.model.dart';
import 'package:immich_mobile/modules/album/providers/album.provider.dart';
import 'package:immich_mobile/modules/album/providers/album_title.provider.dart';
@ -34,11 +34,11 @@ class CreateAlbumPage extends HookConsumerWidget {
final selectedAssets = useState<Set<Asset>>(
initialAssets != null ? Set.from(initialAssets!) : const {},
);
final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
showSelectUserPage() async {
final bool? ok = await AutoRouter.of(context)
.push<bool?>(SelectUserForSharingRoute(assets: selectedAssets.value));
final bool? ok = await context.autoPush<bool?>(
SelectUserForSharingRoute(assets: selectedAssets.value),
);
if (ok == true) {
selectedAssets.value = {};
}
@ -58,7 +58,7 @@ class CreateAlbumPage extends HookConsumerWidget {
onSelectPhotosButtonPressed() async {
AssetSelectionPageResult? selectedAsset =
await AutoRouter.of(context).push<AssetSelectionPageResult?>(
await context.autoPush<AssetSelectionPageResult?>(
AssetSelectionRoute(
existingAssets: selectedAssets.value,
canDeselect: true,
@ -94,10 +94,10 @@ class CreateAlbumPage extends HookConsumerWidget {
padding: const EdgeInsets.only(top: 200, left: 18),
child: Text(
'create_shared_album_page_share_add_assets',
style: Theme.of(context).textTheme.displayMedium?.copyWith(
fontSize: 12,
fontWeight: FontWeight.normal,
),
style: context.textTheme.displayMedium?.copyWith(
fontSize: 12,
fontWeight: FontWeight.normal,
),
).tr(),
),
);
@ -117,7 +117,7 @@ class CreateAlbumPage extends HookConsumerWidget {
padding:
const EdgeInsets.symmetric(vertical: 22, horizontal: 16),
side: BorderSide(
color: isDarkTheme
color: context.isDarkTheme
? const Color.fromARGB(255, 63, 63, 63)
: const Color.fromARGB(255, 206, 206, 206),
),
@ -128,16 +128,16 @@ class CreateAlbumPage extends HookConsumerWidget {
onPressed: onSelectPhotosButtonPressed,
icon: Icon(
Icons.add_rounded,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
label: Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
'create_shared_album_page_share_select_photos',
style: Theme.of(context).textTheme.labelLarge?.copyWith(
fontSize: 16,
fontWeight: FontWeight.bold,
),
style: context.textTheme.labelLarge?.copyWith(
fontSize: 16,
fontWeight: FontWeight.bold,
),
).tr(),
),
),
@ -206,7 +206,7 @@ class CreateAlbumPage extends HookConsumerWidget {
selectedAssets.value = {};
ref.watch(albumTitleProvider.notifier).clearAlbumTitle();
AutoRouter.of(context).replace(AlbumViewerRoute(albumId: newAlbum.id));
context.autoReplace(AlbumViewerRoute(albumId: newAlbum.id));
}
}
@ -214,19 +214,19 @@ class CreateAlbumPage extends HookConsumerWidget {
appBar: AppBar(
elevation: 0,
centerTitle: false,
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
backgroundColor: context.scaffoldBackgroundColor,
leading: IconButton(
onPressed: () {
selectedAssets.value = {};
AutoRouter.of(context).pop();
context.autoPop();
},
icon: const Icon(Icons.close_rounded),
),
title: Text(
'share_create_album',
style: Theme.of(context).textTheme.displayMedium?.copyWith(
color: Theme.of(context).primaryColor,
),
style: context.textTheme.displayMedium?.copyWith(
color: context.primaryColor,
),
).tr(),
actions: [
if (isSharedAlbum)
@ -239,8 +239,8 @@ class CreateAlbumPage extends HookConsumerWidget {
style: TextStyle(
fontWeight: FontWeight.bold,
color: albumTitleController.text.isEmpty
? Theme.of(context).disabledColor
: Theme.of(context).primaryColor,
? context.themeData.disabledColor
: context.primaryColor,
),
),
),
@ -254,7 +254,7 @@ class CreateAlbumPage extends HookConsumerWidget {
'create_shared_album_page_create'.tr(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
),
),
@ -265,7 +265,7 @@ class CreateAlbumPage extends HookConsumerWidget {
child: CustomScrollView(
slivers: [
SliverAppBar(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
backgroundColor: context.scaffoldBackgroundColor,
elevation: 5,
automaticallyImplyLeading: false,
pinned: true,

View File

@ -1,9 +1,9 @@
import 'package:auto_route/auto_route.dart';
import 'package:collection/collection.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/album/providers/album.provider.dart';
import 'package:immich_mobile/modules/album/ui/album_thumbnail_card.dart';
import 'package:immich_mobile/routing/router.dart';
@ -21,7 +21,7 @@ class LibraryPage extends HookConsumerWidget {
final trashEnabled =
ref.watch(serverInfoProvider.select((v) => v.serverFeatures.trash));
final albums = ref.watch(albumProvider);
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
var isDarkTheme = context.isDarkTheme;
var settings = ref.watch(appSettingsServiceProvider);
useEffect(
@ -96,15 +96,14 @@ class LibraryPage extends HookConsumerWidget {
padding: const EdgeInsets.only(right: 12.0),
child: Icon(
Icons.check,
color: selected
? Theme.of(context).primaryColor
: Colors.transparent,
color:
selected ? context.primaryColor : Colors.transparent,
),
),
Text(
option,
style: TextStyle(
color: selected ? Theme.of(context).primaryColor : null,
color: selected ? context.primaryColor : null,
fontSize: 12.0,
),
),
@ -122,13 +121,13 @@ class LibraryPage extends HookConsumerWidget {
Icon(
Icons.swap_vert_rounded,
size: 18,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
Text(
options[selectedAlbumSortOrder.value],
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontSize: 12.0,
),
),
@ -140,7 +139,7 @@ class LibraryPage extends HookConsumerWidget {
Widget buildCreateAlbumButton() {
return GestureDetector(
onTap: () {
AutoRouter.of(context).push(CreateAlbumRoute(isSharedAlbum: false));
context.autoPush(CreateAlbumRoute(isSharedAlbum: false));
},
child: Padding(
padding: const EdgeInsets.only(bottom: 32),
@ -152,18 +151,18 @@ class LibraryPage extends HookConsumerWidget {
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: isDarkMode
color: isDarkTheme
? const Color.fromARGB(255, 53, 53, 53)
: const Color.fromARGB(255, 203, 203, 203),
),
color: isDarkMode ? Colors.grey[900] : Colors.grey[50],
color: isDarkTheme ? Colors.grey[900] : Colors.grey[50],
borderRadius: BorderRadius.circular(20),
),
child: Center(
child: Icon(
Icons.add_rounded,
size: 28,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
),
),
@ -201,21 +200,21 @@ class LibraryPage extends HookConsumerWidget {
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 13.0,
color: isDarkMode ? Colors.white : Colors.grey[800],
color: isDarkTheme ? Colors.white : Colors.grey[800],
),
),
),
style: OutlinedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
backgroundColor: isDarkMode ? Colors.grey[900] : Colors.grey[50],
backgroundColor: isDarkTheme ? Colors.grey[900] : Colors.grey[50],
side: BorderSide(
color: isDarkMode ? Colors.grey[800]! : Colors.grey[300]!,
color: isDarkTheme ? Colors.grey[800]! : Colors.grey[300]!,
),
alignment: Alignment.centerLeft,
),
icon: Icon(
icon,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
),
);
@ -228,7 +227,7 @@ class LibraryPage extends HookConsumerWidget {
Widget? shareTrashButton() {
return trashEnabled
? InkWell(
onTap: () => AutoRouter.of(context).push(const TrashRoute()),
onTap: () => context.autoPush(const TrashRoute()),
borderRadius: BorderRadius.circular(12),
child: const Icon(
Icons.delete_rounded,
@ -257,12 +256,12 @@ class LibraryPage extends HookConsumerWidget {
children: [
buildLibraryNavButton(
"library_page_favorites".tr(), Icons.favorite_border, () {
AutoRouter.of(context).navigate(const FavoritesRoute());
context.autoNavigate(const FavoritesRoute());
}),
const SizedBox(width: 12.0),
buildLibraryNavButton(
"library_page_archive".tr(), Icons.archive_outlined, () {
AutoRouter.of(context).navigate(const ArchiveRoute());
context.autoNavigate(const ArchiveRoute());
}),
],
),
@ -306,7 +305,7 @@ class LibraryPage extends HookConsumerWidget {
return AlbumThumbnailCard(
album: sorted[index - 1],
onTap: () => AutoRouter.of(context).push(
onTap: () => context.autoPush(
AlbumViewerRoute(
albumId: sorted[index - 1].id,
),
@ -348,7 +347,7 @@ class LibraryPage extends HookConsumerWidget {
childCount: local.length,
(context, index) => AlbumThumbnailCard(
album: local[index],
onTap: () => AutoRouter.of(context).push(
onTap: () => context.autoPush(
AlbumViewerRoute(
albumId: local[index].id,
),

View File

@ -1,8 +1,8 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/album/providers/suggested_shared_users.provider.dart';
import 'package:immich_mobile/shared/models/album.dart';
import 'package:immich_mobile/shared/models/user.dart';
@ -22,14 +22,13 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget {
final sharedUsersList = useState<Set<User>>({});
addNewUsersHandler() {
AutoRouter.of(context)
.pop(sharedUsersList.value.map((e) => e.id).toList());
context.autoPop(sharedUsersList.value.map((e) => e.id).toList());
}
buildTileIcon(User user) {
if (sharedUsersList.value.contains(user)) {
return CircleAvatar(
backgroundColor: Theme.of(context).primaryColor,
backgroundColor: context.primaryColor,
child: const Icon(
Icons.check_rounded,
size: 25,
@ -50,7 +49,7 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget {
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Chip(
backgroundColor: Theme.of(context).primaryColor.withOpacity(0.15),
backgroundColor: context.primaryColor.withOpacity(0.15),
label: Text(
user.email,
style: const TextStyle(
@ -124,7 +123,7 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget {
leading: IconButton(
icon: const Icon(Icons.close_rounded),
onPressed: () {
AutoRouter.of(context).pop(null);
context.autoPop(null);
},
),
actions: [

View File

@ -1,8 +1,8 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/album/providers/album_title.provider.dart';
import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart';
import 'package:immich_mobile/modules/album/providers/suggested_shared_users.provider.dart';
@ -35,9 +35,9 @@ class SelectUserForSharingPage extends HookConsumerWidget {
await ref.watch(sharedAlbumProvider.notifier).getAllSharedAlbums();
// ref.watch(assetSelectionProvider.notifier).removeAll();
ref.watch(albumTitleProvider.notifier).clearAlbumTitle();
AutoRouter.of(context).pop(true);
AutoRouter.of(context)
.navigate(const TabControllerRoute(children: [SharingRoute()]));
context.autoPop(true);
context
.autoNavigate(const TabControllerRoute(children: [SharingRoute()]));
}
ScaffoldMessenger(
@ -50,7 +50,7 @@ class SelectUserForSharingPage extends HookConsumerWidget {
buildTileIcon(User user) {
if (sharedUsersList.value.contains(user)) {
return CircleAvatar(
backgroundColor: Theme.of(context).primaryColor,
backgroundColor: context.primaryColor,
child: const Icon(
Icons.check_rounded,
size: 25,
@ -71,7 +71,7 @@ class SelectUserForSharingPage extends HookConsumerWidget {
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Chip(
backgroundColor: Theme.of(context).primaryColor.withOpacity(0.15),
backgroundColor: context.primaryColor.withOpacity(0.15),
label: Text(
user.email,
style: const TextStyle(
@ -139,20 +139,20 @@ class SelectUserForSharingPage extends HookConsumerWidget {
appBar: AppBar(
title: Text(
'share_invite',
style: TextStyle(color: Theme.of(context).primaryColor),
style: TextStyle(color: context.primaryColor),
).tr(),
elevation: 0,
centerTitle: false,
leading: IconButton(
icon: const Icon(Icons.close_rounded),
onPressed: () async {
AutoRouter.of(context).pop();
context.autoPop();
},
),
actions: [
TextButton(
style: TextButton.styleFrom(
foregroundColor: Theme.of(context).primaryColor,
foregroundColor: context.primaryColor,
),
onPressed: sharedUsersList.value.isEmpty ? null : createSharedAlbum,
child: const Text(
@ -160,7 +160,7 @@ class SelectUserForSharingPage extends HookConsumerWidget {
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
// color: Theme.of(context).primaryColor,
// color: context.primaryColor,
),
).tr(),
),

View File

@ -1,8 +1,8 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart';
import 'package:immich_mobile/modules/album/ui/album_thumbnail_card.dart';
import 'package:immich_mobile/modules/partner/providers/partner.provider.dart';
@ -21,7 +21,6 @@ class SharingPage extends HookConsumerWidget {
final List<Album> sharedAlbums = ref.watch(sharedAlbumProvider);
final userId = ref.watch(currentUserProvider)?.id;
final partner = ref.watch(partnerSharedWithProvider);
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
useEffect(
() {
@ -47,8 +46,9 @@ class SharingPage extends HookConsumerWidget {
album: sharedAlbums[index],
showOwner: true,
onTap: () {
AutoRouter.of(context)
.push(AlbumViewerRoute(albumId: sharedAlbums[index].id));
context.autoPush(
AlbumViewerRoute(albumId: sharedAlbums[index].id),
);
},
);
},
@ -79,12 +79,11 @@ class SharingPage extends HookConsumerWidget {
album.name,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.bold,
color: isDarkMode
? Theme.of(context).primaryColor
: Colors.black,
),
style: context.textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.bold,
color:
context.isDarkTheme ? context.primaryColor : Colors.black,
),
),
subtitle: isOwner
? Text(
@ -103,8 +102,9 @@ class SharingPage extends HookConsumerWidget {
)
: null,
onTap: () {
AutoRouter.of(context)
.push(AlbumViewerRoute(albumId: sharedAlbums[index].id));
context.autoPush(
AlbumViewerRoute(albumId: sharedAlbums[index].id),
);
},
);
},
@ -127,8 +127,7 @@ class SharingPage extends HookConsumerWidget {
Expanded(
child: ElevatedButton.icon(
onPressed: () {
AutoRouter.of(context)
.push(CreateAlbumRoute(isSharedAlbum: true));
context.autoPush(CreateAlbumRoute(isSharedAlbum: true));
},
icon: const Icon(
Icons.photo_album_outlined,
@ -147,8 +146,7 @@ class SharingPage extends HookConsumerWidget {
const SizedBox(width: 12.0),
Expanded(
child: ElevatedButton.icon(
onPressed: () =>
AutoRouter.of(context).push(const SharedLinkRoute()),
onPressed: () => context.autoPush(const SharedLinkRoute()),
icon: const Icon(
Icons.link,
size: 20,
@ -191,21 +189,21 @@ class SharingPage extends HookConsumerWidget {
child: Icon(
Icons.insert_photo_rounded,
size: 50,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'sharing_page_empty_list',
style: Theme.of(context).textTheme.displaySmall,
style: context.textTheme.displaySmall,
).tr(),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'sharing_page_description',
style: Theme.of(context).textTheme.bodyMedium,
style: context.textTheme.bodyMedium,
).tr(),
),
],
@ -218,7 +216,7 @@ class SharingPage extends HookConsumerWidget {
Widget sharePartnerButton() {
return InkWell(
onTap: () => AutoRouter.of(context).push(const PartnerRoute()),
onTap: () => context.autoPush(const PartnerRoute()),
borderRadius: BorderRadius.circular(12),
child: const Icon(
Icons.swap_horizontal_circle_rounded,

View File

@ -1,8 +1,8 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/archive/providers/archive_asset_provider.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
import 'package:immich_mobile/shared/models/asset.dart';
@ -30,7 +30,7 @@ class ArchivePage extends HookConsumerWidget {
AppBar buildAppBar(String count) {
return AppBar(
leading: IconButton(
onPressed: () => AutoRouter.of(context).pop(),
onPressed: () => context.autoPop(),
icon: const Icon(Icons.arrow_back_ios_rounded),
),
centerTitle: true,

View File

@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/album/services/album.service.dart';
import 'package:immich_mobile/modules/asset_viewer/models/image_viewer_page_state.model.dart';
import 'package:immich_mobile/modules/asset_viewer/services/image_viewer.service.dart';
@ -67,7 +68,7 @@ class ImageViewerStateNotifier extends StateNotifier<ImageViewerPageState> {
gravity: ToastGravity.BOTTOM,
);
}
Navigator.of(buildContext).pop();
context.pop();
},
);
return const ShareDialog();

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/shared/models/asset.dart';
class AdvancedBottomSheet extends HookConsumerWidget {
@ -11,8 +12,6 @@ class AdvancedBottomSheet extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
return SingleChildScrollView(
child: Card(
shape: const RoundedRectangleBorder(
@ -40,7 +39,9 @@ class AdvancedBottomSheet extends HookConsumerWidget {
const SizedBox(height: 32.0),
Container(
decoration: BoxDecoration(
color: isDarkMode ? Colors.grey[900] : Colors.grey[200],
color: context.isDarkTheme
? Colors.grey[900]
: Colors.grey[200],
borderRadius: BorderRadius.circular(15.0),
),
child: Padding(
@ -70,7 +71,7 @@ class AdvancedBottomSheet extends HookConsumerWidget {
icon: Icon(
Icons.copy,
size: 16.0,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
),
),

View File

@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/asset_viewer/providers/asset_description.provider.dart';
import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/providers/user.provider.dart';
@ -19,8 +20,7 @@ class DescriptionInput extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
final textColor = isDarkTheme ? Colors.white : Colors.black;
final textColor = context.isDarkTheme ? Colors.white : Colors.black;
final controller = useTextEditingController();
final focusNode = useFocusNode();
final isFocus = useState(false);

View File

@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:timezone/timezone.dart';
import 'package:immich_mobile/modules/asset_viewer/ui/description_input.dart';
import 'package:immich_mobile/modules/map/ui/map_thumbnail.dart';
@ -28,7 +29,7 @@ class ExifBottomSheet extends HookConsumerWidget {
exifInfo.longitude != 0;
String formatTimeZone(Duration d) =>
"GMT${d.isNegative ? '-': '+'}${d.inHours.abs().toString().padLeft(2, '0')}:${d.inMinutes.abs().remainder(60).toString().padLeft(2, '0')}";
"GMT${d.isNegative ? '-' : '+'}${d.inHours.abs().toString().padLeft(2, '0')}:${d.inMinutes.abs().remainder(60).toString().padLeft(2, '0')}";
String get formattedDateTime {
DateTime dt = asset.fileCreatedAt.toLocal();
@ -41,10 +42,16 @@ class ExifBottomSheet extends HookConsumerWidget {
final location = getLocation(asset.exifInfo!.timeZone!);
dt = TZDateTime.from(dt, location);
} on LocationNotFoundException {
RegExp re = RegExp(r'^utc(?:([+-]\d{1,2})(?::(\d{2}))?)?$', caseSensitive: false);
RegExp re = RegExp(
r'^utc(?:([+-]\d{1,2})(?::(\d{2}))?)?$',
caseSensitive: false,
);
final m = re.firstMatch(asset.exifInfo!.timeZone!);
if (m != null) {
final duration = Duration(hours: int.parse(m.group(1) ?? '0'), minutes: int.parse(m.group(2) ?? '0'));
final duration = Duration(
hours: int.parse(m.group(1) ?? '0'),
minutes: int.parse(m.group(2) ?? '0'),
);
dt = dt.add(duration);
timeZone = formatTimeZone(duration);
}
@ -105,8 +112,7 @@ class ExifBottomSheet extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final assetWithExif = ref.watch(assetDetailProvider(asset));
final exifInfo = (assetWithExif.value ?? asset).exifInfo;
var isDarkTheme = Theme.of(context).brightness == Brightness.dark;
var textColor = isDarkTheme ? Colors.white : Colors.black;
var textColor = context.isDarkTheme ? Colors.white : Colors.black;
buildMap() {
return Padding(
@ -322,9 +328,14 @@ class ExifBottomSheet extends HookConsumerWidget {
fontWeight: FontWeight.bold,
),
),
subtitle: exifInfo.f != null || exifInfo.exposureSeconds != null || exifInfo.mm != null || exifInfo.iso != null ? Text(
"ƒ/${exifInfo.fNumber} ${exifInfo.exposureTime} ${exifInfo.focalLength} mm ISO ${exifInfo.iso ?? ''} ",
) : null,
subtitle: exifInfo.f != null ||
exifInfo.exposureSeconds != null ||
exifInfo.mm != null ||
exifInfo.iso != null
? Text(
"ƒ/${exifInfo.fNumber} ${exifInfo.exposureTime} ${exifInfo.focalLength} mm ISO ${exifInfo.iso ?? ''} ",
)
: null,
),
],
);
@ -393,7 +404,7 @@ class ExifBottomSheet extends HookConsumerWidget {
data: (data) => DescriptionInput(asset: data),
error: (error, stackTrace) => Icon(
Icons.image_not_supported_outlined,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
loading: () => const SizedBox(
width: 75,

View File

@ -1,6 +1,6 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/activities/providers/activity.provider.dart';
import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/providers/asset.provider.dart';
@ -147,7 +147,7 @@ class TopControlAppBar extends HookConsumerWidget {
Widget buildBackButton() {
return IconButton(
onPressed: () {
AutoRouter.of(context).pop();
context.autoPop();
},
icon: Icon(
Icons.arrow_back_ios_new_rounded,

View File

@ -8,6 +8,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/asset_viewer/providers/asset_stack.provider.dart';
import 'package:immich_mobile/modules/asset_viewer/providers/show_controls.provider.dart';
import 'package:immich_mobile/modules/asset_viewer/providers/video_player_controls_provider.dart';
@ -209,7 +210,7 @@ class GalleryViewerPage extends HookConsumerWidget {
if (isDeleted && isParent) {
if (totalAssets == 1) {
// Handle only one asset
AutoRouter.of(context).pop();
context.autoPop();
} else {
// Go to next page otherwise
controller.nextPage(
@ -293,7 +294,7 @@ class GalleryViewerPage extends HookConsumerWidget {
final ratio = d.dy / max(d.dx.abs(), 1);
if (d.dy > sensitivity && ratio > ratioThreshold) {
AutoRouter.of(context).pop();
context.autoPop();
} else if (d.dy < -sensitivity && ratio < -ratioThreshold) {
showInfo();
}
@ -308,7 +309,7 @@ class GalleryViewerPage extends HookConsumerWidget {
.watch(assetProvider.notifier)
.toggleArchive([asset], !asset.isArchived);
if (isParent) {
AutoRouter.of(context).pop();
context.autoPop();
return;
}
removeAssetFromStack();
@ -331,7 +332,7 @@ class GalleryViewerPage extends HookConsumerWidget {
handleActivities() {
if (sharedAlbumId != null) {
AutoRouter.of(context).push(
context.autoPush(
ActivitiesRoute(
albumId: sharedAlbumId!,
assetId: asset().remoteId,
@ -514,7 +515,7 @@ class GalleryViewerPage extends HookConsumerWidget {
stackElements.elementAt(stackIndex.value),
);
Navigator.pop(ctx);
AutoRouter.of(context).pop();
context.autoPop();
},
title: const Text(
"viewer_stack_use_as_main_asset",
@ -541,7 +542,7 @@ class GalleryViewerPage extends HookConsumerWidget {
childrenToRemove: [currentAsset],
);
Navigator.pop(ctx);
AutoRouter.of(context).pop();
context.autoPop();
} else {
await ref.read(assetStackServiceProvider).updateStack(
currentAsset,
@ -569,7 +570,7 @@ class GalleryViewerPage extends HookConsumerWidget {
childrenToRemove: stack,
);
Navigator.pop(ctx);
AutoRouter.of(context).pop();
context.autoPop();
},
title: const Text(
"viewer_unstack",
@ -829,8 +830,8 @@ class GalleryViewerPage extends HookConsumerWidget {
placeholder: Image(
image: provider,
fit: BoxFit.fitWidth,
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
height: context.height,
width: context.width,
alignment: Alignment.center,
),
onVideoEnded: () {

View File

@ -3,6 +3,7 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:chewie/chewie.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/asset_viewer/models/image_viewer_page_state.model.dart';
import 'package:immich_mobile/modules/asset_viewer/providers/image_viewer_page_state.provider.dart';
import 'package:immich_mobile/modules/asset_viewer/ui/video_player_controls.dart';
@ -44,7 +45,7 @@ class VideoViewerPage extends HookConsumerWidget {
),
error: (error, stackTrace) => Icon(
Icons.image_not_supported_outlined,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
loading: () => const Center(
child: SizedBox(
@ -74,8 +75,8 @@ class VideoViewerPage extends HookConsumerWidget {
),
if (downloadAssetStatus == DownloadAssetStatus.loading)
SizedBox(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
height: context.height,
width: context.width,
child: const Center(
child: ImmichLoadingIndicator(),
),
@ -205,8 +206,8 @@ class _VideoPlayerState extends State<VideoPlayer> {
);
} else {
return SizedBox(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
height: context.height,
width: context.width,
child: Center(
child: Stack(
children: [

View File

@ -1,9 +1,9 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/backup/models/available_album.model.dart';
import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
import 'package:immich_mobile/routing/router.dart';
@ -22,10 +22,10 @@ class AlbumInfoCard extends HookConsumerWidget {
ref.watch(backupProvider).selectedBackupAlbums.contains(albumInfo);
final bool isExcluded =
ref.watch(backupProvider).excludedBackupAlbums.contains(albumInfo);
final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
final isDarkTheme = context.isDarkTheme;
ColorFilter selectedFilter = ColorFilter.mode(
Theme.of(context).primaryColor.withAlpha(100),
context.primaryColor.withAlpha(100),
BlendMode.darken,
);
ColorFilter excludedFilter =
@ -46,7 +46,7 @@ class AlbumInfoCard extends HookConsumerWidget {
fontWeight: FontWeight.bold,
),
).tr(),
backgroundColor: Theme.of(context).primaryColor,
backgroundColor: context.primaryColor,
);
} else if (isExcluded) {
return Chip(
@ -194,7 +194,7 @@ class AlbumInfoCard extends HookConsumerWidget {
albumInfo.name,
style: TextStyle(
fontSize: 14,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontWeight: FontWeight.bold,
),
),
@ -224,13 +224,13 @@ class AlbumInfoCard extends HookConsumerWidget {
),
IconButton(
onPressed: () {
AutoRouter.of(context).push(
context.autoPush(
AlbumPreviewRoute(album: albumInfo.albumEntity),
);
},
icon: Icon(
Icons.image_outlined,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
size: 24,
),
splashRadius: 25,

View File

@ -1,10 +1,10 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/backup/models/available_album.model.dart';
import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
import 'package:immich_mobile/routing/router.dart';
@ -25,14 +25,13 @@ class AlbumInfoListTile extends HookConsumerWidget {
ref.watch(backupProvider).excludedBackupAlbums.contains(albumInfo);
ColorFilter selectedFilter = ColorFilter.mode(
Theme.of(context).primaryColor.withAlpha(100),
context.primaryColor.withAlpha(100),
BlendMode.darken,
);
ColorFilter excludedFilter =
ColorFilter.mode(Colors.red.withAlpha(75), BlendMode.darken);
ColorFilter unselectedFilter =
const ColorFilter.mode(Colors.black, BlendMode.color);
var isDarkTheme = Theme.of(context).brightness == Brightness.dark;
var assetCount = useState(0);
@ -56,11 +55,11 @@ class AlbumInfoListTile extends HookConsumerWidget {
buildTileColor() {
if (isSelected) {
return isDarkTheme
? Theme.of(context).primaryColor.withAlpha(100)
: Theme.of(context).primaryColor.withAlpha(25);
return context.isDarkTheme
? context.primaryColor.withAlpha(100)
: context.primaryColor.withAlpha(25);
} else if (isExcluded) {
return isDarkTheme
return context.isDarkTheme
? Colors.red[300]?.withAlpha(150)
: Colors.red[100]?.withAlpha(150);
} else {
@ -159,13 +158,13 @@ class AlbumInfoListTile extends HookConsumerWidget {
subtitle: Text(assetCount.value.toString()),
trailing: IconButton(
onPressed: () {
AutoRouter.of(context).push(
context.autoPush(
AlbumPreviewRoute(album: albumInfo.albumEntity),
);
},
icon: Icon(
Icons.image_outlined,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
size: 24,
),
splashRadius: 25,

View File

@ -1,5 +1,6 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
class BackupInfoCard extends StatelessWidget {
final String title;
@ -14,13 +15,11 @@ class BackupInfoCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20), // if you need this
side: BorderSide(
color: isDarkMode
color: context.isDarkTheme
? const Color.fromARGB(255, 56, 56, 56)
: Colors.black12,
width: 1,

View File

@ -1,9 +1,9 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/backup/models/backup_state.model.dart';
import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
import 'package:immich_mobile/modules/backup/providers/error_backup_list.provider.dart';
@ -53,7 +53,7 @@ class CurrentUploadingAssetInfoBox extends HookConsumerWidget {
),
backgroundColor: Colors.white,
onPressed: () {
AutoRouter.of(context).push(const FailedBackupStatusRoute());
context.autoPush(const FailedBackupStatusRoute());
},
);
}
@ -61,7 +61,7 @@ class CurrentUploadingAssetInfoBox extends HookConsumerWidget {
Widget buildAssetInfoTable() {
return Table(
border: TableBorder.all(
color: Theme.of(context).primaryColorLight,
color: context.themeData.primaryColorLight,
width: 1,
),
children: [
@ -176,7 +176,7 @@ class CurrentUploadingAssetInfoBox extends HookConsumerWidget {
onTap: () => isShowThumbnail.value = true,
child: Icon(
Icons.image_outlined,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
size: 30,
),
),
@ -206,7 +206,7 @@ class CurrentUploadingAssetInfoBox extends HookConsumerWidget {
minHeight: 10.0,
value: uploadProgress / 100.0,
backgroundColor: Colors.grey,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
),
Text(

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/backup/providers/ios_background_settings.provider.dart';
import 'package:intl/intl.dart';
@ -43,7 +44,7 @@ class IosDebugInfoTile extends HookConsumerWidget {
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
),
subtitle: Text(
@ -54,7 +55,7 @@ class IosDebugInfoTile extends HookConsumerWidget {
),
leading: Icon(
Icons.bug_report,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
);
}

View File

@ -1,9 +1,9 @@
import 'dart:typed_data';
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
import 'package:photo_manager/photo_manager.dart';
@ -53,7 +53,7 @@ class AlbumPreviewPage extends HookConsumerWidget {
],
),
leading: IconButton(
onPressed: () => AutoRouter.of(context).pop(),
onPressed: () => context.autoPop(),
icon: const Icon(Icons.arrow_back_ios_new_rounded),
),
),

View File

@ -1,10 +1,10 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/immich_colors.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
import 'package:immich_mobile/modules/backup/ui/album_info_card.dart';
import 'package:immich_mobile/modules/backup/ui/album_info_list_tile.dart';
@ -18,7 +18,7 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
// final availableAlbums = ref.watch(backupProvider).availableAlbums;
final selectedBackupAlbums = ref.watch(backupProvider).selectedBackupAlbums;
final excludedBackupAlbums = ref.watch(backupProvider).excludedBackupAlbums;
final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
final isDarkTheme = context.isDarkTheme;
final allAlbums = ref.watch(backupProvider).availableAlbums;
// Albums which are displayed to the user
@ -118,7 +118,7 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
fontWeight: FontWeight.bold,
),
),
backgroundColor: Theme.of(context).primaryColor,
backgroundColor: context.primaryColor,
deleteIconColor: isDarkTheme ? Colors.black : Colors.white,
deleteIcon: const Icon(
Icons.cancel_rounded,
@ -211,7 +211,7 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
return Scaffold(
appBar: AppBar(
leading: IconButton(
onPressed: () => AutoRouter.of(context).pop(),
onPressed: () => context.autoPop(),
icon: const Icon(Icons.arrow_back_ios_rounded),
),
title: const Text(
@ -315,7 +315,7 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
"backup_album_selection_page_albums_tap",
style: TextStyle(
fontSize: 12,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontWeight: FontWeight.bold,
),
).tr(),
@ -325,7 +325,7 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
icon: Icon(
Icons.info,
size: 20,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
onPressed: () {
// show the dialog
@ -342,7 +342,7 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
).tr(),
content: SingleChildScrollView(

View File

@ -1,11 +1,11 @@
import 'dart:io';
import 'package:auto_route/auto_route.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/backup/background_service/background.service.dart';
import 'package:immich_mobile/modules/backup/providers/error_backup_list.provider.dart';
import 'package:immich_mobile/modules/backup/providers/ios_background_settings.provider.dart';
@ -49,7 +49,6 @@ class BackupControllerPage extends HookConsumerWidget {
!hasExclusiveAccess
? false
: true;
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
final checkInProgress = useState(false);
useEffect(
@ -151,7 +150,7 @@ class BackupControllerPage extends HookConsumerWidget {
return ListTile(
leading: Icon(
Icons.warning_rounded,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
title: const Text(
"Check for corrupt asset backups",
@ -187,7 +186,7 @@ class BackupControllerPage extends HookConsumerWidget {
leading: isAutoBackup
? Icon(
Icons.cloud_done_rounded,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
)
: const Icon(Icons.cloud_off_rounded),
title: Text(
@ -266,7 +265,7 @@ class BackupControllerPage extends HookConsumerWidget {
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12),
).tr(),
onPressed: () {
Navigator.of(context).pop();
context.pop();
},
),
],
@ -279,7 +278,7 @@ class BackupControllerPage extends HookConsumerWidget {
final bool isBackgroundEnabled = backupState.backgroundBackup;
final bool isWifiRequired = backupState.backupRequireWifi;
final bool isChargingRequired = backupState.backupRequireCharging;
final Color activeColor = Theme.of(context).primaryColor;
final Color activeColor = context.primaryColor;
String formatBackupDelaySliderValue(double v) {
if (v == 0.0) {
@ -410,7 +409,7 @@ class BackupControllerPage extends HookConsumerWidget {
max: 3.0,
divisions: 3,
label: formatBackupDelaySliderValue(triggerDelay.value),
activeColor: Theme.of(context).primaryColor,
activeColor: context.primaryColor,
),
),
ElevatedButton(
@ -511,7 +510,7 @@ class BackupControllerPage extends HookConsumerWidget {
child: Text(
text.trim().substring(0, text.length - 2),
style: TextStyle(
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontSize: 12,
fontWeight: FontWeight.bold,
),
@ -523,7 +522,7 @@ class BackupControllerPage extends HookConsumerWidget {
child: Text(
"backup_controller_page_none_selected".tr(),
style: TextStyle(
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontSize: 12,
fontWeight: FontWeight.bold,
),
@ -562,7 +561,7 @@ class BackupControllerPage extends HookConsumerWidget {
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
side: BorderSide(
color: isDarkMode
color: context.isDarkTheme
? const Color.fromARGB(255, 56, 56, 56)
: Colors.black12,
width: 1,
@ -592,7 +591,7 @@ class BackupControllerPage extends HookConsumerWidget {
),
trailing: ElevatedButton(
onPressed: () {
AutoRouter.of(context).push(const BackupAlbumSelectionRoute());
context.autoPush(const BackupAlbumSelectionRoute());
},
child: const Text(
"backup_controller_page_select",
@ -678,7 +677,7 @@ class BackupControllerPage extends HookConsumerWidget {
leading: IconButton(
onPressed: () {
ref.watch(websocketProvider.notifier).listenUploadEvent();
AutoRouter.of(context).pop(true);
context.autoPop(true);
},
splashRadius: 24,
icon: const Icon(

View File

@ -1,6 +1,6 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/backup/providers/error_backup_list.provider.dart';
import 'package:intl/intl.dart';
import 'package:photo_manager/photo_manager.dart';
@ -20,7 +20,7 @@ class FailedBackupStatusPage extends HookConsumerWidget {
),
leading: IconButton(
onPressed: () {
AutoRouter.of(context).pop(true);
context.autoPop(true);
},
splashRadius: 24,
icon: const Icon(
@ -114,7 +114,7 @@ class FailedBackupStatusPage extends HookConsumerWidget {
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 12,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
),
),

View File

@ -1,8 +1,8 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/favorite/providers/favorite_provider.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
import 'package:immich_mobile/shared/models/asset.dart';
@ -28,7 +28,7 @@ class FavoritesPage extends HookConsumerWidget {
AppBar buildAppBar() {
return AppBar(
leading: IconButton(
onPressed: () => AutoRouter.of(context).pop(),
onPressed: () => context.autoPop(),
icon: const Icon(Icons.arrow_back_ios_rounded),
),
centerTitle: true,

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
class GroupDividerTitle extends ConsumerWidget {
const GroupDividerTitle({
@ -51,7 +52,7 @@ class GroupDividerTitle extends ConsumerWidget {
child: multiselectEnabled && selected
? Icon(
Icons.check_circle_rounded,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
)
: const Icon(
Icons.check_circle_outline_rounded,

View File

@ -4,10 +4,11 @@ import 'dart:math';
import 'package:collection/collection.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/asset_viewer/providers/scroll_notifier.provider.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_image.dart';
import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/utils/builtin_extensions.dart';
import 'package:immich_mobile/extensions/collection_extensions.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'asset_grid_data_structure.dart';
import 'group_divider_title.dart';
@ -224,7 +225,7 @@ class ImmichAssetGridViewState extends State<ImmichAssetGridView> {
style: TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
color: Theme.of(context).textTheme.displayLarge?.color,
color: context.textTheme.displayLarge?.color,
),
),
);
@ -372,7 +373,7 @@ class ImmichAssetGridViewState extends State<ImmichAssetGridView> {
scrollStateListener: dragScrolling,
itemPositionsListener: _itemPositionsListener,
controller: _itemScrollController,
backgroundColor: Theme.of(context).hintColor,
backgroundColor: context.themeData.hintColor,
labelTextBuilder: _labelBuilder,
labelConstraints: const BoxConstraints(maxHeight: 28),
scrollbarAnimationDuration: const Duration(milliseconds: 300),

View File

@ -1,6 +1,6 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/ui/immich_image.dart';
@ -43,9 +43,9 @@ class ThumbnailImage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
final assetContainerColor =
isDarkTheme ? Colors.blueGrey : Theme.of(context).primaryColorLight;
final assetContainerColor = context.isDarkTheme
? Colors.blueGrey
: context.themeData.primaryColorLight;
// Assets from response DTOs do not have an isar id, querying which would give us the default autoIncrement id
final isFromDto = asset.id == Isar.autoIncrement;
@ -58,7 +58,7 @@ class ThumbnailImage extends StatelessWidget {
),
child: Icon(
Icons.check_circle_rounded,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
);
} else {
@ -178,7 +178,7 @@ class ThumbnailImage extends StatelessWidget {
onSelect?.call();
}
} else {
AutoRouter.of(context).push(
context.autoPush(
GalleryViewerRoute(
initialIndex: index,
loadAsset: loadAsset,

View File

@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/album/ui/add_to_album_sliverlist.dart';
import 'package:immich_mobile/modules/home/models/selection_state.dart';
import 'package:immich_mobile/modules/home/ui/delete_dialog.dart';
@ -42,7 +43,6 @@ class ControlBottomAppBar extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
var hasRemote =
selectionAssetState.hasRemote || selectionAssetState.hasMerged;
var hasLocal = selectionAssetState.hasLocal;
@ -128,7 +128,7 @@ class ControlBottomAppBar extends ConsumerWidget {
ScrollController scrollController,
) {
return Card(
color: isDarkMode ? Colors.grey[900] : Colors.grey[100],
color: context.isDarkTheme ? Colors.grey[900] : Colors.grey[100],
surfaceTintColor: Colors.transparent,
elevation: 18.0,
shape: const RoundedRectangleBorder(
@ -211,12 +211,12 @@ class AddToAlbumTitleRow extends StatelessWidget {
onPressed: onCreateNewAlbum,
icon: Icon(
Icons.add,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
label: Text(
"common_create_new_album",
style: TextStyle(
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontWeight: FontWeight.bold,
fontSize: 14,
),

View File

@ -1,12 +1,12 @@
import 'dart:async';
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/album/providers/album.provider.dart';
import 'package:immich_mobile/modules/album/providers/album_detail.provider.dart';
import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart';
@ -106,8 +106,7 @@ class HomePage extends HookConsumerWidget {
handleShareAssets(ref, context, selection.value.toList());
} else {
final ids = remoteOnlySelection().map((e) => e.remoteId!);
AutoRouter.of(context)
.push(SharedLinkEditRoute(assetsList: ids.toList()));
context.autoPush(SharedLinkEditRoute(assetsList: ids.toList()));
}
processing.value = false;
selectionEnabledHook.value = false;
@ -243,7 +242,7 @@ class HomePage extends HookConsumerWidget {
ref.watch(sharedAlbumProvider.notifier).getAllSharedAlbums();
selectionEnabledHook.value = false;
AutoRouter.of(context).push(AlbumViewerRoute(albumId: result.id));
context.autoPush(AlbumViewerRoute(albumId: result.id));
}
} finally {
processing.value = false;
@ -300,7 +299,7 @@ class HomePage extends HookConsumerWidget {
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
).tr(),
),

View File

@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
import 'package:immich_mobile/modules/backup/providers/manual_upload.provider.dart';
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
@ -37,7 +38,7 @@ class ChangePasswordForm extends HookConsumerWidget {
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
),
Padding(
@ -191,7 +192,7 @@ class ChangePasswordButton extends ConsumerWidget {
return ElevatedButton(
style: ElevatedButton.styleFrom(
visualDensity: VisualDensity.standard,
backgroundColor: Theme.of(context).primaryColor,
backgroundColor: context.primaryColor,
foregroundColor: Colors.grey[50],
elevation: 2,
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 25),

View File

@ -1,9 +1,9 @@
import 'dart:io';
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/login/providers/oauth.provider.dart';
import 'package:immich_mobile/modules/onboarding/providers/gallery_permission.provider.dart';
import 'package:immich_mobile/routing/router.dart';
@ -150,7 +150,7 @@ class LoginForm extends HookConsumerWidget {
// Resume backup (if enable) then navigate
if (ref.read(authenticationProvider).shouldChangePassword &&
!ref.read(authenticationProvider).isAdmin) {
AutoRouter.of(context).push(const ChangePasswordRoute());
context.autoPush(const ChangePasswordRoute());
} else {
final hasPermission = await ref
.read(galleryPermissionNotifier.notifier)
@ -159,7 +159,7 @@ class LoginForm extends HookConsumerWidget {
// Don't resume the backup until we have gallery permission
ref.read(backupProvider.notifier).resumeBackup();
}
AutoRouter.of(context).replace(const TabControllerRoute());
context.autoReplace(const TabControllerRoute());
}
} else {
ImmichToast.show(
@ -212,9 +212,7 @@ class LoginForm extends HookConsumerWidget {
if (permission.isGranted || permission.isLimited) {
ref.watch(backupProvider.notifier).resumeBackup();
}
AutoRouter.of(context).replace(
const TabControllerRoute(),
);
context.autoReplace(const TabControllerRoute());
} else {
ImmichToast.show(
context: context,
@ -260,8 +258,7 @@ class LoginForm extends HookConsumerWidget {
),
),
),
onPressed: () =>
AutoRouter.of(context).push(const SettingsRoute()),
onPressed: () => context.autoPush(const SettingsRoute()),
icon: const Icon(Icons.settings_rounded),
label: const SizedBox.shrink(),
),
@ -303,7 +300,7 @@ class LoginForm extends HookConsumerWidget {
children: [
Text(
serverEndpointController.text,
style: Theme.of(context).textTheme.displaySmall,
style: context.textTheme.displaySmall,
textAlign: TextAlign.center,
),
if (isPasswordLoginEnable.value) ...[
@ -339,8 +336,7 @@ class LoginForm extends HookConsumerWidget {
horizontal: 16.0,
),
child: Divider(
color: Brightness.dark ==
Theme.of(context).brightness
color: context.isDarkTheme
? Colors.white
: Colors.black,
),
@ -588,7 +584,7 @@ class OAuthLoginButton extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
return ElevatedButton.icon(
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context).primaryColor.withAlpha(230),
backgroundColor: context.primaryColor.withAlpha(230),
padding: const EdgeInsets.symmetric(vertical: 12),
),
onPressed: onPressed,

View File

@ -1,7 +1,7 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/login/ui/login_form.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:package_info_plus/package_info_plus.dart';
@ -47,13 +47,13 @@ class LoginPage extends HookConsumerWidget {
child: Text(
'Logs',
style: TextStyle(
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontWeight: FontWeight.bold,
fontFamily: "Inconsolata",
),
),
onTap: () {
AutoRouter.of(context).push(const AppLogRoute());
context.autoPush(const AppLogRoute());
},
),
],

View File

@ -1,8 +1,8 @@
import 'dart:io';
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/disable_multi_select_button.dart';
import 'package:immich_mobile/modules/map/ui/map_settings_dialog.dart';
@ -30,7 +30,7 @@ class MapAppBar extends HookWidget implements PreferredSizeWidget {
Padding(
padding: const EdgeInsets.only(left: 15, top: 15),
child: ElevatedButton(
onPressed: () => AutoRouter.of(context).pop(),
onPressed: () => context.autoPop(),
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
padding: const EdgeInsets.all(12),

View File

@ -5,6 +5,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/asset_viewer/providers/render_list.provider.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/asset_grid_data_structure.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
@ -56,10 +57,10 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
@override
Widget build(BuildContext context) {
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
final isDarkTheme = context.isDarkTheme;
final bottomPadding =
Platform.isAndroid ? MediaQuery.of(context).padding.bottom - 10 : 0.0;
final maxHeight = MediaQuery.of(context).size.height - bottomPadding;
final maxHeight = context.height - bottomPadding;
final isSheetScrolled = useState(false);
final isSheetExpanded = useState(false);
final assetsInBound = useState(<Asset>[]);
@ -136,7 +137,7 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
SizedBox(
height: 150,
width: 150,
child: isDarkMode
child: isDarkTheme
? const InvertionFilter(
child: SaturationFilter(
saturation: -1,
@ -155,7 +156,7 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
"map_zoom_to_see_photos".tr(),
style: TextStyle(
fontSize: 20,
color: Theme.of(context).textTheme.displayLarge?.color,
color: context.textTheme.displayLarge?.color,
),
),
],
@ -181,7 +182,7 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
height: 60,
width: double.infinity,
decoration: BoxDecoration(
color: isDarkMode ? Colors.grey[900] : Colors.grey[100],
color: isDarkTheme ? Colors.grey[900] : Colors.grey[100],
),
child: Stack(
children: [
@ -196,17 +197,14 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
textToDisplay,
style: TextStyle(
fontSize: 16,
color: Theme.of(context).textTheme.displayLarge?.color,
color: context.textTheme.displayLarge?.color,
fontWeight: FontWeight.bold,
),
),
Divider(
height: 10,
color: Theme.of(context)
.textTheme
.displayLarge
?.color
?.withOpacity(0.5),
color:
context.textTheme.displayLarge?.color?.withOpacity(0.5),
),
],
),
@ -217,7 +215,7 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
child: IconButton(
icon: Icon(
Icons.map_outlined,
color: Theme.of(context).textTheme.displayLarge?.color,
color: context.textTheme.displayLarge?.color,
),
iconSize: 20,
tooltip: 'Zoom to bounds',
@ -265,7 +263,7 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
ScrollController scrollController,
) {
return Card(
color: isDarkMode ? Colors.grey[900] : Colors.grey[100],
color: isDarkTheme ? Colors.grey[900] : Colors.grey[100],
surfaceTintColor: Colors.transparent,
elevation: 18.0,
margin: const EdgeInsets.all(0),

View File

@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/map/providers/map_state.provider.dart';
class MapSettingsDialog extends HookConsumerWidget {
@ -15,7 +16,7 @@ class MapSettingsDialog extends HookConsumerWidget {
final showFavoriteOnly = useState(mapSettings.showFavoriteOnly);
final showIncludeArchived = useState(mapSettings.includeArchived);
final showRelativeDate = useState(mapSettings.relativeTime);
final ThemeData theme = Theme.of(context);
final ThemeData theme = context.themeData;
Widget buildMapThemeSetting() {
return SwitchListTile.adaptive(
@ -125,7 +126,7 @@ class MapSettingsDialog extends HookConsumerWidget {
List<Widget> getDialogActions() {
return <Widget>[
TextButton(
onPressed: () => Navigator.of(context).pop(),
onPressed: () => context.pop(),
style: TextButton.styleFrom(
backgroundColor:
mapSettings.isDarkTheme ? Colors.grey[100] : Colors.grey[700],
@ -146,7 +147,7 @@ class MapSettingsDialog extends HookConsumerWidget {
mapSettingsNotifier.setRelativeTime(showRelativeDate.value);
mapSettingsNotifier
.switchIncludeArchived(showIncludeArchived.value);
Navigator.of(context).pop();
context.pop();
},
style: TextButton.styleFrom(
backgroundColor: theme.primaryColor,
@ -178,7 +179,7 @@ class MapSettingsDialog extends HookConsumerWidget {
width: double.maxFinite,
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.6,
maxHeight: context.height * 0.6,
),
child: ListView(
shrinkWrap: true,

View File

@ -1,7 +1,6 @@
import 'dart:async';
import 'dart:math' as math;
import 'package:auto_route/auto_route.dart';
import 'package:collection/collection.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
@ -12,6 +11,7 @@ import 'package:flutter_map_heatmap/flutter_map_heatmap.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:geolocator/geolocator.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/map/models/map_page_event.model.dart';
import 'package:immich_mobile/modules/map/providers/map_marker.provider.dart';
import 'package:immich_mobile/modules/map/providers/map_state.provider.dart';
@ -24,7 +24,7 @@ import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
import 'package:immich_mobile/shared/ui/immich_toast.dart';
import 'package:immich_mobile/utils/debounce.dart';
import 'package:immich_mobile/utils/flutter_map_extensions.dart';
import 'package:immich_mobile/extensions/flutter_map_extensions.dart';
import 'package:immich_mobile/utils/immich_app_theme.dart';
import 'package:immich_mobile/utils/selection_handlers.dart';
import 'package:latlong2/latlong.dart';
@ -101,7 +101,7 @@ class MapPageState extends ConsumerState<MapPage> {
}
void openAssetInViewer(Asset asset) {
AutoRouter.of(context).push(
context.autoPush(
GalleryViewerRoute(
initialIndex: 0,
loadAsset: (index) => asset,
@ -474,8 +474,8 @@ class MapPageState extends ConsumerState<MapPage> {
),
if (showLoadingIndicator.value || isLoading)
Positioned(
top: MediaQuery.of(context).size.height * 0.35,
left: MediaQuery.of(context).size.width * 0.425,
top: context.height * 0.35,
left: context.width * 0.425,
child: const ImmichLoadingIndicator(),
),
],

View File

@ -1,7 +1,7 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/memories/providers/memory.provider.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/shared/ui/immich_image.dart';
@ -31,7 +31,7 @@ class MemoryLane extends HookConsumerWidget {
child: GestureDetector(
onTap: () {
HapticFeedback.heavyImpact();
AutoRouter.of(context).push(
context.autoPush(
MemoryRoute(
memories: memories,
memoryIndex: index,

View File

@ -1,8 +1,8 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/memories/models/memory.dart';
import 'package:immich_mobile/modules/memories/ui/memory_card.dart';
import 'package:immich_mobile/shared/models/asset.dart';
@ -182,14 +182,14 @@ class MemoryPage extends HookConsumerWidget {
currentMemory.value.assets.length;
if (isLastAsset &&
(offset > notification.metrics.maxScrollExtent + 150)) {
AutoRouter.of(context).pop();
context.autoPop();
return true;
}
}
// Horizontal scroll handling
if (notification.depth == 1 &&
(offset > notification.metrics.maxScrollExtent + 100)) {
AutoRouter.of(context).pop();
context.autoPop();
return true;
}
}
@ -244,7 +244,7 @@ class MemoryPage extends HookConsumerWidget {
child: MemoryCard(
asset: asset,
onTap: () => toNextAsset(index),
onClose: () => AutoRouter.of(context).pop(),
onClose: () => context.autoPop(),
rightCornerText: assetProgress.value,
title: memories[mIndex].title,
showTitle: index == 0,

View File

@ -1,7 +1,7 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
import 'package:immich_mobile/modules/onboarding/providers/gallery_permission.provider.dart';
@ -11,7 +11,6 @@ import 'package:immich_mobile/shared/ui/immich_title_text.dart';
import 'package:permission_handler/permission_handler.dart';
class PermissionOnboardingPage extends HookConsumerWidget {
const PermissionOnboardingPage({super.key});
@override
@ -21,13 +20,10 @@ class PermissionOnboardingPage extends HookConsumerWidget {
// Navigate to the main Tab Controller when permission is granted
void goToHome() {
// Resume backup (if enable) then navigate
ref.watch(backupProvider.notifier).resumeBackup()
.catchError((error) {
ref.watch(backupProvider.notifier).resumeBackup().catchError((error) {
debugPrint('PermissionOnboardingPage error: $error');
});
AutoRouter.of(context).replace(
const TabControllerRoute(),
);
context.autoReplace(const TabControllerRoute());
}
// When the permission is denied, we show a request permission page
@ -38,21 +34,21 @@ class PermissionOnboardingPage extends HookConsumerWidget {
children: [
Text(
'permission_onboarding_request',
style: Theme.of(context).textTheme.titleMedium,
style: context.textTheme.titleMedium,
textAlign: TextAlign.center,
).tr(),
const SizedBox(height: 18),
ElevatedButton(
onPressed: () => ref
.read(galleryPermissionNotifier.notifier)
.requestGalleryPermission()
.then((permission) async {
if (permission.isGranted) {
// If permission is limited, we will show the limited
// permission page
goToHome();
}
}),
.read(galleryPermissionNotifier.notifier)
.requestGalleryPermission()
.then((permission) async {
if (permission.isGranted) {
// If permission is limited, we will show the limited
// permission page
goToHome();
}
}),
child: const Text(
'permission_onboarding_grant_permission',
).tr(),
@ -70,7 +66,7 @@ class PermissionOnboardingPage extends HookConsumerWidget {
children: [
Text(
'permission_onboarding_permission_granted',
style: Theme.of(context).textTheme.titleMedium,
style: context.textTheme.titleMedium,
textAlign: TextAlign.center,
).tr(),
const SizedBox(height: 18),
@ -90,14 +86,15 @@ class PermissionOnboardingPage extends HookConsumerWidget {
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.warning_outlined,
const Icon(
Icons.warning_outlined,
color: Colors.yellow,
size: 48,
),
const SizedBox(height: 8),
Text(
'permission_onboarding_permission_limited',
style: Theme.of(context).textTheme.titleMedium,
style: context.textTheme.titleMedium,
textAlign: TextAlign.center,
).tr(),
const SizedBox(height: 18),
@ -123,14 +120,15 @@ class PermissionOnboardingPage extends HookConsumerWidget {
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.warning_outlined,
const Icon(
Icons.warning_outlined,
color: Colors.red,
size: 48,
),
const SizedBox(height: 8),
Text(
'permission_onboarding_permission_denied',
style: Theme.of(context).textTheme.titleMedium,
style: context.textTheme.titleMedium,
textAlign: TextAlign.center,
).tr(),
const SizedBox(height: 18),
@ -186,13 +184,10 @@ class PermissionOnboardingPage extends HookConsumerWidget {
child: const Text('permission_onboarding_log_out').tr(),
onPressed: () {
ref.read(authenticationProvider.notifier).logout();
AutoRouter.of(context).replace(
const LoginRoute(),
);
context.autoReplace(const LoginRoute());
},
),
],
),
),
),

View File

@ -1,6 +1,6 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/shared/models/user.dart';
import 'package:immich_mobile/shared/ui/user_avatar.dart';
@ -28,10 +28,10 @@ class PartnerList extends HookConsumerWidget {
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
),
onTap: () => AutoRouter.of(context).push(PartnerDetailRoute(partner: p)),
onTap: () => context.autoPush((PartnerDetailRoute(partner: p))),
);
}
}

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/search/models/curated_content.dart';
import 'package:immich_mobile/modules/search/ui/thumbnail_with_info.dart';
import 'package:immich_mobile/shared/models/store.dart';
@ -85,7 +86,7 @@ class CuratedPeopleRow extends StatelessWidget {
"Add name",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
),
),

View File

@ -1,5 +1,5 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/map/ui/map_thumbnail.dart';
import 'package:immich_mobile/modules/search/ui/curated_row.dart';
import 'package:immich_mobile/modules/search/ui/thumbnail_with_info.dart';
@ -25,7 +25,7 @@ class CuratedPlacesRow extends CuratedRow {
final int actualContentIndex = isMapEnabled ? 1 : 0;
Widget buildMapThumbnail() {
return GestureDetector(
onTap: () => AutoRouter.of(context).push(
onTap: () => context.autoPush(
const MapRoute(),
),
child: SizedBox(
@ -43,7 +43,7 @@ class CuratedPlacesRow extends CuratedRow {
),
height: imageSize,
showAttribution: false,
isDarkTheme: Theme.of(context).brightness == Brightness.dark,
isDarkTheme: context.isDarkTheme,
),
),
Padding(

View File

@ -1,5 +1,5 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/search/models/curated_content.dart';
import 'package:immich_mobile/modules/search/ui/thumbnail_with_info.dart';
import 'package:immich_mobile/routing/router.dart';
@ -50,13 +50,13 @@ class ExploreGrid extends StatelessWidget {
borderRadius: 0,
onTap: () {
isPeople
? AutoRouter.of(context).push(
? context.autoPush(
PersonResultRoute(
personId: content.id,
personName: content.label,
),
)
: AutoRouter.of(context).push(
: context.autoPush(
SearchResultRoute(searchTerm: 'm:${content.label}'),
);
},

View File

@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/search/providers/search_page_state.provider.dart';
class ImmichSearchBar extends HookConsumerWidget
@ -57,11 +58,11 @@ class ImmichSearchBar extends HookConsumerWidget
},
decoration: InputDecoration(
hintText: 'search_bar_hint'.tr(),
hintStyle: Theme.of(context).textTheme.titleSmall?.copyWith(
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.5),
fontWeight: FontWeight.w500,
fontSize: 14,
),
hintStyle: context.textTheme.titleSmall?.copyWith(
color: context.themeData.colorScheme.onSurface.withOpacity(0.5),
fontWeight: FontWeight.w500,
fontSize: 14,
),
enabledBorder: const UnderlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
),

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/search/providers/people.provider.dart';
class PersonNameEditFormResult {
@ -71,7 +72,7 @@ class PersonNameEditForm extends HookConsumerWidget {
child: Text(
"Save",
style: TextStyle(
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontWeight: FontWeight.bold,
),
),

View File

@ -1,5 +1,6 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
class SearchRowTitle extends StatelessWidget {
final Function() onViewAllPressed;
@ -26,14 +27,14 @@ class SearchRowTitle extends StatelessWidget {
children: [
Text(
title,
style: Theme.of(context).textTheme.titleSmall,
style: context.textTheme.titleSmall,
),
TextButton(
onPressed: onViewAllPressed,
child: Text(
'search_page_view_all_button',
style: TextStyle(
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontWeight: FontWeight.bold,
fontSize: 14.0,
),

View File

@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/search/providers/search_page_state.provider.dart';
class SearchSuggestionList extends ConsumerWidget {
@ -13,17 +14,16 @@ class SearchSuggestionList extends ConsumerWidget {
final searchTerm = ref.watch(searchPageStateProvider).searchTerm;
final searchSuggestion =
ref.watch(searchPageStateProvider).searchSuggestion;
var isDarkTheme = Theme.of(context).brightness == Brightness.dark;
return Container(
color: searchTerm.isEmpty
? Colors.black.withOpacity(0.5)
: Theme.of(context).scaffoldBackgroundColor,
: context.scaffoldBackgroundColor,
child: CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: Container(
color: isDarkTheme ? Colors.grey[800] : Colors.grey[100],
color: context.isDarkTheme ? Colors.grey[800] : Colors.grey[100],
child: Padding(
padding: const EdgeInsets.all(16.0),
child: RichText(
@ -31,14 +31,14 @@ class SearchSuggestionList extends ConsumerWidget {
children: [
TextSpan(
text: 'search_suggestion_list_smart_search_hint_1'.tr(),
style: Theme.of(context).textTheme.bodyMedium,
style: context.textTheme.bodyMedium,
),
TextSpan(
text: 'search_suggestion_list_smart_search_hint_2'.tr(),
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.bold,
),
style: context.textTheme.bodyMedium?.copyWith(
color: context.primaryColor,
fontWeight: FontWeight.bold,
),
),
],
),

View File

@ -1,7 +1,8 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/shared/models/store.dart';
import 'package:immich_mobile/utils/capitalize.dart';
import 'package:immich_mobile/extensions/string_extensions.dart';
// ignore: must_be_immutable
class ThumbnailWithInfo extends StatelessWidget {
@ -22,8 +23,8 @@ class ThumbnailWithInfo extends StatelessWidget {
@override
Widget build(BuildContext context) {
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
var textAndIconColor = isDarkMode ? Colors.grey[100] : Colors.grey[700];
var textAndIconColor =
context.isDarkTheme ? Colors.grey[100] : Colors.grey[700];
return GestureDetector(
onTap: () {
onTap();
@ -34,7 +35,7 @@ class ThumbnailWithInfo extends StatelessWidget {
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(borderRadius),
color: isDarkMode ? Colors.grey[900] : Colors.grey[100],
color: context.isDarkTheme ? Colors.grey[900] : Colors.grey[100],
),
child: imageUrl != null
? ClipRRect(

View File

@ -1,7 +1,7 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
import 'package:immich_mobile/modules/search/providers/all_motion_photos.provider.dart';
import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
@ -17,7 +17,7 @@ class AllMotionPhotosPage extends HookConsumerWidget {
appBar: AppBar(
title: const Text('motion_photos_page_title').tr(),
leading: IconButton(
onPressed: () => AutoRouter.of(context).pop(),
onPressed: () => context.autoPop(),
icon: const Icon(Icons.arrow_back_ios_rounded),
),
),

View File

@ -1,7 +1,7 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/search/models/curated_content.dart';
import 'package:immich_mobile/modules/search/providers/people.provider.dart';
import 'package:immich_mobile/modules/search/ui/explore_grid.dart';
@ -19,13 +19,13 @@ class AllPeoplePage extends HookConsumerWidget {
title: Text(
'all_people_page_title',
style: TextStyle(
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontWeight: FontWeight.bold,
fontSize: 16.0,
),
).tr(),
leading: IconButton(
onPressed: () => AutoRouter.of(context).pop(),
onPressed: () => context.autoPop(),
icon: const Icon(Icons.arrow_back_ios_rounded),
),
),

View File

@ -1,7 +1,7 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
import 'package:immich_mobile/modules/search/providers/all_video_assets.provider.dart';
import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
@ -17,7 +17,7 @@ class AllVideosPage extends HookConsumerWidget {
appBar: AppBar(
title: const Text('all_videos_page_title').tr(),
leading: IconButton(
onPressed: () => AutoRouter.of(context).pop(),
onPressed: () => context.autoPop(),
icon: const Icon(Icons.arrow_back_ios_rounded),
),
),

View File

@ -1,7 +1,7 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/search/models/curated_content.dart';
import 'package:immich_mobile/modules/search/providers/search_page_state.provider.dart';
import 'package:immich_mobile/modules/search/ui/explore_grid.dart';
@ -21,13 +21,13 @@ class CuratedLocationPage extends HookConsumerWidget {
title: Text(
'curated_location_page_title',
style: TextStyle(
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontWeight: FontWeight.bold,
fontSize: 16.0,
),
).tr(),
leading: IconButton(
onPressed: () => AutoRouter.of(context).pop(),
onPressed: () => context.autoPop(),
icon: const Icon(Icons.arrow_back_ios_rounded),
),
),

View File

@ -1,7 +1,7 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
import 'package:immich_mobile/modules/search/providers/people.provider.dart';
import 'package:immich_mobile/modules/search/ui/person_name_edit_form.dart';
@ -40,7 +40,7 @@ class PersonResultPage extends HookConsumerWidget {
void buildBottomSheet() {
showModalBottomSheet(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
backgroundColor: context.scaffoldBackgroundColor,
isScrollControlled: false,
context: context,
useSafeArea: true,
@ -73,13 +73,13 @@ class PersonResultPage extends HookConsumerWidget {
children: [
Text(
'Add a name',
style: Theme.of(context).textTheme.titleSmall?.copyWith(
color: Theme.of(context).colorScheme.secondary,
),
style: context.textTheme.titleSmall?.copyWith(
color: context.themeData.colorScheme.secondary,
),
),
Text(
'Find them fast by name with search',
style: Theme.of(context).textTheme.labelSmall,
style: context.textTheme.labelSmall,
),
],
),
@ -91,7 +91,7 @@ class PersonResultPage extends HookConsumerWidget {
children: [
Text(
name.value,
style: Theme.of(context).textTheme.titleLarge,
style: context.textTheme.titleLarge,
),
],
);
@ -101,7 +101,7 @@ class PersonResultPage extends HookConsumerWidget {
appBar: AppBar(
title: Text(name.value),
leading: IconButton(
onPressed: () => AutoRouter.of(context).pop(),
onPressed: () => context.autoPop(),
icon: const Icon(Icons.arrow_back_ios_rounded),
),
actions: [

View File

@ -1,7 +1,7 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
import 'package:immich_mobile/modules/search/providers/recently_added.provider.dart';
import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
@ -17,7 +17,7 @@ class RecentlyAddedPage extends HookConsumerWidget {
appBar: AppBar(
title: const Text('recently_added_page_title').tr(),
leading: IconButton(
onPressed: () => AutoRouter.of(context).pop(),
onPressed: () => context.autoPop(),
icon: const Icon(Icons.arrow_back_ios_rounded),
),
),

View File

@ -1,9 +1,9 @@
import 'dart:math' as math;
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/search/models/curated_content.dart';
import 'package:immich_mobile/modules/search/providers/people.provider.dart';
import 'package:immich_mobile/modules/search/providers/search_page_state.provider.dart';
@ -30,15 +30,14 @@ class SearchPage extends HookConsumerWidget {
final curatedPeople = ref.watch(getCuratedPeopleProvider);
final isMapEnabled =
ref.watch(serverInfoProvider.select((v) => v.serverFeatures.map));
var isDarkTheme = Theme.of(context).brightness == Brightness.dark;
double imageSize = math.min(MediaQuery.of(context).size.width / 3, 150);
double imageSize = math.min(context.width / 3, 150);
TextStyle categoryTitleStyle = const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14.0,
);
Color categoryIconColor = isDarkTheme ? Colors.white : Colors.black;
Color categoryIconColor = context.isDarkTheme ? Colors.white : Colors.black;
useEffect(
() {
@ -52,7 +51,7 @@ class SearchPage extends HookConsumerWidget {
searchFocusNode.unfocus();
ref.watch(searchPageStateProvider.notifier).disableSearch();
AutoRouter.of(context).push(
context.autoPush(
SearchResultRoute(
searchTerm: searchTerm,
),
@ -88,7 +87,7 @@ class SearchPage extends HookConsumerWidget {
.take(12)
.toList(),
onTap: (content, index) {
AutoRouter.of(context).push(
context.autoPush(
PersonResultRoute(
personId: content.id,
personName: content.label,
@ -121,7 +120,7 @@ class SearchPage extends HookConsumerWidget {
.toList(),
imageSize: imageSize,
onTap: (content, index) {
AutoRouter.of(context).push(
context.autoPush(
SearchResultRoute(
searchTerm: 'm:${content.label}',
),
@ -148,16 +147,14 @@ class SearchPage extends HookConsumerWidget {
children: [
SearchRowTitle(
title: "search_page_people".tr(),
onViewAllPressed: () => AutoRouter.of(context).push(
const AllPeopleRoute(),
),
onViewAllPressed: () =>
context.autoPush(const AllPeopleRoute()),
),
buildPeople(),
SearchRowTitle(
title: "search_page_places".tr(),
onViewAllPressed: () => AutoRouter.of(context).push(
const CuratedLocationRoute(),
),
onViewAllPressed: () =>
context.autoPush(const CuratedLocationRoute()),
top: 0,
),
const SizedBox(height: 10.0),
@ -167,7 +164,7 @@ class SearchPage extends HookConsumerWidget {
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
'search_page_your_activity',
style: Theme.of(context).textTheme.titleSmall,
style: context.textTheme.titleSmall,
).tr(),
),
ListTile(
@ -178,9 +175,7 @@ class SearchPage extends HookConsumerWidget {
title:
Text('search_page_favorites', style: categoryTitleStyle)
.tr(),
onTap: () => AutoRouter.of(context).push(
const FavoritesRoute(),
),
onTap: () => context.autoPush(const FavoritesRoute()),
),
const CategoryDivider(),
ListTile(
@ -192,16 +187,14 @@ class SearchPage extends HookConsumerWidget {
'search_page_recently_added',
style: categoryTitleStyle,
).tr(),
onTap: () => AutoRouter.of(context).push(
const RecentlyAddedRoute(),
),
onTap: () => context.autoPush(const RecentlyAddedRoute()),
),
const SizedBox(height: 24.0),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'search_page_categories',
style: Theme.of(context).textTheme.titleSmall,
style: context.textTheme.titleSmall,
).tr(),
),
ListTile(
@ -210,7 +203,7 @@ class SearchPage extends HookConsumerWidget {
Icons.screenshot,
color: categoryIconColor,
),
onTap: () => AutoRouter.of(context).push(
onTap: () => context.autoPush(
SearchResultRoute(
searchTerm: 'screenshots',
),
@ -224,7 +217,7 @@ class SearchPage extends HookConsumerWidget {
Icons.photo_camera_front_outlined,
color: categoryIconColor,
),
onTap: () => AutoRouter.of(context).push(
onTap: () => context.autoPush(
SearchResultRoute(
searchTerm: 'selfies',
),
@ -238,9 +231,7 @@ class SearchPage extends HookConsumerWidget {
Icons.play_circle_outline,
color: categoryIconColor,
),
onTap: () => AutoRouter.of(context).push(
const AllVideosRoute(),
),
onTap: () => context.autoPush(const AllVideosRoute()),
),
const CategoryDivider(),
ListTile(
@ -252,9 +243,7 @@ class SearchPage extends HookConsumerWidget {
Icons.motion_photos_on_outlined,
color: categoryIconColor,
),
onTap: () => AutoRouter.of(context).push(
const AllMotionPhotosRoute(),
),
onTap: () => context.autoPush(const AllMotionPhotosRoute()),
),
],
),

View File

@ -1,8 +1,8 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
import 'package:immich_mobile/modules/search/providers/search_page_state.provider.dart';
import 'package:immich_mobile/modules/search/providers/search_result_page.provider.dart';
@ -38,7 +38,6 @@ class SearchResultPage extends HookConsumerWidget {
final searchTermController = useTextEditingController(text: "");
final isNewSearch = useState(false);
final currentSearchTerm = useState(searchTerm);
final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
final isDisplayDateGroup = useState(true);
FocusNode? searchFocusNode;
@ -112,8 +111,9 @@ class SearchResultPage extends HookConsumerWidget {
hintStyle: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.0,
color:
isDarkTheme ? Colors.grey[500] : Colors.black.withOpacity(0.5),
color: context.isDarkTheme
? Colors.grey[500]
: Colors.black.withOpacity(0.5),
),
),
);
@ -130,7 +130,7 @@ class SearchResultPage extends HookConsumerWidget {
Text(
currentSearchTerm.value,
style: TextStyle(
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontSize: 13,
fontWeight: FontWeight.bold,
),
@ -138,12 +138,12 @@ class SearchResultPage extends HookConsumerWidget {
),
Icon(
Icons.close_rounded,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
size: 20,
),
],
),
backgroundColor: Theme.of(context).primaryColor.withAlpha(50),
backgroundColor: context.primaryColor.withAlpha(50),
);
}
@ -185,7 +185,7 @@ class SearchResultPage extends HookConsumerWidget {
if (isNewSearch.value) {
isNewSearch.value = false;
} else {
AutoRouter.of(context).pop(true);
context.autoPop(true);
}
},
icon: const Icon(Icons.arrow_back_ios_rounded),

View File

@ -2,6 +2,7 @@ import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart' show useEffect, useState;
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/shared/models/store.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
@ -43,7 +44,7 @@ class AdvancedSettings extends HookConsumerWidget {
final logLevel = Level.LEVELS[levelId.value].name;
return ExpansionTile(
textColor: Theme.of(context).primaryColor,
textColor: context.primaryColor,
title: const Text(
"advanced_settings_tile_title",
style: TextStyle(
@ -86,7 +87,7 @@ class AdvancedSettings extends HookConsumerWidget {
min: 1.0,
divisions: 7,
label: logLevel,
activeColor: Theme.of(context).primaryColor,
activeColor: context.primaryColor,
),
),
SettingsSwitchListTile(

View File

@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/asset_grid_data_structure.dart';
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
@ -50,12 +51,10 @@ class LayoutSettings extends HookConsumerWidget {
return Column(
children: [
SwitchListTile.adaptive(
activeColor: Theme.of(context).primaryColor,
activeColor: context.primaryColor,
title: Text(
"asset_list_layout_settings_dynamic_layout_title",
style: Theme.of(context)
.textTheme
.labelLarge
style: context.textTheme.labelLarge
?.copyWith(fontWeight: FontWeight.bold),
).tr(),
onChanged: switchChanged,
@ -75,10 +74,10 @@ class LayoutSettings extends HookConsumerWidget {
).tr(),
),
RadioListTile(
activeColor: Theme.of(context).primaryColor,
activeColor: context.primaryColor,
title: Text(
"asset_list_layout_settings_group_by_month_day",
style: Theme.of(context).textTheme.labelLarge,
style: context.textTheme.labelLarge,
).tr(),
value: GroupAssetsBy.day,
groupValue: groupBy.value,
@ -86,10 +85,10 @@ class LayoutSettings extends HookConsumerWidget {
controlAffinity: ListTileControlAffinity.trailing,
),
RadioListTile(
activeColor: Theme.of(context).primaryColor,
activeColor: context.primaryColor,
title: Text(
"asset_list_layout_settings_group_by_month",
style: Theme.of(context).textTheme.labelLarge,
style: context.textTheme.labelLarge,
).tr(),
value: GroupAssetsBy.month,
groupValue: groupBy.value,
@ -97,10 +96,10 @@ class LayoutSettings extends HookConsumerWidget {
controlAffinity: ListTileControlAffinity.trailing,
),
RadioListTile(
activeColor: Theme.of(context).primaryColor,
activeColor: context.primaryColor,
title: Text(
"asset_list_layout_settings_group_automatically",
style: Theme.of(context).textTheme.labelLarge,
style: context.textTheme.labelLarge,
).tr(),
value: GroupAssetsBy.auto,
groupValue: groupBy.value,

View File

@ -1,5 +1,6 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/settings/ui/asset_list_settings/asset_list_layout_settings.dart';
import 'package:immich_mobile/modules/settings/ui/asset_list_settings/asset_list_storage_indicator.dart';
import 'asset_list_tiles_per_row.dart';
@ -12,7 +13,7 @@ class AssetListSettings extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ExpansionTile(
textColor: Theme.of(context).primaryColor,
textColor: context.primaryColor,
title: const Text(
'asset_list_settings_title',
style: TextStyle(

View File

@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
@ -33,13 +34,11 @@ class StorageIndicator extends HookConsumerWidget {
);
return SwitchListTile.adaptive(
activeColor: Theme.of(context).primaryColor,
activeColor: context.primaryColor,
title: Text(
"theme_setting_asset_list_storage_indicator_title",
style: Theme.of(context)
.textTheme
.labelLarge
?.copyWith(fontWeight: FontWeight.bold),
style:
context.textTheme.labelLarge?.copyWith(fontWeight: FontWeight.bold),
).tr(),
onChanged: switchChanged,
value: showStorageIndicator.value,

View File

@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
@ -51,7 +52,7 @@ class TilesPerRow extends HookConsumerWidget {
max: 6,
divisions: 4,
label: "${itemsValue.value.toInt()}",
activeColor: Theme.of(context).primaryColor,
activeColor: context.primaryColor,
),
],
);

View File

@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
import 'package:immich_mobile/modules/settings/ui/settings_switch_list_tile.dart';
@ -26,7 +27,7 @@ class ImageViewerQualitySetting extends HookConsumerWidget {
);
return ExpansionTile(
textColor: Theme.of(context).primaryColor,
textColor: context.primaryColor,
title: const Text(
'theme_setting_image_viewer_quality_title',
style: TextStyle(

View File

@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart' show useEffect, useState;
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/backup/models/duplicated_asset.model.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/shared/providers/db.provider.dart';
@ -25,7 +26,7 @@ class LocalStorageSettings extends HookConsumerWidget {
}
return ExpansionTile(
textColor: Theme.of(context).primaryColor,
textColor: context.primaryColor,
title: const Text(
"cache_settings_tile_title",
style: TextStyle(
@ -42,9 +43,7 @@ class LocalStorageSettings extends HookConsumerWidget {
ListTile(
title: Text(
"Duplicated Assets (${cacheItemCount.value})",
style: Theme.of(context)
.textTheme
.labelLarge
style: context.textTheme.labelLarge
?.copyWith(fontWeight: FontWeight.bold),
).tr(),
subtitle: const Text(

View File

@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
import 'package:immich_mobile/modules/settings/providers/notification_permission.provider.dart';
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
@ -49,12 +50,12 @@ class NotificationSetting extends HookConsumerWidget {
actions: [
TextButton(
child: const Text('notification_permission_dialog_cancel').tr(),
onPressed: () => Navigator.of(context).pop(),
onPressed: () => context.pop(),
),
TextButton(
child: const Text('notification_permission_dialog_settings').tr(),
onPressed: () {
Navigator.of(context).pop();
context.pop();
openAppSettings();
},
),
@ -65,7 +66,7 @@ class NotificationSetting extends HookConsumerWidget {
final String formattedValue = _formatSliderValue(sliderValue.value);
return ExpansionTile(
textColor: Theme.of(context).primaryColor,
textColor: context.primaryColor,
title: const Text(
'setting_notifications_title',
style: TextStyle(
@ -84,9 +85,7 @@ class NotificationSetting extends HookConsumerWidget {
leading: const Icon(Icons.notifications_outlined),
title: Text(
'notification_permission_list_tile_title',
style: Theme.of(context)
.textTheme
.labelLarge
style: context.textTheme.labelLarge
?.copyWith(fontWeight: FontWeight.bold),
).tr(),
subtitle: Column(
@ -94,7 +93,7 @@ class NotificationSetting extends HookConsumerWidget {
children: [
Text(
'notification_permission_list_tile_content',
style: Theme.of(context).textTheme.labelMedium,
style: context.textTheme.labelMedium,
).tr(),
const SizedBox(height: 8),
ElevatedButton(
@ -149,7 +148,7 @@ class NotificationSetting extends HookConsumerWidget {
max: 5.0,
divisions: 5,
label: formattedValue,
activeColor: Theme.of(context).primaryColor,
activeColor: context.primaryColor,
),
),
],

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
class SettingsSwitchListTile extends StatelessWidget {
@ -23,7 +24,7 @@ class SettingsSwitchListTile extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SwitchListTile.adaptive(
selectedTileColor: enabled ? null : Theme.of(context).disabledColor,
selectedTileColor: enabled ? null : context.themeData.disabledColor,
value: valueNotifier.value,
onChanged: (bool value) {
if (enabled) {
@ -34,16 +35,13 @@ class SettingsSwitchListTile extends StatelessWidget {
onChanged!(value);
}
},
activeColor: enabled
? Theme.of(context).primaryColor
: Theme.of(context).disabledColor,
activeColor:
enabled ? context.primaryColor : context.themeData.disabledColor,
dense: true,
title: Text(
title,
style: Theme.of(context)
.textTheme
.labelLarge
?.copyWith(fontWeight: FontWeight.bold),
style:
context.textTheme.labelLarge?.copyWith(fontWeight: FontWeight.bold),
),
subtitle: subtitle != null ? Text(subtitle!) : null,
);

View File

@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
import 'package:immich_mobile/utils/immich_app_theme.dart';
@ -24,7 +25,7 @@ class ThemeSetting extends HookConsumerWidget {
);
return ExpansionTile(
textColor: Theme.of(context).primaryColor,
textColor: context.primaryColor,
title: const Text(
'theme_setting_theme_title',
style: TextStyle(
@ -39,12 +40,10 @@ class ThemeSetting extends HookConsumerWidget {
).tr(),
children: [
SwitchListTile.adaptive(
activeColor: Theme.of(context).primaryColor,
activeColor: context.primaryColor,
title: Text(
'theme_setting_system_theme_switch',
style: Theme.of(context)
.textTheme
.labelLarge
style: context.textTheme.labelLarge
?.copyWith(fontWeight: FontWeight.bold),
).tr(),
value: currentTheme.value == ThemeMode.system,
@ -77,12 +76,10 @@ class ThemeSetting extends HookConsumerWidget {
),
if (currentTheme.value != ThemeMode.system)
SwitchListTile.adaptive(
activeColor: Theme.of(context).primaryColor,
activeColor: context.primaryColor,
title: Text(
'theme_setting_dark_mode_switch',
style: Theme.of(context)
.textTheme
.labelLarge
style: context.textTheme.labelLarge
?.copyWith(fontWeight: FontWeight.bold),
).tr(),
value: ref.watch(immichThemeProvider) == ThemeMode.dark,

View File

@ -1,9 +1,9 @@
import 'dart:math' as math;
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/search/ui/thumbnail_with_info.dart';
import 'package:immich_mobile/modules/shared_link/models/shared_link.dart';
import 'package:immich_mobile/modules/shared_link/providers/shared_link.provider.dart';
@ -58,12 +58,12 @@ class SharedLinkItem extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final themeData = Theme.of(context);
final themeData = context.themeData;
final isDarkMode = themeData.brightness == Brightness.dark;
final thumbnailUrl = sharedLink.thumbAssetId != null
? getThumbnailUrlForRemoteId(sharedLink.thumbAssetId!)
: null;
final imageSize = math.min(MediaQuery.of(context).size.width / 4, 100.0);
final imageSize = math.min(context.width / 4, 100.0);
void copyShareLinkToClipboard() {
final serverUrl = getServerUrl();
@ -194,8 +194,8 @@ class SharedLinkItem extends ConsumerWidget {
tapTargetSize:
MaterialTapTargetSize.shrinkWrap, // the '2023' part
),
onPressed: () => AutoRouter.of(context)
.push(SharedLinkEditRoute(existingLink: sharedLink)),
onPressed: () =>
context.autoPush(SharedLinkEditRoute(existingLink: sharedLink)),
),
IconButton(
splashRadius: 25,

View File

@ -1,10 +1,10 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/shared_link/models/shared_link.dart';
import 'package:immich_mobile/modules/shared_link/providers/shared_link.provider.dart';
import 'package:immich_mobile/modules/shared_link/services/shared_link.service.dart';
@ -26,7 +26,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
const padding = 20.0;
final themeData = Theme.of(context);
final themeData = context.themeData;
final descriptionController =
useTextEditingController(text: existingLink?.description ?? "");
final descriptionFocusNode = useFocusNode();
@ -215,7 +215,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
).tr(),
enableSearch: false,
enableFilter: false,
width: MediaQuery.of(context).size.width - 40,
width: context.width - 40,
initialSelection: expiryAfter.value,
enabled: newShareLink.value.isEmpty &&
(existingLink == null || editExpiry.value),
@ -307,7 +307,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
alignment: Alignment.bottomRight,
child: ElevatedButton(
onPressed: () {
AutoRouter.of(context).pop();
context.autoPop();
},
child: const Text(
"Done",
@ -403,7 +403,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
changeExpiry: changeExpiry,
);
ref.invalidate(sharedLinksStateProvider);
AutoRouter.of(context).pop();
context.autoPop();
}
return Scaffold(

View File

@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/shared_link/models/shared_link.dart';
import 'package:immich_mobile/modules/shared_link/providers/shared_link.provider.dart';
import 'package:immich_mobile/modules/shared_link/ui/shared_link_item.dart';
@ -52,7 +53,7 @@ class SharedLinkPage extends HookConsumerWidget {
child: Icon(
Icons.link_off,
size: 100,
color: Theme.of(context).iconTheme.color?.withOpacity(0.5),
color: context.themeData.iconTheme.color?.withOpacity(0.5),
),
),
),

View File

@ -1,9 +1,9 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
import 'package:immich_mobile/modules/home/ui/delete_dialog.dart';
import 'package:immich_mobile/modules/trash/providers/trashed_asset.provider.dart';
@ -137,7 +137,7 @@ class TrashPage extends HookConsumerWidget {
return AppBar(
leading: IconButton(
onPressed: !selectionEnabledHook.value
? () => AutoRouter.of(context).pop()
? () => context.autoPop()
: () {
selectionEnabledHook.value = false;
selection.value = {};
@ -177,7 +177,7 @@ class TrashPage extends HookConsumerWidget {
child: SizedBox(
height: 64,
child: Container(
color: Theme.of(context).canvasColor,
color: context.themeData.canvasColor,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [

View File

@ -6,7 +6,7 @@ import 'package:immich_mobile/utils/hash.dart';
import 'package:isar/isar.dart';
import 'package:openapi/api.dart';
import 'package:photo_manager/photo_manager.dart';
import 'package:immich_mobile/utils/builtin_extensions.dart';
import 'package:immich_mobile/extensions/string_extensions.dart';
import 'package:path/path.dart' as p;
part 'asset.g.dart';

View File

@ -10,7 +10,7 @@ import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/models/device_asset.dart';
import 'package:immich_mobile/shared/models/ios_device_asset.dart';
import 'package:immich_mobile/shared/providers/db.provider.dart';
import 'package:immich_mobile/utils/builtin_extensions.dart';
import 'package:immich_mobile/extensions/string_extensions.dart';
import 'package:isar/isar.dart';
import 'package:logging/logging.dart';
import 'package:photo_manager/photo_manager.dart';

View File

@ -11,7 +11,7 @@ import 'package:immich_mobile/shared/models/user.dart';
import 'package:immich_mobile/shared/providers/db.provider.dart';
import 'package:immich_mobile/shared/services/hash.service.dart';
import 'package:immich_mobile/utils/async_mutex.dart';
import 'package:immich_mobile/utils/builtin_extensions.dart';
import 'package:immich_mobile/extensions/collection_extensions.dart';
import 'package:immich_mobile/utils/diff.dart';
import 'package:isar/isar.dart';
import 'package:logging/logging.dart';

View File

@ -1,8 +1,8 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/backup/models/backup_state.model.dart';
import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
import 'package:immich_mobile/modules/backup/providers/manual_upload.provider.dart';
@ -22,9 +22,8 @@ class ImmichAppBarDialog extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
BackUpState backupState = ref.watch(backupProvider);
final theme = Theme.of(context);
bool isDarkTheme = theme.brightness == Brightness.dark;
bool isHorizontal = MediaQuery.of(context).size.width > 600;
final theme = context.themeData;
bool isHorizontal = !context.isMobile;
final horizontalPadding = isHorizontal ? 100.0 : 20.0;
final user = ref.watch(currentUserProvider);
@ -40,7 +39,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
return Row(
children: [
InkWell(
onTap: () => Navigator.of(context).pop(),
onTap: () => context.pop(),
child: const Icon(
Icons.close,
size: 20,
@ -54,7 +53,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
style: TextStyle(
fontFamily: 'SnowburstOne',
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontSize: 15,
),
),
@ -90,7 +89,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
return buildActionButton(
Icons.settings_rounded,
"profile_drawer_settings",
() => AutoRouter.of(context).push(const SettingsRoute()),
() => context.autoPush(const SettingsRoute()),
);
}
@ -98,7 +97,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
return buildActionButton(
Icons.assignment_outlined,
"profile_drawer_app_logs",
() => AutoRouter.of(context).push(const AppLogRoute()),
() => context.autoPush(const AppLogRoute()),
);
}
@ -121,7 +120,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
ref.watch(backupProvider.notifier).cancelBackup();
ref.watch(assetProvider.notifier).clearAllAsset();
ref.watch(websocketProvider.notifier).disconnect();
AutoRouter.of(context).replace(const LoginRoute());
context.autoReplace(const LoginRoute());
},
);
},
@ -136,8 +135,8 @@ class ImmichAppBarDialog extends HookConsumerWidget {
child: Container(
padding: const EdgeInsets.symmetric(vertical: 4),
decoration: BoxDecoration(
color: isDarkTheme
? Theme.of(context).scaffoldBackgroundColor
color: context.isDarkTheme
? context.scaffoldBackgroundColor
: const Color.fromARGB(255, 225, 229, 240),
),
child: ListTile(
@ -191,7 +190,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
children: [
InkWell(
onTap: () {
Navigator.of(context).pop();
context.pop();
launchUrl(
Uri.parse('https://immich.app'),
mode: LaunchMode.externalApplication,
@ -199,7 +198,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
},
child: Text(
"profile_drawer_documentation",
style: Theme.of(context).textTheme.bodySmall,
style: context.textTheme.bodySmall,
).tr(),
),
const SizedBox(
@ -211,7 +210,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
),
InkWell(
onTap: () {
Navigator.of(context).pop();
context.pop();
launchUrl(
Uri.parse('https://github.com/immich-app/immich'),
mode: LaunchMode.externalApplication,
@ -219,7 +218,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
},
child: Text(
"profile_drawer_github",
style: Theme.of(context).textTheme.bodySmall,
style: context.textTheme.bodySmall,
).tr(),
),
],

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:image_picker/image_picker.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/modules/home/providers/upload_profile_image.provider.dart';
import 'package:immich_mobile/shared/models/store.dart';
import 'package:immich_mobile/shared/ui/user_circle_avatar.dart';
@ -18,7 +19,6 @@ class AppBarProfileInfoBox extends HookConsumerWidget {
AuthenticationState authState = ref.watch(authenticationProvider);
final uploadProfileImageStatus =
ref.watch(uploadProfileImageProvider).status;
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
final user = Store.tryGet(StoreKey.currentUser);
buildUserProfileImage() {
@ -91,8 +91,8 @@ class AppBarProfileInfoBox extends HookConsumerWidget {
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: Theme.of(context).brightness == Brightness.dark
? Theme.of(context).scaffoldBackgroundColor
color: context.isDarkTheme
? context.scaffoldBackgroundColor
: const Color.fromARGB(255, 225, 229, 240),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(10),
@ -111,7 +111,9 @@ class AppBarProfileInfoBox extends HookConsumerWidget {
bottom: -5,
right: -8,
child: Material(
color: isDarkMode ? Colors.blueGrey[800] : Colors.white,
color: context.isDarkTheme
? Colors.blueGrey[800]
: Colors.white,
elevation: 3,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50.0),
@ -120,7 +122,7 @@ class AppBarProfileInfoBox extends HookConsumerWidget {
padding: const EdgeInsets.all(5.0),
child: Icon(
Icons.camera_alt_outlined,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
size: 14,
),
),
@ -132,16 +134,16 @@ class AppBarProfileInfoBox extends HookConsumerWidget {
title: Text(
"${authState.firstName} ${authState.lastName}",
style: TextStyle(
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
subtitle: Text(
authState.userEmail,
style: Theme.of(context).textTheme.labelMedium?.copyWith(
fontSize: 12,
),
style: context.textTheme.labelMedium?.copyWith(
fontSize: 12,
),
),
),
),

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/shared/models/server_info/server_info.model.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:immich_mobile/shared/providers/server_info.provider.dart';
@ -39,8 +40,8 @@ class AppBarServerInfo extends HookConsumerWidget {
padding: const EdgeInsets.only(left: 10.0, right: 10.0, bottom: 10.0),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).brightness == Brightness.dark
? Theme.of(context).scaffoldBackgroundColor
color: context.isDarkTheme
? context.scaffoldBackgroundColor
: const Color.fromARGB(255, 225, 229, 240),
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(10),
@ -61,7 +62,7 @@ class AppBarServerInfo extends HookConsumerWidget {
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 11,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontWeight: FontWeight.w600,
),
),
@ -83,7 +84,7 @@ class AppBarServerInfo extends HookConsumerWidget {
"server_info_box_app_version".tr(),
style: TextStyle(
fontSize: 11,
color: Theme.of(context).textTheme.labelSmall?.color,
color: context.textTheme.labelSmall?.color,
fontWeight: FontWeight.bold,
),
),
@ -97,10 +98,7 @@ class AppBarServerInfo extends HookConsumerWidget {
"${appInfo.value["version"]} build.${appInfo.value["buildNumber"]}",
style: TextStyle(
fontSize: 11,
color: Theme.of(context)
.textTheme
.labelSmall
?.color
color: context.textTheme.labelSmall?.color
?.withOpacity(0.5),
fontWeight: FontWeight.bold,
),
@ -126,7 +124,7 @@ class AppBarServerInfo extends HookConsumerWidget {
"server_info_box_server_version".tr(),
style: TextStyle(
fontSize: 11,
color: Theme.of(context).textTheme.labelSmall?.color,
color: context.textTheme.labelSmall?.color,
fontWeight: FontWeight.bold,
),
),
@ -142,10 +140,7 @@ class AppBarServerInfo extends HookConsumerWidget {
: "?",
style: TextStyle(
fontSize: 11,
color: Theme.of(context)
.textTheme
.labelSmall
?.color
color: context.textTheme.labelSmall?.color
?.withOpacity(0.5),
fontWeight: FontWeight.bold,
),
@ -171,7 +166,7 @@ class AppBarServerInfo extends HookConsumerWidget {
"server_info_box_server_url".tr(),
style: TextStyle(
fontSize: 11,
color: Theme.of(context).textTheme.labelSmall?.color,
color: context.textTheme.labelSmall?.color,
fontWeight: FontWeight.bold,
),
),
@ -185,14 +180,12 @@ class AppBarServerInfo extends HookConsumerWidget {
child: Tooltip(
verticalOffset: 0,
decoration: BoxDecoration(
color:
Theme.of(context).primaryColor.withOpacity(0.9),
color: context.primaryColor.withOpacity(0.9),
borderRadius: BorderRadius.circular(10),
),
textStyle: TextStyle(
color: Theme.of(context).brightness == Brightness.dark
? Colors.black
: Colors.white,
color:
context.isDarkTheme ? Colors.black : Colors.white,
fontWeight: FontWeight.bold,
),
message: getServerUrl() ?? '--',
@ -202,10 +195,7 @@ class AppBarServerInfo extends HookConsumerWidget {
getServerUrl() ?? '--',
style: TextStyle(
fontSize: 11,
color: Theme.of(context)
.textTheme
.labelSmall
?.color
color: context.textTheme.labelSmall?.color
?.withOpacity(0.5),
fontWeight: FontWeight.bold,
overflow: TextOverflow.ellipsis,

View File

@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
class ConfirmDialog extends ConsumerWidget {
final Function onOk;
@ -26,11 +27,11 @@ class ConfirmDialog extends ConsumerWidget {
content: Text(content).tr(),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(false),
onPressed: () => context.pop(false),
child: Text(
cancel,
style: TextStyle(
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontWeight: FontWeight.bold,
),
).tr(),
@ -38,7 +39,7 @@ class ConfirmDialog extends ConsumerWidget {
TextButton(
onPressed: () {
onOk();
Navigator.of(context).pop(true);
context.pop(true);
},
child: Text(
ok,

View File

@ -1,6 +1,6 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/shared/models/store.dart';
import 'package:immich_mobile/shared/ui/app_bar_dialog/app_bar_dialog.dart';
import 'package:immich_mobile/shared/ui/user_circle_avatar.dart';
@ -28,7 +28,7 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
final ServerInfo serverInfoState = ref.watch(serverInfoProvider);
AuthenticationState authState = ref.watch(authenticationProvider);
final user = Store.tryGet(StoreKey.currentUser);
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
final isDarkTheme = context.isDarkTheme;
const widgetSize = 30.0;
buildProfileIndicator() {
@ -70,7 +70,7 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
}
getBackupBadgeIcon() {
final iconColor = isDarkMode ? Colors.white : Colors.black;
final iconColor = isDarkTheme ? Colors.white : Colors.black;
if (isEnableAutoBackup) {
if (backupState.backupProgress == BackUpProgressEnum.inProgress) {
@ -104,10 +104,10 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
buildBackupIndicator() {
final indicatorIcon = getBackupBadgeIcon();
final badgeBackground = isDarkMode ? Colors.blueGrey[800] : Colors.white;
final badgeBackground = isDarkTheme ? Colors.blueGrey[800] : Colors.white;
return InkWell(
onTap: () => AutoRouter.of(context).push(const BackupControllerRoute()),
onTap: () => context.autoPush(const BackupControllerRoute()),
borderRadius: BorderRadius.circular(12),
child: Badge(
label: Container(
@ -116,7 +116,7 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
decoration: BoxDecoration(
color: badgeBackground,
border: Border.all(
color: isDarkMode ? Colors.black : Colors.grey,
color: isDarkTheme ? Colors.black : Colors.grey,
),
borderRadius: BorderRadius.circular(widgetSize / 2),
),
@ -129,14 +129,14 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget {
child: Icon(
Icons.backup_rounded,
size: widgetSize,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
),
);
}
return AppBar(
backgroundColor: Theme.of(context).appBarTheme.backgroundColor,
backgroundColor: context.themeData.appBarTheme.backgroundColor,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(5),

View File

@ -2,6 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/models/store.dart';
import 'package:immich_mobile/utils/image_url_builder.dart';
@ -86,7 +87,7 @@ class ImmichImage extends StatelessWidget {
}
return Icon(
Icons.image_not_supported_outlined,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
);
},
);
@ -137,7 +138,7 @@ class ImmichImage extends StatelessWidget {
}
return Icon(
Icons.image_not_supported_outlined,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
);
},
);

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
class ImmichLoadingIndicator extends StatelessWidget {
final double? borderRadius;
@ -14,7 +15,7 @@ class ImmichLoadingIndicator extends StatelessWidget {
height: 60,
width: 60,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor.withAlpha(200),
color: context.primaryColor.withAlpha(200),
borderRadius: BorderRadius.circular(borderRadius ?? 10),
),
padding: const EdgeInsets.all(15),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
class ImmichTitleText extends StatelessWidget {
final double fontSize;
@ -18,9 +19,8 @@ class ImmichTitleText extends StatelessWidget {
fontFamily: 'SnowburstOne',
fontWeight: FontWeight.bold,
fontSize: fontSize,
color: color ?? Theme.of(context).primaryColor,
color: color ?? context.primaryColor,
),
);
}
}

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
enum ToastType { info, success, error }
@ -11,14 +12,13 @@ class ImmichToast {
ToastGravity gravity = ToastGravity.TOP,
int durationInSecond = 3,
}) {
final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
final fToast = FToast();
fToast.init(context);
Color getColor(ToastType type, BuildContext context) {
switch (type) {
case ToastType.info:
return Theme.of(context).primaryColor;
return context.primaryColor;
case ToastType.success:
return const Color.fromARGB(255, 78, 140, 124);
case ToastType.error:
@ -31,7 +31,7 @@ class ImmichToast {
case ToastType.info:
return Icon(
Icons.info_outline_rounded,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
);
case ToastType.success:
return const Icon(
@ -51,7 +51,7 @@ class ImmichToast {
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: isDarkTheme ? Colors.grey[900] : Colors.grey[50],
color: context.isDarkTheme ? Colors.grey[900] : Colors.grey[50],
border: Border.all(
color: Colors.black12,
width: 1,

View File

@ -1,5 +1,6 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/shared/models/store.dart';
import 'package:immich_mobile/shared/models/user.dart';
@ -10,7 +11,7 @@ Widget userAvatar(BuildContext context, User u, {double? radius}) {
final lastNameFirstLetter = u.lastName.isNotEmpty ? u.lastName[0] : "";
return CircleAvatar(
radius: radius,
backgroundColor: Theme.of(context).primaryColor.withAlpha(50),
backgroundColor: context.primaryColor.withAlpha(50),
foregroundImage: CachedNetworkImageProvider(
url,
headers: {"Authorization": "Bearer ${Store.get(StoreKey.accessToken)}"},

View File

@ -3,6 +3,7 @@ import 'dart:math';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/shared/models/store.dart';
import 'package:immich_mobile/shared/models/user.dart';
import 'package:immich_mobile/shared/ui/transparent_image.dart';
@ -45,15 +46,13 @@ class UserCircleAvatar extends ConsumerWidget {
user.firstName[0].toUpperCase(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).brightness == Brightness.dark
? Colors.black
: Colors.white,
color: context.isDarkTheme ? Colors.black : Colors.white,
),
);
return CircleAvatar(
backgroundColor: useRandomBackgroundColor
? randomColors[Random().nextInt(randomColors.length)]
: Theme.of(context).primaryColor,
: context.primaryColor,
radius: radius,
child: user.profileImagePath == ""
? textIcon

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/shared/models/logger_message.model.dart';
import 'package:flutter/services.dart';
@ -10,7 +11,7 @@ class AppLogDetailPage extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
var isDarkTheme = context.isDarkTheme;
buildStackMessage(String stackTrace) {
return Padding(
@ -28,7 +29,7 @@ class AppLogDetailPage extends HookConsumerWidget {
"STACK TRACES",
style: TextStyle(
fontSize: 12.0,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontWeight: FontWeight.bold,
),
),
@ -45,14 +46,14 @@ class AppLogDetailPage extends HookConsumerWidget {
icon: Icon(
Icons.copy,
size: 16.0,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
),
],
),
Container(
decoration: BoxDecoration(
color: isDarkMode ? Colors.grey[900] : Colors.grey[200],
color: isDarkTheme ? Colors.grey[900] : Colors.grey[200],
borderRadius: BorderRadius.circular(15.0),
),
child: Padding(
@ -88,7 +89,7 @@ class AppLogDetailPage extends HookConsumerWidget {
"MESSAGE",
style: TextStyle(
fontSize: 12.0,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontWeight: FontWeight.bold,
),
),
@ -104,14 +105,14 @@ class AppLogDetailPage extends HookConsumerWidget {
icon: Icon(
Icons.copy,
size: 16.0,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
),
),
],
),
Container(
decoration: BoxDecoration(
color: isDarkMode ? Colors.grey[900] : Colors.grey[200],
color: isDarkTheme ? Colors.grey[900] : Colors.grey[200],
borderRadius: BorderRadius.circular(15.0),
),
child: Padding(
@ -143,14 +144,14 @@ class AppLogDetailPage extends HookConsumerWidget {
"FROM",
style: TextStyle(
fontSize: 12.0,
color: Theme.of(context).primaryColor,
color: context.primaryColor,
fontWeight: FontWeight.bold,
),
),
),
Container(
decoration: BoxDecoration(
color: isDarkMode ? Colors.grey[900] : Colors.grey[200],
color: isDarkTheme ? Colors.grey[900] : Colors.grey[200],
borderRadius: BorderRadius.circular(15.0),
),
child: Padding(

Some files were not shown because too many files have changed in this diff Show More