mirror of
https://github.com/immich-app/immich.git
synced 2025-12-05 20:40:29 -08:00
chore: optimisation of several UI components of the mobile app (#24098)
* fix(mobile): normalize scrolling behavior in networking settings Remove ClampingScrollPhysics from networking settings page to match the scrolling behavior of other settings pages. This restores the standard iOS bounce/elastic scrolling effect. * fix(mobile): use consistent native transitions for Library pages Change Trash, Shared Links, and Folders routes from CustomRoute to AutoRoute to enable native iOS transitions with swipe-back gesture support. * fix(mobile): remove SafeArea wrapper and ClampingScrollPhysics from Settings Remove SafeArea wrapper (Scaffold handles safe areas automatically) and ClampingScrollPhysics to enable native iOS bounce scrolling. * fix(mobile): remove bottom white space in Sync Status page Replace Padding wrapper with ListView padding to match other Settings pages and eliminate bottom white space. * chore: fix Dart formatting Run dart format to fix formatting issues in settings.page.dart and sync_status_and_actions.dart * Format Dart files --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: kao-byte <benjaminliu@MacBook-Air.local>
This commit is contained in:
@@ -58,7 +58,7 @@ class SettingsPage extends StatelessWidget {
|
|||||||
context.locale;
|
context.locale;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(centerTitle: false, title: const Text('settings').tr()),
|
appBar: AppBar(centerTitle: false, title: const Text('settings').tr()),
|
||||||
body: context.isMobile ? const SafeArea(child: _MobileLayout()) : const SafeArea(child: _TabletLayout()),
|
body: context.isMobile ? const _MobileLayout() : const _TabletLayout(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,11 +89,7 @@ class _MobileLayout extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
.toList();
|
.toList();
|
||||||
return ListView(
|
return ListView(padding: const EdgeInsets.only(top: 10.0, bottom: 16), children: [...settings]);
|
||||||
physics: const ClampingScrollPhysics(),
|
|
||||||
padding: const EdgeInsets.only(top: 10.0, bottom: 16),
|
|
||||||
children: [...settings],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -245,23 +245,15 @@ class AppRouter extends RootStackRouter {
|
|||||||
guards: [_authGuard, _duplicateGuard],
|
guards: [_authGuard, _duplicateGuard],
|
||||||
transitionsBuilder: TransitionsBuilders.slideLeft,
|
transitionsBuilder: TransitionsBuilders.slideLeft,
|
||||||
),
|
),
|
||||||
CustomRoute(page: FolderRoute.page, guards: [_authGuard], transitionsBuilder: TransitionsBuilders.fadeIn),
|
AutoRoute(page: FolderRoute.page, guards: [_authGuard]),
|
||||||
AutoRoute(page: PartnerDetailRoute.page, guards: [_authGuard, _duplicateGuard]),
|
AutoRoute(page: PartnerDetailRoute.page, guards: [_authGuard, _duplicateGuard]),
|
||||||
AutoRoute(page: PersonResultRoute.page, guards: [_authGuard, _duplicateGuard]),
|
AutoRoute(page: PersonResultRoute.page, guards: [_authGuard, _duplicateGuard]),
|
||||||
AutoRoute(page: AllPeopleRoute.page, guards: [_authGuard, _duplicateGuard]),
|
AutoRoute(page: AllPeopleRoute.page, guards: [_authGuard, _duplicateGuard]),
|
||||||
AutoRoute(page: MemoryRoute.page, guards: [_authGuard, _duplicateGuard]),
|
AutoRoute(page: MemoryRoute.page, guards: [_authGuard, _duplicateGuard]),
|
||||||
AutoRoute(page: MapRoute.page, guards: [_authGuard, _duplicateGuard]),
|
AutoRoute(page: MapRoute.page, guards: [_authGuard, _duplicateGuard]),
|
||||||
AutoRoute(page: AlbumOptionsRoute.page, guards: [_authGuard, _duplicateGuard]),
|
AutoRoute(page: AlbumOptionsRoute.page, guards: [_authGuard, _duplicateGuard]),
|
||||||
CustomRoute(
|
AutoRoute(page: TrashRoute.page, guards: [_authGuard, _duplicateGuard]),
|
||||||
page: TrashRoute.page,
|
AutoRoute(page: SharedLinkRoute.page, guards: [_authGuard, _duplicateGuard]),
|
||||||
guards: [_authGuard, _duplicateGuard],
|
|
||||||
transitionsBuilder: TransitionsBuilders.slideLeft,
|
|
||||||
),
|
|
||||||
CustomRoute(
|
|
||||||
page: SharedLinkRoute.page,
|
|
||||||
guards: [_authGuard, _duplicateGuard],
|
|
||||||
transitionsBuilder: TransitionsBuilders.slideLeft,
|
|
||||||
),
|
|
||||||
AutoRoute(page: SharedLinkEditRoute.page, guards: [_authGuard, _duplicateGuard]),
|
AutoRoute(page: SharedLinkEditRoute.page, guards: [_authGuard, _duplicateGuard]),
|
||||||
CustomRoute(
|
CustomRoute(
|
||||||
page: ActivitiesRoute.page,
|
page: ActivitiesRoute.page,
|
||||||
|
|||||||
@@ -108,82 +108,80 @@ class SyncStatusAndActions extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Padding(
|
return ListView(
|
||||||
padding: const EdgeInsets.only(top: 16, bottom: 32),
|
padding: const EdgeInsets.only(top: 16, bottom: 96),
|
||||||
child: ListView(
|
children: [
|
||||||
children: [
|
const _SyncStatsCounts(),
|
||||||
const _SyncStatsCounts(),
|
const Divider(height: 1, indent: 16, endIndent: 16),
|
||||||
const Divider(height: 1, indent: 16, endIndent: 16),
|
const SizedBox(height: 24),
|
||||||
const SizedBox(height: 24),
|
_SectionHeaderText(text: "jobs".t(context: context)),
|
||||||
_SectionHeaderText(text: "jobs".t(context: context)),
|
ListTile(
|
||||||
ListTile(
|
title: Text(
|
||||||
title: Text(
|
"sync_local".t(context: context),
|
||||||
"sync_local".t(context: context),
|
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
|
||||||
),
|
|
||||||
subtitle: Text("tap_to_run_job".t(context: context)),
|
|
||||||
leading: const Icon(Icons.sync),
|
|
||||||
trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).localSyncStatus),
|
|
||||||
onTap: () {
|
|
||||||
ref.read(backgroundSyncProvider).syncLocal(full: true);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
ListTile(
|
subtitle: Text("tap_to_run_job".t(context: context)),
|
||||||
title: Text(
|
leading: const Icon(Icons.sync),
|
||||||
"sync_remote".t(context: context),
|
trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).localSyncStatus),
|
||||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
onTap: () {
|
||||||
),
|
ref.read(backgroundSyncProvider).syncLocal(full: true);
|
||||||
subtitle: Text("tap_to_run_job".t(context: context)),
|
},
|
||||||
leading: const Icon(Icons.cloud_sync),
|
),
|
||||||
trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).remoteSyncStatus),
|
ListTile(
|
||||||
onTap: () {
|
title: Text(
|
||||||
ref.read(backgroundSyncProvider).syncRemote();
|
"sync_remote".t(context: context),
|
||||||
},
|
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
ListTile(
|
subtitle: Text("tap_to_run_job".t(context: context)),
|
||||||
title: Text(
|
leading: const Icon(Icons.cloud_sync),
|
||||||
"hash_asset".t(context: context),
|
trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).remoteSyncStatus),
|
||||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
onTap: () {
|
||||||
),
|
ref.read(backgroundSyncProvider).syncRemote();
|
||||||
leading: const Icon(Icons.tag),
|
},
|
||||||
subtitle: Text("tap_to_run_job".t(context: context)),
|
),
|
||||||
trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).hashJobStatus),
|
ListTile(
|
||||||
onTap: () {
|
title: Text(
|
||||||
ref.read(backgroundSyncProvider).hashAssets();
|
"hash_asset".t(context: context),
|
||||||
},
|
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
const Divider(height: 1, indent: 16, endIndent: 16),
|
leading: const Icon(Icons.tag),
|
||||||
const SizedBox(height: 24),
|
subtitle: Text("tap_to_run_job".t(context: context)),
|
||||||
_SectionHeaderText(text: "actions".t(context: context)),
|
trailing: _SyncStatusIcon(status: ref.watch(syncStatusProvider).hashJobStatus),
|
||||||
ListTile(
|
onTap: () {
|
||||||
title: Text(
|
ref.read(backgroundSyncProvider).hashAssets();
|
||||||
"clear_file_cache".t(context: context),
|
},
|
||||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
),
|
||||||
),
|
const Divider(height: 1, indent: 16, endIndent: 16),
|
||||||
leading: const Icon(Icons.playlist_remove_rounded),
|
const SizedBox(height: 24),
|
||||||
onTap: clearFileCache,
|
_SectionHeaderText(text: "actions".t(context: context)),
|
||||||
|
ListTile(
|
||||||
|
title: Text(
|
||||||
|
"clear_file_cache".t(context: context),
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
ListTile(
|
leading: const Icon(Icons.playlist_remove_rounded),
|
||||||
title: Text(
|
onTap: clearFileCache,
|
||||||
"export_database".t(context: context),
|
),
|
||||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
ListTile(
|
||||||
),
|
title: Text(
|
||||||
subtitle: Text("export_database_description".t(context: context)),
|
"export_database".t(context: context),
|
||||||
leading: const Icon(Icons.download),
|
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
onTap: exportDatabase,
|
|
||||||
),
|
),
|
||||||
ListTile(
|
subtitle: Text("export_database_description".t(context: context)),
|
||||||
title: Text(
|
leading: const Icon(Icons.download),
|
||||||
"reset_sqlite".t(context: context),
|
onTap: exportDatabase,
|
||||||
style: TextStyle(color: context.colorScheme.error, fontWeight: FontWeight.w500),
|
),
|
||||||
),
|
ListTile(
|
||||||
leading: Icon(Icons.settings_backup_restore_rounded, color: context.colorScheme.error),
|
title: Text(
|
||||||
onTap: () async {
|
"reset_sqlite".t(context: context),
|
||||||
await resetSqliteDb(context);
|
style: TextStyle(color: context.colorScheme.error, fontWeight: FontWeight.w500),
|
||||||
},
|
|
||||||
),
|
),
|
||||||
],
|
leading: Icon(Icons.settings_backup_restore_rounded, color: context.colorScheme.error),
|
||||||
),
|
onTap: () async {
|
||||||
|
await resetSqliteDb(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,6 @@ class NetworkingSettings extends HookConsumerWidget {
|
|||||||
|
|
||||||
return ListView(
|
return ListView(
|
||||||
padding: const EdgeInsets.only(bottom: 96),
|
padding: const EdgeInsets.only(bottom: 96),
|
||||||
physics: const ClampingScrollPhysics(),
|
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 8, left: 16, bottom: 8),
|
padding: const EdgeInsets.only(top: 8, left: 16, bottom: 8),
|
||||||
|
|||||||
Reference in New Issue
Block a user