💄 Optimize chat indicator style

This commit is contained in:
2025-09-27 21:17:14 +08:00
parent 3379dcb7f3
commit 9d5b71bead
2 changed files with 97 additions and 72 deletions

View File

@@ -131,7 +131,6 @@ class ChatRoomScreen extends HookConsumerWidget {
final messages = ref.watch(messagesNotifierProvider(id)); final messages = ref.watch(messagesNotifierProvider(id));
final messagesNotifier = ref.read(messagesNotifierProvider(id).notifier); final messagesNotifier = ref.read(messagesNotifierProvider(id).notifier);
final chatSubscribe = ref.watch(chatSubscribeNotifierProvider(id));
final chatSubscribeNotifier = ref.read( final chatSubscribeNotifier = ref.read(
chatSubscribeNotifierProvider(id).notifier, chatSubscribeNotifierProvider(id).notifier,
); );
@@ -613,77 +612,6 @@ class ChatRoomScreen extends HookConsumerWidget {
(room) => Column( (room) => Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
AnimatedSwitcher(
duration: const Duration(milliseconds: 150),
switchInCurve: Curves.fastEaseInToSlowEaseOut,
switchOutCurve: Curves.fastEaseInToSlowEaseOut,
transitionBuilder: (
Widget child,
Animation<double> animation,
) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(0, -0.3),
end: Offset.zero,
).animate(
CurvedAnimation(
parent: animation,
curve: Curves.easeOutCubic,
),
),
child: SizeTransition(
sizeFactor: animation,
axisAlignment: -1.0,
child: FadeTransition(
opacity: animation,
child: child,
),
),
);
},
child:
chatSubscribe.isNotEmpty
? Container(
key: const ValueKey('typing-indicator'),
width: double.infinity,
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 4,
),
child: Row(
children: [
const Icon(
Symbols.more_horiz,
size: 16,
).padding(horizontal: 8),
const Gap(8),
Expanded(
child: Text(
'typingHint'.plural(
chatSubscribe.length,
args: [
chatSubscribe
.map(
(x) =>
x.nick ??
x.account.nick,
)
.join(', '),
],
),
style:
Theme.of(
context,
).textTheme.bodySmall,
),
),
],
),
)
: const SizedBox.shrink(
key: ValueKey('typing-indicator-none'),
),
),
ChatInput( ChatInput(
messageController: messageController, messageController: messageController,
chatRoom: room!, chatRoom: room!,
@@ -748,6 +676,30 @@ class ChatRoomScreen extends HookConsumerWidget {
top: 0, top: 0,
child: CallOverlayBar().padding(horizontal: 8, top: 12), child: CallOverlayBar().padding(horizontal: 8, top: 12),
), ),
if (isSyncing)
Positioned(
top: 16,
right: 16,
child: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor.withOpacity(0.8),
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(strokeWidth: 2),
),
const SizedBox(width: 8),
Text('Syncing...', style: Theme.of(context).textTheme.bodySmall),
],
),
),
),
], ],
), ),
); );

View File

@@ -15,6 +15,7 @@ import "package:pasteboard/pasteboard.dart";
import "package:styled_widget/styled_widget.dart"; import "package:styled_widget/styled_widget.dart";
import "package:material_symbols_icons/symbols.dart"; import "package:material_symbols_icons/symbols.dart";
import "package:island/widgets/stickers/picker.dart"; import "package:island/widgets/stickers/picker.dart";
import "package:island/pods/chat/chat_subscribe.dart";
class ChatInput extends HookConsumerWidget { class ChatInput extends HookConsumerWidget {
final TextEditingController messageController; final TextEditingController messageController;
@@ -53,6 +54,7 @@ class ChatInput extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final inputFocusNode = useFocusNode(); final inputFocusNode = useFocusNode();
final chatSubscribe = ref.watch(chatSubscribeNotifierProvider(chatRoom.id));
void send() { void send() {
onSend.call(); onSend.call();
@@ -125,6 +127,77 @@ class ChatInput extends HookConsumerWidget {
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 8), padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 8),
child: Column( child: Column(
children: [ children: [
AnimatedSwitcher(
duration: const Duration(milliseconds: 150),
switchInCurve: Curves.fastEaseInToSlowEaseOut,
switchOutCurve: Curves.fastEaseInToSlowEaseOut,
transitionBuilder: (
Widget child,
Animation<double> animation,
) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(0, -0.3),
end: Offset.zero,
).animate(
CurvedAnimation(
parent: animation,
curve: Curves.easeOutCubic,
),
),
child: SizeTransition(
sizeFactor: animation,
axisAlignment: -1.0,
child: FadeTransition(
opacity: animation,
child: child,
),
),
);
},
child:
chatSubscribe.isNotEmpty
? Container(
key: const ValueKey('typing-indicator'),
width: double.infinity,
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 4,
),
child: Row(
children: [
const Icon(
Symbols.more_horiz,
size: 16,
).padding(horizontal: 8),
const Gap(8),
Expanded(
child: Text(
'typingHint'.plural(
chatSubscribe.length,
args: [
chatSubscribe
.map(
(x) =>
x.nick ??
x.account.nick,
)
.join(', '),
],
),
style:
Theme.of(
context,
).textTheme.bodySmall,
),
),
],
),
)
: const SizedBox.shrink(
key: ValueKey('typing-indicator-none'),
),
),
if (attachments.isNotEmpty) if (attachments.isNotEmpty)
SizedBox( SizedBox(
height: 180, height: 180,