feat(mobile): unify partner assets on timeline (#4974)
* feat(mobile): unify partner assets on timeline * skip non-owned assets in bulk actions * add message when trying to delete partner assets
This commit is contained in:
committed by
GitHub
parent
0c482960ce
commit
9fa9ad05b1
@@ -2,21 +2,31 @@ import 'dart:async';
|
||||
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/modules/album/providers/suggested_shared_users.provider.dart';
|
||||
import 'package:immich_mobile/modules/partner/services/partner.service.dart';
|
||||
import 'package:immich_mobile/shared/models/user.dart';
|
||||
import 'package:immich_mobile/shared/providers/db.provider.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
class PartnerSharedWithNotifier extends StateNotifier<List<User>> {
|
||||
PartnerSharedWithNotifier(Isar db) : super([]) {
|
||||
PartnerSharedWithNotifier(Isar db, this._ps) : super([]) {
|
||||
final query = db.users.filter().isPartnerSharedWithEqualTo(true);
|
||||
query.findAll().then((partners) => state = partners);
|
||||
query.watch().listen((partners) => state = partners);
|
||||
}
|
||||
|
||||
Future<bool> updatePartner(User partner, {required bool inTimeline}) {
|
||||
return _ps.updatePartner(partner, inTimeline: inTimeline);
|
||||
}
|
||||
|
||||
final PartnerService _ps;
|
||||
}
|
||||
|
||||
final partnerSharedWithProvider =
|
||||
StateNotifierProvider<PartnerSharedWithNotifier, List<User>>((ref) {
|
||||
return PartnerSharedWithNotifier(ref.watch(dbProvider));
|
||||
return PartnerSharedWithNotifier(
|
||||
ref.watch(dbProvider),
|
||||
ref.watch(partnerServiceProvider),
|
||||
);
|
||||
});
|
||||
|
||||
class PartnerSharedByNotifier extends StateNotifier<List<User>> {
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:immich_mobile/shared/providers/db.provider.dart';
|
||||
import 'package:immich_mobile/shared/services/api.service.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
|
||||
final partnerServiceProvider = Provider(
|
||||
(ref) => PartnerService(
|
||||
@@ -69,4 +70,19 @@ class PartnerService {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Future<bool> updatePartner(User partner, {required bool inTimeline}) async {
|
||||
try {
|
||||
final dto = await _apiService.partnerApi
|
||||
.updatePartner(partner.id, UpdatePartnerDto(inTimeline: inTimeline));
|
||||
if (dto != null) {
|
||||
partner.inTimeline = dto.inTimeline ?? partner.inTimeline;
|
||||
await _db.writeTxn(() => _db.users.put(partner));
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
_log.warning("failed to update partner ${partner.id}:\n$e");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
|
||||
import 'package:immich_mobile/modules/partner/providers/partner.provider.dart';
|
||||
import 'package:immich_mobile/shared/models/user.dart';
|
||||
import 'package:immich_mobile/shared/providers/asset.provider.dart';
|
||||
import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
|
||||
import 'package:immich_mobile/shared/ui/immich_toast.dart';
|
||||
|
||||
class PartnerDetailPage extends HookConsumerWidget {
|
||||
const PartnerDetailPage({Key? key, required this.partner}) : super(key: key);
|
||||
@@ -14,6 +16,8 @@ class PartnerDetailPage extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final assets = ref.watch(assetsProvider(partner.isarId));
|
||||
final inTimeline = useState(partner.inTimeline);
|
||||
bool toggleInProcess = false;
|
||||
|
||||
useEffect(
|
||||
() {
|
||||
@@ -23,11 +27,49 @@ class PartnerDetailPage extends HookConsumerWidget {
|
||||
[],
|
||||
);
|
||||
|
||||
void toggleInTimeline() async {
|
||||
if (toggleInProcess) return;
|
||||
toggleInProcess = true;
|
||||
try {
|
||||
final ok = await ref
|
||||
.read(partnerSharedWithProvider.notifier)
|
||||
.updatePartner(partner, inTimeline: !inTimeline.value);
|
||||
if (ok) {
|
||||
inTimeline.value = !inTimeline.value;
|
||||
final action = inTimeline.value ? "shown on" : "hidden from";
|
||||
ImmichToast.show(
|
||||
context: context,
|
||||
toastType: ToastType.success,
|
||||
durationInSecond: 1,
|
||||
msg: "${partner.name}'s assets $action your timeline",
|
||||
);
|
||||
} else {
|
||||
ImmichToast.show(
|
||||
context: context,
|
||||
toastType: ToastType.error,
|
||||
durationInSecond: 1,
|
||||
msg: "Failed to toggle the timeline setting",
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
toggleInProcess = false;
|
||||
}
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(partner.name),
|
||||
elevation: 0,
|
||||
centerTitle: false,
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: toggleInTimeline,
|
||||
icon: Icon(
|
||||
inTimeline.value ? Icons.collections : Icons.collections_outlined,
|
||||
),
|
||||
tooltip: "Show/hide photos on your main timeline",
|
||||
),
|
||||
],
|
||||
),
|
||||
body: assets.when(
|
||||
data: (renderList) => renderList.isEmpty
|
||||
|
||||
Reference in New Issue
Block a user