mirror of
https://github.com/KevinMidboe/immich.git
synced 2025-10-29 17:40:28 +00:00
feature(mobile): sync assets, albums & users to local database on device (#1759)
* feature(mobile): sync assets, albums & users to local database on device * try to fix tests * move DB sync operations to new SyncService * clear db on user logout * fix reason for endless loading timeline * fix error when deleting album * fix thumbnail of device albums * add a few comments * fix Hive box not open in album service when loading local assets * adjust tests to int IDs * fix bug: show all albums when Recent is selected * update generated api * reworked Recents album isAll handling * guard against wrongly interleaved sync operations * fix: timeline asset ordering (sort asset state by created at) * fix: sort assets in albums by created at
This commit is contained in:
committed by
GitHub
parent
8f11529a75
commit
8708867c1c
@@ -25,7 +25,7 @@ class AddToAlbumBottomSheet extends HookConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final albums = ref.watch(albumProvider);
|
||||
final albums = ref.watch(albumProvider).where((a) => a.isRemote).toList();
|
||||
final albumService = ref.watch(albumServiceProvider);
|
||||
final sharedAlbums = ref.watch(sharedAlbumProvider);
|
||||
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:immich_mobile/constants/hive_box.dart';
|
||||
import 'package:immich_mobile/shared/models/album.dart';
|
||||
import 'package:immich_mobile/utils/image_url_builder.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
import 'package:immich_mobile/shared/ui/immich_image.dart';
|
||||
|
||||
class AlbumThumbnailCard extends StatelessWidget {
|
||||
final Function()? onTap;
|
||||
@@ -20,7 +16,6 @@ class AlbumThumbnailCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var box = Hive.box(userInfoBox);
|
||||
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
@@ -42,21 +37,11 @@ class AlbumThumbnailCard extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
buildAlbumThumbnail() {
|
||||
return CachedNetworkImage(
|
||||
width: cardSize,
|
||||
height: cardSize,
|
||||
fit: BoxFit.cover,
|
||||
fadeInDuration: const Duration(milliseconds: 200),
|
||||
imageUrl: getAlbumThumbnailUrl(
|
||||
album,
|
||||
type: ThumbnailFormat.JPEG,
|
||||
),
|
||||
httpHeaders: {"Authorization": "Bearer ${box.get(accessTokenKey)}"},
|
||||
cacheKey:
|
||||
getAlbumThumbNailCacheKey(album, type: ThumbnailFormat.JPEG),
|
||||
);
|
||||
}
|
||||
buildAlbumThumbnail() => ImmichImage(
|
||||
album.thumbnail.value,
|
||||
width: cardSize,
|
||||
height: cardSize,
|
||||
);
|
||||
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
@@ -72,7 +57,7 @@ class AlbumThumbnailCard extends StatelessWidget {
|
||||
height: cardSize,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
child: album.albumThumbnailAssetId == null
|
||||
child: album.thumbnail.value == null
|
||||
? buildEmptyThumbnail()
|
||||
: buildAlbumThumbnail(),
|
||||
),
|
||||
|
||||
@@ -68,7 +68,7 @@ class AlbumThumbnailListTile extends StatelessWidget {
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: album.albumThumbnailAssetId == null
|
||||
child: album.thumbnail.value == null
|
||||
? buildEmptyThumbnail()
|
||||
: buildAlbumThumbnail(),
|
||||
),
|
||||
|
||||
@@ -7,7 +7,6 @@ import 'package:immich_mobile/modules/album/providers/album.provider.dart';
|
||||
import 'package:immich_mobile/modules/album/providers/album_viewer.provider.dart';
|
||||
import 'package:immich_mobile/modules/album/providers/asset_selection.provider.dart';
|
||||
import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart';
|
||||
import 'package:immich_mobile/modules/album/services/album.service.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
import 'package:immich_mobile/shared/models/album.dart';
|
||||
import 'package:immich_mobile/shared/ui/immich_toast.dart';
|
||||
@@ -35,19 +34,18 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget {
|
||||
void onDeleteAlbumPressed() async {
|
||||
ImmichLoadingOverlayController.appLoader.show();
|
||||
|
||||
bool isSuccess = await ref.watch(albumServiceProvider).deleteAlbum(album);
|
||||
|
||||
if (isSuccess) {
|
||||
if (album.shared) {
|
||||
ref.watch(sharedAlbumProvider.notifier).deleteAlbum(album);
|
||||
AutoRouter.of(context)
|
||||
.navigate(const TabControllerRoute(children: [SharingRoute()]));
|
||||
} else {
|
||||
ref.watch(albumProvider.notifier).deleteAlbum(album);
|
||||
AutoRouter.of(context)
|
||||
.navigate(const TabControllerRoute(children: [LibraryRoute()]));
|
||||
}
|
||||
final bool success;
|
||||
if (album.shared) {
|
||||
success =
|
||||
await ref.watch(sharedAlbumProvider.notifier).deleteAlbum(album);
|
||||
AutoRouter.of(context)
|
||||
.navigate(const TabControllerRoute(children: [SharingRoute()]));
|
||||
} else {
|
||||
success = await ref.watch(albumProvider.notifier).deleteAlbum(album);
|
||||
AutoRouter.of(context)
|
||||
.navigate(const TabControllerRoute(children: [LibraryRoute()]));
|
||||
}
|
||||
if (!success) {
|
||||
ImmichToast.show(
|
||||
context: context,
|
||||
msg: "album_viewer_appbar_share_err_delete".tr(),
|
||||
@@ -208,11 +206,12 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget {
|
||||
: null,
|
||||
centerTitle: false,
|
||||
actions: [
|
||||
IconButton(
|
||||
splashRadius: 25,
|
||||
onPressed: buildBottomSheet,
|
||||
icon: const Icon(Icons.more_horiz_rounded),
|
||||
),
|
||||
if (album.isRemote)
|
||||
IconButton(
|
||||
splashRadius: 25,
|
||||
onPressed: buildBottomSheet,
|
||||
icon: const Icon(Icons.more_horiz_rounded),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/modules/favorite/providers/favorite_provider.dart';
|
||||
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
|
||||
import 'package:immich_mobile/modules/album/providers/asset_selection.provider.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
import 'package:immich_mobile/shared/models/asset.dart';
|
||||
@@ -22,7 +21,6 @@ class AlbumViewerThumbnail extends HookConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
var deviceId = ref.watch(authenticationProvider).deviceId;
|
||||
final selectedAssetsInAlbumViewer =
|
||||
ref.watch(assetSelectionProvider).selectedAssetsInAlbumViewer;
|
||||
final isMultiSelectionEnable =
|
||||
@@ -88,7 +86,7 @@ class AlbumViewerThumbnail extends HookConsumerWidget {
|
||||
bottom: 5,
|
||||
child: Icon(
|
||||
asset.isRemote
|
||||
? (deviceId == asset.deviceId
|
||||
? (asset.isLocal
|
||||
? Icons.cloud_done_outlined
|
||||
: Icons.cloud_outlined)
|
||||
: Icons.cloud_off_outlined,
|
||||
|
||||
Reference in New Issue
Block a user