feat(market): search + pull-to-refresh in the market list
Match the inventory patterns the market was missing: - Search: OffersState gains a `query` + `visibleOffers` getter and OffersCubit.search() filters the already-discovered offers locally by summary (case-insensitive), never re-hitting the transport. The filter survives a refresh. Rounded search field mirrors inventory's. - Pull-to-refresh: RefreshIndicator re-runs discovery for the current area (empty state included, so a swipe re-scans). Text filter kept. - i18n: market.searchHint / market.noMatches (en/es/pt). Note: the shared slang output (strings*.g.dart, incl. the generated Asturian locale) is regenerated wholesale, so it also carries the in-progress `ast` locale keys already present in the working tree.
This commit is contained in:
parent
cc762a139c
commit
8d1a66e7b8
11 changed files with 1614 additions and 21 deletions
|
|
@ -102,6 +102,56 @@ void main() {
|
|||
await cubit.close();
|
||||
});
|
||||
|
||||
test('search narrows visible offers by summary, keeping the full list',
|
||||
() async {
|
||||
final transport = FakeOfferTransport();
|
||||
for (final s in ['Tomate rosa', 'Judía verde', 'Tomate rojo']) {
|
||||
await transport.publish(OfferMapper.fromSharedLot(
|
||||
lotId: s,
|
||||
authorPubkeyHex: 'ab' * 32,
|
||||
summary: s,
|
||||
sharing: OfferStatus.shared,
|
||||
areaGeohash: 'sp3e9',
|
||||
));
|
||||
}
|
||||
final cubit = OffersCubit(transport);
|
||||
await cubit.discover('sp3');
|
||||
await pumpEventQueue();
|
||||
expect(cubit.state.offers, hasLength(3));
|
||||
|
||||
cubit.search('tomate'); // case-insensitive
|
||||
expect(cubit.state.visibleOffers.map((o) => o.summary),
|
||||
containsAll(['Tomate rosa', 'Tomate rojo']));
|
||||
expect(cubit.state.visibleOffers, hasLength(2));
|
||||
expect(cubit.state.offers, hasLength(3)); // underlying list untouched
|
||||
|
||||
cubit.search(''); // clearing shows everything again
|
||||
expect(cubit.state.visibleOffers, hasLength(3));
|
||||
await cubit.close();
|
||||
});
|
||||
|
||||
test('the search filter survives a refresh (re-discovery)', () async {
|
||||
final transport = FakeOfferTransport();
|
||||
await transport.publish(OfferMapper.fromSharedLot(
|
||||
lotId: 'lot-1',
|
||||
authorPubkeyHex: 'ab' * 32,
|
||||
summary: 'Pimiento',
|
||||
sharing: OfferStatus.shared,
|
||||
areaGeohash: 'sp3e9',
|
||||
));
|
||||
final cubit = OffersCubit(transport);
|
||||
await cubit.discover('sp3');
|
||||
await pumpEventQueue();
|
||||
cubit.search('pim');
|
||||
expect(cubit.state.query, 'pim');
|
||||
|
||||
await cubit.discover('sp3'); // pull-to-refresh
|
||||
await pumpEventQueue();
|
||||
expect(cubit.state.query, 'pim'); // kept across the refresh
|
||||
expect(cubit.state.visibleOffers, hasLength(1));
|
||||
await cubit.close();
|
||||
});
|
||||
|
||||
test('a different area finds nothing', () async {
|
||||
final transport = FakeOfferTransport();
|
||||
await transport.publish(OfferMapper.fromSharedLot(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue