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:
Hai Sullivan
2025-12-01 06:01:01 +11:00
committed by GitHub
parent 922282b2b4
commit 46e1967760
4 changed files with 73 additions and 88 deletions

View File

@@ -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],
);
} }
} }

View File

@@ -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,

View File

@@ -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);
},
),
],
); );
} }
} }

View File

@@ -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),