diff --git a/mobile/ios/Podfile.lock b/mobile/ios/Podfile.lock index f1d5b2169bceb..4a2e3fe1e26d6 100644 --- a/mobile/ios/Podfile.lock +++ b/mobile/ios/Podfile.lock @@ -1,4 +1,7 @@ PODS: + - connectivity_plus (0.0.1): + - Flutter + - ReachabilitySwift - device_info_plus (0.0.1): - Flutter - Flutter (1.0.0) @@ -33,6 +36,7 @@ PODS: - photo_manager (2.0.0): - Flutter - FlutterMacOS + - ReachabilitySwift (5.0.0) - SAMKeychain (1.5.3) - share_plus (0.0.1): - Flutter @@ -51,6 +55,7 @@ PODS: - Flutter DEPENDENCIES: + - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - Flutter (from `Flutter`) - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) @@ -75,10 +80,13 @@ DEPENDENCIES: SPEC REPOS: trunk: - FMDB + - ReachabilitySwift - SAMKeychain - Toast EXTERNAL SOURCES: + connectivity_plus: + :path: ".symlinks/plugins/connectivity_plus/ios" device_info_plus: :path: ".symlinks/plugins/device_info_plus/ios" Flutter: @@ -121,6 +129,7 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/wakelock/ios" SPEC CHECKSUMS: + connectivity_plus: 07c49e96d7fc92bc9920617b83238c4d178b446a device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef @@ -136,6 +145,7 @@ SPEC CHECKSUMS: path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce photo_manager: 4f6810b7dfc4feb03b461ac1a70dacf91fba7604 + ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c diff --git a/mobile/lib/modules/album/views/sharing_page.dart b/mobile/lib/modules/album/views/sharing_page.dart index b2025ef864988..b87cbdb06a0f8 100644 --- a/mobile/lib/modules/album/views/sharing_page.dart +++ b/mobile/lib/modules/album/views/sharing_page.dart @@ -236,7 +236,7 @@ class SharingPage extends HookConsumerWidget { SliverToBoxAdapter(child: buildTopBottons()), if (partner.isNotEmpty) SliverPadding( - padding: const EdgeInsets.only(left: 12, right: 12, bottom: 4), + padding: const EdgeInsets.all(12), sliver: SliverToBoxAdapter( child: const Text( "partner_page_title", @@ -246,11 +246,7 @@ class SharingPage extends HookConsumerWidget { ), if (partner.isNotEmpty) PartnerList(partner: partner), SliverPadding( - padding: EdgeInsets.only( - left: 12, - right: 12, - top: partner.isEmpty ? 0 : 16, - ), + padding: const EdgeInsets.all(12), sliver: SliverToBoxAdapter( child: const Text( "sharing_page_album", diff --git a/mobile/lib/modules/home/ui/asset_grid/group_divider_title.dart b/mobile/lib/modules/home/ui/asset_grid/group_divider_title.dart index 97c1b45549e15..6d9b293dff1db 100644 --- a/mobile/lib/modules/home/ui/asset_grid/group_divider_title.dart +++ b/mobile/lib/modules/home/ui/asset_grid/group_divider_title.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; class GroupDividerTitle extends ConsumerWidget { @@ -20,6 +21,7 @@ class GroupDividerTitle extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { void handleTitleIconClick() { + HapticFeedback.heavyImpact(); if (selected) { onDeselect(); } else { @@ -30,7 +32,7 @@ class GroupDividerTitle extends ConsumerWidget { return Padding( padding: const EdgeInsets.only( top: 12.0, - bottom: 4.0, + bottom: 16.0, left: 12.0, right: 12.0, ), diff --git a/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid_view.dart b/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid_view.dart index 2686afeac23cf..30a7de6691b3b 100644 --- a/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid_view.dart +++ b/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid_view.dart @@ -19,6 +19,45 @@ typedef ImmichAssetGridSelectionListener = void Function( Set, ); +class ImmichAssetGridView extends StatefulWidget { + final RenderList renderList; + final int assetsPerRow; + final double margin; + final bool showStorageIndicator; + final ImmichAssetGridSelectionListener? listener; + final bool selectionActive; + final Future Function()? onRefresh; + final Set? preselectedAssets; + final bool canDeselect; + final bool dynamicLayout; + final bool showMultiSelectIndicator; + final void Function(ItemPosition start, ItemPosition end)? + visibleItemsListener; + final Widget? topWidget; + + const ImmichAssetGridView({ + super.key, + required this.renderList, + required this.assetsPerRow, + required this.showStorageIndicator, + this.listener, + this.margin = 5.0, + this.selectionActive = false, + this.onRefresh, + this.preselectedAssets, + this.canDeselect = true, + this.dynamicLayout = true, + this.showMultiSelectIndicator = true, + this.visibleItemsListener, + this.topWidget, + }); + + @override + State createState() { + return ImmichAssetGridViewState(); + } +} + class ImmichAssetGridViewState extends State { final ItemScrollController _itemScrollController = ItemScrollController(); final ItemPositionsListener _itemPositionsListener = @@ -383,42 +422,3 @@ class ImmichAssetGridViewState extends State { ); } } - -class ImmichAssetGridView extends StatefulWidget { - final RenderList renderList; - final int assetsPerRow; - final double margin; - final bool showStorageIndicator; - final ImmichAssetGridSelectionListener? listener; - final bool selectionActive; - final Future Function()? onRefresh; - final Set? preselectedAssets; - final bool canDeselect; - final bool dynamicLayout; - final bool showMultiSelectIndicator; - final void Function(ItemPosition start, ItemPosition end)? - visibleItemsListener; - final Widget? topWidget; - - const ImmichAssetGridView({ - super.key, - required this.renderList, - required this.assetsPerRow, - required this.showStorageIndicator, - this.listener, - this.margin = 5.0, - this.selectionActive = false, - this.onRefresh, - this.preselectedAssets, - this.canDeselect = true, - this.dynamicLayout = true, - this.showMultiSelectIndicator = true, - this.visibleItemsListener, - this.topWidget, - }); - - @override - State createState() { - return ImmichAssetGridViewState(); - } -} diff --git a/mobile/lib/modules/home/ui/home_page_app_bar.dart b/mobile/lib/modules/home/ui/home_page_app_bar.dart index d8091a050ba62..cff37b0bb1a74 100644 --- a/mobile/lib/modules/home/ui/home_page_app_bar.dart +++ b/mobile/lib/modules/home/ui/home_page_app_bar.dart @@ -71,8 +71,8 @@ class HomePageAppBar extends ConsumerWidget implements PreferredSizeWidget { ), if (serverInfoState.isVersionMismatch) Positioned( - bottom: 12, - right: 12, + bottom: 4, + right: 6, child: GestureDetector( onTap: () => Scaffold.of(context).openDrawer(), child: Material( diff --git a/mobile/lib/modules/memories/ui/memory_lane.dart b/mobile/lib/modules/memories/ui/memory_lane.dart index ffad6d5e183ed..f3405aaa25370 100644 --- a/mobile/lib/modules/memories/ui/memory_lane.dart +++ b/mobile/lib/modules/memories/ui/memory_lane.dart @@ -1,9 +1,11 @@ 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/modules/memories/providers/memory.provider.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/shared/ui/immich_image.dart'; +import 'package:openapi/api.dart'; class MemoryLane extends HookConsumerWidget { const MemoryLane({super.key}); @@ -27,6 +29,7 @@ class MemoryLane extends HookConsumerWidget { padding: const EdgeInsets.only(right: 8.0, bottom: 8), child: GestureDetector( onTap: () { + HapticFeedback.heavyImpact(); AutoRouter.of(context).push( VerticalRouteView( memories: memories, @@ -53,6 +56,7 @@ class MemoryLane extends HookConsumerWidget { width: 130, height: 200, useGrayBoxPlaceholder: true, + type: ThumbnailFormat.JPEG, ), ), ), @@ -66,7 +70,7 @@ class MemoryLane extends HookConsumerWidget { child: Text( memory.title, style: const TextStyle( - fontWeight: FontWeight.w500, + fontWeight: FontWeight.bold, color: Colors.white, fontSize: 14, ), diff --git a/mobile/lib/modules/partner/ui/partner_list.dart b/mobile/lib/modules/partner/ui/partner_list.dart index 92bfcd15fa082..64db045b15691 100644 --- a/mobile/lib/modules/partner/ui/partner_list.dart +++ b/mobile/lib/modules/partner/ui/partner_list.dart @@ -23,7 +23,14 @@ class PartnerList extends HookConsumerWidget { return ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 12.0), leading: userAvatar(context, p, radius: 30), - title: Text("${p.firstName} ${p.lastName}"), + title: Text( + "${p.firstName} ${p.lastName}'s photos", + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + color: Theme.of(context).primaryColor, + ), + ), onTap: () => AutoRouter.of(context).push(PartnerDetailRoute(partner: p)), ); } diff --git a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_layout_settings.dart b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_layout_settings.dart index e37874335572d..8ff719da3341a 100644 --- a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_layout_settings.dart +++ b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_layout_settings.dart @@ -51,31 +51,34 @@ class LayoutSettings extends HookConsumerWidget { children: [ SwitchListTile.adaptive( activeColor: Theme.of(context).primaryColor, - title: const Text( + title: Text( "asset_list_layout_settings_dynamic_layout_title", - style: TextStyle( - fontSize: 12, - ), + style: Theme.of(context) + .textTheme + .labelLarge + ?.copyWith(fontWeight: FontWeight.bold), ).tr(), onChanged: switchChanged, value: useDynamicLayout.value, ), + const Divider( + indent: 18, + endIndent: 18, + ), ListTile( title: const Text( "asset_list_layout_settings_group_by", style: TextStyle( - fontSize: 12, + fontSize: 16, fontWeight: FontWeight.bold, ), ).tr(), ), RadioListTile( activeColor: Theme.of(context).primaryColor, - title: const Text( + title: Text( "asset_list_layout_settings_group_by_month_day", - style: TextStyle( - fontSize: 12, - ), + style: Theme.of(context).textTheme.labelLarge, ).tr(), value: GroupAssetsBy.day, groupValue: groupBy.value, @@ -84,11 +87,9 @@ class LayoutSettings extends HookConsumerWidget { ), RadioListTile( activeColor: Theme.of(context).primaryColor, - title: const Text( + title: Text( "asset_list_layout_settings_group_by_month", - style: TextStyle( - fontSize: 12, - ), + style: Theme.of(context).textTheme.labelLarge, ).tr(), value: GroupAssetsBy.month, groupValue: groupBy.value, @@ -97,11 +98,9 @@ class LayoutSettings extends HookConsumerWidget { ), RadioListTile( activeColor: Theme.of(context).primaryColor, - title: const Text( + title: Text( "asset_list_layout_settings_group_automatically", - style: TextStyle( - fontSize: 12, - ), + style: Theme.of(context).textTheme.labelLarge, ).tr(), value: GroupAssetsBy.auto, groupValue: groupBy.value, diff --git a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_storage_indicator.dart b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_storage_indicator.dart index 376ed357658e1..ae0e02148284e 100644 --- a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_storage_indicator.dart +++ b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_storage_indicator.dart @@ -34,11 +34,12 @@ class StorageIndicator extends HookConsumerWidget { return SwitchListTile.adaptive( activeColor: Theme.of(context).primaryColor, - title: const Text( + title: Text( "theme_setting_asset_list_storage_indicator_title", - style: TextStyle( - fontSize: 12, - ), + style: Theme.of(context) + .textTheme + .labelLarge + ?.copyWith(fontWeight: FontWeight.bold), ).tr(), onChanged: switchChanged, value: showStorageIndicator.value, diff --git a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_tiles_per_row.dart b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_tiles_per_row.dart index eeb0f6c01989d..89ac79133a43d 100644 --- a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_tiles_per_row.dart +++ b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_tiles_per_row.dart @@ -39,7 +39,7 @@ class TilesPerRow extends HookConsumerWidget { title: const Text( "theme_setting_asset_list_tiles_per_row_title", style: TextStyle( - fontSize: 12, + fontSize: 14, fontWeight: FontWeight.bold, ), ).tr(args: ["${itemsValue.value.toInt()}"]), diff --git a/mobile/lib/modules/settings/ui/settings_switch_list_tile.dart b/mobile/lib/modules/settings/ui/settings_switch_list_tile.dart index fce440732700f..003d94c3f41ff 100644 --- a/mobile/lib/modules/settings/ui/settings_switch_list_tile.dart +++ b/mobile/lib/modules/settings/ui/settings_switch_list_tile.dart @@ -22,15 +22,21 @@ class SettingsSwitchListTile extends StatelessWidget { Widget build(BuildContext context) { return SwitchListTile.adaptive( value: valueNotifier.value, - onChanged: !enabled ? null : (value) { - valueNotifier.value = value; - appSettingService.setSetting(settingsEnum, value); - }, - activeColor: Theme - .of(context) - .primaryColor, + onChanged: !enabled + ? null + : (value) { + valueNotifier.value = value; + appSettingService.setSetting(settingsEnum, value); + }, + activeColor: Theme.of(context).primaryColor, dense: true, - title: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)), + title: Text( + title, + style: Theme.of(context) + .textTheme + .labelLarge + ?.copyWith(fontWeight: FontWeight.bold), + ), subtitle: subtitle != null ? Text(subtitle!) : null, ); } diff --git a/mobile/lib/modules/settings/ui/theme_setting/theme_setting.dart b/mobile/lib/modules/settings/ui/theme_setting/theme_setting.dart index 1e6348e42c82b..2e3b7134cc5e9 100644 --- a/mobile/lib/modules/settings/ui/theme_setting/theme_setting.dart +++ b/mobile/lib/modules/settings/ui/theme_setting/theme_setting.dart @@ -40,12 +40,12 @@ class ThemeSetting extends HookConsumerWidget { children: [ SwitchListTile.adaptive( activeColor: Theme.of(context).primaryColor, - title: const Text( + title: Text( 'theme_setting_system_theme_switch', - style: TextStyle( - fontSize: 12.0, - fontWeight: FontWeight.bold, - ), + style: Theme.of(context) + .textTheme + .labelLarge + ?.copyWith(fontWeight: FontWeight.bold), ).tr(), value: currentTheme.value == ThemeMode.system, onChanged: (bool isSystem) { @@ -78,12 +78,12 @@ class ThemeSetting extends HookConsumerWidget { if (currentTheme.value != ThemeMode.system) SwitchListTile.adaptive( activeColor: Theme.of(context).primaryColor, - title: const Text( + title: Text( 'theme_setting_dark_mode_switch', - style: TextStyle( - fontSize: 12.0, - fontWeight: FontWeight.bold, - ), + style: Theme.of(context) + .textTheme + .labelLarge + ?.copyWith(fontWeight: FontWeight.bold), ).tr(), value: ref.watch(immichThemeProvider) == ThemeMode.dark, onChanged: (bool isDark) { diff --git a/mobile/lib/shared/ui/immich_image.dart b/mobile/lib/shared/ui/immich_image.dart index f17bb3b3ff3d9..3259f58bc0d67 100644 --- a/mobile/lib/shared/ui/immich_image.dart +++ b/mobile/lib/shared/ui/immich_image.dart @@ -92,7 +92,7 @@ class ImmichImage extends StatelessWidget { return CachedNetworkImage( imageUrl: thumbnailRequestUrl, httpHeaders: {"Authorization": "Bearer $token"}, - cacheKey: getThumbnailCacheKey(asset), + cacheKey: getThumbnailCacheKey(asset, type: type), width: width, height: height, // keeping memCacheWidth, memCacheHeight, maxWidthDiskCache and