Skip to content

Commit 9f5dab4

Browse files
committed
fix: assorted changes to alerter widget
1 parent b927cff commit 9f5dab4

File tree

6 files changed

+38
-20
lines changed

6 files changed

+38
-20
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.0.4
2+
3+
- Updates the `Alerter` widget to include an `Option` type for the previous alert state in its `listenAlertsIf` function, as it may be absent when there is no default alert, unlike the default state which is always present.
4+
15
## 0.0.3
26

37
- README updates.

README.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,9 @@ class AuthTrent extends Trent<AuthTypes> {
150150
..as<C>((_) {
151151
// Called if `C` is alerted
152152
}),
153-
154153
// Only trigger listens if...
155-
listenAlertsIf: (oldAlert, newAlert) => true,
156-
listenStatesIf: (oldState, newState) => true,
154+
listenAlertsIf: (oldAlert, newAlert) => true, // oldAlert is wrapped in an Option type because it may not exist
155+
listenStatesIf: (oldState, newState) => true, // Both of these are pure types since there will always be an old and new state
157156
child: Container(),
158157
);
159158
```
@@ -376,7 +375,6 @@ class AuthTrent extends Trent<AuthTypes> {
376375
- `watchMap<T, S>()`: Map state to specific UI widgets dynamically and reactively.
377376

378377
```dart
379-
Copy code
380378
watchMap<WeatherTrent, WeatherTypes>(context, (mapper) {
381379
mapper
382380
..as<Sunny>((state) => Text("Sunny: ${state.temperature}°C"))
@@ -512,7 +510,7 @@ class MyApp extends StatelessWidget {
512510

513511
### 5. Call Business Logic Functions From UI
514512

515-
To call business logic functions from the UI, use the `get<T>()` utility to retrieve your Trent instance. This allows you to trigger state changes or logic directly from the UI layer.
513+
To call business logic functions from the UI, use the `get<T>()` utility to retrieve your Trent instance. This allows you to trigger state changes or logic directly from the UI layer. This, of course, is assuming you have a `Trent` instance registered in the `TrentManager`.
516514

517515
#### Example
518516

@@ -576,7 +574,7 @@ class WeatherScreen extends StatelessWidget {
576574

577575
1. Retrieve the Trent instance: Use `get<T>()` to fetch the Trent instance. We use `get` instead of `watch` because `get` retrieves the Trent instance directly, while `watch` is used for reactive UI updates.
578576
2. Call methods: Trigger the desired business logic function, such as `updateToSunny`, `updateToRainy`, or `resetState`.
579-
3. UI updates: The UI automatically reacts to the state changes if `Digester`, `watch`, `watchMap`, or `Alerter` is used in the same widget tree.
577+
3. UI updates: The UI automatically reacts to the state changes if `Digester`, `watch`, `watchMap`, or `Alerter` are used in the widget tree below where the Trent was registered.
580578

581579
### 6. Use `Alerter`, `Digester`, `watch`, and `watchMap` in Your UI
582580

@@ -597,6 +595,13 @@ class WeatherScreen extends StatelessWidget {
597595
);
598596
});
599597
},
598+
listenAlertsIf: (oldState, newState) => true,
599+
listenStates: (mapper) {
600+
mapper
601+
..as<Sunny>((state) => print(state))
602+
..as<Rainy>((state) => print(state))
603+
..orElse((_) => const Text("No Data"));
604+
},
600605
child: Digester<WeatherTrent, WeatherTypes>(
601606
child: (mapper) {
602607
mapper
@@ -648,7 +653,7 @@ class WeatherScreen extends StatelessWidget {
648653

649654
### 7. Testing Your Trent
650655

651-
Add tests to ensure your Trent works as expected.
656+
Add tests to ensure your Trent works as expected. Existing tests can be found [here](https://github.com/mattrltrent/trent/tree/main/test).
652657

653658
```dart
654659
void main() {

example/lib/main.dart

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ class _HomeScreenState extends State<HomeScreen> {
7979
_latitudeController.clear();
8080
_longitudeController.clear();
8181
}),
82-
8382
child: Padding(
8483
padding: const EdgeInsets.all(16.0),
8584
child: Column(
@@ -106,7 +105,8 @@ class _HomeScreenState extends State<HomeScreen> {
106105
TextButton(
107106
onPressed: () {
108107
final latitude = double.tryParse(_latitudeController.text);
109-
final longitude = double.tryParse(_longitudeController.text);
108+
final longitude =
109+
double.tryParse(_longitudeController.text);
110110

111111
if (latitude != null && longitude != null) {
112112
weatherTrent.fetchWeather(latitude, longitude);
@@ -122,8 +122,10 @@ class _HomeScreenState extends State<HomeScreen> {
122122
child: Digester<WeatherTrent, WeatherTypes>(
123123
child: (mapper) {
124124
mapper
125-
..as<NoData>((state) => const Text("Please enter location to fetch weather."))
126-
..as<Loading>((state) => const CupertinoActivityIndicator())
125+
..as<NoData>((state) => const Text(
126+
"Please enter location to fetch weather."))
127+
..as<Loading>(
128+
(state) => const CupertinoActivityIndicator())
127129
..as<Data>((state) => Text(
128130
"${state.location} has temperature ${state.temperature}°C",
129131
style: const TextStyle(fontSize: 18),
@@ -192,7 +194,9 @@ class WeatherTrent extends Trent<WeatherTypes> {
192194
emit(Loading());
193195
Future.delayed(const Duration(milliseconds: 500), () {
194196
final mockData = {
195-
"temperature": double.parse((15 + (latitude % 10) + Random().nextDouble() * 5).toStringAsFixed(1)),
197+
"temperature": double.parse(
198+
(15 + (latitude % 10) + Random().nextDouble() * 5)
199+
.toStringAsFixed(1)),
196200
"location": "$latitude, $longitude",
197201
};
198202

lib/src/logic/trent.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,18 @@ abstract class Trents<Base> extends ChangeNotifier {
9696
/// to return to D(value: 10) instead of D(value: some_value_you_must_define).
9797
Option<T> getExStateAs<T extends Base>() {
9898
return _lastStates[T] != null
99-
? _lastStates[T]!.match(some: (v) => Option.some(v as T), none: () => Option<T>.none())
99+
? _lastStates[T]!.match(
100+
some: (v) => Option.some(v as T), none: () => Option<T>.none())
100101
: Option<T>.none();
101102
}
102103

103104
/// Retrieve the current state as a specific type.
104105
///
105106
/// Will return None if the current state is not of the specified type.
106107
Option<T> getCurrStateAs<T extends Base>() {
107-
return _state.runtimeType == T ? Option.some(_state as T) : Option<T>.none();
108+
return _state.runtimeType == T
109+
? Option.some(_state as T)
110+
: Option<T>.none();
108111
}
109112

110113
/// Dispose of the Trent.
@@ -129,6 +132,7 @@ abstract class Copyable<T> {
129132
}
130133

131134
/// A generic Trent that manages state transitions.
132-
abstract class Trent<Base extends EquatableCopyable<Base>> extends Trents<Base> {
135+
abstract class Trent<Base extends EquatableCopyable<Base>>
136+
extends Trents<Base> {
133137
Trent(super.state);
134138
}

lib/src/widgets/alerter.dart

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ class Alerter<TrentType extends Trents<StateType>, StateType>
99
final void Function(LogicSubTypeMapper<StateType> mapper)? listenAlerts;
1010

1111
/// Determines whether `listenAlerts` should trigger for a given alert.
12-
final bool Function(StateType oldAlert, StateType newAlert)? listenAlertsIf;
12+
final bool Function(Option<StateType> oldAlert, StateType newAlert)?
13+
listenAlertsIf;
1314

1415
/// Called when the normal state changes, using a mapper.
1516
final void Function(LogicSubTypeMapper<StateType> mapper)? listenStates;
@@ -36,15 +37,15 @@ class Alerter<TrentType extends Trents<StateType>, StateType>
3637
class AlerterState<TrentType extends Trents<StateType>, StateType>
3738
extends State<Alerter<TrentType, StateType>> {
3839
late final TrentType sm = get<TrentType>(context);
39-
late StateType _previousAlert; // Tracks the previous alert state
40+
Option<StateType> _previousAlert =
41+
Option.none(); // Tracks the previous alert state
4042
late StateType _previousState; // Tracks the previous normal state
4143
bool _hasInitialStateTriggered =
4244
false; // Tracks if the initial state has been emitted
4345

4446
@override
4547
void initState() {
4648
super.initState();
47-
_previousAlert = sm.state;
4849
_previousState = sm.state;
4950

5051
// Listen to the alert stream
@@ -57,7 +58,7 @@ class AlerterState<TrentType extends Trents<StateType>, StateType>
5758
widget.listenAlerts!(mapper);
5859
}
5960
}
60-
_previousAlert = alert;
61+
_previousAlert = Option.some(alert);
6162
});
6263

6364
// Listen to the state stream

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: trent
22
description: A Flutter package for simple, scalable, and reactive state management with built-in dependency injection and efficient stream-based state handling.
3-
version: 0.0.3
3+
version: 0.0.4
44

55
homepage: https://matthewtrent.me
66
repository: https://github.com/mattrltrent/trent

0 commit comments

Comments
 (0)