🐛 Fix chat newline on desktop
This commit is contained in:
@@ -1,7 +1,5 @@
|
|||||||
import "dart:async";
|
import "dart:async";
|
||||||
import "dart:io";
|
|
||||||
import "package:easy_localization/easy_localization.dart";
|
import "package:easy_localization/easy_localization.dart";
|
||||||
import "package:flutter/foundation.dart";
|
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter/services.dart";
|
import "package:flutter/services.dart";
|
||||||
import "package:flutter_hooks/flutter_hooks.dart";
|
import "package:flutter_hooks/flutter_hooks.dart";
|
||||||
@@ -56,10 +54,6 @@ class ChatInput extends HookConsumerWidget {
|
|||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final inputFocusNode = useFocusNode();
|
final inputFocusNode = useFocusNode();
|
||||||
|
|
||||||
final enterToSend = ref.watch(appSettingsNotifierProvider).enterToSend;
|
|
||||||
|
|
||||||
final isMobile = !kIsWeb && (Platform.isAndroid || Platform.isIOS);
|
|
||||||
|
|
||||||
void send() {
|
void send() {
|
||||||
onSend.call();
|
onSend.call();
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
@@ -67,6 +61,18 @@ class ChatInput extends HookConsumerWidget {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void insertNewLine() {
|
||||||
|
final text = messageController.text;
|
||||||
|
final selection = messageController.selection;
|
||||||
|
final start = selection.start >= 0 ? selection.start : text.length;
|
||||||
|
final end = selection.end >= 0 ? selection.end : text.length;
|
||||||
|
final newText = text.replaceRange(start, end, '\n');
|
||||||
|
messageController.value = TextEditingValue(
|
||||||
|
text: newText,
|
||||||
|
selection: TextSelection.collapsed(offset: start + 1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> handlePaste() async {
|
Future<void> handlePaste() async {
|
||||||
final clipboard = await Pasteboard.image;
|
final clipboard = await Pasteboard.image;
|
||||||
if (clipboard == null) return;
|
if (clipboard == null) return;
|
||||||
@@ -80,32 +86,34 @@ class ChatInput extends HookConsumerWidget {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleKeyPress(
|
inputFocusNode.onKeyEvent = (node, event) {
|
||||||
BuildContext context,
|
if (event is! KeyDownEvent) return KeyEventResult.ignored;
|
||||||
WidgetRef ref,
|
|
||||||
RawKeyEvent event,
|
|
||||||
) {
|
|
||||||
if (event is! RawKeyDownEvent) return;
|
|
||||||
|
|
||||||
final isPaste = event.logicalKey == LogicalKeyboardKey.keyV;
|
final isPaste = event.logicalKey == LogicalKeyboardKey.keyV;
|
||||||
final isModifierPressed = event.isMetaPressed || event.isControlPressed;
|
final isModifierPressed =
|
||||||
|
HardwareKeyboard.instance.isMetaPressed ||
|
||||||
|
HardwareKeyboard.instance.isControlPressed;
|
||||||
|
|
||||||
if (isPaste && isModifierPressed) {
|
if (isPaste && isModifierPressed) {
|
||||||
handlePaste();
|
handlePaste();
|
||||||
return;
|
return KeyEventResult.handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
final enterToSend = ref.read(appSettingsNotifierProvider).enterToSend;
|
final enterToSend = ref.read(appSettingsNotifierProvider).enterToSend;
|
||||||
final isEnter = event.logicalKey == LogicalKeyboardKey.enter;
|
final isEnter = event.logicalKey == LogicalKeyboardKey.enter;
|
||||||
|
|
||||||
if (isEnter) {
|
if (isEnter) {
|
||||||
if (enterToSend && !isModifierPressed) {
|
if (isModifierPressed) {
|
||||||
send();
|
insertNewLine();
|
||||||
} else if (!enterToSend && isModifierPressed) {
|
return KeyEventResult.handled;
|
||||||
|
} else if (enterToSend) {
|
||||||
send();
|
send();
|
||||||
|
return KeyEventResult.handled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return KeyEventResult.ignored;
|
||||||
|
};
|
||||||
|
|
||||||
return Material(
|
return Material(
|
||||||
elevation: 8,
|
elevation: 8,
|
||||||
@@ -260,59 +268,36 @@ class ChatInput extends HookConsumerWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: RawKeyboardListener(
|
child: TextField(
|
||||||
focusNode: FocusNode(),
|
focusNode: inputFocusNode,
|
||||||
onKey: (event) => handleKeyPress(context, ref, event),
|
controller: messageController,
|
||||||
child: TextField(
|
keyboardType: TextInputType.multiline,
|
||||||
focusNode: inputFocusNode,
|
decoration: InputDecoration(
|
||||||
controller: messageController,
|
hintText:
|
||||||
onSubmitted:
|
(chatRoom.type == 1 && chatRoom.name == null)
|
||||||
(enterToSend && isMobile)
|
? 'chatDirectMessageHint'.tr(
|
||||||
? (_) {
|
args: [
|
||||||
send();
|
chatRoom.members!
|
||||||
}
|
.map((e) => e.account.nick)
|
||||||
: null,
|
.join(', '),
|
||||||
keyboardType:
|
],
|
||||||
(enterToSend && isMobile)
|
)
|
||||||
? TextInputType.text
|
: 'chatMessageHint'.tr(args: [chatRoom.name!]),
|
||||||
: TextInputType.multiline,
|
border: InputBorder.none,
|
||||||
textInputAction: TextInputAction.send,
|
isDense: true,
|
||||||
inputFormatters: [
|
contentPadding: const EdgeInsets.symmetric(
|
||||||
if (enterToSend && !isMobile)
|
horizontal: 12,
|
||||||
TextInputFormatter.withFunction((oldValue, newValue) {
|
vertical: 4,
|
||||||
if (newValue.text.endsWith('\n')) {
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
return newValue;
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText:
|
|
||||||
(chatRoom.type == 1 && chatRoom.name == null)
|
|
||||||
? 'chatDirectMessageHint'.tr(
|
|
||||||
args: [
|
|
||||||
chatRoom.members!
|
|
||||||
.map((e) => e.account.nick)
|
|
||||||
.join(', '),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
: 'chatMessageHint'.tr(args: [chatRoom.name!]),
|
|
||||||
border: InputBorder.none,
|
|
||||||
isDense: true,
|
|
||||||
contentPadding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 12,
|
|
||||||
vertical: 4,
|
|
||||||
),
|
|
||||||
counterText:
|
|
||||||
messageController.text.length > 1024
|
|
||||||
? '${messageController.text.length}/4096'
|
|
||||||
: null,
|
|
||||||
),
|
),
|
||||||
maxLines: 3,
|
counterText:
|
||||||
minLines: 1,
|
messageController.text.length > 1024
|
||||||
onTapOutside:
|
? '${messageController.text.length}/4096'
|
||||||
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
: null,
|
||||||
),
|
),
|
||||||
|
maxLines: 3,
|
||||||
|
minLines: 1,
|
||||||
|
onTapOutside:
|
||||||
|
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
|
Reference in New Issue
Block a user