🐛 Fixes on enter to send
This commit is contained in:
parent
3dd7c8a5b2
commit
b2a118bbd0
@ -3,7 +3,7 @@
|
|||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 77;
|
objectVersion = 54;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
@ -448,14 +448,10 @@
|
|||||||
inputFileListPaths = (
|
inputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
);
|
);
|
||||||
inputPaths = (
|
|
||||||
);
|
|
||||||
name = "[CP] Copy Pods Resources";
|
name = "[CP] Copy Pods Resources";
|
||||||
outputFileListPaths = (
|
outputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
);
|
);
|
||||||
outputPaths = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
||||||
@ -491,14 +487,10 @@
|
|||||||
inputFileListPaths = (
|
inputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
);
|
);
|
||||||
inputPaths = (
|
|
||||||
);
|
|
||||||
name = "[CP] Embed Pods Frameworks";
|
name = "[CP] Embed Pods Frameworks";
|
||||||
outputFileListPaths = (
|
outputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
);
|
);
|
||||||
outputPaths = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||||
|
@ -309,7 +309,7 @@ class MessageRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<LocalChatMessage> retryMessage(String pendingMessageId) async {
|
Future<LocalChatMessage> retryMessage(String pendingMessageId) async {
|
||||||
final message = pendingMessages[pendingMessageId];
|
final message = await getMessageById(pendingMessageId);
|
||||||
if (message == null) {
|
if (message == null) {
|
||||||
throw Exception('Message not found');
|
throw Exception('Message not found');
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
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';
|
||||||
@ -319,6 +321,15 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sendTypingStatus() async {
|
||||||
|
final wsState = ref.read(websocketStateProvider.notifier);
|
||||||
|
wsState.sendMessage(
|
||||||
|
jsonEncode(
|
||||||
|
WebSocketPacket(type: 'messages.typing', data: {'chat_room_id': id}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
var isLoading = false;
|
var isLoading = false;
|
||||||
|
|
||||||
// Add scroll listener for pagination
|
// Add scroll listener for pagination
|
||||||
@ -414,6 +425,8 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() {});
|
||||||
|
|
||||||
final compactHeader = isWideScreen(context);
|
final compactHeader = isWideScreen(context);
|
||||||
|
|
||||||
final listController = useMemoized(() => ListController(), []);
|
final listController = useMemoized(() => ListController(), []);
|
||||||
@ -720,7 +733,7 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ChatInput extends ConsumerWidget {
|
class _ChatInput extends HookConsumerWidget {
|
||||||
final TextEditingController messageController;
|
final TextEditingController messageController;
|
||||||
final SnChatRoom chatRoom;
|
final SnChatRoom chatRoom;
|
||||||
final VoidCallback onSend;
|
final VoidCallback onSend;
|
||||||
@ -751,46 +764,59 @@ class _ChatInput extends ConsumerWidget {
|
|||||||
required this.onAttachmentsChanged,
|
required this.onAttachmentsChanged,
|
||||||
});
|
});
|
||||||
|
|
||||||
void _handleKeyPress(BuildContext context, WidgetRef ref, RawKeyEvent event) {
|
|
||||||
if (event is! RawKeyDownEvent) return;
|
|
||||||
|
|
||||||
final isPaste = event.logicalKey == LogicalKeyboardKey.keyV;
|
|
||||||
final isModifierPressed = event.isMetaPressed || event.isControlPressed;
|
|
||||||
|
|
||||||
if (isPaste && isModifierPressed) {
|
|
||||||
_handlePaste();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final enterToSend = ref.read(appSettingsNotifierProvider).enterToSend;
|
|
||||||
final isEnter = event.logicalKey == LogicalKeyboardKey.enter;
|
|
||||||
|
|
||||||
if (isEnter) {
|
|
||||||
if (enterToSend && !isModifierPressed) {
|
|
||||||
onSend();
|
|
||||||
} else if (!enterToSend && isModifierPressed) {
|
|
||||||
onSend();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _handlePaste() async {
|
|
||||||
final clipboard = await Pasteboard.image;
|
|
||||||
if (clipboard == null) return;
|
|
||||||
|
|
||||||
onAttachmentsChanged([
|
|
||||||
...attachments,
|
|
||||||
UniversalFile(
|
|
||||||
data: XFile.fromData(clipboard, mimeType: "image/jpeg"),
|
|
||||||
type: UniversalFileType.image,
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final inputFocusNode = useFocusNode();
|
||||||
|
|
||||||
final enterToSend = ref.watch(appSettingsNotifierProvider).enterToSend;
|
final enterToSend = ref.watch(appSettingsNotifierProvider).enterToSend;
|
||||||
|
|
||||||
|
final isMobile = !kIsWeb && (Platform.isAndroid || Platform.isIOS);
|
||||||
|
|
||||||
|
void send() {
|
||||||
|
inputFocusNode.requestFocus();
|
||||||
|
onSend.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> handlePaste() async {
|
||||||
|
final clipboard = await Pasteboard.image;
|
||||||
|
if (clipboard == null) return;
|
||||||
|
|
||||||
|
onAttachmentsChanged([
|
||||||
|
...attachments,
|
||||||
|
UniversalFile(
|
||||||
|
data: XFile.fromData(clipboard, mimeType: "image/jpeg"),
|
||||||
|
type: UniversalFileType.image,
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleKeyPress(
|
||||||
|
BuildContext context,
|
||||||
|
WidgetRef ref,
|
||||||
|
RawKeyEvent event,
|
||||||
|
) {
|
||||||
|
if (event is! RawKeyDownEvent) return;
|
||||||
|
|
||||||
|
final isPaste = event.logicalKey == LogicalKeyboardKey.keyV;
|
||||||
|
final isModifierPressed = event.isMetaPressed || event.isControlPressed;
|
||||||
|
|
||||||
|
if (isPaste && isModifierPressed) {
|
||||||
|
handlePaste();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final enterToSend = ref.read(appSettingsNotifierProvider).enterToSend;
|
||||||
|
final isEnter = event.logicalKey == LogicalKeyboardKey.enter;
|
||||||
|
|
||||||
|
if (isEnter) {
|
||||||
|
if (enterToSend && !isModifierPressed) {
|
||||||
|
send();
|
||||||
|
} else if (!enterToSend && isModifierPressed) {
|
||||||
|
send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Material(
|
return Material(
|
||||||
elevation: 8,
|
elevation: 8,
|
||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
@ -892,12 +918,23 @@ class _ChatInput extends ConsumerWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: RawKeyboardListener(
|
child: RawKeyboardListener(
|
||||||
focusNode: FocusNode(),
|
focusNode: FocusNode(),
|
||||||
onKey: (event) => _handleKeyPress(context, ref, event),
|
onKey: (event) => handleKeyPress(context, ref, event),
|
||||||
child: TextField(
|
child: TextField(
|
||||||
|
focusNode: inputFocusNode,
|
||||||
controller: messageController,
|
controller: messageController,
|
||||||
onSubmitted: enterToSend ? (_) => onSend() : null,
|
onSubmitted:
|
||||||
|
(enterToSend && isMobile)
|
||||||
|
? (_) {
|
||||||
|
send();
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
keyboardType:
|
||||||
|
(enterToSend && isMobile)
|
||||||
|
? TextInputType.text
|
||||||
|
: TextInputType.multiline,
|
||||||
|
textInputAction: TextInputAction.send,
|
||||||
inputFormatters: [
|
inputFormatters: [
|
||||||
if (enterToSend)
|
if (enterToSend && !isMobile)
|
||||||
TextInputFormatter.withFunction((oldValue, newValue) {
|
TextInputFormatter.withFunction((oldValue, newValue) {
|
||||||
if (newValue.text.endsWith('\n')) {
|
if (newValue.text.endsWith('\n')) {
|
||||||
return oldValue;
|
return oldValue;
|
||||||
@ -932,7 +969,7 @@ class _ChatInput extends ConsumerWidget {
|
|||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.send),
|
icon: const Icon(Icons.send),
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
onPressed: onSend,
|
onPressed: send,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
).padding(bottom: MediaQuery.of(context).padding.bottom),
|
).padding(bottom: MediaQuery.of(context).padding.bottom),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user