Skip to content

Commit 260323e

Browse files
authored
feat(llc, samples): add network and lifecycle state providers (#44)
1 parent 8ca0f19 commit 260323e

File tree

12 files changed

+118
-8
lines changed

12 files changed

+118
-8
lines changed

melos.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ command:
3434
firebase_messaging: ^15.0.0
3535
flex_grid_view: ^0.1.0
3636
flutter_local_notifications: ^18.0.1
37-
injectable: ^2.5.1
3837
http: ^1.1.0
38+
injectable: ^2.5.1
3939
intl: ">=0.18.1 <=0.21.0"
40+
internet_connection_checker_plus: ^2.9.0
4041
jiffy: ^6.3.2
4142
photo_view: ^0.15.0
4243
json_annotation: ^4.9.0
@@ -46,7 +47,7 @@ command:
4647
shared_preferences: ^2.5.3
4748
state_notifier: ^1.0.0
4849
stream_feeds: ^0.2.0
49-
stream_core: ^0.1.0
50+
stream_core: ^0.2.0
5051
video_player: ^2.10.0
5152
uuid: ^4.5.1
5253

packages/stream_feeds/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## Unreleased
2+
- [BREAKING] Renamed `AppLifecycleStateProvider` to `LifecycleStateProvider` and `AppLifecycleState` to `LifecycleState`.
3+
14
## 0.2.0
25
- [BREAKING] Update API client code, specifically the FeedOwnCapability enum.
36
- Fix unknown enums for `List<FeedOwnCapability>` in `GetOrCreateFeedResponse` to be `FeedOwnCapability.unknown`.

packages/stream_feeds/lib/src/client/feeds_client_impl.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class StreamFeedsClientImpl implements StreamFeedsClient {
6363
TokenProvider? tokenProvider,
6464
RetryStrategy? retryStrategy,
6565
NetworkStateProvider? networkStateProvider,
66-
AppLifecycleStateProvider? appLifecycleStateProvider,
66+
LifecycleStateProvider? lifecycleStateProvider,
6767
List<AutomaticReconnectionPolicy>? reconnectionPolicies,
6868
}) {
6969
// TODO: Make this configurable
@@ -111,7 +111,7 @@ class StreamFeedsClientImpl implements StreamFeedsClient {
111111
client: _ws,
112112
retryStrategy: retryStrategy,
113113
networkStateProvider: networkStateProvider,
114-
appLifecycleStateProvider: appLifecycleStateProvider,
114+
lifecycleStateProvider: lifecycleStateProvider,
115115
policies: reconnectionPolicies,
116116
);
117117

packages/stream_feeds/lib/src/feeds_client.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ abstract interface class StreamFeedsClient {
158158
TokenProvider? tokenProvider,
159159
RetryStrategy? retryStrategy,
160160
NetworkStateProvider? networkStateProvider,
161-
AppLifecycleStateProvider? appLifecycleStateProvider,
161+
LifecycleStateProvider? lifecycleStateProvider,
162162
List<AutomaticReconnectionPolicy>? reconnectionPolicies,
163163
}) = StreamFeedsClientImpl;
164164

packages/stream_feeds/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ dependencies:
3232
retrofit: ^4.6.0
3333
rxdart: ^0.28.0
3434
state_notifier: ^1.0.0
35-
stream_core: ^0.1.0
35+
stream_core: ^0.2.0
3636
uuid: ^4.5.1
3737

3838
dev_dependencies:

sample_app/lib/app/content/auth_controller.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@ class AuthController extends ValueNotifier<AuthState> {
1414
this._appPreferences,
1515
@Named('apn') this._iosPushProvider,
1616
@Named('firebase') this._androidPushProvider,
17+
this._networkStateProvider,
18+
this._lifecycleStateProvider,
1719
) : super(const Unauthenticated());
1820

1921
final AppPreferences _appPreferences;
2022
final PushProvider _iosPushProvider;
2123
final PushProvider _androidPushProvider;
24+
final NetworkStateProvider _networkStateProvider;
25+
final LifecycleStateProvider _lifecycleStateProvider;
2226

2327
PushTokenManager? _pushTokenManager;
2428

@@ -31,6 +35,8 @@ class AuthController extends ValueNotifier<AuthState> {
3135
user: credentials.user,
3236
apiKey: DemoAppConfig.current.apiKey,
3337
tokenProvider: TokenProvider.static(token),
38+
networkStateProvider: _networkStateProvider,
39+
lifecycleStateProvider: _lifecycleStateProvider,
3440
);
3541

3642
final result = await runSafely(client.connect);

sample_app/lib/core/di/app_module.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:firebase_core/firebase_core.dart';
22
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
33
import 'package:injectable/injectable.dart';
4+
import 'package:internet_connection_checker_plus/internet_connection_checker_plus.dart';
45
import 'package:shared_preferences/shared_preferences.dart';
56

67
import '../../firebase_options.dart';
@@ -30,4 +31,7 @@ abstract class AppModule {
3031

3132
@lazySingleton
3233
LocalNotification get localNotifications => LocalNotification();
34+
35+
@lazySingleton
36+
InternetConnection get internet => InternetConnection.createInstance();
3337
}

sample_app/lib/core/di/di_initializer.config.dart

Lines changed: 13 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import 'dart:async';
2+
3+
import 'package:flutter/cupertino.dart';
4+
import 'package:injectable/injectable.dart';
5+
import 'package:stream_feeds/stream_feeds.dart';
6+
7+
@LazySingleton(as: LifecycleStateProvider)
8+
class AppLifecycleStateProvider
9+
with Disposable, WidgetsBindingObserver
10+
implements LifecycleStateProvider {
11+
AppLifecycleStateProvider() {
12+
// Start listening to lifecycle changes.
13+
WidgetsBinding.instance.addObserver(this);
14+
}
15+
16+
@override
17+
LifecycleStateEmitter get state => _state;
18+
late final _state = MutableStateEmitter(LifecycleState.foreground);
19+
20+
@override
21+
void didChangeAppLifecycleState(AppLifecycleState state) {
22+
final wasInBackground = _state.value == LifecycleState.background;
23+
final isInBackground = !_isAppInForeground(state);
24+
25+
if (wasInBackground && !isInBackground) {
26+
_state.value = LifecycleState.foreground;
27+
} else if (!wasInBackground && isInBackground) {
28+
_state.value = LifecycleState.background;
29+
}
30+
}
31+
32+
bool _isAppInForeground(AppLifecycleState state) {
33+
return switch (state) {
34+
AppLifecycleState.resumed || AppLifecycleState.inactive => true,
35+
_ => false,
36+
};
37+
}
38+
39+
@override
40+
Future<void> dispose() async {
41+
await _state.close();
42+
WidgetsBinding.instance.removeObserver(this);
43+
return super.dispose();
44+
}
45+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import 'dart:async';
2+
3+
import 'package:injectable/injectable.dart';
4+
import 'package:internet_connection_checker_plus/internet_connection_checker_plus.dart';
5+
import 'package:stream_feeds/stream_feeds.dart';
6+
7+
@LazySingleton(as: NetworkStateProvider)
8+
final class InternetStateProvider
9+
with Disposable
10+
implements NetworkStateProvider {
11+
InternetStateProvider({
12+
required InternetConnection checker,
13+
}) : _checker = checker {
14+
// Subscribe to the status changes.
15+
_connectionSubscription = _checker.onStatusChange.listen(_onStatusChange);
16+
}
17+
18+
final InternetConnection _checker;
19+
20+
@override
21+
NetworkStateEmitter get state => _state;
22+
late final _state = MutableStateEmitter(NetworkState.unknown);
23+
24+
StreamSubscription<InternetStatus>? _connectionSubscription;
25+
void _onStatusChange(InternetStatus status) {
26+
_state.value = switch (status) {
27+
InternetStatus.connected => NetworkState.connected,
28+
InternetStatus.disconnected => NetworkState.disconnected,
29+
};
30+
}
31+
32+
@override
33+
Future<void> dispose() async {
34+
await _state.close();
35+
await _connectionSubscription?.cancel();
36+
return super.dispose();
37+
}
38+
}

0 commit comments

Comments
 (0)