diff --git a/assets/translations/strings.i18n.json b/assets/translations/strings.i18n.json index 0aacd383..c9ac05bf 100644 --- a/assets/translations/strings.i18n.json +++ b/assets/translations/strings.i18n.json @@ -21,9 +21,7 @@ }, "stats": { "traffic": "Live Traffic", - "trafficTotal": "Total Traffic", - "uplink": "↑", - "downlink": "↓" + "trafficTotal": "Total Traffic" } }, "profile": { @@ -32,7 +30,7 @@ "subscription": { "traffic": "Traffic", "updatedTimeAgo": "Updated ${timeago}", - "remainingDuration": "📅 ${duration} Days Remaining", + "remainingDuration": "${duration} Days Remaining", "expired": "Expired", "noTraffic": "No more traffic" }, @@ -109,7 +107,7 @@ "silentStart": "Silent Start", "openWorkingDir": "Open Working Directory", "ignoreBatteryOptimizations": "Ignore Battery Optimization", - "ignoreBatteryOptimizationsMsg": "Remove restrictions for optimal VPN performance" + "ignoreBatteryOptimizationsMsg": "Remove restrictions for optimal VPN performance" }, "advanced": { "sectionTitle": "Advanced", diff --git a/assets/translations/strings_fa.i18n.json b/assets/translations/strings_fa.i18n.json index 5ca75ce1..74c8b6a9 100644 --- a/assets/translations/strings_fa.i18n.json +++ b/assets/translations/strings_fa.i18n.json @@ -21,9 +21,7 @@ }, "stats": { "traffic": "مصرف لحظه‌ای", - "trafficTotal": "مصرف کل", - "uplink": "↑", - "downlink": "↓" + "trafficTotal": "مصرف کل" } }, "profile": { @@ -32,7 +30,7 @@ "subscription": { "traffic": "ترافیک", "updatedTimeAgo": "بروزرسانی شده در ${timeago}", - "remainingDuration": "📅 ${duration} روز باقی مانده", + "remainingDuration": "${duration} روز باقی مانده", "expired": "منقضی شده", "noTraffic": "پایان ترافیک" }, diff --git a/lib/domain/profiles/profile.dart b/lib/domain/profiles/profile.dart index 62768888..6976151d 100644 --- a/lib/domain/profiles/profile.dart +++ b/lib/domain/profiles/profile.dart @@ -45,7 +45,7 @@ class Profile with _$Profile { if (title.isEmpty) { final contentDisposition = headers['content-disposition']?.single; if (contentDisposition != null) { - final RegExp regExp = RegExp(r'filename="([^"]*)"'); + final RegExp regExp = RegExp('filename="([^"]*)"'); final match = regExp.firstMatch(contentDisposition); if (match != null && match.groupCount >= 1) { title = match.group(1) ?? ''; diff --git a/lib/features/common/stats/stats_overview.dart b/lib/features/common/stats/stats_overview.dart index 3e83ea16..92599321 100644 --- a/lib/features/common/stats/stats_overview.dart +++ b/lib/features/common/stats/stats_overview.dart @@ -24,11 +24,11 @@ class StatsOverview extends HookConsumerWidget { _StatCard( title: t.home.stats.traffic, firstStat: ( - label: t.home.stats.uplink, + label: "↑", data: stats.uplink.speed(), ), secondStat: ( - label: t.home.stats.downlink, + label: "↓", data: stats.downlink.speed(), ), ), @@ -36,11 +36,11 @@ class StatsOverview extends HookConsumerWidget { _StatCard( title: t.home.stats.trafficTotal, firstStat: ( - label: t.home.stats.uplink, + label: "↑", data: stats.uplinkTotal.size(), ), secondStat: ( - label: t.home.stats.downlink, + label: "↓", data: stats.downlinkTotal.size(), ), ), @@ -80,7 +80,7 @@ class _StatCard extends HookConsumerWidget { children: [ Text( firstStat.label, - style: TextStyle(color: Colors.green), + style: const TextStyle(color: Colors.green), ), Text( firstStat.data, @@ -93,7 +93,7 @@ class _StatCard extends HookConsumerWidget { children: [ Text( secondStat.label, - style: TextStyle(color: Colors.red), + style: TextStyle(color: theme.colorScheme.error), ), Text( secondStat.data, diff --git a/lib/features/proxies/notifier/proxies_notifier.dart b/lib/features/proxies/notifier/proxies_notifier.dart index 5613c8e6..f7a49c66 100644 --- a/lib/features/proxies/notifier/proxies_notifier.dart +++ b/lib/features/proxies/notifier/proxies_notifier.dart @@ -8,6 +8,7 @@ import 'package:hiddify/domain/core_service_failure.dart'; import 'package:hiddify/domain/singbox/singbox.dart'; import 'package:hiddify/features/common/connectivity/connectivity_controller.dart'; import 'package:hiddify/utils/pref_notifier.dart'; +import 'package:hiddify/utils/riverpod_utils.dart'; import 'package:hiddify/utils/utils.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; @@ -36,6 +37,7 @@ final proxiesSortProvider = AlwaysAlivePrefNotifier.provider( class ProxiesNotifier extends _$ProxiesNotifier with AppLogger { @override Stream> build() async* { + ref.disposeDelay(const Duration(seconds: 15)); final serviceRunning = await ref.watch(serviceRunningProvider.future); if (!serviceRunning) { throw const CoreServiceNotRunning(); diff --git a/lib/utils/riverpod_utils.dart b/lib/utils/riverpod_utils.dart new file mode 100644 index 00000000..2c7db43d --- /dev/null +++ b/lib/utils/riverpod_utils.dart @@ -0,0 +1,23 @@ +import 'dart:async'; + +import 'package:hooks_riverpod/hooks_riverpod.dart'; + +extension RefLifeCycle on AutoDisposeRef { + void disposeDelay(Duration duration) { + final link = keepAlive(); + Timer? timer; + + onCancel(() { + timer?.cancel(); + timer = Timer(duration, link.close); + }); + + onDispose(() { + timer?.cancel(); + }); + + onResume(() { + timer?.cancel(); + }); + } +}