implemented comprehensive accessibility (A11y) support across the app
This commit is contained in:
@@ -6,6 +6,7 @@ import '../../../../api/marianumcloud/talk/delete_react_message/delete_react_mes
|
||||
import '../../../../api/marianumcloud/talk/react_message/react_message.dart';
|
||||
import '../../../../api/marianumcloud/talk/react_message/react_message_params.dart';
|
||||
import '../../../../api/marianumcloud/talk/room/get_room_response.dart';
|
||||
import '../../../../widget/a11y/a11y_labels.dart';
|
||||
import '../../../../widget/async_action_button.dart';
|
||||
import '../../../../widget/demo_restricted.dart';
|
||||
import '../../../../widget/emoji_text.dart';
|
||||
@@ -41,44 +42,58 @@ class ChatBubbleReactions extends StatelessWidget {
|
||||
children: reactions.entries.map<Widget>((e) {
|
||||
final hasSelfReacted =
|
||||
bubbleData.reactionsSelf?.contains(e.key) ?? false;
|
||||
void toggle() {
|
||||
if (guardDemoAction(context)) return;
|
||||
runWithErrorDialog(context, () async {
|
||||
if (hasSelfReacted) {
|
||||
await DeleteReactMessage(
|
||||
chatToken: chatData.token,
|
||||
messageId: bubbleData.id,
|
||||
params: DeleteReactMessageParams(e.key),
|
||||
).run();
|
||||
} else {
|
||||
await ReactMessage(
|
||||
chatToken: chatData.token,
|
||||
messageId: bubbleData.id,
|
||||
params: ReactMessageParams(e.key),
|
||||
).run();
|
||||
}
|
||||
onChanged(renew: true);
|
||||
});
|
||||
}
|
||||
|
||||
// Ownership (eigene Reaktion) wird visuell nur über die
|
||||
// Hintergrundfarbe transportiert – für den Screenreader ins Label.
|
||||
final label = hasSelfReacted
|
||||
? '${e.key} ${e.value}, ${A11yLabels.yourReaction}'
|
||||
: '${e.key} ${e.value}';
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(right: 2.5, left: 2.5),
|
||||
child: ActionChip(
|
||||
label: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
EmojiText(e.key, size: EmojiText.sizeInline),
|
||||
const SizedBox(width: 4),
|
||||
Text('${e.value}'),
|
||||
],
|
||||
child: Semantics(
|
||||
button: true,
|
||||
label: label,
|
||||
onTap: toggle,
|
||||
child: ExcludeSemantics(
|
||||
child: ActionChip(
|
||||
label: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
EmojiText(e.key, size: EmojiText.sizeInline),
|
||||
const SizedBox(width: 4),
|
||||
Text('${e.value}'),
|
||||
],
|
||||
),
|
||||
visualDensity: const VisualDensity(
|
||||
vertical: VisualDensity.minimumDensity,
|
||||
horizontal: VisualDensity.minimumDensity,
|
||||
),
|
||||
padding: EdgeInsets.zero,
|
||||
backgroundColor: hasSelfReacted
|
||||
? Theme.of(context).primaryColor
|
||||
: null,
|
||||
onPressed: toggle,
|
||||
),
|
||||
),
|
||||
visualDensity: const VisualDensity(
|
||||
vertical: VisualDensity.minimumDensity,
|
||||
horizontal: VisualDensity.minimumDensity,
|
||||
),
|
||||
padding: EdgeInsets.zero,
|
||||
backgroundColor: hasSelfReacted
|
||||
? Theme.of(context).primaryColor
|
||||
: null,
|
||||
onPressed: () {
|
||||
if (guardDemoAction(context)) return;
|
||||
runWithErrorDialog(context, () async {
|
||||
if (hasSelfReacted) {
|
||||
await DeleteReactMessage(
|
||||
chatToken: chatData.token,
|
||||
messageId: bubbleData.id,
|
||||
params: DeleteReactMessageParams(e.key),
|
||||
).run();
|
||||
} else {
|
||||
await ReactMessage(
|
||||
chatToken: chatData.token,
|
||||
messageId: bubbleData.id,
|
||||
params: ReactMessageParams(e.key),
|
||||
).run();
|
||||
}
|
||||
onChanged(renew: true);
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
|
||||
Reference in New Issue
Block a user