feat(market): save others' offers as favorites (Wallapop-style)

Adds a Favorites feature: a heart on the offer detail saves another
person's listing to an encrypted, per-identity SavedOffersStore
(keystore JSON snapshot, no plaintext at rest). A new /favorites screen
(wired from the drawer) lists saved offers offline-first and, when a
relay is reachable, flags ones that are gone as "no longer available".
i18n en/es/pt/ast; store + screen + detail-heart tests.
This commit is contained in:
vjrj 2026-07-13 08:21:43 +02:00
parent f6967e8cbb
commit d6225eed38
19 changed files with 806 additions and 3 deletions

View file

@ -39,6 +39,7 @@ import '../services/message_store.dart';
import '../services/offer_outbox.dart';
import '../services/profile_cache.dart';
import '../services/profile_store.dart';
import '../services/saved_offers_store.dart';
import '../services/social_account_store.dart';
import '../services/social_connection.dart';
import '../services/social_service.dart';
@ -184,6 +185,9 @@ Future<void> configureDependencies() async {
..registerSingleton<ProfileCache>(
ProfileCache(secretStore, accountScope: scope),
)
..registerSingleton<SavedOffersStore>(
SavedOffersStore(secretStore, accountScope: scope),
)
..registerSingleton<ExportImportService>(
ExportImportService(
repository: varietyRepository,
@ -301,6 +305,8 @@ Future<void> switchSocialAccount(int account) async {
await getIt.unregister<MessageStore>();
await getIt.unregister<ProfileStore>();
await getIt.unregister<ProfileCache>();
await getIt<SavedOffersStore>().close();
await getIt.unregister<SavedOffersStore>();
// Re-register the per-identity stores under the new scope, then the identity.
getIt
@ -313,6 +319,9 @@ Future<void> switchSocialAccount(int account) async {
..registerSingleton<ProfileCache>(
ProfileCache(secretStore, accountScope: scope),
)
..registerSingleton<SavedOffersStore>(
SavedOffersStore(secretStore, accountScope: scope),
)
..registerSingleton<UnreadService>(
UnreadService(getIt<MessageStore>(), secretStore),
);