95 lines
3.3 KiB
Dart
95 lines
3.3 KiB
Dart
|
|
import 'package:dartx/dartx.dart';
|
||
|
|
import 'package:fl_chart/fl_chart.dart';
|
||
|
|
import 'package:flutter/material.dart';
|
||
|
|
import 'package:gap/gap.dart';
|
||
|
|
import 'package:hiddify/domain/connectivity/connectivity.dart';
|
||
|
|
import 'package:hiddify/features/common/traffic/traffic_notifier.dart';
|
||
|
|
import 'package:hiddify/utils/utils.dart';
|
||
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||
|
|
|
||
|
|
// TODO: test implementation, rewrite
|
||
|
|
class TrafficChart extends HookConsumerWidget {
|
||
|
|
const TrafficChart({
|
||
|
|
super.key,
|
||
|
|
this.chartSteps = 20,
|
||
|
|
});
|
||
|
|
|
||
|
|
final int chartSteps;
|
||
|
|
|
||
|
|
@override
|
||
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
||
|
|
final asyncTraffics = ref.watch(trafficNotifierProvider);
|
||
|
|
|
||
|
|
switch (asyncTraffics) {
|
||
|
|
case AsyncData(value: final traffics):
|
||
|
|
final latest =
|
||
|
|
traffics.lastOrNull ?? const Traffic(upload: 0, download: 0);
|
||
|
|
final latestUploadData = formatByteSpeed(latest.upload);
|
||
|
|
final latestDownloadData = formatByteSpeed(latest.download);
|
||
|
|
|
||
|
|
final uploadChartSpots = traffics.takeLast(chartSteps).mapIndexed(
|
||
|
|
(index, p) => FlSpot(index.toDouble(), p.upload.toDouble()),
|
||
|
|
);
|
||
|
|
final downloadChartSpots = traffics.takeLast(chartSteps).mapIndexed(
|
||
|
|
(index, p) => FlSpot(index.toDouble(), p.download.toDouble()),
|
||
|
|
);
|
||
|
|
|
||
|
|
return Column(
|
||
|
|
mainAxisSize: MainAxisSize.min,
|
||
|
|
// mainAxisAlignment: MainAxisAlignment.end,
|
||
|
|
children: [
|
||
|
|
SizedBox(
|
||
|
|
height: 68,
|
||
|
|
child: LineChart(
|
||
|
|
LineChartData(
|
||
|
|
minY: 0,
|
||
|
|
borderData: FlBorderData(show: false),
|
||
|
|
titlesData: const FlTitlesData(show: false),
|
||
|
|
gridData: const FlGridData(show: false),
|
||
|
|
lineTouchData: const LineTouchData(enabled: false),
|
||
|
|
lineBarsData: [
|
||
|
|
LineChartBarData(
|
||
|
|
isCurved: true,
|
||
|
|
preventCurveOverShooting: true,
|
||
|
|
dotData: const FlDotData(show: false),
|
||
|
|
spots: uploadChartSpots.toList(),
|
||
|
|
),
|
||
|
|
LineChartBarData(
|
||
|
|
color: Theme.of(context).colorScheme.tertiary,
|
||
|
|
isCurved: true,
|
||
|
|
preventCurveOverShooting: true,
|
||
|
|
dotData: const FlDotData(show: false),
|
||
|
|
spots: downloadChartSpots.toList(),
|
||
|
|
),
|
||
|
|
],
|
||
|
|
),
|
||
|
|
duration: Duration.zero,
|
||
|
|
),
|
||
|
|
),
|
||
|
|
const Gap(16),
|
||
|
|
Row(
|
||
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||
|
|
children: [
|
||
|
|
const Text("↑"),
|
||
|
|
Text(latestUploadData.size),
|
||
|
|
Text(latestUploadData.unit),
|
||
|
|
],
|
||
|
|
),
|
||
|
|
Row(
|
||
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||
|
|
children: [
|
||
|
|
const Text("↓"),
|
||
|
|
Text(latestDownloadData.size),
|
||
|
|
Text(latestDownloadData.unit),
|
||
|
|
],
|
||
|
|
),
|
||
|
|
const Gap(16),
|
||
|
|
],
|
||
|
|
);
|
||
|
|
// TODO: handle loading and error
|
||
|
|
default:
|
||
|
|
return const SizedBox();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|