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:
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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(),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)}"},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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/routing/router.dart';
|
||||
import 'package:immich_mobile/shared/models/logger_message.model.dart';
|
||||
import 'package:immich_mobile/shared/services/immich_logger.service.dart';
|
||||
@@ -16,6 +16,7 @@ class AppLogPage extends HookConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final immichLogger = ImmichLogger();
|
||||
final logMessages = useState(immichLogger.messages);
|
||||
final isDarkTheme = context.isDarkTheme;
|
||||
|
||||
Widget colorStatusIndicator(Color color) {
|
||||
return Column(
|
||||
@@ -36,7 +37,7 @@ class AppLogPage extends HookConsumerWidget {
|
||||
Widget buildLeadingIcon(LogLevel level) {
|
||||
switch (level) {
|
||||
case LogLevel.INFO:
|
||||
return colorStatusIndicator(Theme.of(context).primaryColor);
|
||||
return colorStatusIndicator(context.primaryColor);
|
||||
case LogLevel.SEVERE:
|
||||
return colorStatusIndicator(Colors.redAccent);
|
||||
|
||||
@@ -52,15 +53,15 @@ class AppLogPage extends HookConsumerWidget {
|
||||
case LogLevel.INFO:
|
||||
return Colors.transparent;
|
||||
case LogLevel.SEVERE:
|
||||
return Theme.of(context).brightness == Brightness.dark
|
||||
return isDarkTheme
|
||||
? Colors.redAccent.withOpacity(0.25)
|
||||
: Colors.redAccent.withOpacity(0.075);
|
||||
case LogLevel.WARNING:
|
||||
return Theme.of(context).brightness == Brightness.dark
|
||||
return isDarkTheme
|
||||
? Colors.orangeAccent.withOpacity(0.25)
|
||||
: Colors.orangeAccent.withOpacity(0.075);
|
||||
default:
|
||||
return Theme.of(context).primaryColor.withOpacity(0.1);
|
||||
return context.primaryColor.withOpacity(0.1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +80,7 @@ class AppLogPage extends HookConsumerWidget {
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.delete_outline_rounded,
|
||||
color: Theme.of(context).primaryColor,
|
||||
color: context.primaryColor,
|
||||
semanticLabel: "Clear logs",
|
||||
size: 20.0,
|
||||
),
|
||||
@@ -91,7 +92,7 @@ class AppLogPage extends HookConsumerWidget {
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.share_rounded,
|
||||
color: Theme.of(context).primaryColor,
|
||||
color: context.primaryColor,
|
||||
semanticLabel: "Share logs",
|
||||
size: 20.0,
|
||||
),
|
||||
@@ -102,7 +103,7 @@ class AppLogPage extends HookConsumerWidget {
|
||||
],
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
AutoRouter.of(context).pop();
|
||||
context.autoPop();
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.arrow_back_ios_new_rounded,
|
||||
@@ -115,16 +116,14 @@ class AppLogPage extends HookConsumerWidget {
|
||||
separatorBuilder: (context, index) {
|
||||
return Divider(
|
||||
height: 0,
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white70
|
||||
: Colors.grey[600],
|
||||
color: isDarkTheme ? Colors.white70 : Colors.grey[600],
|
||||
);
|
||||
},
|
||||
itemCount: logMessages.value.length,
|
||||
itemBuilder: (context, index) {
|
||||
var logMessage = logMessages.value[index];
|
||||
return ListTile(
|
||||
onTap: () => AutoRouter.of(context).push(
|
||||
onTap: () => context.autoPush(
|
||||
AppLogDetailRoute(
|
||||
logMessage: logMessage,
|
||||
),
|
||||
@@ -140,9 +139,7 @@ class AppLogPage extends HookConsumerWidget {
|
||||
TextSpan(
|
||||
text: "#$index ",
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white70
|
||||
: Colors.grey[600],
|
||||
color: isDarkTheme ? Colors.white70 : Colors.grey[600],
|
||||
fontSize: 14.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
@@ -170,7 +167,7 @@ class AppLogPage extends HookConsumerWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/// Truncate the log message to a certain number of lines
|
||||
/// @param int maxLines - Max number of lines to truncate
|
||||
String truncateLogMessage(String message, int maxLines) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:auto_route/auto_route.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/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';
|
||||
@@ -51,7 +51,7 @@ class SplashScreenPage extends HookConsumerWidget {
|
||||
// If the device is offline and there is a currentUser stored locallly
|
||||
// Proceed into the app
|
||||
if (deviceIsOffline && Store.tryGet(StoreKey.currentUser) != null) {
|
||||
AutoRouter.of(context).replace(const TabControllerRoute());
|
||||
context.autoReplace(const TabControllerRoute());
|
||||
} else if (isSuccess) {
|
||||
// If device was able to login through the internet successfully
|
||||
final hasPermission =
|
||||
@@ -60,10 +60,10 @@ class SplashScreenPage extends HookConsumerWidget {
|
||||
// Resume backup (if enable) then navigate
|
||||
ref.watch(backupProvider.notifier).resumeBackup();
|
||||
}
|
||||
AutoRouter.of(context).replace(const TabControllerRoute());
|
||||
context.autoReplace(const TabControllerRoute());
|
||||
} else {
|
||||
// User was unable to login through either offline or online methods
|
||||
AutoRouter.of(context).replace(const LoginRoute());
|
||||
context.autoReplace(const LoginRoute());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ class SplashScreenPage extends HookConsumerWidget {
|
||||
if (serverUrl != null && accessToken != null) {
|
||||
performLoggingIn();
|
||||
} else {
|
||||
AutoRouter.of(context).replace(const LoginRoute());
|
||||
context.autoReplace(const LoginRoute());
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.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/asset_viewer/providers/scroll_notifier.provider.dart';
|
||||
import 'package:immich_mobile/modules/home/providers/multiselect.provider.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
@@ -31,7 +32,7 @@ class TabControllerPage extends HookConsumerWidget {
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
Theme.of(context).primaryColor,
|
||||
context.primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -55,10 +56,10 @@ class TabControllerPage extends HookConsumerWidget {
|
||||
ref.read(tabProvider.notifier).state = TabEnum.values[index];
|
||||
},
|
||||
selectedIconTheme: IconThemeData(
|
||||
color: Theme.of(context).primaryColor,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
selectedLabelTextStyle: TextStyle(
|
||||
color: Theme.of(context).primaryColor,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
useIndicator: false,
|
||||
destinations: [
|
||||
@@ -116,7 +117,7 @@ class TabControllerPage extends HookConsumerWidget {
|
||||
selectedIcon: buildIcon(
|
||||
Icon(
|
||||
Icons.photo_library,
|
||||
color: Theme.of(context).primaryColor,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -127,7 +128,7 @@ class TabControllerPage extends HookConsumerWidget {
|
||||
),
|
||||
selectedIcon: Icon(
|
||||
Icons.search,
|
||||
color: Theme.of(context).primaryColor,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
),
|
||||
NavigationDestination(
|
||||
@@ -137,7 +138,7 @@ class TabControllerPage extends HookConsumerWidget {
|
||||
),
|
||||
selectedIcon: Icon(
|
||||
Icons.group,
|
||||
color: Theme.of(context).primaryColor,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
),
|
||||
NavigationDestination(
|
||||
@@ -148,7 +149,7 @@ class TabControllerPage extends HookConsumerWidget {
|
||||
selectedIcon: buildIcon(
|
||||
Icon(
|
||||
Icons.photo_album_rounded,
|
||||
color: Theme.of(context).primaryColor,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user