mirror of
https://github.com/block/buzz.git
synced 2026-10-31 06:21:34 +00:00
fix(mobile): apply approved channel accessibility guards
Signed-off-by: Fast Fizz <2df81cb51f05a9d5387ef24d7b9ecb8fcdfcd1c70ffabc67061c9596e1b5b1c4@buzz.block.builderlab.xyz> Co-authored-by: Fast Fizz <2df81cb51f05a9d5387ef24d7b9ecb8fcdfcd1c70ffabc67061c9596e1b5b1c4@buzz.block.builderlab.xyz>
This commit is contained in:
@@ -158,37 +158,44 @@ class AddChannelMembersSheet extends HookConsumerWidget {
|
||||
final selected = selectedPubkeys.contains(
|
||||
user.pubkey.toLowerCase(),
|
||||
);
|
||||
return ListTile(
|
||||
return Semantics(
|
||||
key: ValueKey(
|
||||
'add-channel-member-${user.pubkey}',
|
||||
),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: AvatarImage(
|
||||
imageUrl: user.avatarUrl,
|
||||
radius: 20,
|
||||
backgroundColor:
|
||||
context.colors.primaryContainer,
|
||||
fallback: Text(user.initial),
|
||||
button: true,
|
||||
selected: selected,
|
||||
label: selected
|
||||
? '${user.label}, selected'
|
||||
: user.label,
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: AvatarImage(
|
||||
imageUrl: user.avatarUrl,
|
||||
radius: 20,
|
||||
backgroundColor:
|
||||
context.colors.primaryContainer,
|
||||
fallback: Text(user.initial),
|
||||
),
|
||||
title: Text(
|
||||
user.label,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
subtitle: Text(
|
||||
user.secondaryLabel,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
trailing: Icon(
|
||||
selected
|
||||
? LucideIcons.circleCheck
|
||||
: LucideIcons.plus,
|
||||
color: selected
|
||||
? context.colors.primary
|
||||
: context.colors.onSurfaceVariant,
|
||||
),
|
||||
onTap: () => toggleUser(user),
|
||||
),
|
||||
title: Text(
|
||||
user.label,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
subtitle: Text(
|
||||
user.secondaryLabel,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
trailing: Icon(
|
||||
selected
|
||||
? LucideIcons.circleCheck
|
||||
: LucideIcons.plus,
|
||||
color: selected
|
||||
? context.colors.primary
|
||||
: context.colors.onSurfaceVariant,
|
||||
),
|
||||
onTap: () => toggleUser(user),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
@@ -220,7 +220,11 @@ class ChannelActionsSheet extends ConsumerWidget {
|
||||
maxWidth: 640,
|
||||
maxHeight: MediaQuery.sizeOf(context).height * 0.9,
|
||||
),
|
||||
builder: (_) => ManageChannelSheet(channel: channel),
|
||||
builder: (_) => ManageChannelSheet(
|
||||
channel: channel,
|
||||
canEditDetails:
|
||||
canManageLifecycle && !channel.isArchived,
|
||||
),
|
||||
);
|
||||
if (shouldClose == true && context.mounted) {
|
||||
Navigator.of(context).pop(true);
|
||||
|
||||
@@ -197,6 +197,7 @@ class ChannelDetailsPage extends HookConsumerWidget {
|
||||
),
|
||||
builder: (_) => ManageChannelSheet(
|
||||
channel: resolvedChannel,
|
||||
canEditDetails: canEdit,
|
||||
onChannelUpdated: (updated) => displayedChannel.value = updated,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -11,10 +11,12 @@ class ManageChannelSheet extends HookConsumerWidget {
|
||||
const ManageChannelSheet({
|
||||
super.key,
|
||||
required this.channel,
|
||||
this.canEditDetails = true,
|
||||
this.onChannelUpdated,
|
||||
});
|
||||
|
||||
final Channel channel;
|
||||
final bool canEditDetails;
|
||||
final ValueChanged<Channel>? onChannelUpdated;
|
||||
|
||||
@override
|
||||
@@ -48,6 +50,7 @@ class ManageChannelSheet extends HookConsumerWidget {
|
||||
final nameDirty = canonicalName != channel.name.trim();
|
||||
final descriptionDirty = description != channel.description.trim();
|
||||
final canSaveDetails =
|
||||
canEditDetails &&
|
||||
canonicalName.isNotEmpty &&
|
||||
(nameDirty || descriptionDirty) &&
|
||||
!isSavingDetails.value;
|
||||
@@ -113,7 +116,7 @@ class ManageChannelSheet extends HookConsumerWidget {
|
||||
fieldKey: const ValueKey('manage-channel-name'),
|
||||
outlineKey: const ValueKey('manage-channel-name-outline'),
|
||||
controller: nameController,
|
||||
enabled: !isSavingDetails.value,
|
||||
enabled: canEditDetails && !isSavingDetails.value,
|
||||
hintText: 'Channel name',
|
||||
textInputAction: TextInputAction.next,
|
||||
),
|
||||
@@ -122,7 +125,7 @@ class ManageChannelSheet extends HookConsumerWidget {
|
||||
fieldKey: const ValueKey('manage-channel-description'),
|
||||
outlineKey: const ValueKey('manage-channel-description-outline'),
|
||||
controller: descriptionController,
|
||||
enabled: !isSavingDetails.value,
|
||||
enabled: canEditDetails && !isSavingDetails.value,
|
||||
hintText: 'Description',
|
||||
minLines: 2,
|
||||
maxLines: 4,
|
||||
@@ -284,28 +287,32 @@ class _ManageChannelTextField extends StatelessWidget {
|
||||
),
|
||||
borderRadius: BorderRadius.circular(Radii.card),
|
||||
),
|
||||
child: TextField(
|
||||
key: fieldKey,
|
||||
controller: controller,
|
||||
enabled: enabled,
|
||||
minLines: minLines,
|
||||
maxLines: maxLines,
|
||||
style: context.textTheme.bodyLarge,
|
||||
decoration: InputDecoration(
|
||||
hintText: hintText,
|
||||
hintStyle: context.textTheme.bodyLarge?.copyWith(
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
border: InputBorder.none,
|
||||
enabledBorder: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
isDense: true,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: Grid.xs,
|
||||
vertical: Grid.twelve,
|
||||
child: Semantics(
|
||||
label: hintText,
|
||||
textField: true,
|
||||
child: TextField(
|
||||
key: fieldKey,
|
||||
controller: controller,
|
||||
enabled: enabled,
|
||||
minLines: minLines,
|
||||
maxLines: maxLines,
|
||||
style: context.textTheme.bodyLarge,
|
||||
decoration: InputDecoration(
|
||||
hintText: hintText,
|
||||
hintStyle: context.textTheme.bodyLarge?.copyWith(
|
||||
color: context.colors.onSurfaceVariant,
|
||||
),
|
||||
border: InputBorder.none,
|
||||
enabledBorder: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
isDense: true,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: Grid.xs,
|
||||
vertical: Grid.twelve,
|
||||
),
|
||||
),
|
||||
textInputAction: textInputAction,
|
||||
),
|
||||
textInputAction: textInputAction,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1107,8 +1107,27 @@ void main() {
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.pump();
|
||||
final unselectedSemantics = tester.getSemantics(
|
||||
find.byKey(const ValueKey('add-channel-member-alice')),
|
||||
);
|
||||
expect(unselectedSemantics.flagsCollection.isButton, isTrue);
|
||||
expect(
|
||||
unselectedSemantics.flagsCollection.isSelected.toString(),
|
||||
'Tristate.isFalse',
|
||||
);
|
||||
|
||||
await tester.tap(find.byKey(const ValueKey('add-channel-member-alice')));
|
||||
await tester.pump();
|
||||
final selectedSemantics = tester.getSemantics(
|
||||
find.byKey(const ValueKey('add-channel-member-alice')),
|
||||
);
|
||||
expect(selectedSemantics.flagsCollection.isButton, isTrue);
|
||||
expect(
|
||||
selectedSemantics.flagsCollection.isSelected.toString(),
|
||||
'Tristate.isTrue',
|
||||
);
|
||||
expect(selectedSemantics.label, 'Alice, selected');
|
||||
await tester.tap(
|
||||
find.byKey(const ValueKey('add-channel-members-submit')),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user