2023-08-30 16:18:38 +03:30
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:gap/gap.dart';
|
|
|
|
|
import 'package:hiddify/core/core_providers.dart';
|
|
|
|
|
import 'package:hiddify/domain/singbox/singbox.dart';
|
|
|
|
|
import 'package:hiddify/features/common/stats/stats_notifier.dart';
|
|
|
|
|
import 'package:hiddify/utils/utils.dart';
|
|
|
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
|
|
|
|
|
|
|
|
class StatsOverview extends HookConsumerWidget {
|
|
|
|
|
const StatsOverview({super.key});
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
|
|
|
final t = ref.watch(translationsProvider);
|
|
|
|
|
|
|
|
|
|
final stats =
|
|
|
|
|
ref.watch(statsNotifierProvider).asData?.value ?? CoreStatus.empty();
|
|
|
|
|
|
|
|
|
|
return Padding(
|
|
|
|
|
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16),
|
|
|
|
|
child: Column(
|
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
|
children: [
|
|
|
|
|
_StatCard(
|
2023-09-07 01:56:59 +03:30
|
|
|
title: t.home.stats.traffic,
|
2023-08-30 16:18:38 +03:30
|
|
|
firstStat: (
|
2023-09-10 20:27:07 +03:30
|
|
|
label: "↑",
|
2023-08-30 16:18:38 +03:30
|
|
|
data: stats.uplink.speed(),
|
2023-09-12 00:05:44 +03:30
|
|
|
semanticLabel: t.home.stats.uplink,
|
2023-08-30 16:18:38 +03:30
|
|
|
),
|
|
|
|
|
secondStat: (
|
2023-09-10 20:27:07 +03:30
|
|
|
label: "↓",
|
2023-08-30 16:18:38 +03:30
|
|
|
data: stats.downlink.speed(),
|
2023-09-12 00:05:44 +03:30
|
|
|
semanticLabel: t.home.stats.downlink,
|
2023-08-30 16:18:38 +03:30
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const Gap(8),
|
|
|
|
|
_StatCard(
|
2023-09-07 01:56:59 +03:30
|
|
|
title: t.home.stats.trafficTotal,
|
2023-08-30 16:18:38 +03:30
|
|
|
firstStat: (
|
2023-09-10 20:27:07 +03:30
|
|
|
label: "↑",
|
2023-08-30 16:18:38 +03:30
|
|
|
data: stats.uplinkTotal.size(),
|
2023-09-12 00:05:44 +03:30
|
|
|
semanticLabel: t.home.stats.uplink,
|
2023-08-30 16:18:38 +03:30
|
|
|
),
|
|
|
|
|
secondStat: (
|
2023-09-10 20:27:07 +03:30
|
|
|
label: "↓",
|
2023-08-30 16:18:38 +03:30
|
|
|
data: stats.downlinkTotal.size(),
|
2023-09-12 00:05:44 +03:30
|
|
|
semanticLabel: t.home.stats.downlink,
|
2023-08-30 16:18:38 +03:30
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _StatCard extends HookConsumerWidget {
|
|
|
|
|
const _StatCard({
|
|
|
|
|
required this.title,
|
|
|
|
|
required this.firstStat,
|
|
|
|
|
required this.secondStat,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
final String title;
|
2023-09-12 00:05:44 +03:30
|
|
|
final ({String label, String data, String semanticLabel}) firstStat;
|
|
|
|
|
final ({String label, String data, String semanticLabel}) secondStat;
|
2023-08-30 16:18:38 +03:30
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
|
|
|
final theme = Theme.of(context);
|
|
|
|
|
|
|
|
|
|
return Card(
|
|
|
|
|
margin: EdgeInsets.zero,
|
|
|
|
|
shadowColor: Colors.transparent,
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
Text(title),
|
|
|
|
|
const Gap(4),
|
|
|
|
|
Row(
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
|
children: [
|
|
|
|
|
Text(
|
|
|
|
|
firstStat.label,
|
2023-09-12 00:05:44 +03:30
|
|
|
semanticsLabel: firstStat.semanticLabel,
|
2023-09-10 20:27:07 +03:30
|
|
|
style: const TextStyle(color: Colors.green),
|
2023-09-10 12:09:42 +02:00
|
|
|
),
|
|
|
|
|
Text(
|
|
|
|
|
firstStat.data,
|
2023-08-30 16:18:38 +03:30
|
|
|
style: theme.textTheme.bodySmall,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
Row(
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
|
children: [
|
|
|
|
|
Text(
|
|
|
|
|
secondStat.label,
|
2023-09-12 00:05:44 +03:30
|
|
|
semanticsLabel: secondStat.semanticLabel,
|
2023-09-10 20:27:07 +03:30
|
|
|
style: TextStyle(color: theme.colorScheme.error),
|
2023-09-10 12:09:42 +02:00
|
|
|
),
|
|
|
|
|
Text(
|
|
|
|
|
secondStat.data,
|
2023-08-30 16:18:38 +03:30
|
|
|
style: theme.textTheme.bodySmall,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|