refactor: DCM - const border radius, constructor & switch expressions (#19515)

* enable border radius, switch exp, const constructor

* regenerate provider

* more formatting

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
shenlong 2025-06-25 13:06:24 +05:30 committed by GitHub
parent 05064f87f0
commit 5b0575b956
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
130 changed files with 338 additions and 264 deletions

View File

@ -109,7 +109,7 @@ jobs:
working-directory: ./mobile working-directory: ./mobile
- name: Run DCM - name: Run DCM
run: dcm analyze lib run: dcm analyze lib --fatal-style --fatal-warnings
working-directory: ./mobile working-directory: ./mobile
zizmor: zizmor:

View File

@ -146,6 +146,7 @@ dart_code_metrics:
# - no-empty-block # - no-empty-block
# - no-equal-then-else # - no-equal-then-else
# - prefer-correct-test-file-name # - prefer-correct-test-file-name
- prefer-const-border-radius
# - prefer-match-file-name # - prefer-match-file-name
# - prefer-return-await # - prefer-return-await
# - avoid-self-assignment # - avoid-self-assignment
@ -290,7 +291,8 @@ dart_code_metrics:
# Style # Style
# - prefer-trailing-comma # - prefer-trailing-comma
# - unnecessary-trailing-comma # - unnecessary-trailing-comma
# - prefer-declaring-const-constructor - prefer-declaring-const-constructor
# - prefer-single-widget-per-file # - prefer-single-widget-per-file
- prefer-switch-expression
# - prefer-prefixed-global-constants # - prefer-prefixed-global-constants
# - prefer-correct-callback-field-name # - prefer-correct-callback-field-name

View File

@ -7,7 +7,7 @@ import 'general_helper.dart';
class ImmichTestLoginHelper { class ImmichTestLoginHelper {
final WidgetTester tester; final WidgetTester tester;
ImmichTestLoginHelper(this.tester); const ImmichTestLoginHelper(this.tester);
Future<void> waitForLoginScreen() async { Future<void> waitForLoginScreen() async {
await pumpUntilFound(tester, find.text("Login")); await pumpUntilFound(tester, find.text("Login"));
@ -60,11 +60,11 @@ class ImmichTestLoginHelper {
await tester.tap(button); await tester.tap(button);
} }
Future<void> assertLoginSuccess({int timeoutSeconds = 15}) async { Future<void> assertLoginSuccess() async {
await pumpUntilFound(tester, find.text("home_page_building_timeline".tr())); await pumpUntilFound(tester, find.text("home_page_building_timeline".tr()));
} }
Future<void> assertLoginFailed({int timeoutSeconds = 15}) async { Future<void> assertLoginFailed() async {
await pumpUntilFound(tester, find.text("login_form_failed_login".tr())); await pumpUntilFound(tester, find.text("login_form_failed_login".tr()));
} }
} }

View File

@ -4,6 +4,8 @@ sealed class ImmichErrors {
} }
class NoResponseDtoError extends ImmichErrors implements Exception { class NoResponseDtoError extends ImmichErrors implements Exception {
const NoResponseDtoError();
@override @override
String toString() => "Response Dto is null"; String toString() => "Response Dto is null";
} }

View File

@ -1,7 +1,7 @@
import 'dart:convert'; import 'dart:convert';
class Person { class Person {
Person({ const Person({
required this.id, required this.id,
this.birthDate, this.birthDate,
required this.isHidden, required this.isHidden,

View File

@ -554,18 +554,12 @@ class Asset {
}"""; }""";
} }
static getVisibility(AssetVisibility visibility) { static getVisibility(AssetVisibility visibility) => switch (visibility) {
switch (visibility) { AssetVisibility.archive => AssetVisibilityEnum.archive,
case AssetVisibility.timeline: AssetVisibility.hidden => AssetVisibilityEnum.hidden,
return AssetVisibilityEnum.timeline; AssetVisibility.locked => AssetVisibilityEnum.locked,
case AssetVisibility.archive: AssetVisibility.timeline || _ => AssetVisibilityEnum.timeline,
return AssetVisibilityEnum.archive; };
case AssetVisibility.hidden:
return AssetVisibilityEnum.hidden;
case AssetVisibility.locked:
return AssetVisibilityEnum.locked;
}
}
} }
enum AssetType { enum AssetType {

View File

@ -11,7 +11,7 @@ class SSLClientCertStoreVal {
final Uint8List data; final Uint8List data;
final String? password; final String? password;
SSLClientCertStoreVal(this.data, this.password); const SSLClientCertStoreVal(this.data, this.password);
void save() { void save() {
final b64Str = base64Encode(data); final b64Str = base64Encode(data);

View File

@ -5,7 +5,7 @@ class ApiRepository {
Future<T> checkNull<T>(Future<T?> future) async { Future<T> checkNull<T>(Future<T?> future) async {
final response = await future; final response = await future;
if (response == null) throw NoResponseDtoError(); if (response == null) throw const NoResponseDtoError();
return response; return response;
} }
} }

View File

@ -5,7 +5,7 @@ class AlbumViewerPageState {
final String editTitleText; final String editTitleText;
final String editDescriptionText; final String editDescriptionText;
AlbumViewerPageState({ const AlbumViewerPageState({
required this.isEditAlbum, required this.isEditAlbum,
required this.editTitleText, required this.editTitleText,
required this.editDescriptionText, required this.editDescriptionText,

View File

@ -4,7 +4,7 @@ import 'package:immich_mobile/entities/asset.entity.dart';
class AssetSelectionPageResult { class AssetSelectionPageResult {
final Set<Asset> selectedAssets; final Set<Asset> selectedAssets;
AssetSelectionPageResult({ const AssetSelectionPageResult({
required this.selectedAssets, required this.selectedAssets,
}); });
@override @override

View File

@ -7,7 +7,7 @@ class AuthState {
final bool isAdmin; final bool isAdmin;
final String profileImagePath; final String profileImagePath;
AuthState({ const AuthState({
required this.deviceId, required this.deviceId,
required this.userId, required this.userId,
required this.userEmail, required this.userEmail,

View File

@ -5,7 +5,7 @@ class AuxilaryEndpoint {
final String url; final String url;
final AuxCheckStatus status; final AuxCheckStatus status;
AuxilaryEndpoint({ const AuxilaryEndpoint({
required this.url, required this.url,
required this.status, required this.status,
}); });
@ -55,7 +55,7 @@ class AuxilaryEndpoint {
class AuxCheckStatus { class AuxCheckStatus {
final String name; final String name;
AuxCheckStatus({ const AuxCheckStatus({
required this.name, required this.name,
}); });
const AuxCheckStatus._(this.name); const AuxCheckStatus._(this.name);

View File

@ -13,7 +13,7 @@ class LoginResponse {
final String userId; final String userId;
LoginResponse({ const LoginResponse({
required this.accessToken, required this.accessToken,
required this.isAdmin, required this.isAdmin,
required this.name, required this.name,

View File

@ -4,7 +4,7 @@ class AvailableAlbum {
final Album album; final Album album;
final int assetCount; final int assetCount;
final DateTime? lastBackup; final DateTime? lastBackup;
AvailableAlbum({ const AvailableAlbum({
required this.album, required this.album,
required this.assetCount, required this.assetCount,
this.lastBackup, this.lastBackup,

View File

@ -9,7 +9,7 @@ class CurrentUploadAsset {
final int? fileSize; final int? fileSize;
final bool? iCloudAsset; final bool? iCloudAsset;
CurrentUploadAsset({ const CurrentUploadAsset({
required this.id, required this.id,
required this.fileCreatedAt, required this.fileCreatedAt,
required this.fileName, required this.fileName,

View File

@ -5,7 +5,7 @@ class SuccessUploadAsset {
final String remoteAssetId; final String remoteAssetId;
final bool isDuplicate; final bool isDuplicate;
SuccessUploadAsset({ const SuccessUploadAsset({
required this.candidate, required this.candidate,
required this.remoteAssetId, required this.remoteAssetId,
required this.isDuplicate, required this.isDuplicate,

View File

@ -10,7 +10,7 @@ class DownloadInfo {
// enum // enum
final TaskStatus status; final TaskStatus status;
DownloadInfo({ const DownloadInfo({
required this.fileName, required this.fileName,
required this.progress, required this.progress,
required this.status, required this.status,
@ -71,7 +71,7 @@ class DownloadState {
final TaskStatus downloadStatus; final TaskStatus downloadStatus;
final Map<String, DownloadInfo> taskProgress; final Map<String, DownloadInfo> taskProgress;
final bool showProgress; final bool showProgress;
DownloadState({ const DownloadState({
required this.downloadStatus, required this.downloadStatus,
required this.taskProgress, required this.taskProgress,
required this.showProgress, required this.showProgress,

View File

@ -3,7 +3,7 @@ import 'package:immich_mobile/models/folder/root_folder.model.dart';
class RecursiveFolder extends RootFolder { class RecursiveFolder extends RootFolder {
final String name; final String name;
RecursiveFolder({ const RecursiveFolder({
required this.name, required this.name,
required super.path, required super.path,
required super.subfolders, required super.subfolders,

View File

@ -4,7 +4,7 @@ class RootFolder {
final List<RecursiveFolder> subfolders; final List<RecursiveFolder> subfolders;
final String path; final String path;
RootFolder({ const RootFolder({
required this.subfolders, required this.subfolders,
required this.path, required this.path,
}); });

View File

@ -8,4 +8,6 @@ class MapAssetsInBoundsUpdated extends MapEvent {
const MapAssetsInBoundsUpdated(this.assetRemoteIds); const MapAssetsInBoundsUpdated(this.assetRemoteIds);
} }
class MapCloseBottomSheet extends MapEvent {} class MapCloseBottomSheet extends MapEvent {
const MapCloseBottomSheet();
}

View File

@ -4,7 +4,7 @@ import 'package:openapi/api.dart';
class MapMarker { class MapMarker {
final LatLng latLng; final LatLng latLng;
final String assetRemoteId; final String assetRemoteId;
MapMarker({ const MapMarker({
required this.latLng, required this.latLng,
required this.assetRemoteId, required this.assetRemoteId,
}); });

View File

@ -11,7 +11,7 @@ class MapState {
final AsyncValue<String> lightStyleFetched; final AsyncValue<String> lightStyleFetched;
final AsyncValue<String> darkStyleFetched; final AsyncValue<String> darkStyleFetched;
MapState({ const MapState({
this.themeMode = ThemeMode.system, this.themeMode = ThemeMode.system,
this.showFavoriteOnly = false, this.showFavoriteOnly = false,
this.includeArchived = false, this.includeArchived = false,

View File

@ -7,7 +7,7 @@ import 'package:immich_mobile/entities/asset.entity.dart';
class Memory { class Memory {
final String title; final String title;
final List<Asset> assets; final List<Asset> assets;
Memory({ const Memory({
required this.title, required this.title,
required this.assets, required this.assets,
}); });

View File

@ -14,7 +14,7 @@ class SearchCuratedContent {
/// The id to lookup the asset from the server /// The id to lookup the asset from the server
final String id; final String id;
SearchCuratedContent({ const SearchCuratedContent({
required this.label, required this.label,
required this.id, required this.id,
this.subtitle, this.subtitle,

View File

@ -6,7 +6,7 @@ class SearchResult {
final List<Asset> assets; final List<Asset> assets;
final int? nextPage; final int? nextPage;
SearchResult({ const SearchResult({
required this.assets, required this.assets,
this.nextPage, this.nextPage,
}); });

View File

@ -8,7 +8,7 @@ class SearchResultPageState {
final bool isSmart; final bool isSmart;
final List<Asset> searchResult; final List<Asset> searchResult;
SearchResultPageState({ const SearchResultPageState({
required this.isLoading, required this.isLoading,
required this.isSuccess, required this.isSuccess,
required this.isError, required this.isError,

View File

@ -13,7 +13,7 @@ class ServerInfo {
final bool isNewReleaseAvailable; final bool isNewReleaseAvailable;
final String versionMismatchErrorMessage; final String versionMismatchErrorMessage;
ServerInfo({ const ServerInfo({
required this.serverVersion, required this.serverVersion,
required this.latestVersion, required this.latestVersion,
required this.serverFeatures, required this.serverFeatures,

View File

@ -105,7 +105,9 @@ class AlbumsPage extends HookConsumerWidget {
color: context.colorScheme.onSurface.withAlpha(0), color: context.colorScheme.onSurface.withAlpha(0),
width: 0, width: 0,
), ),
borderRadius: BorderRadius.circular(24), borderRadius: const BorderRadius.all(
Radius.circular(24),
),
gradient: LinearGradient( gradient: LinearGradient(
colors: [ colors: [
context.colorScheme.primary.withValues(alpha: 0.075), context.colorScheme.primary.withValues(alpha: 0.075),
@ -301,7 +303,9 @@ class QuickFilterButton extends StatelessWidget {
), ),
shape: WidgetStateProperty.all( shape: WidgetStateProperty.all(
RoundedRectangleBorder( RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20), borderRadius: const BorderRadius.all(
Radius.circular(20),
),
side: BorderSide( side: BorderSide(
color: context.colorScheme.onSurface.withAlpha(25), color: context.colorScheme.onSurface.withAlpha(25),
width: 1, width: 1,
@ -334,8 +338,10 @@ class SortButton extends ConsumerWidget {
style: MenuStyle( style: MenuStyle(
elevation: const WidgetStatePropertyAll(1), elevation: const WidgetStatePropertyAll(1),
shape: WidgetStateProperty.all( shape: WidgetStateProperty.all(
RoundedRectangleBorder( const RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24), borderRadius: BorderRadius.all(
Radius.circular(24),
),
), ),
), ),
padding: const WidgetStatePropertyAll( padding: const WidgetStatePropertyAll(
@ -384,8 +390,10 @@ class SortButton extends ConsumerWidget {
: Colors.transparent, : Colors.transparent,
), ),
shape: WidgetStateProperty.all( shape: WidgetStateProperty.all(
RoundedRectangleBorder( const RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24), borderRadius: BorderRadius.all(
Radius.circular(24),
),
), ),
), ),
), ),

View File

@ -246,8 +246,10 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
return AlertDialog( return AlertDialog(
shape: RoundedRectangleBorder( shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.all(
Radius.circular(10),
),
), ),
elevation: 5, elevation: 5,
title: Text( title: Text(

View File

@ -147,7 +147,9 @@ class BackupControllerPage extends HookConsumerWidget {
padding: const EdgeInsets.only(top: 8.0), padding: const EdgeInsets.only(top: 8.0),
child: Card( child: Card(
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20), borderRadius: const BorderRadius.all(
Radius.circular(20),
),
side: BorderSide( side: BorderSide(
color: context.colorScheme.outlineVariant, color: context.colorScheme.outlineVariant,
width: 1, width: 1,

View File

@ -42,9 +42,11 @@ class FailedBackupStatusPage extends HookConsumerWidget {
vertical: 4, vertical: 4,
), ),
child: Card( child: Card(
shape: RoundedRectangleBorder( shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15), // if you need this borderRadius: BorderRadius.all(
side: const BorderSide( Radius.circular(15), // if you need this
),
side: BorderSide(
color: Colors.black12, color: Colors.black12,
width: 1, width: 1,
), ),

View File

@ -60,7 +60,9 @@ class AppLogDetailPage extends HookConsumerWidget {
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: context.colorScheme.surfaceContainerHigh, color: context.colorScheme.surfaceContainerHigh,
borderRadius: BorderRadius.circular(15.0), borderRadius: const BorderRadius.all(
Radius.circular(15.0),
),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
@ -99,7 +101,9 @@ class AppLogDetailPage extends HookConsumerWidget {
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: context.colorScheme.surfaceContainerHigh, color: context.colorScheme.surfaceContainerHigh,
borderRadius: BorderRadius.circular(15.0), borderRadius: const BorderRadius.all(
Radius.circular(15.0),
),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),

View File

@ -120,8 +120,10 @@ class CreateAlbumPage extends HookConsumerWidget {
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
padding: padding:
const EdgeInsets.symmetric(vertical: 24, horizontal: 16), const EdgeInsets.symmetric(vertical: 24, horizontal: 16),
shape: RoundedRectangleBorder( shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.all(
Radius.circular(10),
),
), ),
backgroundColor: context.colorScheme.surfaceContainerHigh, backgroundColor: context.colorScheme.surfaceContainerHigh,
), ),

View File

@ -90,8 +90,10 @@ class DownloadTaskTile extends StatelessWidget {
width: context.width - 32, width: context.width - 32,
child: Card( child: Card(
clipBehavior: Clip.antiAlias, clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder( shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.all(
Radius.circular(16),
),
), ),
child: ListTile( child: ListTile(
minVerticalPadding: 18, minVerticalPadding: 18,

View File

@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/widgets/settings/advanced_settings.dart'; import 'package:immich_mobile/widgets/settings/advanced_settings.dart';
import 'package:immich_mobile/widgets/settings/asset_list_settings/asset_list_settings.dart'; import 'package:immich_mobile/widgets/settings/asset_list_settings/asset_list_settings.dart';
import 'package:immich_mobile/widgets/settings/asset_viewer_settings/asset_viewer_settings.dart'; import 'package:immich_mobile/widgets/settings/asset_viewer_settings/asset_viewer_settings.dart';
@ -11,7 +12,6 @@ import 'package:immich_mobile/widgets/settings/language_settings.dart';
import 'package:immich_mobile/widgets/settings/networking_settings/networking_settings.dart'; import 'package:immich_mobile/widgets/settings/networking_settings/networking_settings.dart';
import 'package:immich_mobile/widgets/settings/notification_setting.dart'; import 'package:immich_mobile/widgets/settings/notification_setting.dart';
import 'package:immich_mobile/widgets/settings/preference_settings/preference_setting.dart'; import 'package:immich_mobile/widgets/settings/preference_settings/preference_setting.dart';
import 'package:immich_mobile/routing/router.dart';
enum SettingSection { enum SettingSection {
advanced( advanced(
@ -85,12 +85,13 @@ class SettingsPage extends StatelessWidget {
centerTitle: false, centerTitle: false,
title: const Text('settings').tr(), title: const Text('settings').tr(),
), ),
body: context.isMobile ? _MobileLayout() : _TabletLayout(), body: context.isMobile ? const _MobileLayout() : const _TabletLayout(),
); );
} }
} }
class _MobileLayout extends StatelessWidget { class _MobileLayout extends StatelessWidget {
const _MobileLayout();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ListView( return ListView(
@ -147,6 +148,7 @@ class _MobileLayout extends StatelessWidget {
} }
class _TabletLayout extends HookWidget { class _TabletLayout extends HookWidget {
const _TabletLayout();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final selectedSection = final selectedSection =

View File

@ -124,7 +124,9 @@ class EditImagePage extends ConsumerWidget {
), ),
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7), borderRadius: const BorderRadius.all(
Radius.circular(7),
),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
color: Colors.black.withValues(alpha: 0.2), color: Colors.black.withValues(alpha: 0.2),
@ -135,7 +137,9 @@ class EditImagePage extends ConsumerWidget {
], ],
), ),
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(7), borderRadius: const BorderRadius.all(
Radius.circular(7),
),
child: Image( child: Image(
image: image.image, image: image.image,
fit: BoxFit.contain, fit: BoxFit.contain,
@ -149,7 +153,9 @@ class EditImagePage extends ConsumerWidget {
margin: const EdgeInsets.only(bottom: 60, right: 10, left: 10, top: 10), margin: const EdgeInsets.only(bottom: 60, right: 10, left: 10, top: 10),
decoration: BoxDecoration( decoration: BoxDecoration(
color: context.scaffoldBackgroundColor, color: context.scaffoldBackgroundColor,
borderRadius: BorderRadius.circular(30), borderRadius: const BorderRadius.all(
Radius.circular(30),
),
), ),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,

View File

@ -162,13 +162,17 @@ class _FilterButton extends StatelessWidget {
width: 80, width: 80,
height: 80, height: 80,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), borderRadius: const BorderRadius.all(
Radius.circular(10),
),
border: isSelected border: isSelected
? Border.all(color: context.primaryColor, width: 3) ? Border.all(color: context.primaryColor, width: 3)
: null, : null,
), ),
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(10), borderRadius: const BorderRadius.all(
Radius.circular(10),
),
child: ColorFiltered( child: ColorFiltered(
colorFilter: filter, colorFilter: filter,
child: FittedBox( child: FittedBox(

View File

@ -105,7 +105,9 @@ class QuickAccessButtons extends ConsumerWidget {
color: context.colorScheme.onSurface.withAlpha(10), color: context.colorScheme.onSurface.withAlpha(10),
width: 1, width: 1,
), ),
borderRadius: BorderRadius.circular(20), borderRadius: const BorderRadius.all(
Radius.circular(20),
),
gradient: LinearGradient( gradient: LinearGradient(
colors: [ colors: [
context.colorScheme.primary.withAlpha(10), context.colorScheme.primary.withAlpha(10),
@ -240,7 +242,9 @@ class PeopleCollectionCard extends ConsumerWidget {
height: size, height: size,
width: size, width: size,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20), borderRadius: const BorderRadius.all(
Radius.circular(20),
),
gradient: LinearGradient( gradient: LinearGradient(
colors: [ colors: [
context.colorScheme.primary.withAlpha(30), context.colorScheme.primary.withAlpha(30),

View File

@ -80,7 +80,9 @@ class PartnerDetailPage extends HookConsumerWidget {
color: context.colorScheme.onSurface.withAlpha(10), color: context.colorScheme.onSurface.withAlpha(10),
width: 1, width: 1,
), ),
borderRadius: BorderRadius.circular(20), borderRadius: const BorderRadius.all(
Radius.circular(20),
),
gradient: LinearGradient( gradient: LinearGradient(
colors: [ colors: [
context.colorScheme.primary.withAlpha(10), context.colorScheme.primary.withAlpha(10),

View File

@ -143,7 +143,9 @@ class PlaceTile extends StatelessWidget {
), ),
), ),
leading: ClipRRect( leading: ClipRRect(
borderRadius: BorderRadius.circular(20), borderRadius: const BorderRadius.all(
Radius.circular(20),
),
child: CachedNetworkImage( child: CachedNetworkImage(
width: 80, width: 80,
height: 80, height: 80,

View File

@ -156,7 +156,7 @@ class MapPage extends HookConsumerWidget {
} else { } else {
// If no asset was previously selected and no new asset is available, close the bottom sheet // If no asset was previously selected and no new asset is available, close the bottom sheet
if (selectedMarker.value == null) { if (selectedMarker.value == null) {
bottomSheetStreamController.add(MapCloseBottomSheet()); bottomSheetStreamController.add(const MapCloseBottomSheet());
} }
selectedMarker.value = null; selectedMarker.value = null;
} }

View File

@ -511,16 +511,11 @@ class SearchPage extends HookConsumerWidget {
search(); search();
} }
IconData getSearchPrefixIcon() { IconData getSearchPrefixIcon() => switch (textSearchType.value) {
switch (textSearchType.value) { TextSearchType.context => Icons.image_search_rounded,
case TextSearchType.context: TextSearchType.filename => Icons.abc_rounded,
return Icons.image_search_rounded; TextSearchType.description => Icons.text_snippet_outlined,
case TextSearchType.filename: };
return Icons.abc_rounded;
case TextSearchType.description:
return Icons.text_snippet_outlined;
}
}
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
@ -533,8 +528,10 @@ class SearchPage extends HookConsumerWidget {
style: MenuStyle( style: MenuStyle(
elevation: const WidgetStatePropertyAll(1), elevation: const WidgetStatePropertyAll(1),
shape: WidgetStateProperty.all( shape: WidgetStateProperty.all(
RoundedRectangleBorder( const RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24), borderRadius: BorderRadius.all(
Radius.circular(24),
),
), ),
), ),
padding: const WidgetStatePropertyAll( padding: const WidgetStatePropertyAll(
@ -631,7 +628,9 @@ class SearchPage extends HookConsumerWidget {
color: context.colorScheme.onSurface.withAlpha(0), color: context.colorScheme.onSurface.withAlpha(0),
width: 0, width: 0,
), ),
borderRadius: BorderRadius.circular(24), borderRadius: const BorderRadius.all(
Radius.circular(24),
),
gradient: LinearGradient( gradient: LinearGradient(
colors: [ colors: [
context.colorScheme.primary.withValues(alpha: 0.075), context.colorScheme.primary.withValues(alpha: 0.075),
@ -823,7 +822,9 @@ class QuickLinkList extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20), borderRadius: const BorderRadius.all(
Radius.circular(20),
),
border: Border.all( border: Border.all(
color: context.colorScheme.outline.withAlpha(10), color: context.colorScheme.outline.withAlpha(10),
width: 1, width: 1,

View File

@ -15,7 +15,7 @@ class RemoteThumbProvider extends ImageProvider<RemoteThumbProvider> {
final double width; final double width;
final CacheManager? cacheManager; final CacheManager? cacheManager;
RemoteThumbProvider({ const RemoteThumbProvider({
required this.assetId, required this.assetId,
this.height = kTimelineFixedTileExtent, this.height = kTimelineFixedTileExtent,
this.width = kTimelineFixedTileExtent, this.width = kTimelineFixedTileExtent,

View File

@ -8,7 +8,7 @@ import 'package:thumbhash/thumbhash.dart';
class ThumbHashProvider extends ImageProvider<ThumbHashProvider> { class ThumbHashProvider extends ImageProvider<ThumbHashProvider> {
final String thumbHash; final String thumbHash;
ThumbHashProvider({ const ThumbHashProvider({
required this.thumbHash, required this.thumbHash,
}); });

View File

@ -15,18 +15,12 @@ abstract class SegmentBuilder {
this.groupBy = GroupAssetsBy.day, this.groupBy = GroupAssetsBy.day,
}); });
static double headerExtent(HeaderType header) { static double headerExtent(HeaderType header) => switch (header) {
switch (header) { HeaderType.month => kTimelineHeaderExtent,
case HeaderType.month: HeaderType.day => kTimelineHeaderExtent * 0.90,
return kTimelineHeaderExtent; HeaderType.monthAndDay => kTimelineHeaderExtent * 1.6,
case HeaderType.day: HeaderType.none => 0.0,
return kTimelineHeaderExtent * 0.90; };
case HeaderType.monthAndDay:
return kTimelineHeaderExtent * 1.6;
case HeaderType.none:
return 0.0;
}
}
static Widget buildPlaceholder( static Widget buildPlaceholder(
BuildContext context, BuildContext context,

View File

@ -1,12 +1,12 @@
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/entities/album.entity.dart';
import 'package:immich_mobile/models/albums/album_viewer_page_state.model.dart'; import 'package:immich_mobile/models/albums/album_viewer_page_state.model.dart';
import 'package:immich_mobile/services/album.service.dart'; import 'package:immich_mobile/services/album.service.dart';
import 'package:immich_mobile/entities/album.entity.dart';
class AlbumViewerNotifier extends StateNotifier<AlbumViewerPageState> { class AlbumViewerNotifier extends StateNotifier<AlbumViewerPageState> {
AlbumViewerNotifier(this.ref) AlbumViewerNotifier(this.ref)
: super( : super(
AlbumViewerPageState( const AlbumViewerPageState(
editTitleText: "", editTitleText: "",
isEditAlbum: false, isEditAlbum: false,
editDescriptionText: "", editDescriptionText: "",

View File

@ -5,4 +5,4 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'app_settings.provider.g.dart'; part 'app_settings.provider.g.dart';
@Riverpod(keepAlive: true) @Riverpod(keepAlive: true)
AppSettingsService appSettingsService(Ref _) => AppSettingsService(); AppSettingsService appSettingsService(Ref _) => const AppSettingsService();

View File

@ -7,7 +7,7 @@ part of 'app_settings.provider.dart';
// ************************************************************************** // **************************************************************************
String _$appSettingsServiceHash() => String _$appSettingsServiceHash() =>
r'2aa16d76a8df869c39486325efc1d08b2d2c284c'; r'89cece3a19e06612f5639ae290120e854a0c5a31';
/// See also [appSettingsService]. /// See also [appSettingsService].
@ProviderFor(appSettingsService) @ProviderFor(appSettingsService)

View File

@ -23,7 +23,7 @@ class DownloadStateNotifier extends StateNotifier<DownloadState> {
this._shareService, this._shareService,
this._albumService, this._albumService,
) : super( ) : super(
DownloadState( const DownloadState(
downloadStatus: TaskStatus.complete, downloadStatus: TaskStatus.complete,
showProgress: false, showProgress: false,
taskProgress: <String, DownloadInfo>{}, taskProgress: <String, DownloadInfo>{},

View File

@ -45,7 +45,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
this._secureStorageService, this._secureStorageService,
this._widgetService, this._widgetService,
) : super( ) : super(
AuthState( const AuthState(
deviceId: "", deviceId: "",
userId: "", userId: "",
userEmail: "", userEmail: "",
@ -89,7 +89,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
} }
Future<void> _cleanUp() async { Future<void> _cleanUp() async {
state = AuthState( state = const AuthState(
deviceId: "", deviceId: "",
userId: "", userId: "",
userEmail: "", userEmail: "",

View File

@ -7,7 +7,7 @@ class IOSBackgroundSettings {
final DateTime? timeOfLastFetch; final DateTime? timeOfLastFetch;
final DateTime? timeOfLastProcessing; final DateTime? timeOfLastProcessing;
IOSBackgroundSettings({ const IOSBackgroundSettings({
required this.appRefreshEnabled, required this.appRefreshEnabled,
required this.numberOfBackgroundTasksQueued, required this.numberOfBackgroundTasksQueued,
this.timeOfLastFetch, this.timeOfLastFetch,

View File

@ -42,6 +42,6 @@ class ImageLoader {
} }
// If we get here, the image failed to load from the cache stream // If we get here, the image failed to load from the cache stream
throw ImageLoadingException('Could not load image from stream'); throw const ImageLoadingException('Could not load image from stream');
} }
} }

View File

@ -1,5 +1,5 @@
/// An exception for the [ImageLoader] and the Immich image providers /// An exception for the [ImageLoader] and the Immich image providers
class ImageLoadingException implements Exception { class ImageLoadingException implements Exception {
final String message; final String message;
ImageLoadingException(this.message); const ImageLoadingException(this.message);
} }

View File

@ -23,7 +23,7 @@ class ImmichRemoteImageProvider
/// The image cache manager /// The image cache manager
final CacheManager? cacheManager; final CacheManager? cacheManager;
ImmichRemoteImageProvider({ const ImmichRemoteImageProvider({
required this.assetId, required this.assetId,
this.cacheManager, this.cacheManager,
}); });

View File

@ -24,7 +24,7 @@ class ImmichRemoteThumbnailProvider
/// The image cache manager /// The image cache manager
final CacheManager? cacheManager; final CacheManager? cacheManager;
ImmichRemoteThumbnailProvider({ const ImmichRemoteThumbnailProvider({
required this.assetId, required this.assetId,
this.height, this.height,
this.width, this.width,

View File

@ -17,7 +17,7 @@ class PaginatedSearchNotifier extends StateNotifier<SearchResult> {
final SearchService _searchService; final SearchService _searchService;
PaginatedSearchNotifier(this._searchService) PaginatedSearchNotifier(this._searchService)
: super(SearchResult(assets: [], nextPage: 1)); : super(const SearchResult(assets: [], nextPage: 1));
Future<bool> search(SearchFilter filter) async { Future<bool> search(SearchFilter filter) async {
if (state.nextPage == null) { if (state.nextPage == null) {
@ -39,7 +39,7 @@ class PaginatedSearchNotifier extends StateNotifier<SearchResult> {
} }
clear() { clear() {
state = SearchResult(assets: [], nextPage: 1); state = const SearchResult(assets: [], nextPage: 1);
} }
} }

View File

@ -1,36 +1,35 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/models/server_info/server_disk_info.model.dart';
import 'package:immich_mobile/models/server_info/server_info.model.dart';
import 'package:immich_mobile/services/server_info.service.dart';
import 'package:immich_mobile/models/server_info/server_config.model.dart'; import 'package:immich_mobile/models/server_info/server_config.model.dart';
import 'package:immich_mobile/models/server_info/server_disk_info.model.dart';
import 'package:immich_mobile/models/server_info/server_features.model.dart'; import 'package:immich_mobile/models/server_info/server_features.model.dart';
import 'package:immich_mobile/models/server_info/server_info.model.dart';
import 'package:immich_mobile/models/server_info/server_version.model.dart'; import 'package:immich_mobile/models/server_info/server_version.model.dart';
import 'package:immich_mobile/services/server_info.service.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
class ServerInfoNotifier extends StateNotifier<ServerInfo> { class ServerInfoNotifier extends StateNotifier<ServerInfo> {
ServerInfoNotifier(this._serverInfoService) ServerInfoNotifier(this._serverInfoService)
: super( : super(
ServerInfo( const ServerInfo(
serverVersion: const ServerVersion( serverVersion: ServerVersion(
major: 0, major: 0,
minor: 0, minor: 0,
patch: 0, patch: 0,
), ),
latestVersion: const ServerVersion( latestVersion: ServerVersion(
major: 0, major: 0,
minor: 0, minor: 0,
patch: 0, patch: 0,
), ),
serverFeatures: const ServerFeatures( serverFeatures: ServerFeatures(
map: true, map: true,
trash: true, trash: true,
oauthEnabled: false, oauthEnabled: false,
passwordLogin: true, passwordLogin: true,
), ),
serverConfig: const ServerConfig( serverConfig: ServerConfig(
trashDays: 30, trashDays: 30,
oauthButtonText: '', oauthButtonText: '',
externalDomain: '', externalDomain: '',
@ -38,7 +37,7 @@ class ServerInfoNotifier extends StateNotifier<ServerInfo> {
'https://tiles.immich.cloud/v1/style/light.json', 'https://tiles.immich.cloud/v1/style/light.json',
mapDarkStyleUrl: 'https://tiles.immich.cloud/v1/style/dark.json', mapDarkStyleUrl: 'https://tiles.immich.cloud/v1/style/dark.json',
), ),
serverDiskInfo: const ServerDiskInfo( serverDiskInfo: ServerDiskInfo(
diskAvailable: "0", diskAvailable: "0",
diskSize: "0", diskSize: "0",
diskUse: "0", diskUse: "0",

View File

@ -14,7 +14,7 @@ final multiSelectProvider =
class MultiSelectState { class MultiSelectState {
final Set<BaseAsset> selectedAssets; final Set<BaseAsset> selectedAssets;
MultiSelectState({ const MultiSelectState({
required this.selectedAssets, required this.selectedAssets,
}); });
@ -50,7 +50,7 @@ class MultiSelectNotifier extends Notifier<MultiSelectState> {
MultiSelectState build() { MultiSelectState build() {
_timelineService = ref.read(timelineServiceProvider); _timelineService = ref.read(timelineServiceProvider);
return MultiSelectState( return const MultiSelectState(
selectedAssets: {}, selectedAssets: {},
); );
} }

View File

@ -17,7 +17,7 @@ class UploadProfileImageState {
// enum // enum
final UploadProfileStatus status; final UploadProfileStatus status;
final String profileImagePath; final String profileImagePath;
UploadProfileImageState({ const UploadProfileImageState({
required this.status, required this.status,
required this.profileImagePath, required this.profileImagePath,
}); });
@ -74,7 +74,7 @@ class UploadProfileImageNotifier
extends StateNotifier<UploadProfileImageState> { extends StateNotifier<UploadProfileImageState> {
UploadProfileImageNotifier(this._userService) UploadProfileImageNotifier(this._userService)
: super( : super(
UploadProfileImageState( const UploadProfileImageState(
profileImagePath: '', profileImagePath: '',
status: UploadProfileStatus.idle, status: UploadProfileStatus.idle,
), ),

View File

@ -56,7 +56,7 @@ class WebsocketState {
final bool isConnected; final bool isConnected;
final List<PendingChange> pendingChanges; final List<PendingChange> pendingChanges;
WebsocketState({ const WebsocketState({
this.socket, this.socket,
required this.isConnected, required this.isConnected,
required this.pendingChanges, required this.pendingChanges,
@ -94,7 +94,11 @@ class WebsocketState {
class WebsocketNotifier extends StateNotifier<WebsocketState> { class WebsocketNotifier extends StateNotifier<WebsocketState> {
WebsocketNotifier(this._ref) WebsocketNotifier(this._ref)
: super( : super(
WebsocketState(socket: null, isConnected: false, pendingChanges: []), const WebsocketState(
socket: null,
isConnected: false,
pendingChanges: [],
),
); );
final _log = Logger('WebsocketNotifier'); final _log = Logger('WebsocketNotifier');

View File

@ -18,7 +18,7 @@ final albumRepositoryProvider =
Provider((ref) => AlbumRepository(ref.watch(dbProvider))); Provider((ref) => AlbumRepository(ref.watch(dbProvider)));
class AlbumRepository extends DatabaseRepository { class AlbumRepository extends DatabaseRepository {
AlbumRepository(super.db); const AlbumRepository(super.db);
Future<int> count({bool? local}) { Future<int> count({bool? local}) {
final baseQuery = db.albums.where(); final baseQuery = db.albums.where();

View File

@ -3,7 +3,7 @@ import 'package:immich_mobile/constants/errors.dart';
abstract class ApiRepository { abstract class ApiRepository {
Future<T> checkNull<T>(Future<T?> future) async { Future<T> checkNull<T>(Future<T?> future) async {
final response = await future; final response = await future;
if (response == null) throw NoResponseDtoError(); if (response == null) throw const NoResponseDtoError();
return response; return response;
} }
} }

View File

@ -15,7 +15,7 @@ final assetRepositoryProvider =
Provider((ref) => AssetRepository(ref.watch(dbProvider))); Provider((ref) => AssetRepository(ref.watch(dbProvider)));
class AssetRepository extends DatabaseRepository { class AssetRepository extends DatabaseRepository {
AssetRepository(super.db); const AssetRepository(super.db);
Future<List<Asset>> getByAlbum( Future<List<Asset>> getByAlbum(
Album album, { Album album, {

View File

@ -56,18 +56,12 @@ class AssetApiRepository extends ApiRepository {
); );
} }
_mapVisibility(AssetVisibilityEnum visibility) { _mapVisibility(AssetVisibilityEnum visibility) => switch (visibility) {
switch (visibility) { AssetVisibilityEnum.timeline => AssetVisibility.timeline,
case AssetVisibilityEnum.timeline: AssetVisibilityEnum.hidden => AssetVisibility.hidden,
return AssetVisibility.timeline; AssetVisibilityEnum.locked => AssetVisibility.locked,
case AssetVisibilityEnum.hidden: AssetVisibilityEnum.archive => AssetVisibility.archive,
return AssetVisibility.hidden; };
case AssetVisibilityEnum.locked:
return AssetVisibility.locked;
case AssetVisibilityEnum.archive:
return AssetVisibility.archive;
}
}
Future<String?> getAssetMIMEType(String assetId) async { Future<String?> getAssetMIMEType(String assetId) async {
final response = await checkNull(_api.getAssetInfo(assetId)); final response = await checkNull(_api.getAssetInfo(assetId));

View File

@ -6,9 +6,11 @@ import 'package:immich_mobile/entities/store.entity.dart';
import 'package:immich_mobile/utils/hash.dart'; import 'package:immich_mobile/utils/hash.dart';
import 'package:photo_manager/photo_manager.dart' hide AssetType; import 'package:photo_manager/photo_manager.dart' hide AssetType;
final assetMediaRepositoryProvider = Provider((ref) => AssetMediaRepository()); final assetMediaRepositoryProvider =
Provider((ref) => const AssetMediaRepository());
class AssetMediaRepository { class AssetMediaRepository {
const AssetMediaRepository();
Future<List<String>> deleteAll(List<String> ids) => Future<List<String>> deleteAll(List<String> ids) =>
PhotoManager.editor.deleteWithIds(ids); PhotoManager.editor.deleteWithIds(ids);

View File

@ -22,7 +22,7 @@ final authRepositoryProvider = Provider<AuthRepository>(
class AuthRepository extends DatabaseRepository { class AuthRepository extends DatabaseRepository {
final Drift _drift; final Drift _drift;
AuthRepository(super.db, this._drift); const AuthRepository(super.db, this._drift);
Future<void> clearLocalData() { Future<void> clearLocalData() {
return db.writeTxn(() { return db.writeTxn(() {

View File

@ -10,7 +10,7 @@ final backupAlbumRepositoryProvider =
Provider((ref) => BackupAlbumRepository(ref.watch(dbProvider))); Provider((ref) => BackupAlbumRepository(ref.watch(dbProvider)));
class BackupAlbumRepository extends DatabaseRepository { class BackupAlbumRepository extends DatabaseRepository {
BackupAlbumRepository(super.db); const BackupAlbumRepository(super.db);
Future<List<BackupAlbum>> getAll({BackupAlbumSort? sort}) { Future<List<BackupAlbum>> getAll({BackupAlbumSort? sort}) {
final baseQuery = db.backupAlbums.where(); final baseQuery = db.backupAlbums.where();

View File

@ -9,7 +9,7 @@ final biometricRepositoryProvider =
class BiometricRepository { class BiometricRepository {
final LocalAuthentication _localAuth; final LocalAuthentication _localAuth;
BiometricRepository(this._localAuth); const BiometricRepository(this._localAuth);
Future<BiometricStatus> getStatus() async { Future<BiometricStatus> getStatus() async {
final bool canAuthenticateWithBiometrics = final bool canAuthenticateWithBiometrics =

View File

@ -7,7 +7,7 @@ const Symbol _zoneTxn = #zoneTxn;
abstract class DatabaseRepository implements IDatabaseRepository { abstract class DatabaseRepository implements IDatabaseRepository {
final Isar db; final Isar db;
DatabaseRepository(this.db); const DatabaseRepository(this.db);
bool get inTxn => Zone.current[_zoneTxn] != null; bool get inTxn => Zone.current[_zoneTxn] != null;

View File

@ -8,7 +8,7 @@ final etagRepositoryProvider =
Provider((ref) => ETagRepository(ref.watch(dbProvider))); Provider((ref) => ETagRepository(ref.watch(dbProvider)));
class ETagRepository extends DatabaseRepository { class ETagRepository extends DatabaseRepository {
ETagRepository(super.db); const ETagRepository(super.db);
Future<List<String>> getAllIds() => db.eTags.where().idProperty().findAll(); Future<List<String>> getAllIds() => db.eTags.where().idProperty().findAll();

View File

@ -6,9 +6,11 @@ import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:immich_mobile/repositories/asset_media.repository.dart'; import 'package:immich_mobile/repositories/asset_media.repository.dart';
import 'package:photo_manager/photo_manager.dart' hide AssetType; import 'package:photo_manager/photo_manager.dart' hide AssetType;
final fileMediaRepositoryProvider = Provider((ref) => FileMediaRepository()); final fileMediaRepositoryProvider =
Provider((ref) => const FileMediaRepository());
class FileMediaRepository { class FileMediaRepository {
const FileMediaRepository();
Future<Asset?> saveImage( Future<Asset?> saveImage(
Uint8List data, { Uint8List data, {
required String title, required String title,

View File

@ -7,7 +7,7 @@ final localFilesManagerRepositoryProvider = Provider(
); );
class LocalFilesManagerRepository { class LocalFilesManagerRepository {
LocalFilesManagerRepository(this._service); const LocalFilesManagerRepository(this._service);
final LocalFilesManagerService _service; final LocalFilesManagerService _service;

View File

@ -12,7 +12,7 @@ final networkRepositoryProvider = Provider((_) {
class NetworkRepository { class NetworkRepository {
final NetworkInfo _networkInfo; final NetworkInfo _networkInfo;
NetworkRepository(this._networkInfo); const NetworkRepository(this._networkInfo);
Future<String?> getWifiName() { Future<String?> getWifiName() {
if (Platform.isAndroid) { if (Platform.isAndroid) {

View File

@ -11,7 +11,7 @@ final partnerRepositoryProvider = Provider(
); );
class PartnerRepository extends DatabaseRepository { class PartnerRepository extends DatabaseRepository {
PartnerRepository(super.db); const PartnerRepository(super.db);
Future<List<UserDto>> getSharedBy() async { Future<List<UserDto>> getSharedBy() async {
return (await db.users return (await db.users

View File

@ -2,11 +2,11 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
final permissionRepositoryProvider = Provider((_) { final permissionRepositoryProvider = Provider((_) {
return PermissionRepository(); return const PermissionRepository();
}); });
class PermissionRepository implements IPermissionRepository { class PermissionRepository implements IPermissionRepository {
PermissionRepository(); const PermissionRepository();
@override @override
Future<bool> hasLocationWhenInUsePermission() { Future<bool> hasLocationWhenInUsePermission() {

View File

@ -2,12 +2,12 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
final secureStorageRepositoryProvider = final secureStorageRepositoryProvider =
Provider((ref) => SecureStorageRepository(const FlutterSecureStorage())); Provider((ref) => const SecureStorageRepository(FlutterSecureStorage()));
class SecureStorageRepository { class SecureStorageRepository {
final FlutterSecureStorage _secureStorage; final FlutterSecureStorage _secureStorage;
SecureStorageRepository(this._secureStorage); const SecureStorageRepository(this._secureStorage);
Future<String?> read(String key) { Future<String?> read(String key) {
return _secureStorage.read(key: key); return _secureStorage.read(key: key);

View File

@ -13,7 +13,7 @@ final timelineRepositoryProvider =
Provider((ref) => TimelineRepository(ref.watch(dbProvider))); Provider((ref) => TimelineRepository(ref.watch(dbProvider)));
class TimelineRepository extends DatabaseRepository { class TimelineRepository extends DatabaseRepository {
TimelineRepository(super.db); const TimelineRepository(super.db);
Future<List<String>> getTimelineUserIds(String id) { Future<List<String>> getTimelineUserIds(String id) {
return db.users return db.users

View File

@ -1,10 +1,10 @@
import 'package:home_widget/home_widget.dart'; import 'package:home_widget/home_widget.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
final widgetRepositoryProvider = Provider((_) => WidgetRepository()); final widgetRepositoryProvider = Provider((_) => const WidgetRepository());
class WidgetRepository { class WidgetRepository {
WidgetRepository(); const WidgetRepository();
Future<void> saveData(String key, String value) async { Future<void> saveData(String key, String value) async {
await HomeWidget.saveWidgetData<String>(key, value); await HomeWidget.saveWidgetData<String>(key, value);

View File

@ -5,7 +5,7 @@ import 'package:immich_mobile/routing/router.dart';
class BackupPermissionGuard extends AutoRouteGuard { class BackupPermissionGuard extends AutoRouteGuard {
final GalleryPermissionNotifier _permission; final GalleryPermissionNotifier _permission;
BackupPermissionGuard(this._permission); const BackupPermissionGuard(this._permission);
@override @override
void onNavigation(NavigationResolver resolver, StackRouter router) async { void onNavigation(NavigationResolver resolver, StackRouter router) async {

View File

@ -3,7 +3,7 @@ import 'package:flutter/foundation.dart';
/// Guards against duplicate navigation to this route /// Guards against duplicate navigation to this route
class DuplicateGuard extends AutoRouteGuard { class DuplicateGuard extends AutoRouteGuard {
DuplicateGuard(); const DuplicateGuard();
@override @override
void onNavigation(NavigationResolver resolver, StackRouter router) async { void onNavigation(NavigationResolver resolver, StackRouter router) async {
// Duplicate navigation // Duplicate navigation

View File

@ -106,7 +106,7 @@ class AppRouter extends RootStackRouter {
LocalAuthService localAuthService, LocalAuthService localAuthService,
) { ) {
_authGuard = AuthGuard(apiService); _authGuard = AuthGuard(apiService);
_duplicateGuard = DuplicateGuard(); _duplicateGuard = const DuplicateGuard();
_lockedGuard = _lockedGuard =
LockedGuard(apiService, secureStorageService, localAuthService); LockedGuard(apiService, secureStorageService, localAuthService);
_backupPermissionGuard = BackupPermissionGuard(galleryPermissionNotifier); _backupPermissionGuard = BackupPermissionGuard(galleryPermissionNotifier);

View File

@ -100,6 +100,7 @@ enum AppSettingsEnum<T> {
} }
class AppSettingsService { class AppSettingsService {
const AppSettingsService();
T getSetting<T>(AppSettingsEnum<T> setting) { T getSetting<T>(AppSettingsEnum<T> setting) {
return Store.get(setting.storeKey, setting.defaultValue); return Store.get(setting.storeKey, setting.defaultValue);
} }

View File

@ -9,7 +9,7 @@ final backupAlbumServiceProvider = Provider<BackupAlbumService>((ref) {
class BackupAlbumService { class BackupAlbumService {
final BackupAlbumRepository _backupAlbumRepository; final BackupAlbumRepository _backupAlbumRepository;
BackupAlbumService(this._backupAlbumRepository); const BackupAlbumService(this._backupAlbumRepository);
Future<List<BackupAlbum>> getAll({BackupAlbumSort? sort}) { Future<List<BackupAlbum>> getAll({BackupAlbumSort? sort}) {
return _backupAlbumRepository.getAll(sort: sort); return _backupAlbumRepository.getAll(sort: sort);

View File

@ -25,7 +25,7 @@ class DeepLinkService {
final CurrentAsset _currentAsset; final CurrentAsset _currentAsset;
final CurrentAlbum _currentAlbum; final CurrentAlbum _currentAlbum;
DeepLinkService( const DeepLinkService(
this._memoryService, this._memoryService,
this._assetService, this._assetService,
this._albumService, this._albumService,
@ -38,16 +38,12 @@ class DeepLinkService {
final intent = link.uri.host; final intent = link.uri.host;
final queryParams = link.uri.queryParameters; final queryParams = link.uri.queryParameters;
PageRouteInfo<dynamic>? deepLinkRoute; PageRouteInfo<dynamic>? deepLinkRoute = switch (intent) {
"memory" => await _buildMemoryDeepLink(queryParams['id'] ?? ''),
switch (intent) { "asset" => await _buildAssetDeepLink(queryParams['id'] ?? ''),
case "memory": "album" => await _buildAlbumDeepLink(queryParams['id'] ?? ''),
deepLinkRoute = await _buildMemoryDeepLink(queryParams['id'] ?? ''); _ => null,
case "asset": };
deepLinkRoute = await _buildAssetDeepLink(queryParams['id'] ?? '');
case "album":
deepLinkRoute = await _buildAlbumDeepLink(queryParams['id'] ?? '');
}
// Deep link resolution failed, safely handle it based on the app state // Deep link resolution failed, safely handle it based on the app state
if (deepLinkRoute == null) { if (deepLinkRoute == null) {
@ -98,7 +94,7 @@ class DeepLinkService {
]); ]);
} }
Future<MemoryRoute?> _buildMemoryDeepLink(String memoryId) async { Future<PageRouteInfo?> _buildMemoryDeepLink(String memoryId) async {
final memory = await _memoryService.getMemoryById(memoryId); final memory = await _memoryService.getMemoryById(memoryId);
if (memory == null) { if (memory == null) {
@ -108,7 +104,7 @@ class DeepLinkService {
return MemoryRoute(memories: [memory], memoryIndex: 0); return MemoryRoute(memories: [memory], memoryIndex: 0);
} }
Future<GalleryViewerRoute?> _buildAssetDeepLink(String assetId) async { Future<PageRouteInfo?> _buildAssetDeepLink(String assetId) async {
final asset = await _assetService.getAssetByRemoteId(assetId); final asset = await _assetService.getAssetByRemoteId(assetId);
if (asset == null) { if (asset == null) {
@ -126,7 +122,7 @@ class DeepLinkService {
); );
} }
Future<AlbumViewerRoute?> _buildAlbumDeepLink(String albumId) async { Future<PageRouteInfo?> _buildAlbumDeepLink(String albumId) async {
final album = await _albumService.getAlbumByRemoteId(albumId); final album = await _albumService.getAlbumByRemoteId(albumId);
if (album == null) { if (album == null) {

View File

@ -3,10 +3,10 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/domain/models/store.model.dart';
import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/entities/store.entity.dart';
final deviceServiceProvider = Provider((ref) => DeviceService()); final deviceServiceProvider = Provider((ref) => const DeviceService());
class DeviceService { class DeviceService {
DeviceService(); const DeviceService();
createDeviceId() { createDeviceId() {
return FlutterUdid.consistentUdid; return FlutterUdid.consistentUdid;

View File

@ -8,7 +8,7 @@ import 'package:immich_mobile/repositories/asset.repository.dart';
class EntityService { class EntityService {
final AssetRepository _assetRepository; final AssetRepository _assetRepository;
final IsarUserRepository _isarUserRepository; final IsarUserRepository _isarUserRepository;
EntityService( const EntityService(
this._assetRepository, this._assetRepository,
this._isarUserRepository, this._isarUserRepository,
); );

View File

@ -7,7 +7,7 @@ final etagServiceProvider =
class ETagService { class ETagService {
final ETagRepository _eTagRepository; final ETagRepository _eTagRepository;
ETagService(this._eTagRepository); const ETagService(this._eTagRepository);
Future<void> clearTable() { Future<void> clearTable() {
return _eTagRepository.clearTable(); return _eTagRepository.clearTable();

View File

@ -11,7 +11,7 @@ final localAuthServiceProvider = Provider(
class LocalAuthService { class LocalAuthService {
final BiometricRepository _biometricRepository; final BiometricRepository _biometricRepository;
LocalAuthService(this._biometricRepository); const LocalAuthService(this._biometricRepository);
Future<BiometricStatus> getStatus() { Future<BiometricStatus> getStatus() {
return _biometricRepository.getStatus(); return _biometricRepository.getStatus();

View File

@ -3,10 +3,11 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
final localFileManagerServiceProvider = Provider<LocalFilesManagerService>( final localFileManagerServiceProvider = Provider<LocalFilesManagerService>(
(ref) => LocalFilesManagerService(), (ref) => const LocalFilesManagerService(),
); );
class LocalFilesManagerService { class LocalFilesManagerService {
const LocalFilesManagerService();
static final Logger _logger = Logger('LocalFilesManager'); static final Logger _logger = Logger('LocalFilesManager');
static const MethodChannel _channel = MethodChannel('file_trash'); static const MethodChannel _channel = MethodChannel('file_trash');

View File

@ -13,7 +13,7 @@ class NetworkService {
final NetworkRepository _repository; final NetworkRepository _repository;
final IPermissionRepository _permissionRepository; final IPermissionRepository _permissionRepository;
NetworkService(this._repository, this._permissionRepository); const NetworkService(this._repository, this._permissionRepository);
Future<bool> getLocationWhenInUserPermission() { Future<bool> getLocationWhenInUserPermission() {
return _permissionRepository.hasLocationWhenInUsePermission(); return _permissionRepository.hasLocationWhenInUsePermission();

View File

@ -10,7 +10,7 @@ final secureStorageServiceProvider = Provider(
class SecureStorageService { class SecureStorageService {
final SecureStorageRepository _secureStorageRepository; final SecureStorageRepository _secureStorageRepository;
SecureStorageService(this._secureStorageRepository); const SecureStorageService(this._secureStorageRepository);
Future<void> write(String key, String value) async { Future<void> write(String key, String value) async {
await _secureStorageRepository.write(key, value); await _secureStorageRepository.write(key, value);

View File

@ -16,7 +16,7 @@ final serverInfoServiceProvider = Provider(
class ServerInfoService { class ServerInfoService {
final ApiService _apiService; final ApiService _apiService;
ServerInfoService(this._apiService); const ServerInfoService(this._apiService);
Future<ServerDiskInfo?> getDiskInfo() async { Future<ServerDiskInfo?> getDiskInfo() async {
try { try {

View File

@ -7,7 +7,7 @@ import 'package:immich_mobile/services/api.service.dart';
import 'package:openapi/api.dart'; import 'package:openapi/api.dart';
class StackService { class StackService {
StackService(this._api, this._assetRepository); const StackService(this._api, this._assetRepository);
final ApiService _api; final ApiService _api;
final AssetRepository _assetRepository; final AssetRepository _assetRepository;

View File

@ -11,7 +11,7 @@ final widgetServiceProvider = Provider((ref) {
class WidgetService { class WidgetService {
final WidgetRepository _repository; final WidgetRepository _repository;
WidgetService(this._repository); const WidgetService(this._repository);
Future<void> writeCredentials(String serverURL, String sessionKey) async { Future<void> writeCredentials(String serverURL, String sessionKey) async {
await _repository.setAppGroupId(appShareGroupId); await _repository.setAppGroupId(appShareGroupId);

View File

@ -4,7 +4,7 @@ import 'package:dynamic_color/dynamic_color.dart';
import 'package:immich_mobile/theme/theme_data.dart'; import 'package:immich_mobile/theme/theme_data.dart';
abstract final class DynamicTheme { abstract final class DynamicTheme {
DynamicTheme._(); const DynamicTheme._();
static ImmichTheme? _theme; static ImmichTheme? _theme;
// Method to fetch dynamic system colors // Method to fetch dynamic system colors

View File

@ -7,7 +7,7 @@ import 'package:logging/logging.dart';
import 'package:maplibre_gl/maplibre_gl.dart'; import 'package:maplibre_gl/maplibre_gl.dart';
class MapUtils { class MapUtils {
MapUtils._(); const MapUtils._();
static final Logger _log = Logger("MapUtils"); static final Logger _log = Logger("MapUtils");
static const defaultSourceId = 'asset-map-markers'; static const defaultSourceId = 'asset-map-markers';

View File

@ -106,7 +106,9 @@ class AlbumThumbnailCard extends ConsumerWidget {
width: cardSize, width: cardSize,
height: cardSize, height: cardSize,
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(20), borderRadius: const BorderRadius.all(
Radius.circular(20),
),
child: album.thumbnail.value == null child: album.thumbnail.value == null
? buildEmptyThumbnail() ? buildEmptyThumbnail()
: buildAlbumThumbnail(), : buildAlbumThumbnail(),

View File

@ -59,13 +59,17 @@ class AlbumTitleTextField extends ConsumerWidget {
splashRadius: 10, splashRadius: 10,
) )
: null, : null,
enabledBorder: OutlineInputBorder( enabledBorder: const OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent), borderSide: BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.all(
Radius.circular(10),
),
), ),
focusedBorder: OutlineInputBorder( focusedBorder: const OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent), borderSide: BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.all(
Radius.circular(10),
),
), ),
hintText: 'add_a_title'.tr(), hintText: 'add_a_title'.tr(),
hintStyle: context.themeData.inputDecorationTheme.hintStyle?.copyWith( hintStyle: context.themeData.inputDecorationTheme.hintStyle?.copyWith(

View File

@ -23,7 +23,7 @@ class RenderAssetGridElement {
final int offset; final int offset;
final int totalCount; final int totalCount;
RenderAssetGridElement( const RenderAssetGridElement(
this.type, { this.type, {
this.title, this.title,
required this.date, required this.date,

View File

@ -210,7 +210,7 @@ class DraggableScrollbar extends StatefulWidget {
BoxConstraints? labelConstraints, BoxConstraints? labelConstraints,
}) { }) {
final scrollThumb = ClipPath( final scrollThumb = ClipPath(
clipper: ArrowClipper(), clipper: const ArrowClipper(),
child: Container( child: Container(
height: height, height: height,
width: 20.0, width: 20.0,
@ -570,6 +570,7 @@ class ArrowCustomPainter extends CustomPainter {
///This cut 2 lines in arrow shape ///This cut 2 lines in arrow shape
class ArrowClipper extends CustomClipper<Path> { class ArrowClipper extends CustomClipper<Path> {
const ArrowClipper();
@override @override
Path getClip(Size size) { Path getClip(Size size) {
Path path = Path(); Path path = Path();

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