-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathrepository_feature.dart
106 lines (92 loc) · 3.2 KB
/
repository_feature.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import 'package:dart_board_core/dart_board_core.dart';
import 'package:dart_board_locator/dart_board_locator.dart';
import 'package:faker_dart/faker_dart.dart';
import 'package:flutter/material.dart';
/// This is a repository Feature, it provides access to a Repository
class RepositoryFeature extends DartBoardFeature {
/// We give the repository to the feature to wire up.
final Repository repository;
/// Namespace is required for all Feature's. It must be unique per-feature
@override
String get namespace => "RepositoryFeature";
/// Construct this feature. Give it a repository interface
///
/// For our cases here, we'll just use a MockRepository
/// However you could implement your on Repository to fetch over the network
RepositoryFeature({required this.repository});
@override
List<DartBoardDecoration> get appDecorations => [
/// This decoration injects the Repository into the Widget tree
LocatorDecoration(() => repository),
];
}
/// A short record placeholder
/// meant to represent a search result
class ShortRecord {
final int id;
final String title;
final String price;
final String imageUrl;
ShortRecord(
{required this.id,
required this.title,
required this.price,
required this.imageUrl});
}
/// A long record, meant to represent the details page
class LongRecord extends ShortRecord {
final String description;
final String companyName;
LongRecord({
required int id,
required String title,
required String price,
required String imageUrl,
required this.description,
required this.companyName,
}) : super(id: id, title: title, price: price, imageUrl: imageUrl);
}
/// This is the interface for a Repository
///
/// It can pull a list of records or a long record by ID
/// In our case ID = idx of the record
abstract class Repository {
Future<List<ShortRecord>> performSearch();
Future<LongRecord> fetchDetails(int id);
}
/// This messenger is used to pass messages to the bound repository
///
/// This is syntactic sugar for the apps to use.
/// i.e.
/// `RepositoryMessenger.performSearch(context)`
/// or
/// `RepositoryMessenger.fetchDetails(context, id)`
class RepositoryMessenger {
/// Perform a "search"
static Future<List<ShortRecord>> performSearch(BuildContext context) =>
locate<Repository>().performSearch();
/// Fetch the "details"
static Future<LongRecord> fetchDetails(BuildContext context, int id) =>
locate<Repository>().fetchDetails(id);
}
/// This is a mock repository
class MockRepository extends Repository {
/// Internal record list, we generate on the fly.
late final List<LongRecord> _records = List.generate(200, (index) {
final city = Faker.instance.address.country();
return LongRecord(
id: index,
imageUrl:
Faker.instance.image.unsplash.nature(w: 200, h: 200, keyword: city),
title: city,
price: Faker.instance.commerce.price(),
description: Faker.instance.commerce.productDescription(),
companyName: Faker.instance.company.bsNoun());
});
@override
Future<List<ShortRecord>> performSearch() async {
return _records;
}
@override
Future<LongRecord> fetchDetails(int id) async => _records[id];
}