Skip to content

Commit 0954f67

Browse files
agordn52Anthony Gordon
authored andcommitted
chore(release): bump version to 7.19.0
1 parent e7a1dd0 commit 0954f67

6 files changed

Lines changed: 89 additions & 83 deletions

File tree

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
## [7.19.0] - 2026-04-12
2+
3+
### Changed (BREAKING)
4+
5+
* **`Connective` widget redesigned** - Flipped semantics from "show when connected" to "show when missing". Removed `onWifi`, `onMobile`, `onEthernet`, `onVpn`, `onBluetooth`, `onSatellite`, `onOther`, `onNone` parameters in favour of a single `noInternet` parameter that displays a fallback when the device has no internet (wifi, mobile, or ethernet). Migration: replace `onNone: widget` with `noInternet: widget`. Use `Connective.builder()` for any custom connectivity handling
6+
* **Removed `showLoadingOnInit` and `loadingWidget`** from `Connective` - the initial connectivity check is near-instant, making a loading state unnecessary
7+
* **`OfflineBanner` now checks for internet absence** (wifi/mobile/ethernet) rather than `NyConnectivityState.none`, correctly showing the banner when the device only has non-internet connections
8+
9+
### Added
10+
11+
* **New `NyConnectivity.hasInternet()` helper** - Checks specifically for wifi, mobile, or ethernet connectivity. Stricter than `isOnline()` which passes for any non-none result
12+
13+
### Fixed
14+
15+
* **`CollectionView.refreshData` state action** - Re-fetches data explicitly for both pullable and regular modes instead of relying on `reboot()`, resetting pagination, loading state, and footer state correctly
16+
117
## [7.18.1] - 2026-04-11
218

319
### Fixed

example/pubspec.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ packages:
483483
path: ".."
484484
relative: true
485485
source: path
486-
version: "7.17.0"
486+
version: "7.18.1"
487487
objective_c:
488488
dependency: transitive
489489
description:

lib/helpers/src/ny_connectivity.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,17 @@ class NyConnectivity {
8181
return results.contains(ConnectivityResult.bluetooth);
8282
}
8383

84+
/// Check if the device has internet connectivity (wifi, mobile, or ethernet).
85+
///
86+
/// Unlike [isOnline], this does not consider VPN, bluetooth, or satellite
87+
/// as internet connections.
88+
static Future<bool> hasInternet() async {
89+
final results = await status();
90+
return results.contains(ConnectivityResult.wifi) ||
91+
results.contains(ConnectivityResult.mobile) ||
92+
results.contains(ConnectivityResult.ethernet);
93+
}
94+
8495
/// Get a stream of connectivity changes.
8596
///
8697
/// Example:

lib/widgets/src/collection_view.dart

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,8 +621,30 @@ class _CollectionViewState<T> extends NyState<CollectionView<T>> {
621621
setState(() {});
622622
},
623623
'refreshData': (_) async {
624+
setLoading(true);
624625
_data = [];
625-
await reboot();
626+
_iteration = 1;
627+
_syncDataInitialized = false;
628+
if (widget.isPullable) {
629+
_refreshController.refreshCompleted(resetFooterState: true);
630+
}
631+
632+
try {
633+
dynamic result;
634+
if (widget.isPullable && widget.paginatedData != null) {
635+
result = await Future.value(widget.paginatedData!(_iteration));
636+
} else if (widget.data != null) {
637+
result = await Future.value(widget.data!());
638+
}
639+
if (result != null) {
640+
assert(result is List<T>, "Data must be a List<$T>");
641+
_data = result;
642+
}
643+
} catch (e) {
644+
NyLogger.error(e.toString());
645+
}
646+
647+
setLoading(false);
626648
},
627649
'addItem': (data) {
628650
if (data is! Map || !data.containsKey('item')) return;

lib/widgets/src/connective.dart

Lines changed: 37 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,18 @@ import '/localization/ny_localization.dart';
66

77
/// A widget that rebuilds based on connectivity state.
88
///
9-
/// Provides different builders for different connection types,
10-
/// or a general builder that receives the connectivity state.
9+
/// Use [noInternet] to show a fallback widget when the device has no
10+
/// internet connection (wifi, mobile, or ethernet).
1111
///
12-
/// Example with specific builders:
12+
/// Example:
1313
/// ```dart
1414
/// Connective(
15-
/// onWifi: Text('Connected via WiFi'),
16-
/// onMobile: Text('Connected via Mobile Data'),
17-
/// onNone: Text('No connection'),
15+
/// noInternet: Center(child: Text('No internet connection')),
16+
/// child: MyContent(),
1817
/// )
1918
/// ```
2019
///
21-
/// Example with builder:
20+
/// Example with builder for full control:
2221
/// ```dart
2322
/// Connective.builder(
2423
/// builder: (context, state, results) {
@@ -30,31 +29,10 @@ import '/localization/ny_localization.dart';
3029
/// )
3130
/// ```
3231
class Connective extends StatefulWidget {
33-
/// Widget to show when connected via WiFi.
34-
final Widget? onWifi;
35-
36-
/// Widget to show when connected via mobile data.
37-
final Widget? onMobile;
38-
39-
/// Widget to show when connected via Ethernet.
40-
final Widget? onEthernet;
41-
42-
/// Widget to show when connected via VPN.
43-
final Widget? onVpn;
44-
45-
/// Widget to show when connected via Bluetooth.
46-
final Widget? onBluetooth;
47-
48-
/// Widget to show when connected via Satellite.
49-
final Widget? onSatellite;
50-
51-
/// Widget to show for other connection types.
52-
final Widget? onOther;
32+
/// Widget to show when internet is unavailable (wifi, mobile, ethernet all absent).
33+
final Widget? noInternet;
5334

54-
/// Widget to show when offline.
55-
final Widget? onNone;
56-
57-
/// Default widget to show if no specific handler is provided.
35+
/// Default widget to show when internet is available.
5836
final Widget? child;
5937

6038
/// Builder function for custom handling.
@@ -65,59 +43,34 @@ class Connective extends StatefulWidget {
6543
)?
6644
builder;
6745

68-
/// Whether to show a loading indicator while checking initial state.
69-
final bool showLoadingOnInit;
70-
71-
/// Custom loading widget.
72-
final Widget? loadingWidget;
73-
7446
/// Callback when connectivity changes.
7547
final void Function(
7648
NyConnectivityState state,
7749
List<ConnectivityResult> results,
7850
)?
7951
onConnectivityChanged;
8052

81-
/// Creates a Connective widget with specific builders for each state.
53+
/// Creates a Connective widget with connectivity requirements.
8254
const Connective({
8355
super.key,
84-
this.onWifi,
85-
this.onMobile,
86-
this.onEthernet,
87-
this.onVpn,
88-
this.onBluetooth,
89-
this.onSatellite,
90-
this.onOther,
91-
this.onNone,
56+
this.noInternet,
9257
this.child,
93-
this.showLoadingOnInit = false,
94-
this.loadingWidget,
9558
this.onConnectivityChanged,
9659
}) : builder = null;
9760

9861
/// Creates a Connective widget with a custom builder.
9962
const Connective.builder({
10063
super.key,
10164
required this.builder,
102-
this.showLoadingOnInit = false,
103-
this.loadingWidget,
10465
this.onConnectivityChanged,
105-
}) : onWifi = null,
106-
onMobile = null,
107-
onEthernet = null,
108-
onVpn = null,
109-
onBluetooth = null,
110-
onSatellite = null,
111-
onOther = null,
112-
onNone = null,
66+
}) : noInternet = null,
11367
child = null;
11468

11569
@override
11670
State<Connective> createState() => _ConnectiveState();
11771
}
11872

11973
class _ConnectiveState extends State<Connective> {
120-
static const _defaultLoading = Center(child: CircularProgressIndicator());
12174
static const _empty = SizedBox.shrink();
12275

12376
StreamSubscription<List<ConnectivityResult>>? _subscription;
@@ -188,30 +141,29 @@ class _ConnectiveState extends State<Connective> {
188141
super.dispose();
189142
}
190143

144+
bool _hasInternet() {
145+
return _results.contains(ConnectivityResult.wifi) ||
146+
_results.contains(ConnectivityResult.mobile) ||
147+
_results.contains(ConnectivityResult.ethernet);
148+
}
149+
191150
@override
192151
Widget build(BuildContext context) {
193-
if (_isLoading && widget.showLoadingOnInit) {
194-
return widget.loadingWidget ?? _defaultLoading;
152+
if (_isLoading && widget.builder == null) {
153+
return widget.child ?? _empty;
195154
}
196155

197156
// Use custom builder if provided
198157
if (widget.builder != null) {
199158
return widget.builder!(context, _state, _results);
200159
}
201160

202-
// Use specific state widgets
203-
final stateWidget = switch (_state) {
204-
NyConnectivityState.wifi => widget.onWifi,
205-
NyConnectivityState.mobile => widget.onMobile,
206-
NyConnectivityState.ethernet => widget.onEthernet,
207-
NyConnectivityState.vpn => widget.onVpn,
208-
NyConnectivityState.bluetooth => widget.onBluetooth,
209-
NyConnectivityState.satellite => widget.onSatellite,
210-
NyConnectivityState.other => widget.onOther,
211-
NyConnectivityState.none => widget.onNone,
212-
};
213-
214-
return stateWidget ?? widget.child ?? _empty;
161+
// Show fallback if no internet connection
162+
if (widget.noInternet != null && !_hasInternet()) {
163+
return widget.noInternet!;
164+
}
165+
166+
return widget.child ?? _empty;
215167
}
216168
}
217169

@@ -268,7 +220,10 @@ class OfflineBanner extends StatelessWidget {
268220

269221
return Connective.builder(
270222
builder: (context, state, results) {
271-
final isOffline = state == NyConnectivityState.none;
223+
final isOffline =
224+
!results.contains(ConnectivityResult.wifi) &&
225+
!results.contains(ConnectivityResult.mobile) &&
226+
!results.contains(ConnectivityResult.ethernet);
272227

273228
if (animate) {
274229
return AnimatedPositioned(
@@ -319,21 +274,23 @@ class OfflineBanner extends StatelessWidget {
319274
extension ConnectiveExtension on Widget {
320275
/// Wraps the widget in a Connective that shows an offline placeholder.
321276
Widget connectiveOr({required Widget offline}) {
322-
return Connective(onNone: offline, child: this);
277+
return Connective(noInternet: offline, child: this);
323278
}
324279

325280
/// Only shows the widget when online, otherwise shows nothing.
326281
Widget onlyOnline() {
327-
return Connective(onNone: const SizedBox.shrink(), child: this);
282+
return Connective(noInternet: const SizedBox.shrink(), child: this);
328283
}
329284

330285
/// Only shows the widget when offline, otherwise shows nothing.
331286
Widget onlyOffline() {
332287
return Connective.builder(
333288
builder: (context, state, results) {
334-
return state == NyConnectivityState.none
335-
? this
336-
: const SizedBox.shrink();
289+
final hasInternet =
290+
results.contains(ConnectivityResult.wifi) ||
291+
results.contains(ConnectivityResult.mobile) ||
292+
results.contains(ConnectivityResult.ethernet);
293+
return hasInternet ? const SizedBox.shrink() : this;
337294
},
338295
);
339296
}

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: nylo_support
22
description: Support library for the Nylo framework. This library supports routing, widgets, localization, cli, storage and more.
3-
version: 7.18.1
3+
version: 7.19.0
44
homepage: https://nylo.dev
55
repository: https://github.com/nylo-core/support/tree/7.x
66
issue_tracker: https://github.com/nylo-core/support/issues

0 commit comments

Comments
 (0)