Skip to content

Commit

Permalink
Merge pull request #2142 from nextcloud/feat/neon_talk/multiline-mess…
Browse files Browse the repository at this point in the history
…age-input
  • Loading branch information
provokateurin authored Jun 12, 2024
2 parents aecbe4f + 7de05bf commit ea62226
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 2 deletions.
33 changes: 31 additions & 2 deletions packages/neon/neon_talk/lib/src/widgets/message_input.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:neon_framework/blocs.dart';
import 'package:neon_framework/models.dart';
Expand All @@ -22,7 +23,29 @@ class TalkMessageInput extends StatefulWidget {

class _TalkMessageInputState extends State<TalkMessageInput> {
final controller = TextEditingController();
final focusNode = FocusNode();
late final focusNode = FocusNode(
onKeyEvent: (node, event) {
if (event.logicalKey.keyLabel == 'Enter') {
if (event is KeyDownEvent) {
if (HardwareKeyboard.instance.isShiftPressed) {
final selection = controller.selection;
final text = controller.text;
controller
..text = '${text.substring(0, selection.start)}\n${text.substring(selection.start)}'
..selection = selection.copyWith(
baseOffset: selection.start + 1,
extentOffset: selection.end + 1,
);
} else {
sendMessage();
}
}
return KeyEventResult.handled;
} else {
return KeyEventResult.ignored;
}
},
);
late TalkRoomBloc bloc;

@override
Expand Down Expand Up @@ -127,7 +150,10 @@ class _TalkMessageInputState extends State<TalkMessageInput> {
builder: (context, controller, focusNode) => TextFormField(
controller: controller,
focusNode: focusNode,
textInputAction: TextInputAction.send,
textInputAction: TextInputAction.newline,
keyboardType: TextInputType.multiline,
minLines: 1,
maxLines: 5,
decoration: InputDecoration(
prefixIcon: emojiButton,
suffixIcon: IconButton(
Expand All @@ -136,6 +162,9 @@ class _TalkMessageInputState extends State<TalkMessageInput> {
onPressed: sendMessage,
),
hintText: TalkLocalizations.of(context).roomWriteMessage,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(28),
),
),
onFieldSubmitted: (_) {
sendMessage();
Expand Down
Binary file modified packages/neon/neon_talk/test/goldens/message_input_emoji.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified packages/neon/neon_talk/test/goldens/room_page_error.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified packages/neon/neon_talk/test/goldens/room_page_messages.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions packages/neon/neon_talk/test/message_input_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,48 @@ void main() {
await tester.testTextInput.receiveAction(TextInputAction.send);
verify(() => bloc.sendMessage('123 @"id" 456')).called(1);
});

testWidgets('Multiline', (tester) async {
final account = mockTalkAccount();

final room = MockRoom();
when(() => room.token).thenReturn('token');
when(() => bloc.room).thenAnswer((_) => BehaviorSubject.seeded(Result.success(room)));

await tester.pumpWidgetWithAccessibility(
TestApp(
localizationsDelegates: TalkLocalizations.localizationsDelegates,
supportedLocales: TalkLocalizations.supportedLocales,
providers: [
NeonProvider<TalkRoomBloc>.value(value: bloc),
Provider<Account>.value(value: account),
],
child: const Align(
alignment: Alignment.bottomCenter,
child: TalkMessageInput(),
),
),
);

await tester.enterText(find.byType(TextField), '123456');

for (var i = 0; i < 3; i++) {
await simulateKeyDownEvent(LogicalKeyboardKey.arrowLeft);
await simulateKeyUpEvent(LogicalKeyboardKey.arrowLeft);
}

await simulateKeyDownEvent(LogicalKeyboardKey.shift);
await simulateKeyDownEvent(LogicalKeyboardKey.enter);
await simulateKeyUpEvent(LogicalKeyboardKey.shift);
await simulateKeyUpEvent(LogicalKeyboardKey.enter);

await tester.pumpAndSettle();

await expectLater(find.byType(TestApp), matchesGoldenFile('goldens/message_input_multiline.png'));

await simulateKeyDownEvent(LogicalKeyboardKey.enter);
await simulateKeyUpEvent(LogicalKeyboardKey.enter);

verify(() => bloc.sendMessage('123\n456')).called(1);
});
}

0 comments on commit ea62226

Please sign in to comment.