Skip to content

Commit

Permalink
Merge pull request #2656 from nextcloud/fix/talk_app/read-only-chat-p…
Browse files Browse the repository at this point in the history
…ermission-checks
  • Loading branch information
provokateurin authored Nov 19, 2024
2 parents 632508c + a511491 commit 291b405
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:intl/intl.dart';
import 'package:neon_framework/blocs.dart';
import 'package:neon_framework/utils.dart';
import 'package:neon_framework/widgets.dart';
import 'package:nextcloud/spreed.dart' as spreed;
import 'package:talk_app/src/blocs/room.dart';
import 'package:talk_app/src/theme.dart';
import 'package:talk_app/src/utils/helpers.dart';
Expand Down Expand Up @@ -175,7 +176,10 @@ class _TalkRoomPageState extends State<TalkRoomPage> {
),
);

if (room.readOnly == 0) {
if (room.readOnly == 0 &&
spreed.ParticipantPermission.values
.byBinary(room.permissions)
.contains(spreed.ParticipantPermission.canSendMessageAndShareAndReact)) {
body = Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ class _TalkCommentMessageState extends State<TalkCommentMessage> {
),
if (!widget.isParent && widget.chatMessage.reactions.isNotEmpty)
TalkReactions(
room: widget.room,
chatMessage: widget.chatMessage,
),
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,26 @@ import 'package:talk_app/src/widgets/reactions_overview_dialog.dart';
class TalkReactions extends StatelessWidget {
/// Creates new Talk reactions.
const TalkReactions({
required this.room,
required this.chatMessage,
super.key,
});

/// {@macro TalkMessage.room}
final spreed.Room room;

/// The chat message to display the reactions for.
final spreed.$ChatMessageInterface chatMessage;

@override
Widget build(BuildContext context) {
final bloc = NeonProvider.of<TalkRoomBloc>(context);

final canUpdateReactions = room.readOnly == 0 &&
spreed.ParticipantPermission.values
.byBinary(room.permissions)
.contains(spreed.ParticipantPermission.canSendMessageAndShareAndReact);

const shape = RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(50)),
);
Expand Down Expand Up @@ -61,46 +70,50 @@ class TalkReactions extends StatelessWidget {
bottom: -2.5,
right: 10,
),
onPressed: () {
if (isSelf) {
bloc.removeReaction(chatMessage, reaction.key);
} else {
bloc.addReaction(chatMessage, reaction.key);
}
},
onPressed: canUpdateReactions
? () {
if (isSelf) {
bloc.removeReaction(chatMessage, reaction.key);
} else {
bloc.addReaction(chatMessage, reaction.key);
}
}
: null,
),
);
}

children.add(
ActionChip(
shape: shape,
avatar: Icon(
Icons.add_reaction_outlined,
color: Theme.of(context).colorScheme.onSurfaceVariant,
size: 16,
),
label: const SizedBox(),
padding: EdgeInsets.zero,
labelPadding: const EdgeInsets.symmetric(vertical: -2.5),
tooltip: TalkLocalizations.of(context).reactionsAddNew,
onPressed: () async {
final reaction = await showDialog<String>(
context: context,
builder: (context) => const NeonEmojiPickerDialog(),
);
if (reaction == null) {
return;
}
if (canUpdateReactions) {
children.add(
ActionChip(
shape: shape,
avatar: Icon(
Icons.add_reaction_outlined,
color: Theme.of(context).colorScheme.onSurfaceVariant,
size: 16,
),
label: const SizedBox(),
padding: EdgeInsets.zero,
labelPadding: const EdgeInsets.symmetric(vertical: -2.5),
tooltip: TalkLocalizations.of(context).reactionsAddNew,
onPressed: () async {
final reaction = await showDialog<String>(
context: context,
builder: (context) => const NeonEmojiPickerDialog(),
);
if (reaction == null) {
return;
}

if (!context.mounted) {
return;
}
if (!context.mounted) {
return;
}

bloc.addReaction(chatMessage, reaction);
},
),
);
bloc.addReaction(chatMessage, reaction);
},
),
);
}

if (chatMessage.reactions.isNotEmpty) {
children.add(
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 57 additions & 0 deletions packages/neon_framework/packages/talk_app/test/reactions_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ spreed.Reaction getReaction() {
}

void main() {
late spreed.Room room;
late spreed.ChatMessage chatMessage;
late TalkRoomBloc bloc;

Expand All @@ -42,6 +43,10 @@ void main() {
});

setUp(() {
room = MockRoom();
when(() => room.readOnly).thenReturn(0);
when(() => room.permissions).thenReturn(spreed.ParticipantPermission.canSendMessageAndShareAndReact.binary);

chatMessage = MockChatMessage();
when(() => chatMessage.id).thenReturn(0);
when(() => chatMessage.reactions).thenReturn(BuiltMap({'😀': 1, '😊': 2}));
Expand Down Expand Up @@ -70,6 +75,7 @@ void main() {
NeonProvider<TalkRoomBloc>.value(value: bloc),
],
child: TalkReactions(
room: room,
chatMessage: chatMessage,
),
),
Expand All @@ -90,6 +96,7 @@ void main() {
NeonProvider<TalkRoomBloc>.value(value: bloc),
],
child: TalkReactions(
room: room,
chatMessage: chatMessage,
),
),
Expand All @@ -109,6 +116,7 @@ void main() {
NeonProvider<TalkRoomBloc>.value(value: bloc),
],
child: TalkReactions(
room: room,
chatMessage: chatMessage,
),
),
Expand All @@ -130,6 +138,7 @@ void main() {
NeonProvider<TalkRoomBloc>.value(value: bloc),
],
child: TalkReactions(
room: room,
chatMessage: chatMessage,
),
),
Expand All @@ -156,6 +165,7 @@ void main() {
NeonProvider<TalkRoomBloc>.value(value: bloc),
],
child: TalkReactions(
room: room,
chatMessage: chatMessage,
),
),
Expand Down Expand Up @@ -183,6 +193,7 @@ void main() {
Provider<Account>.value(value: account),
],
child: TalkReactions(
room: room,
chatMessage: chatMessage,
),
),
Expand All @@ -195,4 +206,50 @@ void main() {
expect(find.byType(TalkReactionsOverviewDialog), findsOne);
});
});

testWidgets('Read-only', (tester) async {
when(() => room.readOnly).thenReturn(1);

await tester.pumpWidgetWithAccessibility(
TestApp(
localizationsDelegates: TalkLocalizations.localizationsDelegates,
supportedLocales: TalkLocalizations.supportedLocales,
providers: [
NeonProvider<TalkRoomBloc>.value(value: bloc),
],
child: TalkReactions(
room: room,
chatMessage: chatMessage,
),
),
);

expect(find.byIcon(Icons.add_reaction_outlined), findsNothing);

await tester.tap(find.text('😀'), warnIfMissed: false);
verifyNever(() => bloc.addReaction(chatMessage, '😀'));
});

testWidgets('No chat permission', (tester) async {
when(() => room.permissions).thenReturn(0);

await tester.pumpWidgetWithAccessibility(
TestApp(
localizationsDelegates: TalkLocalizations.localizationsDelegates,
supportedLocales: TalkLocalizations.supportedLocales,
providers: [
NeonProvider<TalkRoomBloc>.value(value: bloc),
],
child: TalkReactions(
room: room,
chatMessage: chatMessage,
),
),
);

expect(find.byIcon(Icons.add_reaction_outlined), findsNothing);

await tester.tap(find.text('😀'), warnIfMissed: false);
verifyNever(() => bloc.addReaction(chatMessage, '😀'));
});
}
23 changes: 20 additions & 3 deletions packages/neon_framework/packages/talk_app/test/room_page_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import 'package:built_collection/built_collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:mocktail/mocktail.dart';
import 'package:neon_framework/blocs.dart';
import 'package:neon_framework/models.dart';
Expand All @@ -18,6 +17,7 @@ import 'package:talk_app/src/blocs/room.dart';
import 'package:talk_app/src/pages/room.dart';
import 'package:talk_app/src/theme.dart';
import 'package:talk_app/src/widgets/message.dart';
import 'package:talk_app/src/widgets/message_input.dart';
import 'package:timezone/data/latest.dart' as tzdata;
import 'package:timezone/timezone.dart' as tz;

Expand Down Expand Up @@ -215,8 +215,25 @@ void main() {
),
);

expect(find.byType(TypeAheadField), findsNothing);
expect(find.byIcon(Icons.emoji_emotions_outlined), findsNothing);
expect(find.byType(TalkMessageInput), findsNothing);
await expectLater(find.byType(TestApp), matchesGoldenFile('goldens/room_page_read_only.png'));
});

testWidgets('No chat permission', (tester) async {
when(() => room.permissions).thenReturn(0);

await tester.pumpWidgetWithAccessibility(
TestApp(
localizationsDelegates: TalkLocalizations.localizationsDelegates,
supportedLocales: TalkLocalizations.supportedLocales,
providers: [
NeonProvider<TalkRoomBloc>.value(value: bloc),
],
child: const TalkRoomPage(),
),
);

expect(find.byType(TalkMessageInput), findsNothing);
await expectLater(find.byType(TestApp), matchesGoldenFile('goldens/room_page_no_chat_permission.png'));
});
}

0 comments on commit 291b405

Please sign in to comment.