feat(market): saved searches with in-app alerts (Wallapop-style)
Save the current market search (query + facets) and get notified when a matching offer appears in your zone while the app is open, with a catch-up scan on start. Adds a save affordance in the search bar, a saved-searches list (apply/delete) with a per-search new-match badge, an AppBar entry badged with the unseen total, and notification-tap routing to the list. Alerts evaluate against the user's current area, dedup via seen keys, and skip own/blocked/hidden/non-active offers. en+es strings.
This commit is contained in:
parent
c0cd299408
commit
93028c4933
9 changed files with 549 additions and 4 deletions
|
|
@ -18,6 +18,7 @@ import 'services/onboarding_store.dart';
|
|||
import 'services/profile_cache.dart';
|
||||
import 'services/profile_store.dart';
|
||||
import 'services/saved_offers_store.dart';
|
||||
import 'services/saved_searches_store.dart';
|
||||
import 'services/social_account_store.dart';
|
||||
import 'services/social_connection.dart';
|
||||
import 'services/social_service.dart';
|
||||
|
|
@ -36,6 +37,7 @@ import 'ui/inventory_list_screen.dart';
|
|||
import 'ui/legal_screen.dart';
|
||||
import 'ui/plantares_screen.dart';
|
||||
import 'ui/sales_screen.dart';
|
||||
import 'ui/saved_searches_screen.dart';
|
||||
import 'ui/market_offer_detail_screen.dart';
|
||||
import 'ui/market_screen.dart';
|
||||
import 'ui/offline_banner.dart';
|
||||
|
|
@ -62,6 +64,7 @@ class TaneApp extends StatelessWidget {
|
|||
this.profileStore,
|
||||
this.profileCache,
|
||||
this.savedOffers,
|
||||
this.savedSearches,
|
||||
this.socialAccounts,
|
||||
this.inbox,
|
||||
this.notifications,
|
||||
|
|
@ -81,6 +84,7 @@ class TaneApp extends StatelessWidget {
|
|||
profileStore,
|
||||
profileCache,
|
||||
savedOffers,
|
||||
savedSearches,
|
||||
socialAccounts,
|
||||
inbox,
|
||||
) {
|
||||
|
|
@ -88,6 +92,8 @@ class TaneApp extends StatelessWidget {
|
|||
// the router only exists now; taps only happen while the app is foreground,
|
||||
// so a live router reference is enough.
|
||||
notifications?.onTapChat = (pubkey) => _router.push('/chat/$pubkey');
|
||||
// A tapped saved-search alert opens the saved-searches list.
|
||||
notifications?.onTapSearch = (_) => _router.push('/saved-searches');
|
||||
}
|
||||
|
||||
final VarietyRepository repository;
|
||||
|
|
@ -120,6 +126,9 @@ class TaneApp extends StatelessWidget {
|
|||
/// Optional store of the user's saved ("favorite") market offers.
|
||||
final SavedOffersStore? savedOffers;
|
||||
|
||||
/// Optional store of the user's saved market searches (with alerts).
|
||||
final SavedSearchesStore? savedSearches;
|
||||
|
||||
/// Optional store of the active social identity, for the profile switcher.
|
||||
final SocialAccountStore? socialAccounts;
|
||||
|
||||
|
|
@ -149,6 +158,7 @@ class TaneApp extends StatelessWidget {
|
|||
ProfileStore? profileStore,
|
||||
ProfileCache? profileCache,
|
||||
SavedOffersStore? savedOffers,
|
||||
SavedSearchesStore? savedSearches,
|
||||
SocialAccountStore? socialAccounts,
|
||||
InboxService? inbox,
|
||||
) {
|
||||
|
|
@ -170,6 +180,7 @@ class TaneApp extends StatelessWidget {
|
|||
location: location,
|
||||
outbox: outbox,
|
||||
onboarding: onboarding,
|
||||
savedSearches: savedSearches,
|
||||
),
|
||||
),
|
||||
if (social != null && connection != null)
|
||||
|
|
@ -196,6 +207,12 @@ class TaneApp extends StatelessWidget {
|
|||
connection: connection,
|
||||
),
|
||||
),
|
||||
if (social != null && savedSearches != null)
|
||||
GoRoute(
|
||||
path: '/saved-searches',
|
||||
builder: (context, state) =>
|
||||
SavedSearchesScreen(store: savedSearches),
|
||||
),
|
||||
if (messageStore != null)
|
||||
GoRoute(
|
||||
path: '/messages',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue