Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 37 additions & 30 deletions mobile/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,52 +26,59 @@ linter:
# producing the lint.

rules:
# Formatting
avoid_print: true
require_trailing_commas: true
unrelated_type_equality_checks: true
prefer_const_constructors: true
always_use_package_imports: true
always_put_control_body_on_new_line: true
unnecessary_null_checks: true
unnecessary_parenthesis: true
prefer_final_locals: true
prefer_const_declarations: true
prefer_const_literals_to_create_immutables: true
use_super_parameters: true
directives_ordering: true
no_leading_underscores_for_local_identifiers: true
# Correctness
always_declare_return_types: true
avoid_type_to_string: true
avoid_unused_constructor_parameters: true
avoid_void_async: true
noop_primitive_operations: true
use_named_constants: true
combinators_ordering: true
avoid_multiple_declarations_per_line: true
unnecessary_breaks: true

# Correctness
no_adjacent_strings_in_list: true
cancel_subscriptions: true
cast_nullable_to_non_nullable: true
close_sinks: true
unawaited_futures: true
collection_methods_unrelated_type: true
deprecated_consistency: true
discarded_futures: true
no_adjacent_strings_in_list: true
no_self_assignments: true
noop_primitive_operations: true
only_throw_errors: true
parameter_assignments: true
throw_in_finally: true
collection_methods_unrelated_type: true
cast_nullable_to_non_nullable: true
tighten_type_of_initializing_formals: true
unawaited_futures: true
unnecessary_ignore: true
unnecessary_null_checks: true
unnecessary_statements: true
unrelated_type_equality_checks: true

# Known issues
# Performance
avoid_slow_async_io: true
avoid_type_to_string: true
prefer_const_constructors: true
prefer_const_declarations: true
prefer_const_literals_to_create_immutables: true

# Flutter specific
use_build_context_synchronously: true
avoid_unnecessary_containers: true
sized_box_for_whitespace: true
use_build_context_synchronously: true
use_colored_box: true
use_decorated_box: true
avoid_unnecessary_containers: true
use_full_hex_values_for_flutter_colors: true

# Style
always_put_control_body_on_new_line: true
always_use_package_imports: true
avoid_multiple_declarations_per_line: true
avoid_print: true
combinators_ordering: true
directives_ordering: true
no_leading_underscores_for_local_identifiers: true
prefer_final_locals: true
require_trailing_commas: true
unnecessary_breaks: true
unnecessary_parenthesis: true
use_named_constants: true
use_super_parameters: true

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
analyzer:
Expand Down
1 change: 0 additions & 1 deletion mobile/lib/domain/models/memory.model.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert';

import 'package:freezed_annotation/freezed_annotation.dart';
Expand Down
1 change: 0 additions & 1 deletion mobile/lib/domain/models/user.model.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:ui';

import 'package:freezed_annotation/freezed_annotation.dart';
Expand Down
1 change: 0 additions & 1 deletion mobile/lib/models/download/download_state.model.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'package:background_downloader/background_downloader.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert';

enum LivePhotosPart { video, image }
Expand Down
1 change: 0 additions & 1 deletion mobile/lib/models/search/search_filter.model.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert';

import 'package:freezed_annotation/freezed_annotation.dart';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert';
import 'dart:io';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:async';
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/domain/models/person.model.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/string_extensions.dart';
import 'package:immich_mobile/generated/translations.g.dart';
Expand Down Expand Up @@ -65,12 +66,15 @@ class _DriftPeopleCollectionPageState extends ConsumerState<DriftPeopleCollectio
body: SafeArea(
child: people.when(
data: (people) {
final List<Person> filtered;
if (_search != null) {
people = people.where((person) {
filtered = people.where((person) {
return person.name.toLowerCase().removeDiacritics().contains(
_search!.toLowerCase().removeDiacritics(),
);
}).toList();
} else {
filtered = people;
}
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
Expand All @@ -79,9 +83,9 @@ class _DriftPeopleCollectionPageState extends ConsumerState<DriftPeopleCollectio
mainAxisSpacing: isPortrait && isTablet ? 36 : 0,
),
padding: const EdgeInsets.symmetric(vertical: 32),
itemCount: people.length,
itemCount: filtered.length,
itemBuilder: (context, index) {
final person = people[index];
final person = filtered[index];

return Column(
key: ValueKey(person.id),
Expand Down
9 changes: 6 additions & 3 deletions mobile/lib/presentation/pages/drift_place.page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,19 @@ class _PlaceList extends ConsumerWidget {
),
),
data: (places) {
final List<(String, String)> filtered;
if (search.value != null) {
places = places.where((place) {
filtered = places.where((place) {
return place.$1.toLowerCase().contains(search.value!.toLowerCase());
}).toList();
} else {
filtered = places;
}

return SliverList.builder(
itemCount: places.length,
itemCount: filtered.length,
itemBuilder: (context, index) {
final place = places[index];
final place = filtered[index];
return _PlaceTile(place: place);
},
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// ignore_for_file: require_trailing_commas

import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:immich_mobile/domain/models/events.model.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ class Scrubber extends ConsumerStatefulWidget {

Scrubber({
super.key,
Key? scrollThumbKey,
required this.layoutSegments,
required this.timelineHeight,
this.topPadding = 0,
Expand Down
33 changes: 9 additions & 24 deletions mobile/lib/providers/backup/backup_album.provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,40 +22,25 @@ class BackupAlbumNotifier extends StateNotifier<List<LocalAlbum>> {
}

Future<void> selectAlbum(LocalAlbum album) async {
album = album.copyWith(backupSelection: BackupSelection.selected);
await _localAlbumService.update(album);
final selectedAlbum = album.copyWith(backupSelection: BackupSelection.selected);
await _localAlbumService.update(selectedAlbum);

state = state
.map(
(currentAlbum) => currentAlbum.id == album.id
? currentAlbum.copyWith(backupSelection: BackupSelection.selected)
: currentAlbum,
)
.toList();
state = state.map((currentAlbum) => currentAlbum.id == selectedAlbum.id ? selectedAlbum : currentAlbum).toList();
}

Future<void> deselectAlbum(LocalAlbum album) async {
album = album.copyWith(backupSelection: BackupSelection.none);
await _localAlbumService.update(album);
final deselectedAlbum = album.copyWith(backupSelection: BackupSelection.none);
await _localAlbumService.update(deselectedAlbum);

state = state
.map(
(currentAlbum) =>
currentAlbum.id == album.id ? currentAlbum.copyWith(backupSelection: BackupSelection.none) : currentAlbum,
)
.map((currentAlbum) => currentAlbum.id == deselectedAlbum.id ? deselectedAlbum : currentAlbum)
.toList();
}

Future<void> excludeAlbum(LocalAlbum album) async {
album = album.copyWith(backupSelection: BackupSelection.excluded);
await _localAlbumService.update(album);
final excludedAlbum = album.copyWith(backupSelection: BackupSelection.excluded);
await _localAlbumService.update(excludedAlbum);

state = state
.map(
(currentAlbum) => currentAlbum.id == album.id
? currentAlbum.copyWith(backupSelection: BackupSelection.excluded)
: currentAlbum,
)
.toList();
state = state.map((currentAlbum) => currentAlbum.id == excludedAlbum.id ? excludedAlbum : currentAlbum).toList();
}
}
3 changes: 0 additions & 3 deletions mobile/lib/routing/router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ import 'package:immich_mobile/presentation/pages/profile/profile_picture_crop.pa
import 'package:immich_mobile/presentation/pages/search/drift_search.page.dart';
import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.page.dart';
import 'package:immich_mobile/providers/api.provider.dart';
import 'package:immich_mobile/providers/gallery_permission.provider.dart';
import 'package:immich_mobile/routing/auth_guard.dart';
import 'package:immich_mobile/routing/duplicate_guard.dart';
import 'package:immich_mobile/routing/locked_guard.dart';
Expand All @@ -88,7 +87,6 @@ final appRouterProvider = Provider(
(ref) => AppRouter(
ref.watch(apiServiceProvider),
ref.watch(authServiceProvider),
ref.watch(galleryPermissionNotifier.notifier),
ref.watch(secureStorageServiceProvider),
ref.watch(localAuthServiceProvider),
),
Expand All @@ -103,7 +101,6 @@ class AppRouter extends RootStackRouter {
AppRouter(
ApiService apiService,
AuthService authService,
GalleryPermissionNotifier galleryPermissionNotifier,
SecureStorageService secureStorageService,
LocalAuthService localAuthService,
) {
Expand Down
6 changes: 2 additions & 4 deletions mobile/lib/services/api.service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,10 @@ class ApiService {
}

Future<bool> _isEndpointAvailable(String serverUrl) async {
if (!serverUrl.endsWith('/api')) {
serverUrl += '/api';
}
final endpoint = serverUrl.endsWith('/api') ? serverUrl : '$serverUrl/api';

try {
setEndpoint(serverUrl);
setEndpoint(endpoint);
await serverInfoApi.pingServer().timeout(const Duration(seconds: 5));
} on TimeoutException catch (_) {
return false;
Expand Down
15 changes: 6 additions & 9 deletions mobile/lib/widgets/photo_view/photo_view_gallery.dart
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ class PhotoViewGallery extends StatefulWidget {
/// The builder must return a [PhotoViewGalleryPageOptions].
const PhotoViewGallery.builder({
super.key,
required this.itemCount,
required this.builder,
required int this.itemCount,
required PhotoViewGalleryBuilder this.builder,
this.loadingBuilder,
this.backgroundDecoration,
this.wantKeepAlive = false,
Expand All @@ -145,9 +145,7 @@ class PhotoViewGallery extends StatefulWidget {
this.customSize,
this.allowImplicitScrolling = false,
this.enablePanAlways = false,
}) : pageOptions = null,
assert(itemCount != null),
assert(builder != null);
}) : pageOptions = null;

/// A list of options to describe the items in the gallery
final List<PhotoViewGalleryPageOptions>? pageOptions;
Expand Down Expand Up @@ -352,9 +350,9 @@ class _PhotoViewGalleryState extends State<PhotoViewGallery> {
/// The [maxScale], [minScale] and [initialScale] options may be [double] or a [PhotoViewComputedScale] constant
///
class PhotoViewGalleryPageOptions {
PhotoViewGalleryPageOptions({
const PhotoViewGalleryPageOptions({
this.key,
required this.imageProvider,
required ImageProvider this.imageProvider,
this.heroAttributes,
this.semanticLabel,
this.minScale,
Expand All @@ -379,8 +377,7 @@ class PhotoViewGalleryPageOptions {
this.disableGestures,
this.errorBuilder,
}) : child = null,
childSize = null,
assert(imageProvider != null);
childSize = null;

const PhotoViewGalleryPageOptions.customChild({
this.key,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ class PhotoViewGestureRecognizer extends ScaleGestureRecognizer {
super.debugOwner,
this.validateAxis,
this.touchSlopFactor = 1,
PointerDeviceKind? kind,
this.disableScaleGestures = false,
}) : super(supportedDevices: null);
final HitCornersDetector? hitDetector;
Expand Down
30 changes: 12 additions & 18 deletions mobile/lib/widgets/photo_view/src/utils/photo_view_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,10 @@ class ScaleBoundaries {
double get minScale {
assert(_minScale is double || _minScale is PhotoViewComputedScale);
if (_minScale == PhotoViewComputedScale.contained) {
return _scaleForContained(outerSize, childSize) *
(_minScale as PhotoViewComputedScale).multiplier; // ignore: avoid_as
return _scaleForContained(outerSize, childSize) * (_minScale as PhotoViewComputedScale).multiplier;
}
if (_minScale == PhotoViewComputedScale.covered) {
return _scaleForCovering(outerSize, childSize) *
(_minScale as PhotoViewComputedScale).multiplier; // ignore: avoid_as
return _scaleForCovering(outerSize, childSize) * (_minScale as PhotoViewComputedScale).multiplier;
}
assert(_minScale >= 0.0);
return _minScale;
Expand All @@ -46,31 +44,27 @@ class ScaleBoundaries {
double get maxScale {
assert(_maxScale is double || _maxScale is PhotoViewComputedScale);
if (_maxScale == PhotoViewComputedScale.contained) {
return (_scaleForContained(outerSize, childSize) *
(_maxScale as PhotoViewComputedScale) // ignore: avoid_as
.multiplier)
.clamp(minScale, double.infinity);
return (_scaleForContained(outerSize, childSize) * (_maxScale as PhotoViewComputedScale).multiplier).clamp(
minScale,
double.infinity,
);
}
if (_maxScale == PhotoViewComputedScale.covered) {
return (_scaleForCovering(outerSize, childSize) *
(_maxScale as PhotoViewComputedScale) // ignore: avoid_as
.multiplier)
.clamp(minScale, double.infinity);
return (_scaleForCovering(outerSize, childSize) * (_maxScale as PhotoViewComputedScale).multiplier).clamp(
minScale,
double.infinity,
);
}
return _maxScale.clamp(minScale, double.infinity);
}

double get initialScale {
assert(_initialScale is double || _initialScale is PhotoViewComputedScale);
if (_initialScale == PhotoViewComputedScale.contained) {
return _scaleForContained(outerSize, childSize) *
(_initialScale as PhotoViewComputedScale) // ignore: avoid_as
.multiplier;
return _scaleForContained(outerSize, childSize) * (_initialScale as PhotoViewComputedScale).multiplier;
}
if (_initialScale == PhotoViewComputedScale.covered) {
return _scaleForCovering(outerSize, childSize) *
(_initialScale as PhotoViewComputedScale) // ignore: avoid_as
.multiplier;
return _scaleForCovering(outerSize, childSize) * (_initialScale as PhotoViewComputedScale).multiplier;
}
return _initialScale.clamp(minScale, maxScale);
}
Expand Down
2 changes: 1 addition & 1 deletion mobile/test/drift/main/migration_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// dart format width=80
// ignore_for_file: unused_local_variable, unused_import
// ignore_for_file: unused_import
import 'package:drift/drift.dart';
import 'package:drift_dev/api/migrations_native.dart';
import 'package:flutter_test/flutter_test.dart';
Expand Down
Loading
Loading