💄 Redesigned ws indicator

This commit is contained in:
2025-12-24 22:27:02 +08:00
parent d655840e85
commit 78a3cd6dd2

View File

@@ -523,67 +523,118 @@ class _WebSocketIndicator extends HookConsumerWidget {
final isDesktop = final isDesktop =
!kIsWeb && (Platform.isMacOS || Platform.isWindows || Platform.isLinux); !kIsWeb && (Platform.isMacOS || Platform.isWindows || Platform.isLinux);
final devicePadding = MediaQuery.of(context).padding;
final user = ref.watch(userInfoProvider); final user = ref.watch(userInfoProvider);
final websocketState = ref.watch(websocketStateProvider); final websocketState = ref.watch(websocketStateProvider);
final indicatorHeight =
MediaQuery.of(context).padding.top + (isDesktop ? 27.5 : 25);
Color indicatorColor; Color indicatorColor;
String indicatorText; String indicatorText;
Widget indicatorIcon;
bool isInteractive = false; bool isInteractive = false;
double opacity = 0.0;
if (websocketState == WebSocketState.connected()) { if (websocketState == WebSocketState.connected()) {
indicatorColor = Colors.green; indicatorColor = Colors.green;
indicatorText = 'connectionConnected'; indicatorText = 'connectionConnected';
indicatorIcon = Icon(
key: ValueKey('ws_connected'),
Symbols.power,
color: Colors.white,
size: 16,
);
opacity = 0.0;
} else if (websocketState == WebSocketState.connecting()) { } else if (websocketState == WebSocketState.connecting()) {
indicatorColor = Colors.teal; indicatorColor = Colors.teal;
indicatorText = 'connectionReconnecting'; indicatorText = 'connectionReconnecting';
indicatorIcon = SizedBox(
key: ValueKey('ws_connecting'),
width: 16,
height: 16,
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
strokeWidth: 2,
padding: EdgeInsets.zero,
),
);
opacity = 1.0;
} else if (websocketState == WebSocketState.serverDown()) { } else if (websocketState == WebSocketState.serverDown()) {
indicatorColor = Colors.red; indicatorColor = Colors.red;
indicatorText = 'connectionServerDown'; indicatorText = 'connectionServerDown';
isInteractive = true; isInteractive = true;
indicatorIcon = Icon(
key: ValueKey('ws_server_down'),
Symbols.power_off,
color: Colors.white,
size: 16,
);
opacity = 1.0;
} else { } else {
indicatorColor = Colors.red; indicatorColor = Colors.red;
indicatorText = 'connectionDisconnected'; indicatorText = 'connectionDisconnected';
indicatorIcon = Icon(
key: ValueKey('ws_disconnected'),
Symbols.power_off,
color: Colors.white,
size: 16,
);
opacity = 1.0;
} }
final widget = AnimatedPositioned( return Positioned(
duration: Duration(milliseconds: 1850), top: devicePadding.top + (isDesktop ? 27.5 : 25),
top:
user.value == null ||
user.value == null ||
websocketState == WebSocketState.connected()
? -indicatorHeight
: 0,
curve: Curves.fastLinearToSlowEaseIn,
left: 0, left: 0,
right: 0, right: 0,
height: indicatorHeight, child: IgnorePointer(
child: Material( ignoring: !isInteractive,
elevation: child: Align(
user.value == null || websocketState == WebSocketState.connected() alignment: Alignment.topCenter,
? 0 child: AnimatedOpacity(
: 4, duration: Duration(milliseconds: 300),
child: AnimatedContainer( opacity: opacity,
duration: Duration(milliseconds: 300), child: Material(
color: indicatorColor, elevation:
child: InkWell( user.value == null ||
onTap: isInteractive websocketState == WebSocketState.connected()
? () { ? 0
ref.read(websocketStateProvider.notifier).manualReconnect(); : 4,
} borderRadius: BorderRadius.circular(999),
: null, child: InkWell(
child: Center( onTap: isInteractive
child: Text( ? () {
indicatorText, ref
style: TextStyle(color: Colors.white, fontSize: 16), .read(websocketStateProvider.notifier)
).tr(), .manualReconnect();
).padding(top: MediaQuery.of(context).padding.top), }
: null,
borderRadius: BorderRadius.circular(999),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
decoration: BoxDecoration(
color: indicatorColor,
borderRadius: BorderRadius.circular(999),
),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
spacing: 8,
children: [
AnimatedSwitcher(
duration: Duration(milliseconds: 300),
child: indicatorIcon,
),
Text(
indicatorText,
style: TextStyle(color: Colors.white, fontSize: 13),
).tr(),
],
),
),
),
),
), ),
), ),
), ),
); );
return isInteractive ? widget : IgnorePointer(child: widget);
} }
} }