refactor(mobile): Use switch expression when possible (#15852)

refactor: Use `switch` expression when possible

Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
Damiano Ferrari 2025-02-02 22:46:46 +01:00 committed by GitHub
parent 4efacfbb91
commit 96a6cc20b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 219 additions and 374 deletions

View File

@ -545,19 +545,13 @@ enum AssetType {
} }
extension AssetTypeEnumHelper on AssetTypeEnum { extension AssetTypeEnumHelper on AssetTypeEnum {
AssetType toAssetType() { AssetType toAssetType() => switch (this) {
switch (this) { AssetTypeEnum.IMAGE => AssetType.image,
case AssetTypeEnum.IMAGE: AssetTypeEnum.VIDEO => AssetType.video,
return AssetType.image; AssetTypeEnum.AUDIO => AssetType.audio,
case AssetTypeEnum.VIDEO: AssetTypeEnum.OTHER => AssetType.other,
return AssetType.video; _ => throw Exception(),
case AssetTypeEnum.AUDIO: };
return AssetType.audio;
case AssetTypeEnum.OTHER:
return AssetType.other;
}
throw Exception();
}
} }
/// Describes where the information of this asset came from: /// Describes where the information of this asset came from:

View File

@ -96,25 +96,16 @@ class StoreValue {
int? intValue; int? intValue;
String? strValue; String? strValue;
T? _extract<T>(StoreKey<T> key) { T? _extract<T>(StoreKey<T> key) => switch (key.type) {
switch (key.type) { const (int) => intValue as T?,
case const (int): const (bool) => intValue == null ? null : (intValue! == 1) as T,
return intValue as T?; const (DateTime) => intValue == null
case const (bool):
return intValue == null ? null : (intValue! == 1) as T;
case const (DateTime):
return intValue == null
? null ? null
: DateTime.fromMicrosecondsSinceEpoch(intValue!) as T; : DateTime.fromMicrosecondsSinceEpoch(intValue!) as T,
case const (String): const (String) => strValue as T?,
return strValue as T?; _ when key.fromDb != null => key.fromDb!.call(Store._db, intValue!),
default: _ => throw TypeError(),
if (key.fromDb != null) { };
return key.fromDb!.call(Store._db, intValue!);
}
}
throw TypeError();
}
static Future<StoreValue> _of<T>(T? value, StoreKey<T> key) async { static Future<StoreValue> _of<T>(T? value, StoreKey<T> key) async {
int? i; int? i;

View File

@ -149,56 +149,33 @@ enum AvatarColorEnum {
} }
extension AvatarColorEnumHelper on UserAvatarColor { extension AvatarColorEnumHelper on UserAvatarColor {
AvatarColorEnum toAvatarColor() { AvatarColorEnum toAvatarColor() => switch (this) {
switch (this) { UserAvatarColor.primary => AvatarColorEnum.primary,
case UserAvatarColor.primary: UserAvatarColor.pink => AvatarColorEnum.pink,
return AvatarColorEnum.primary; UserAvatarColor.red => AvatarColorEnum.red,
case UserAvatarColor.pink: UserAvatarColor.yellow => AvatarColorEnum.yellow,
return AvatarColorEnum.pink; UserAvatarColor.blue => AvatarColorEnum.blue,
case UserAvatarColor.red: UserAvatarColor.green => AvatarColorEnum.green,
return AvatarColorEnum.red; UserAvatarColor.purple => AvatarColorEnum.purple,
case UserAvatarColor.yellow: UserAvatarColor.orange => AvatarColorEnum.orange,
return AvatarColorEnum.yellow; UserAvatarColor.gray => AvatarColorEnum.gray,
case UserAvatarColor.blue: UserAvatarColor.amber => AvatarColorEnum.amber,
return AvatarColorEnum.blue; _ => AvatarColorEnum.primary,
case UserAvatarColor.green: };
return AvatarColorEnum.green;
case UserAvatarColor.purple:
return AvatarColorEnum.purple;
case UserAvatarColor.orange:
return AvatarColorEnum.orange;
case UserAvatarColor.gray:
return AvatarColorEnum.gray;
case UserAvatarColor.amber:
return AvatarColorEnum.amber;
}
return AvatarColorEnum.primary;
}
} }
extension AvatarColorToColorHelper on AvatarColorEnum { extension AvatarColorToColorHelper on AvatarColorEnum {
Color toColor([bool isDarkTheme = false]) { Color toColor([bool isDarkTheme = false]) => switch (this) {
switch (this) { AvatarColorEnum.primary =>
case AvatarColorEnum.primary: isDarkTheme ? const Color(0xFFABCBFA) : const Color(0xFF4250AF),
return isDarkTheme ? const Color(0xFFABCBFA) : const Color(0xFF4250AF); AvatarColorEnum.pink => const Color.fromARGB(255, 244, 114, 182),
case AvatarColorEnum.pink: AvatarColorEnum.red => const Color.fromARGB(255, 239, 68, 68),
return const Color.fromARGB(255, 244, 114, 182); AvatarColorEnum.yellow => const Color.fromARGB(255, 234, 179, 8),
case AvatarColorEnum.red: AvatarColorEnum.blue => const Color.fromARGB(255, 59, 130, 246),
return const Color.fromARGB(255, 239, 68, 68); AvatarColorEnum.green => const Color.fromARGB(255, 22, 163, 74),
case AvatarColorEnum.yellow: AvatarColorEnum.purple => const Color.fromARGB(255, 147, 51, 234),
return const Color.fromARGB(255, 234, 179, 8); AvatarColorEnum.orange => const Color.fromARGB(255, 234, 88, 12),
case AvatarColorEnum.blue: AvatarColorEnum.gray => const Color.fromARGB(255, 75, 85, 99),
return const Color.fromARGB(255, 59, 130, 246); AvatarColorEnum.amber => const Color.fromARGB(255, 217, 119, 6),
case AvatarColorEnum.green: };
return const Color.fromARGB(255, 22, 163, 74);
case AvatarColorEnum.purple:
return const Color.fromARGB(255, 147, 51, 234);
case AvatarColorEnum.orange:
return const Color.fromARGB(255, 234, 88, 12);
case AvatarColorEnum.gray:
return const Color.fromARGB(255, 75, 85, 99);
case AvatarColorEnum.amber:
return const Color.fromARGB(255, 217, 119, 6);
}
}
} }

View File

@ -36,32 +36,19 @@ class AppLogPage extends HookConsumerWidget {
); );
} }
Widget buildLeadingIcon(LogLevel level) { Widget buildLeadingIcon(LogLevel level) => switch (level) {
switch (level) { LogLevel.INFO => colorStatusIndicator(context.primaryColor),
case LogLevel.INFO: LogLevel.SEVERE => colorStatusIndicator(Colors.redAccent),
return colorStatusIndicator(context.primaryColor); LogLevel.WARNING => colorStatusIndicator(Colors.orangeAccent),
case LogLevel.SEVERE: _ => colorStatusIndicator(Colors.grey),
return colorStatusIndicator(Colors.redAccent); };
case LogLevel.WARNING: Color getTileColor(LogLevel level) => switch (level) {
return colorStatusIndicator(Colors.orangeAccent); LogLevel.INFO => Colors.transparent,
default: LogLevel.SEVERE => Colors.redAccent.withOpacity(0.25),
return colorStatusIndicator(Colors.grey); LogLevel.WARNING => Colors.orangeAccent.withOpacity(0.25),
} _ => context.primaryColor.withOpacity(0.1),
} };
getTileColor(LogLevel level) {
switch (level) {
case LogLevel.INFO:
return Colors.transparent;
case LogLevel.SEVERE:
return Colors.redAccent.withOpacity(0.25);
case LogLevel.WARNING:
return Colors.orangeAccent.withOpacity(0.25);
default:
return context.primaryColor.withOpacity(0.1);
}
}
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(

View File

@ -74,26 +74,16 @@ class DownloadTaskTile extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final progressPercent = (progress * 100).round(); final progressPercent = (progress * 100).round();
getStatusText() { String getStatusText() => switch (status) {
switch (status) { TaskStatus.running => 'downloading'.tr(),
case TaskStatus.running: TaskStatus.complete => 'download_complete'.tr(),
return 'downloading'.tr(); TaskStatus.failed => 'download_failed'.tr(),
case TaskStatus.complete: TaskStatus.canceled => 'download_canceled'.tr(),
return 'download_complete'.tr(); TaskStatus.paused => 'download_paused'.tr(),
case TaskStatus.failed: TaskStatus.enqueued => 'download_enqueue'.tr(),
return 'download_failed'.tr(); TaskStatus.notFound => 'download_notfound'.tr(),
case TaskStatus.canceled: TaskStatus.waitingToRetry => 'download_waiting_to_retry'.tr(),
return 'download_canceled'.tr(); };
case TaskStatus.paused:
return 'download_paused'.tr();
case TaskStatus.enqueued:
return 'download_enqueue'.tr();
case TaskStatus.notFound:
return 'download_notfound'.tr();
case TaskStatus.waitingToRetry:
return 'download_waiting_to_retry'.tr();
}
}
return SizedBox( return SizedBox(
key: const ValueKey('download_progress'), key: const ValueKey('download_progress'),

View File

@ -174,33 +174,19 @@ class _AspectRatioButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
IconData iconData;
switch (label) {
case 'Free':
iconData = Icons.crop_free_rounded;
break;
case '1:1':
iconData = Icons.crop_square_rounded;
break;
case '16:9':
iconData = Icons.crop_16_9_rounded;
break;
case '3:2':
iconData = Icons.crop_3_2_rounded;
break;
case '7:5':
iconData = Icons.crop_7_5_rounded;
break;
default:
iconData = Icons.crop_free_rounded;
}
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
IconButton( IconButton(
icon: Icon( icon: Icon(
iconData, switch (label) {
'Free' => Icons.crop_free_rounded,
'1:1' => Icons.crop_square_rounded,
'16:9' => Icons.crop_16_9_rounded,
'3:2' => Icons.crop_3_2_rounded,
'7:5' => Icons.crop_7_5_rounded,
_ => Icons.crop_free_rounded,
},
color: aspectRatio.value == ratio color: aspectRatio.value == ratio
? context.primaryColor ? context.primaryColor
: context.themeData.iconTheme.color, : context.themeData.iconTheme.color,

View File

@ -136,23 +136,16 @@ class PermissionOnboardingPage extends HookConsumerWidget {
); );
} }
final Widget child; final Widget child = switch (permission) {
switch (permission) { PermissionStatus.limited => buildPermissionLimited(),
case PermissionStatus.limited: PermissionStatus.denied => buildRequestPermission(),
child = buildPermissionLimited(); PermissionStatus.granted ||
break; PermissionStatus.provisional =>
case PermissionStatus.denied: buildPermissionGranted(),
child = buildRequestPermission(); PermissionStatus.restricted ||
break; PermissionStatus.permanentlyDenied =>
case PermissionStatus.granted: buildPermissionDenied()
case PermissionStatus.provisional: };
child = buildPermissionGranted();
break;
case PermissionStatus.restricted:
case PermissionStatus.permanentlyDenied:
child = buildPermissionDenied();
break;
}
return Scaffold( return Scaffold(
body: SafeArea( body: SafeArea(

View File

@ -18,15 +18,11 @@ class AlbumRepository extends DatabaseRepository implements IAlbumRepository {
@override @override
Future<int> count({bool? local}) { Future<int> count({bool? local}) {
final baseQuery = db.albums.where(); final baseQuery = db.albums.where();
final QueryBuilder<Album, Album, QAfterWhereClause> query; final QueryBuilder<Album, Album, QAfterWhereClause> query = switch (local) {
switch (local) { null => baseQuery.noOp(),
case null: true => baseQuery.localIdIsNotNull(),
query = baseQuery.noOp(); false => baseQuery.remoteIdIsNotNull(),
case true: };
query = baseQuery.localIdIsNotNull();
case false:
query = baseQuery.remoteIdIsNotNull();
}
return query.count(); return query.count();
} }
@ -91,15 +87,11 @@ class AlbumRepository extends DatabaseRepository implements IAlbumRepository {
if (ownerId != null) { if (ownerId != null) {
filterQuery = filterQuery.owner((q) => q.isarIdEqualTo(ownerId)); filterQuery = filterQuery.owner((q) => q.isarIdEqualTo(ownerId));
} }
final QueryBuilder<Album, Album, QAfterSortBy> query; final QueryBuilder<Album, Album, QAfterSortBy> query = switch (sortBy) {
switch (sortBy) { null => filterQuery.noOp(),
case null: AlbumSort.remoteId => filterQuery.sortByRemoteId(),
query = filterQuery.noOp(); AlbumSort.localId => filterQuery.sortByLocalId(),
case AlbumSort.remoteId: };
query = filterQuery.sortByRemoteId();
case AlbumSort.localId:
query = filterQuery.sortByLocalId();
}
return query.findAll(); return query.findAll();
} }
@ -150,14 +142,11 @@ class AlbumRepository extends DatabaseRepository implements IAlbumRepository {
query = query.owner( query = query.owner(
(q) => q.not().isarIdEqualTo(Store.get(StoreKey.currentUser).isarId), (q) => q.not().isarIdEqualTo(Store.get(StoreKey.currentUser).isarId),
); );
break;
case QuickFilterMode.myAlbums: case QuickFilterMode.myAlbums:
query = query.owner( query = query.owner(
(q) => q.isarIdEqualTo(Store.get(StoreKey.currentUser).isarId), (q) => q.isarIdEqualTo(Store.get(StoreKey.currentUser).isarId),
); );
break;
case QuickFilterMode.all: case QuickFilterMode.all:
default:
break; break;
} }

View File

@ -38,27 +38,20 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository {
query = query.ownerIdEqualTo(ownerId); query = query.ownerIdEqualTo(ownerId);
} }
switch (state) { if (state != null) {
case null: query = switch (state) {
break; AssetState.local => query.remoteIdIsNull(),
case AssetState.local: AssetState.remote => query.localIdIsNull(),
query = query.remoteIdIsNull(); AssetState.merged => query.localIdIsNotNull().remoteIdIsNotNull(),
case AssetState.remote: };
query = query.localIdIsNull();
case AssetState.merged:
query = query.localIdIsNotNull().remoteIdIsNotNull();
} }
final QueryBuilder<Asset, Asset, QAfterSortBy> sortedQuery; final QueryBuilder<Asset, Asset, QAfterSortBy> sortedQuery =
switch (sortBy) {
switch (sortBy) { null => query.noOp(),
case null: AssetSort.checksum => query.sortByChecksum(),
sortedQuery = query.noOp(); AssetSort.ownerIdChecksum => query.sortByOwnerId().thenByChecksum(),
case AssetSort.checksum: };
sortedQuery = query.sortByChecksum();
case AssetSort.ownerIdChecksum:
sortedQuery = query.sortByOwnerId().thenByChecksum();
}
return sortedQuery.findAll(); return sortedQuery.findAll();
} }
@ -84,16 +77,12 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository {
AssetState? state, AssetState? state,
) { ) {
final query = db.assets.remote(ids).filter(); final query = db.assets.remote(ids).filter();
switch (state) { return switch (state) {
case null: null => query.noOp(),
return query.noOp(); AssetState.local => query.remoteIdIsNull(),
case AssetState.local: AssetState.remote => query.localIdIsNull(),
return query.remoteIdIsNull(); AssetState.merged => query.localIdIsNotEmpty().remoteIdIsNotNull(),
case AssetState.remote: };
return query.localIdIsNull();
case AssetState.merged:
return query.localIdIsNotEmpty().remoteIdIsNotNull();
}
} }
@override @override
@ -104,39 +93,32 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository {
int? limit, int? limit,
}) { }) {
final baseQuery = db.assets.where(); final baseQuery = db.assets.where();
final QueryBuilder<Asset, Asset, QAfterFilterCondition> filteredQuery; final QueryBuilder<Asset, Asset, QAfterFilterCondition> filteredQuery =
switch (state) { switch (state) {
case null: null => baseQuery.ownerIdEqualToAnyChecksum(ownerId).noOp(),
filteredQuery = baseQuery.ownerIdEqualToAnyChecksum(ownerId).noOp(); AssetState.local => baseQuery
case AssetState.local: .remoteIdIsNull()
filteredQuery = baseQuery .filter()
.remoteIdIsNull() .localIdIsNotNull()
.filter() .ownerIdEqualTo(ownerId),
.localIdIsNotNull() AssetState.remote => baseQuery
.ownerIdEqualTo(ownerId); .localIdIsNull()
case AssetState.remote: .filter()
filteredQuery = baseQuery .remoteIdIsNotNull()
.localIdIsNull() .ownerIdEqualTo(ownerId),
.filter() AssetState.merged => baseQuery
.remoteIdIsNotNull() .ownerIdEqualToAnyChecksum(ownerId)
.ownerIdEqualTo(ownerId); .filter()
case AssetState.merged: .remoteIdIsNotNull()
filteredQuery = baseQuery .localIdIsNotNull(),
.ownerIdEqualToAnyChecksum(ownerId) };
.filter()
.remoteIdIsNotNull()
.localIdIsNotNull();
}
final QueryBuilder<Asset, Asset, QAfterSortBy> query; final QueryBuilder<Asset, Asset, QAfterSortBy> query = switch (sortBy) {
switch (sortBy) { null => filteredQuery.noOp(),
case null: AssetSort.checksum => filteredQuery.sortByChecksum(),
query = filteredQuery.noOp(); AssetSort.ownerIdChecksum =>
case AssetSort.checksum: filteredQuery.sortByOwnerId().thenByChecksum(),
query = filteredQuery.sortByChecksum(); };
case AssetSort.ownerIdChecksum:
query = filteredQuery.sortByOwnerId().thenByChecksum();
}
return limit == null ? query.findAll() : query.limit(limit).findAll(); return limit == null ? query.findAll() : query.limit(limit).findAll();
} }
@ -155,17 +137,16 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository {
int limit = 100, int limit = 100,
}) { }) {
final baseQuery = db.assets.where(); final baseQuery = db.assets.where();
final QueryBuilder<Asset, Asset, QAfterFilterCondition> query; final QueryBuilder<Asset, Asset, QAfterFilterCondition> query =
switch (state) { switch (state) {
case null: null => baseQuery.noOp(),
query = baseQuery.noOp(); AssetState.local =>
case AssetState.local: baseQuery.remoteIdIsNull().filter().localIdIsNotNull(),
query = baseQuery.remoteIdIsNull().filter().localIdIsNotNull(); AssetState.remote =>
case AssetState.remote: baseQuery.localIdIsNull().filter().remoteIdIsNotNull(),
query = baseQuery.localIdIsNull().filter().remoteIdIsNotNull(); AssetState.merged =>
case AssetState.merged: baseQuery.localIdIsNotNull().filter().remoteIdIsNotNull(),
query = baseQuery.localIdIsNotNull().filter().remoteIdIsNotNull(); };
}
return _getMatchesImpl(query, ownerId, assets, limit); return _getMatchesImpl(query, ownerId, assets, limit);
} }

View File

@ -14,13 +14,11 @@ class BackupRepository extends DatabaseRepository implements IBackupRepository {
@override @override
Future<List<BackupAlbum>> getAll({BackupAlbumSort? sort}) { Future<List<BackupAlbum>> getAll({BackupAlbumSort? sort}) {
final baseQuery = db.backupAlbums.where(); final baseQuery = db.backupAlbums.where();
final QueryBuilder<BackupAlbum, BackupAlbum, QAfterSortBy> query; final QueryBuilder<BackupAlbum, BackupAlbum, QAfterSortBy> query =
switch (sort) { switch (sort) {
case null: null => baseQuery.noOp(),
query = baseQuery.noOp(); BackupAlbumSort.id => baseQuery.sortById(),
case BackupAlbumSort.id: };
query = baseQuery.sortById();
}
return query.findAll(); return query.findAll();
} }

View File

@ -25,13 +25,10 @@ class UserRepository extends DatabaseRepository implements IUserRepository {
final int userId = Store.get(StoreKey.currentUser).isarId; final int userId = Store.get(StoreKey.currentUser).isarId;
final QueryBuilder<User, User, QAfterWhereClause> afterWhere = final QueryBuilder<User, User, QAfterWhereClause> afterWhere =
self ? baseQuery.noOp() : baseQuery.isarIdNotEqualTo(userId); self ? baseQuery.noOp() : baseQuery.isarIdNotEqualTo(userId);
final QueryBuilder<User, User, QAfterSortBy> query; final QueryBuilder<User, User, QAfterSortBy> query = switch (sortBy) {
switch (sortBy) { null => afterWhere.noOp(),
case null: UserSort.id => afterWhere.sortById(),
query = afterWhere.noOp(); };
case UserSort.id:
query = afterWhere.sortById();
}
return query.findAll(); return query.findAll();
} }

View File

@ -519,18 +519,12 @@ class BackupService {
return responseBody.containsKey('id') ? responseBody['id'] : null; return responseBody.containsKey('id') ? responseBody['id'] : null;
} }
String _getAssetType(AssetType assetType) { String _getAssetType(AssetType assetType) => switch (assetType) {
switch (assetType) { AssetType.audio => "AUDIO",
case AssetType.audio: AssetType.image => "IMAGE",
return "AUDIO"; AssetType.video => "VIDEO",
case AssetType.image: AssetType.other => "OTHER",
return "IMAGE"; };
case AssetType.video:
return "VIDEO";
case AssetType.other:
return "OTHER";
}
}
} }
class MultipartRequest extends http.MultipartRequest { class MultipartRequest extends http.MultipartRequest {

View File

@ -2,13 +2,8 @@ import 'package:flutter/material.dart';
import 'package:immich_mobile/entities/asset.entity.dart'; import 'package:immich_mobile/entities/asset.entity.dart';
/// Returns the suitable [IconData] to represent an [Asset]s storage location /// Returns the suitable [IconData] to represent an [Asset]s storage location
IconData storageIcon(Asset asset) { IconData storageIcon(Asset asset) => switch (asset.storage) {
switch (asset.storage) { AssetState.local => Icons.cloud_off_outlined,
case AssetState.local: AssetState.remote => Icons.cloud_outlined,
return Icons.cloud_off_outlined; AssetState.merged => Icons.cloud_done_outlined,
case AssetState.remote: };
return Icons.cloud_outlined;
case AssetState.merged:
return Icons.cloud_done_outlined;
}
}

View File

@ -15,36 +15,26 @@ class ImmichToast {
final fToast = FToast(); final fToast = FToast();
fToast.init(context); fToast.init(context);
Color getColor(ToastType type, BuildContext context) { Color getColor(ToastType type, BuildContext context) => switch (type) {
switch (type) { ToastType.info => context.primaryColor,
case ToastType.info: ToastType.success => const Color.fromARGB(255, 78, 140, 124),
return context.primaryColor; ToastType.error => const Color.fromARGB(255, 220, 48, 85),
case ToastType.success: };
return const Color.fromARGB(255, 78, 140, 124);
case ToastType.error:
return const Color.fromARGB(255, 220, 48, 85);
}
}
Icon getIcon(ToastType type) { Icon getIcon(ToastType type) => switch (type) {
switch (type) { ToastType.info => Icon(
case ToastType.info: Icons.info_outline_rounded,
return Icon( color: context.primaryColor,
Icons.info_outline_rounded, ),
color: context.primaryColor, ToastType.success => const Icon(
); Icons.check_circle_rounded,
case ToastType.success: color: Color.fromARGB(255, 78, 140, 124),
return const Icon( ),
Icons.check_circle_rounded, ToastType.error => const Icon(
color: Color.fromARGB(255, 78, 140, 124), Icons.error_outline_rounded,
); color: Color.fromARGB(255, 240, 162, 156),
case ToastType.error: ),
return const Icon( };
Icons.error_outline_rounded,
color: Color.fromARGB(255, 240, 162, 156),
);
}
}
fToast.showToast( fToast.showToast(
child: Container( child: Container(

View File

@ -590,21 +590,15 @@ class _PhotoViewState extends State<PhotoView>
} }
/// The default [ScaleStateCycle] /// The default [ScaleStateCycle]
PhotoViewScaleState defaultScaleStateCycle(PhotoViewScaleState actual) { PhotoViewScaleState defaultScaleStateCycle(PhotoViewScaleState actual) =>
switch (actual) { switch (actual) {
case PhotoViewScaleState.initial: PhotoViewScaleState.initial => PhotoViewScaleState.covering,
return PhotoViewScaleState.covering; PhotoViewScaleState.covering => PhotoViewScaleState.originalSize,
case PhotoViewScaleState.covering: PhotoViewScaleState.originalSize => PhotoViewScaleState.initial,
return PhotoViewScaleState.originalSize; PhotoViewScaleState.zoomedIn ||
case PhotoViewScaleState.originalSize: PhotoViewScaleState.zoomedOut =>
return PhotoViewScaleState.initial; PhotoViewScaleState.initial,
case PhotoViewScaleState.zoomedIn: };
case PhotoViewScaleState.zoomedOut:
return PhotoViewScaleState.initial;
default:
return PhotoViewScaleState.initial;
}
}
/// A type definition for a [Function] that receives the actual [PhotoViewScaleState] and returns the next one /// A type definition for a [Function] that receives the actual [PhotoViewScaleState] and returns the next one
/// It is used internally to walk in the "doubletap gesture cycle". /// It is used internally to walk in the "doubletap gesture cycle".

View File

@ -9,25 +9,20 @@ double getScaleForScaleState(
PhotoViewScaleState scaleState, PhotoViewScaleState scaleState,
ScaleBoundaries scaleBoundaries, ScaleBoundaries scaleBoundaries,
) { ) {
switch (scaleState) { return switch (scaleState) {
case PhotoViewScaleState.initial: PhotoViewScaleState.initial ||
case PhotoViewScaleState.zoomedIn: PhotoViewScaleState.zoomedIn ||
case PhotoViewScaleState.zoomedOut: PhotoViewScaleState.zoomedOut =>
return _clampSize(scaleBoundaries.initialScale, scaleBoundaries); _clampSize(scaleBoundaries.initialScale, scaleBoundaries),
case PhotoViewScaleState.covering: PhotoViewScaleState.covering => _clampSize(
return _clampSize(
_scaleForCovering( _scaleForCovering(
scaleBoundaries.outerSize, scaleBoundaries.outerSize,
scaleBoundaries.childSize, scaleBoundaries.childSize,
), ),
scaleBoundaries, scaleBoundaries,
); ),
case PhotoViewScaleState.originalSize: PhotoViewScaleState.originalSize => _clampSize(1.0, scaleBoundaries),
return _clampSize(1.0, scaleBoundaries); };
// Will never be reached
default:
return 0;
}
} }
/// Internal class to wraps custom scale boundaries (min, max and initial) /// Internal class to wraps custom scale boundaries (min, max and initial)

View File

@ -220,23 +220,20 @@ class NetworkStatusIcon extends StatelessWidget {
); );
} }
Widget _buildIcon(BuildContext context) { Widget _buildIcon(BuildContext context) => switch (status) {
switch (status) { AuxCheckStatus.loading => Padding(
case AuxCheckStatus.loading: padding: const EdgeInsets.only(left: 4.0),
return Padding( child: SizedBox(
padding: const EdgeInsets.only(left: 4.0), width: 18,
child: SizedBox( height: 18,
width: 18, child: CircularProgressIndicator(
height: 18, color: context.primaryColor,
child: CircularProgressIndicator( strokeWidth: 2,
color: context.primaryColor, key: const ValueKey('loading'),
strokeWidth: 2, ),
key: const ValueKey('loading'),
), ),
), ),
); AuxCheckStatus.valid => enabled
case AuxCheckStatus.valid:
return enabled
? const Icon( ? const Icon(
Icons.check_circle_rounded, Icons.check_circle_rounded,
color: Colors.green, color: Colors.green,
@ -246,9 +243,8 @@ class NetworkStatusIcon extends StatelessWidget {
Icons.check_circle_rounded, Icons.check_circle_rounded,
color: context.colorScheme.onSurface.withAlpha(100), color: context.colorScheme.onSurface.withAlpha(100),
key: const ValueKey('success'), key: const ValueKey('success'),
); ),
case AuxCheckStatus.error: AuxCheckStatus.error => enabled
return enabled
? const Icon( ? const Icon(
Icons.error_rounded, Icons.error_rounded,
color: Colors.red, color: Colors.red,
@ -258,9 +254,7 @@ class NetworkStatusIcon extends StatelessWidget {
Icons.error_rounded, Icons.error_rounded,
color: Colors.grey, color: Colors.grey,
key: ValueKey('error'), key: ValueKey('error'),
); ),
default: _ => const Icon(Icons.circle_outlined, key: ValueKey('unknown')),
return const Icon(Icons.circle_outlined, key: ValueKey('unknown')); };
}
}
} }