generated from ttipo/project-base
fix(flutter): 추억 보관함·순서 바꾸기도 서버 실패를 견디게
서버에 저장하면서 실패할 수 있게 된 남은 흐름을 정리했다. - 보관하기·다시 불러오기는 성공했을 때만 화면을 옮기고 토스트를 띄운다 - 우리 아이 순서 바꾸기는 화면에 먼저 반영하고, 저장하지 못하면 원래 순서로 되돌린다 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -37,7 +37,7 @@ class ArchivedPetPage extends ConsumerWidget {
|
||||
final String petId;
|
||||
|
||||
Future<void> _restore(BuildContext context, WidgetRef ref) async {
|
||||
await ref.read(archiveActionsProvider).restore(petId);
|
||||
if (!await ref.read(archiveActionsProvider).restore(petId)) return;
|
||||
if (context.mounted) context.go(AppRoutes.archive);
|
||||
}
|
||||
|
||||
|
||||
@@ -78,11 +78,11 @@ class _PetArchiveMovePageState extends ConsumerState<PetArchiveMovePage> {
|
||||
|
||||
Future<void> _submit(Pet pet, DateTime from) async {
|
||||
final memo = _memo.text.trim();
|
||||
await ref.read(archiveActionsProvider).archive(
|
||||
final moved = await ref.read(archiveActionsProvider).archive(
|
||||
pet.id,
|
||||
PetArchive(from: from, to: _to, archivedAt: DateTime.now(), memo: memo.isEmpty ? null : memo),
|
||||
);
|
||||
if (mounted) context.go(AppRoutes.myPage);
|
||||
if (moved && mounted) context.go(AppRoutes.myPage);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:tma_app/core/api/api_guard.dart';
|
||||
import 'package:tma_app/features/pet/domain/pet_archive.dart';
|
||||
import 'package:tma_app/features/pet/presentation/providers/pet_providers.dart';
|
||||
import 'package:tma_app/features/schedule/presentation/providers/schedule_providers.dart';
|
||||
@@ -11,17 +12,20 @@ class ArchiveActions {
|
||||
final Ref _ref;
|
||||
|
||||
/// 아이를 보관함으로 옮긴다. 일정은 지우고(여러 아이 일정이면 그 아이만 뗀다),
|
||||
/// 다이어리·펫 명함·정보는 그대로 두어 보관함에서 다시 볼 수 있게 한다.
|
||||
Future<void> archive(String petId, PetArchive archive) async {
|
||||
await _ref.read(petListProvider.notifier).archivePet(petId, archive);
|
||||
/// 다이어리·펫 명함·정보는 그대로 두어 보관함에서 다시 볼 수 있게 한다 (서버 모드는 일정 정리를 서버가 한다).
|
||||
/// 옮기지 못하면 false — 실패 알림은 인터셉터가 띄웠다.
|
||||
Future<bool> archive(String petId, PetArchive archive) async {
|
||||
if (!await succeeded(_ref.read(petListProvider.notifier).archivePet(petId, archive))) return false;
|
||||
await _ref.read(scheduleProvider.notifier).dropTarget(petId);
|
||||
_ref.read(toastProvider.notifier).show('추억보관함에 보관했어요.', tone: ToastTone.memory);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// 보관함에서 다시 불러온다 — 지운 일정은 돌아오지 않는다
|
||||
Future<void> restore(String petId) async {
|
||||
await _ref.read(petListProvider.notifier).restorePet(petId);
|
||||
/// 보관함에서 다시 불러온다 — 지운 일정은 돌아오지 않는다. 불러오지 못하면 false
|
||||
Future<bool> restore(String petId) async {
|
||||
if (!await succeeded(_ref.read(petListProvider.notifier).restorePet(petId))) return false;
|
||||
_ref.read(toastProvider.notifier).show('다시 불러왔어요');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:tma_app/core/api/api_guard.dart';
|
||||
import 'package:tma_app/core/constants/app_colors.dart';
|
||||
import 'package:tma_app/core/constants/app_sizes.dart';
|
||||
import 'package:tma_app/core/router/app_routes.dart';
|
||||
@@ -57,7 +58,7 @@ class _HomePetsSectionState extends ConsumerState<HomePetsSection> {
|
||||
selectedId: selected?.id,
|
||||
onSelect: (id) => ref.read(selectedPetIdProvider.notifier).select(id),
|
||||
// 꾹 눌러 끌어서 우리 아이 순서를 바꾼다
|
||||
onReorder: (ids) => unawaited(ref.read(petListProvider.notifier).reorder(ids)),
|
||||
onReorder: (ids) => unawaited(succeeded(ref.read(petListProvider.notifier).reorder(ids))),
|
||||
),
|
||||
if (selected != null) ...[
|
||||
const SizedBox(height: 20),
|
||||
|
||||
@@ -39,10 +39,17 @@ class PetListNotifier extends AsyncNotifier<List<Pet>> {
|
||||
|
||||
Future<void> archivePet(String id, PetArchive archive) async => _replace(await _repo.archive(id, archive));
|
||||
|
||||
/// 우리 아이 순서 바꾸기 — 화면에는 바로 반영하고 저장한다
|
||||
/// 우리 아이 순서 바꾸기 — 화면에는 바로 반영하고 저장한다. 저장하지 못하면 원래 순서로 되돌린다
|
||||
Future<void> reorder(List<String> ids) async {
|
||||
state = AsyncData(reorderPets(state.value ?? const <Pet>[], ids));
|
||||
await _repo.reorder(ids);
|
||||
final before = state.value ?? const <Pet>[];
|
||||
state = AsyncData(reorderPets(before, ids));
|
||||
try {
|
||||
final saved = await _repo.reorder(ids);
|
||||
if (ref.mounted) state = AsyncData(saved);
|
||||
} on Exception {
|
||||
if (ref.mounted) state = AsyncData(before);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> restorePet(String id) async => _replace(await _repo.restore(id));
|
||||
|
||||
Reference in New Issue
Block a user