accessiblity fixes

This commit is contained in:
Henry Hiles 2026-03-01 14:40:14 -05:00
commit b594f5a1d1
No known key found for this signature in database
11 changed files with 147 additions and 118 deletions

View file

@ -49,10 +49,15 @@ class Appbar extends StatelessWidget implements PreferredSizeWidget {
if (!(Platform.isAndroid || Platform.isIOS)) ...[
if (!Platform.isLinux)
IconButton(
tooltip: "Maximize window",
onPressed: maximize,
icon: const Icon(Icons.fullscreen),
),
IconButton(onPressed: () => exit(0), icon: const Icon(Icons.close)),
IconButton(
tooltip: "Close window",
onPressed: () => exit(0),
icon: const Icon(Icons.close),
),
],
],
),

View file

@ -95,7 +95,27 @@ class ChatBox extends HookConsumerWidget {
spacing: 8,
children: [
PopupMenuButton(
itemBuilder: (context) => [],
tooltip: "Add media",
itemBuilder: (context) => [
PopupMenuItem(
child: ListTile(
title: Text("Camera"),
leading: Icon(Icons.add_a_photo),
),
),
PopupMenuItem(
child: ListTile(
title: Text("Gallery"),
leading: Icon(Icons.add_photo_alternate),
),
),
PopupMenuItem(
child: ListTile(
title: Text("Files"),
leading: Icon(Icons.add_photo_alternate),
),
),
],
icon: Icon(Icons.add),
// enabled: room.canSendDefaultMessages, TODO: Permissions check
),
@ -138,6 +158,7 @@ class ChatBox extends HookConsumerWidget {
onPressed: send,
// onPressed: room.canSendDefaultMessages ? send : null,
icon: Icon(Icons.send),
tooltip: "Send message",
),
],
),

View file

@ -1,7 +1,6 @@
import "package:flutter/material.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:nexus/controllers/members_controller.dart";
import "package:nexus/helpers/extensions/better_when.dart";
import "package:nexus/models/room.dart";
import "package:nexus/widgets/avatar_or_hash.dart";
@ -10,49 +9,49 @@ class MemberList extends ConsumerWidget {
const MemberList(this.room, {super.key});
@override
Widget build(BuildContext context, WidgetRef ref) => Drawer(
shape: Border(),
child: ref
.watch(MembersController.provider(room))
.betterWhen(
data: (members) => ListView(
children: [
AppBar(
scrolledUnderElevation: 0,
leading: Icon(Icons.people),
title: Text("Members (${members.length})"),
actionsPadding: EdgeInsets.only(right: 4),
actions: [
if (Scaffold.of(context).hasEndDrawer)
IconButton(
onPressed: Scaffold.of(context).closeEndDrawer,
icon: Icon(Icons.close),
),
],
),
...members.map(
(member) => ListTile(
onTap: () => showDialog(
context: context,
builder: (context) =>
Dialog(child: Text("TODO: Open member popover")),
),
leading: AvatarOrHash(
Uri.tryParse(member.content["avatar_url"] ?? ""),
member.content["displayname"].toString(),
),
title: Text(
member.content["displayname"].toString(),
overflow: TextOverflow.ellipsis,
),
subtitle: Text(
member.stateKey ?? "Unknown User",
overflow: TextOverflow.ellipsis,
),
Widget build(BuildContext context, WidgetRef ref) {
final members = ref.watch(MembersController.provider(room));
return Drawer(
shape: Border(),
child: ListView(
children: [
AppBar(
scrolledUnderElevation: 0,
leading: Icon(Icons.people),
title: Text("Members (${members.length})"),
actionsPadding: EdgeInsets.only(right: 4),
actions: [
if (Scaffold.of(context).hasEndDrawer)
IconButton(
onPressed: Scaffold.of(context).closeEndDrawer,
icon: Icon(Icons.close),
tooltip: "Close member list",
),
),
],
),
),
);
...members.map(
(member) => ListTile(
onTap: () => showDialog(
context: context,
builder: (context) =>
Dialog(child: Text("TODO: Open member popover")),
),
leading: AvatarOrHash(
Uri.tryParse(member.content["avatar_url"] ?? ""),
member.content["displayname"].toString(),
),
title: Text(
member.content["displayname"].toString(),
overflow: TextOverflow.ellipsis,
),
subtitle: Text(
member.stateKey ?? "Unknown User",
overflow: TextOverflow.ellipsis,
),
),
),
],
),
);
}
}

View file

@ -2,7 +2,6 @@ import "package:flutter/material.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:nexus/controllers/members_controller.dart";
import "package:nexus/controllers/rooms_controller.dart";
import "package:nexus/helpers/extensions/better_when.dart";
import "package:nexus/models/room.dart";
import "package:nexus/widgets/avatar_or_hash.dart";
import "package:nexus/widgets/loading.dart";
@ -32,60 +31,55 @@ class MentionOverlay extends ConsumerWidget {
color: Theme.of(context).colorScheme.surfaceContainerHigh,
padding: EdgeInsets.all(8),
child: switch (triggerCharacter) {
"@" =>
ref
.watch(MembersController.provider(room))
.betterWhen(
data: (members) => ListView(
children:
(query.isEmpty
? members
: members.where(
(member) =>
member.stateKey
?.toLowerCase()
.contains(
query.toLowerCase(),
) ==
true ||
(member.content["displayname"]
as String?)
?.toLowerCase()
.contains(
query.toLowerCase(),
) ==
true,
))
.map(
(member) => ListTile(
leading: AvatarOrHash(
Uri.tryParse(
member.content["avatar_url"] ?? "",
),
member.content["displayname"] ?? "",
),
title: Text(
member.content["displayname"] as String? ??
member.stateKey ??
"Unknown User",
),
subtitle: member.stateKey != null
? Text(member.stateKey!)
: null,
onTap: () => addTag(
id: "[@${member.content["displayname"]}](https://matrix.to/#/${member.stateKey})",
name:
member.stateKey
?.substring(1)
.split(":")
.first ??
"Unknown User",
),
"@" => Consumer(
builder: (_, ref, _) {
final members = ref.watch(MembersController.provider(room));
return ListView(
children:
(query.isEmpty
? members
: members.where(
(member) =>
member.stateKey?.toLowerCase().contains(
query.toLowerCase(),
) ==
true ||
(member.content["displayname"] as String?)
?.toLowerCase()
.contains(query.toLowerCase()) ==
true,
))
.map(
(member) => ListTile(
leading: AvatarOrHash(
Uri.tryParse(
member.content["avatar_url"] ?? "",
),
)
.toList(),
),
),
member.content["displayname"] ?? "",
),
title: Text(
member.content["displayname"] as String? ??
member.stateKey ??
"Unknown User",
),
subtitle: member.stateKey != null
? Text(member.stateKey!)
: null,
onTap: () => addTag(
id: "[@${member.content["displayname"]}](https://matrix.to/#/${member.stateKey})",
name:
member.stateKey
?.substring(1)
.split(":")
.first ??
"Unknown User",
),
),
)
.toList(),
);
},
),
"#" => ListView(
children:
(query.isEmpty

View file

@ -56,6 +56,8 @@ class RelationPreview extends ConsumerWidget {
),
),
IconButton(
tooltip:
"Cancel ${relationType == RelationType.edit ? "edit" : "reply"}",
onPressed: onDismiss,
icon: Icon(Icons.close),
iconSize: 20,

View file

@ -52,9 +52,14 @@ class RoomAppbar extends StatelessWidget implements PreferredSizeWidget {
],
),
actions: [
IconButton(onPressed: () {}, icon: Icon(Icons.push_pin)),
IconButton(
onPressed: null,
icon: Icon(Icons.push_pin),
tooltip: "Open pinned messages",
),
IconButton(
onPressed: () => onOpenMemberList(context),
tooltip: "Open member list",
icon: Icon(Icons.people),
),
RoomMenu(room),

View file

@ -155,6 +155,7 @@ class Sidebar extends HookConsumerWidget {
icon: Icon(Icons.add),
),
IconButton(
tooltip: "Explore other rooms",
onPressed: () => showDialog(
context: context,
builder: (context) => AlertDialog(title: Text("To-do")),
@ -162,6 +163,7 @@ class Sidebar extends HookConsumerWidget {
icon: Icon(Icons.explore),
),
IconButton(
tooltip: "Open settings",
onPressed: () => Navigator.of(
context,
).push(MaterialPageRoute(builder: (_) => SettingsPage())),