|
@@ -1,11 +1,16 @@
|
|
|
import 'dart:async';
|
|
|
|
|
|
+import 'package:connectivity_plus/connectivity_plus.dart';
|
|
|
+import 'package:fis_common/http/options.dart';
|
|
|
+import 'package:fis_jsonrpc/http_pool.dart';
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
import 'package:flutter/material.dart';
|
|
|
import 'package:vitalapp/architecture/network_connectivity.dart';
|
|
|
import 'package:vitalapp/global.dart';
|
|
|
import 'package:vitalapp/pages/help/help_dialog.dart';
|
|
|
import 'package:fis_common/logger/logger.dart';
|
|
|
+import 'package:vitalapp/rpc.dart';
|
|
|
+import 'package:wifi_iot/wifi_iot.dart';
|
|
|
|
|
|
class HeaderStatusBar extends StatelessWidget {
|
|
|
const HeaderStatusBar({super.key});
|
|
@@ -39,6 +44,7 @@ class _NetStatusWidget extends StatefulWidget {
|
|
|
class _NetStatusWidgetState extends State<_NetStatusWidget> {
|
|
|
Timer? _waitTimer;
|
|
|
bool _isOnline = false;
|
|
|
+ bool _isServerConnectable = true;
|
|
|
|
|
|
@override
|
|
|
void initState() {
|
|
@@ -46,6 +52,9 @@ class _NetStatusWidgetState extends State<_NetStatusWidget> {
|
|
|
_isOnline = kIsOnline;
|
|
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
|
|
netChecker.onlineChangedEvent.addListener(_onlineChanged);
|
|
|
+ if (_isOnline) {
|
|
|
+ _checkServerConnectable();
|
|
|
+ }
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -55,18 +64,76 @@ class _NetStatusWidgetState extends State<_NetStatusWidget> {
|
|
|
super.dispose();
|
|
|
}
|
|
|
|
|
|
- void _onlineChanged(_, e) {
|
|
|
- if (_isOnline == e) {
|
|
|
- return;
|
|
|
- }
|
|
|
- setState(() {
|
|
|
- _isOnline = e;
|
|
|
- if (e) {
|
|
|
- _stopWaitNetRecover();
|
|
|
+ @override
|
|
|
+ Widget build(BuildContext context) {
|
|
|
+ return Tooltip(
|
|
|
+ triggerMode: TooltipTriggerMode.tap,
|
|
|
+ message: _buildTipsText(),
|
|
|
+ child: Column(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.center,
|
|
|
+ children: [
|
|
|
+ _buildIcon(),
|
|
|
+ _buildWifiName(),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ String _buildTipsText() {
|
|
|
+ if (_isOnline) {
|
|
|
+ if (_isServerConnectable) {
|
|
|
+ return "网络已连接";
|
|
|
} else {
|
|
|
- _waitNetRecover();
|
|
|
+ return "无法连接服务器";
|
|
|
}
|
|
|
- });
|
|
|
+ } else {
|
|
|
+ if (_waitTimer == null) {
|
|
|
+ return "网络已断开";
|
|
|
+ } else {
|
|
|
+ return "网络等待中";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget _buildIcon() {
|
|
|
+ if (_isOnline) {
|
|
|
+ if (!_isServerConnectable) {
|
|
|
+ return Icon(Icons.wifi_off_outlined, size: 36, color: Colors.red);
|
|
|
+ }
|
|
|
+ if (netChecker.status == ConnectivityResult.wifi) {
|
|
|
+ return Icon(Icons.wifi, size: 36, color: Colors.green);
|
|
|
+ } else if (netChecker.status == ConnectivityResult.mobile) {
|
|
|
+ return _NetworkIcon4G();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_waitTimer == null) {
|
|
|
+ return Icon(Icons.wifi_off_outlined, size: 36, color: Colors.red);
|
|
|
+ } else {
|
|
|
+ return SizedBox(width: 36, height: 36, child: _NetWaitingWidget());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget _buildWifiName() {
|
|
|
+ if (netChecker.status != ConnectivityResult.wifi) {
|
|
|
+ return const SizedBox();
|
|
|
+ }
|
|
|
+ return _WifiNameWidget();
|
|
|
+ }
|
|
|
+
|
|
|
+ void _onlineChanged(_, e) {
|
|
|
+ if (_isOnline != e) {
|
|
|
+ setState(() {
|
|
|
+ _isOnline = e;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ if (e) {
|
|
|
+ _stopWaitNetRecover();
|
|
|
+ _checkServerConnectable();
|
|
|
+ } else {
|
|
|
+ _waitNetRecover();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void _waitNetRecover() {
|
|
@@ -94,33 +161,34 @@ class _NetStatusWidgetState extends State<_NetStatusWidget> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @override
|
|
|
- Widget build(BuildContext context) {
|
|
|
- if (_isOnline) {
|
|
|
- return const Tooltip(
|
|
|
- triggerMode: TooltipTriggerMode.tap,
|
|
|
- message: "网络已连接",
|
|
|
- child: Icon(Icons.wifi, size: 36, color: Colors.green),
|
|
|
+ Future<void> _checkServerConnectable() async {
|
|
|
+ final result = await _tryConnectRpcOnce();
|
|
|
+ setState(() {
|
|
|
+ _isServerConnectable = result;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ Future<bool> _tryConnectRpcOnce() async {
|
|
|
+ print("${netChecker.status} _tryConnectRpcOnce: ${DateTime.now()}");
|
|
|
+ try {
|
|
|
+ final reqJson =
|
|
|
+ '{"jsonrpc":"2.0","method":"VerifyAccountAsync","params":[{"UserName": "abc123"}],"id":1}';
|
|
|
+ var response = await jrpcHttpPool.getClient(
|
|
|
+ rpc.currentHostAddress,
|
|
|
+
|
|
|
+ headers: {'content-type': "text/plain"},
|
|
|
+ ).post(
|
|
|
+ '/IVitalLoginService',
|
|
|
+ data: reqJson,
|
|
|
+ options: FHttpScopedOptions(timeout: 1000),
|
|
|
);
|
|
|
- } else {
|
|
|
- if (_waitTimer == null) {
|
|
|
- return const Tooltip(
|
|
|
- triggerMode: TooltipTriggerMode.tap,
|
|
|
- message: "网络已断开",
|
|
|
- child: Icon(Icons.wifi_off_outlined, size: 36, color: Colors.red),
|
|
|
- );
|
|
|
- } else {
|
|
|
- return Tooltip(
|
|
|
- triggerMode: TooltipTriggerMode.tap,
|
|
|
- message: "网络等待中",
|
|
|
- child: SizedBox(
|
|
|
- width: 36,
|
|
|
- height: 36,
|
|
|
- child: _NetWaitingWidget(),
|
|
|
- ),
|
|
|
- );
|
|
|
- }
|
|
|
+ print(response);
|
|
|
+ return true;
|
|
|
+ } catch (e) {
|
|
|
+ print("Http unknown error:${e}");
|
|
|
}
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -175,3 +243,74 @@ class _NetWaitingWidgetState extends State<_NetWaitingWidget> {
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+class _NetworkIcon4G extends StatelessWidget {
|
|
|
+ @override
|
|
|
+ Widget build(BuildContext context) {
|
|
|
+ return Expanded(
|
|
|
+ child: Column(
|
|
|
+ children: [
|
|
|
+ Transform.translate(
|
|
|
+ offset: Offset(-4, 10),
|
|
|
+ child: Text(
|
|
|
+ "4G",
|
|
|
+ style: TextStyle(
|
|
|
+ fontSize: 18,
|
|
|
+ color: Colors.white,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Transform.translate(
|
|
|
+ offset: Offset(0, -6),
|
|
|
+ child: Transform.scale(
|
|
|
+ scaleX: 1.2,
|
|
|
+ child: Icon(
|
|
|
+ Icons.signal_cellular_alt_rounded,
|
|
|
+ size: 36,
|
|
|
+ color: Colors.green,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class _WifiNameWidget extends StatelessWidget {
|
|
|
+ @override
|
|
|
+ Widget build(BuildContext context) {
|
|
|
+ return FutureBuilder(
|
|
|
+ builder: (context, snapshot) {
|
|
|
+ if (snapshot.hasData &&
|
|
|
+ snapshot.data != null &&
|
|
|
+ snapshot.data!.isNotEmpty) {
|
|
|
+ return Container(
|
|
|
+ constraints: BoxConstraints(maxWidth: 120),
|
|
|
+ child: Text(
|
|
|
+ _breakWord(snapshot.data!),
|
|
|
+ style: TextStyle(
|
|
|
+ fontSize: 16,
|
|
|
+ color: Colors.white,
|
|
|
+ ),
|
|
|
+ overflow: TextOverflow.ellipsis,
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return const SizedBox();
|
|
|
+ },
|
|
|
+ future: WiFiForIoTPlugin.getSSID(),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ static String _breakWord(String word) {
|
|
|
+ if (word.isEmpty) return word;
|
|
|
+ String breakWord = ' ';
|
|
|
+ for (var element in word.runes) {
|
|
|
+ breakWord += String.fromCharCode(element);
|
|
|
+ breakWord += '\u200B';
|
|
|
+ }
|
|
|
+ return breakWord;
|
|
|
+ }
|
|
|
+}
|