diff --git a/lib/data/provider/container.g.dart b/lib/data/provider/container.g.dart index 21c7e085..77647101 100644 --- a/lib/data/provider/container.g.dart +++ b/lib/data/provider/container.g.dart @@ -58,7 +58,7 @@ final class ContainerNotifierProvider } } -String _$containerNotifierHash() => r'fea65e66499234b0a59bffff8d69c4ab8c93b2fd'; +String _$containerNotifierHash() => r'85457ec75264199c284572ee45beeaccba2044a1'; final class ContainerNotifierFamily extends $Family with diff --git a/lib/data/provider/pve.g.dart b/lib/data/provider/pve.g.dart index 374b0afa..cad05f89 100644 --- a/lib/data/provider/pve.g.dart +++ b/lib/data/provider/pve.g.dart @@ -58,7 +58,7 @@ final class PveNotifierProvider } } -String _$pveNotifierHash() => r'ba5f2d6cb47c33735f7cc09b771b4a86501b86c6'; +String _$pveNotifierHash() => r'1e71faadee074b9c07bee731ef4ae6505e791967'; final class PveNotifierFamily extends $Family with $ClassFamilyOverride { diff --git a/lib/data/provider/server/all.dart b/lib/data/provider/server/all.dart index 7005315e..3475df93 100644 --- a/lib/data/provider/server/all.dart +++ b/lib/data/provider/server/all.dart @@ -103,37 +103,44 @@ class ServersNotifier extends _$ServersNotifier { return; } - await Future.wait( - state.servers.entries.map((entry) async { - final serverId = entry.key; - final spi = entry.value; + final serversToRefresh = >[]; + final idsToResetLimiter = []; - if (onlyFailed) { - final serverState = ref.read(serverProvider(serverId)); - if (serverState.conn != ServerConn.failed) return; - TryLimiter.reset(serverId); - } + for (final entry in state.servers.entries) { + final serverId = entry.key; + final spi = entry.value; - if (state.manualDisconnectedIds.contains(serverId)) return; + if (state.manualDisconnectedIds.contains(serverId)) continue; - final serverState = ref.read(serverProvider(serverId)); - if (serverState.conn == ServerConn.disconnected && !spi.autoConnect) { - return; - } + final serverState = ref.read(serverProvider(serverId)); - final serverNotifier = ref.read(serverProvider(serverId).notifier); - await serverNotifier.refresh(); - }), - ); + if (onlyFailed) { + if (serverState.conn != ServerConn.failed) continue; + idsToResetLimiter.add(serverId); + } + + if (serverState.conn == ServerConn.disconnected && !spi.autoConnect) continue; + + serversToRefresh.add(entry); + } + + for (final id in idsToResetLimiter) { + TryLimiter.reset(id); + } + + for (final entry in serversToRefresh) { + final serverNotifier = ref.read(serverProvider(entry.key).notifier); + serverNotifier.refresh().ignore(); + } } Future startAutoRefresh() async { var duration = Stores.setting.serverStatusUpdateInterval.fetch(); stopAutoRefresh(); if (duration == 0) return; - if (duration < 0 || duration > 10 || duration == 1) { - duration = 3; + if (duration <= 1 || duration > 10) { Loggers.app.warning('Invalid duration: $duration, use default 3'); + duration = 3; } final timer = Timer.periodic(Duration(seconds: duration), (_) async { await refresh(); @@ -145,8 +152,8 @@ class ServersNotifier extends _$ServersNotifier { final timer = state.autoRefreshTimer; if (timer != null) { timer.cancel(); - state = state.copyWith(autoRefreshTimer: null); } + state = state.copyWith(autoRefreshTimer: null); } bool get isAutoRefreshOn => state.autoRefreshTimer != null; diff --git a/lib/data/provider/server/all.g.dart b/lib/data/provider/server/all.g.dart index 9c2c7df5..2fefa053 100644 --- a/lib/data/provider/server/all.g.dart +++ b/lib/data/provider/server/all.g.dart @@ -41,7 +41,7 @@ final class ServersNotifierProvider } } -String _$serversNotifierHash() => r'3292bdce7d602ff64687b05ff81d120e71761ec2'; +String _$serversNotifierHash() => r'dc5da44f9bd8d8dcfba3e6e932cca3e2f379e582'; abstract class _$ServersNotifier extends $Notifier { ServersState build(); diff --git a/lib/data/provider/server/single.dart b/lib/data/provider/server/single.dart index 2c6119ca..5b7df3bb 100644 --- a/lib/data/provider/server/single.dart +++ b/lib/data/provider/server/single.dart @@ -35,7 +35,6 @@ abstract class ServerState with _$ServerState { required ServerStatus status, @Default(ServerConn.disconnected) ServerConn conn, SSHClient? client, - Future? updateFuture, }) = _ServerState; } @@ -81,19 +80,16 @@ class ServerNotifier extends _$ServerNotifier { } // Refresh server status + bool _isRefreshing = false; + Future refresh() async { - if (state.updateFuture != null) { - await state.updateFuture; - return; - } - - final updateFuture = _updateServer(); - state = state.copyWith(updateFuture: updateFuture); + if (_isRefreshing) return; + _isRefreshing = true; try { - await updateFuture; + await _updateServer(); } finally { - state = state.copyWith(updateFuture: null); + _isRefreshing = false; } } diff --git a/lib/data/provider/server/single.freezed.dart b/lib/data/provider/server/single.freezed.dart index a617c2f0..93df4fd0 100644 --- a/lib/data/provider/server/single.freezed.dart +++ b/lib/data/provider/server/single.freezed.dart @@ -14,7 +14,7 @@ T _$identity(T value) => value; /// @nodoc mixin _$ServerState { - Spi get spi; ServerStatus get status; ServerConn get conn; SSHClient? get client; Future? get updateFuture; + Spi get spi; ServerStatus get status; ServerConn get conn; SSHClient? get client; /// Create a copy of ServerState /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -25,16 +25,16 @@ $ServerStateCopyWith get copyWith => _$ServerStateCopyWithImpl Object.hash(runtimeType,spi,status,conn,client,updateFuture); +int get hashCode => Object.hash(runtimeType,spi,status,conn,client); @override String toString() { - return 'ServerState(spi: $spi, status: $status, conn: $conn, client: $client, updateFuture: $updateFuture)'; + return 'ServerState(spi: $spi, status: $status, conn: $conn, client: $client)'; } @@ -45,7 +45,7 @@ abstract mixin class $ServerStateCopyWith<$Res> { factory $ServerStateCopyWith(ServerState value, $Res Function(ServerState) _then) = _$ServerStateCopyWithImpl; @useResult $Res call({ - Spi spi, ServerStatus status, ServerConn conn, SSHClient? client, Future? updateFuture + Spi spi, ServerStatus status, ServerConn conn, SSHClient? client }); @@ -62,14 +62,13 @@ class _$ServerStateCopyWithImpl<$Res> /// Create a copy of ServerState /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? spi = null,Object? status = null,Object? conn = null,Object? client = freezed,Object? updateFuture = freezed,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? spi = null,Object? status = null,Object? conn = null,Object? client = freezed,}) { return _then(_self.copyWith( spi: null == spi ? _self.spi : spi // ignore: cast_nullable_to_non_nullable as Spi,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable as ServerStatus,conn: null == conn ? _self.conn : conn // ignore: cast_nullable_to_non_nullable as ServerConn,client: freezed == client ? _self.client : client // ignore: cast_nullable_to_non_nullable -as SSHClient?,updateFuture: freezed == updateFuture ? _self.updateFuture : updateFuture // ignore: cast_nullable_to_non_nullable -as Future?, +as SSHClient?, )); } /// Create a copy of ServerState @@ -163,10 +162,10 @@ return $default(_that);case _: /// } /// ``` -@optionalTypeArgs TResult maybeWhen(TResult Function( Spi spi, ServerStatus status, ServerConn conn, SSHClient? client, Future? updateFuture)? $default,{required TResult orElse(),}) {final _that = this; +@optionalTypeArgs TResult maybeWhen(TResult Function( Spi spi, ServerStatus status, ServerConn conn, SSHClient? client)? $default,{required TResult orElse(),}) {final _that = this; switch (_that) { case _ServerState() when $default != null: -return $default(_that.spi,_that.status,_that.conn,_that.client,_that.updateFuture);case _: +return $default(_that.spi,_that.status,_that.conn,_that.client);case _: return orElse(); } @@ -184,10 +183,10 @@ return $default(_that.spi,_that.status,_that.conn,_that.client,_that.updateFutur /// } /// ``` -@optionalTypeArgs TResult when(TResult Function( Spi spi, ServerStatus status, ServerConn conn, SSHClient? client, Future? updateFuture) $default,) {final _that = this; +@optionalTypeArgs TResult when(TResult Function( Spi spi, ServerStatus status, ServerConn conn, SSHClient? client) $default,) {final _that = this; switch (_that) { case _ServerState(): -return $default(_that.spi,_that.status,_that.conn,_that.client,_that.updateFuture);case _: +return $default(_that.spi,_that.status,_that.conn,_that.client);case _: throw StateError('Unexpected subclass'); } @@ -204,10 +203,10 @@ return $default(_that.spi,_that.status,_that.conn,_that.client,_that.updateFutur /// } /// ``` -@optionalTypeArgs TResult? whenOrNull(TResult? Function( Spi spi, ServerStatus status, ServerConn conn, SSHClient? client, Future? updateFuture)? $default,) {final _that = this; +@optionalTypeArgs TResult? whenOrNull(TResult? Function( Spi spi, ServerStatus status, ServerConn conn, SSHClient? client)? $default,) {final _that = this; switch (_that) { case _ServerState() when $default != null: -return $default(_that.spi,_that.status,_that.conn,_that.client,_that.updateFuture);case _: +return $default(_that.spi,_that.status,_that.conn,_that.client);case _: return null; } @@ -219,14 +218,13 @@ return $default(_that.spi,_that.status,_that.conn,_that.client,_that.updateFutur class _ServerState implements ServerState { - const _ServerState({required this.spi, required this.status, this.conn = ServerConn.disconnected, this.client, this.updateFuture}); + const _ServerState({required this.spi, required this.status, this.conn = ServerConn.disconnected, this.client}); @override final Spi spi; @override final ServerStatus status; @override@JsonKey() final ServerConn conn; @override final SSHClient? client; -@override final Future? updateFuture; /// Create a copy of ServerState /// with the given fields replaced by the non-null parameter values. @@ -238,16 +236,16 @@ _$ServerStateCopyWith<_ServerState> get copyWith => __$ServerStateCopyWithImpl<_ @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _ServerState&&(identical(other.spi, spi) || other.spi == spi)&&(identical(other.status, status) || other.status == status)&&(identical(other.conn, conn) || other.conn == conn)&&(identical(other.client, client) || other.client == client)&&(identical(other.updateFuture, updateFuture) || other.updateFuture == updateFuture)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ServerState&&(identical(other.spi, spi) || other.spi == spi)&&(identical(other.status, status) || other.status == status)&&(identical(other.conn, conn) || other.conn == conn)&&(identical(other.client, client) || other.client == client)); } @override -int get hashCode => Object.hash(runtimeType,spi,status,conn,client,updateFuture); +int get hashCode => Object.hash(runtimeType,spi,status,conn,client); @override String toString() { - return 'ServerState(spi: $spi, status: $status, conn: $conn, client: $client, updateFuture: $updateFuture)'; + return 'ServerState(spi: $spi, status: $status, conn: $conn, client: $client)'; } @@ -258,7 +256,7 @@ abstract mixin class _$ServerStateCopyWith<$Res> implements $ServerStateCopyWith factory _$ServerStateCopyWith(_ServerState value, $Res Function(_ServerState) _then) = __$ServerStateCopyWithImpl; @override @useResult $Res call({ - Spi spi, ServerStatus status, ServerConn conn, SSHClient? client, Future? updateFuture + Spi spi, ServerStatus status, ServerConn conn, SSHClient? client }); @@ -275,14 +273,13 @@ class __$ServerStateCopyWithImpl<$Res> /// Create a copy of ServerState /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? spi = null,Object? status = null,Object? conn = null,Object? client = freezed,Object? updateFuture = freezed,}) { +@override @pragma('vm:prefer-inline') $Res call({Object? spi = null,Object? status = null,Object? conn = null,Object? client = freezed,}) { return _then(_ServerState( spi: null == spi ? _self.spi : spi // ignore: cast_nullable_to_non_nullable as Spi,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable as ServerStatus,conn: null == conn ? _self.conn : conn // ignore: cast_nullable_to_non_nullable as ServerConn,client: freezed == client ? _self.client : client // ignore: cast_nullable_to_non_nullable -as SSHClient?,updateFuture: freezed == updateFuture ? _self.updateFuture : updateFuture // ignore: cast_nullable_to_non_nullable -as Future?, +as SSHClient?, )); } diff --git a/lib/data/provider/server/single.g.dart b/lib/data/provider/server/single.g.dart index 7556a58b..bfc9f2bb 100644 --- a/lib/data/provider/server/single.g.dart +++ b/lib/data/provider/server/single.g.dart @@ -58,7 +58,7 @@ final class ServerNotifierProvider } } -String _$serverNotifierHash() => r'185c6b4546c3bc526f5b2ca79d16aed665818863'; +String _$serverNotifierHash() => r'04b1beef4d96242fd10d5b523c6f5f17eb774bae'; final class ServerNotifierFamily extends $Family with diff --git a/lib/view/page/server/detail/view.dart b/lib/view/page/server/detail/view.dart index 31a25243..1fffa47e 100644 --- a/lib/view/page/server/detail/view.dart +++ b/lib/view/page/server/detail/view.dart @@ -63,6 +63,9 @@ class _ServerDetailPageState extends ConsumerState with Single final _netSortType = ValueNotifier(_NetSortType.device); late final _collapse = _settings.collapseUIDefault.fetch(); late final _textFactor = TextScaler.linear(_settings.textFactor.fetch()); + late final _cpuViewAsProgress = _settings.cpuViewAsProgress.fetch(); + late final _moveServerFuncs = _settings.moveServerFuncs.fetch(); + late final _displayCpuIndex = _settings.displayCpuIndex.fetch(); @override void dispose() { @@ -97,7 +100,7 @@ class _ServerDetailPageState extends ConsumerState with Single } Widget _buildMainPage(ServerState si) { - final buildFuncs = !Stores.setting.moveServerFuncs.fetch(); + final buildFuncs = !_moveServerFuncs; final logo = _buildLogo(si); final children = [if (logo != null) logo, if (buildFuncs) ServerFuncBtns(spi: si.spi)]; for (final card in _cardsOrder) { @@ -197,7 +200,7 @@ class _ServerDetailPageState extends ConsumerState with Single ]); } - final List children = Stores.setting.cpuViewAsProgress.fetch() + final List children = _cpuViewAsProgress ? _buildCPUProgress(ss.cpu) : [_buildCPUChart(ss)]; @@ -258,7 +261,7 @@ class _ServerDetailPageState extends ConsumerState with Single const kRowThreshold = 4; const kCoresCountThreshold = kMaxColumn * kRowThreshold; final children = []; - final displayCpuIndexSetting = Stores.setting.displayCpuIndex.fetch(); + final displayCpuIndexSetting = _displayCpuIndex; if (cs.coresCount > kCoresCountThreshold) { final numCoresToDisplay = cs.coresCount - 1; diff --git a/pubspec.lock b/pubspec.lock index 1243ea8a..5b574c3c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -205,10 +205,10 @@ packages: dependency: transitive description: name: camera_web - sha256: "595f28c89d1fb62d77c73c633193755b781c6d2e0ebcd8dc25b763b514e6ba8f" + sha256: "57f49a635c8bf249d07fb95eb693d7e4dda6796dedb3777f9127fb54847beba7" url: "https://pub.dev" source: hosted - version: "0.3.5" + version: "0.3.5+3" characters: dependency: transitive description: @@ -440,10 +440,10 @@ packages: dependency: transitive description: name: ffi - sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" + sha256: d07d37192dbf97461359c1518788f203b0c9102cfd2c35a716b823741219542c url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.5" file: dependency: transitive description: @@ -727,18 +727,18 @@ packages: dependency: transitive description: name: hive_ce - sha256: "81d39a03c4c0ba5938260a8c3547d2e71af59defecea21793d57fc3551f0d230" + sha256: "29f8791bf13fa6cf7435a58f1f82a7c9706973c867affa77c34d91e105762664" url: "https://pub.dev" source: hosted - version: "2.15.1" + version: "2.17.0" hive_ce_flutter: dependency: "direct main" description: name: hive_ce_flutter - sha256: "26d656c9e8974f0732f1d09020e2d7b08ba841b8961a02dbfb6caf01474b0e9a" + sha256: "2677e95a333ff15af43ccd06af7eb7abbf1a4f154ea071997f3de4346cae913a" url: "https://pub.dev" source: hosted - version: "2.3.3" + version: "2.3.4" hive_ce_generator: dependency: "direct dev" description: @@ -831,10 +831,10 @@ packages: dependency: transitive description: name: isolate_channel - sha256: f3d36f783b301e6b312c3450eeb2656b0e7d1db81331af2a151d9083a3f6b18d + sha256: "68191008e3a219bc87cc8cddbcd1e29810bd9f3a0fdc2108b574ccbd9aafda08" url: "https://pub.dev" source: hosted - version: "0.2.2+1" + version: "0.3.0" isolate_contactor: dependency: transitive description: @@ -1750,10 +1750,10 @@ packages: dependency: transitive description: name: watcher - sha256: "592ab6e2892f67760543fb712ff0177f4ec76c031f02f5b4ff8d3fc5eb9fb61a" + sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635" url: "https://pub.dev" source: hosted - version: "1.1.4" + version: "1.2.1" web: dependency: transitive description: