Skip to content

Commit 17548fc

Browse files
a11y inbox msglist: Mark headings for semantics in inbox and recipient headers
1 parent 4d82f49 commit 17548fc

File tree

2 files changed

+105
-99
lines changed

2 files changed

+105
-99
lines changed

lib/widgets/inbox.dart

Lines changed: 48 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -269,52 +269,54 @@ abstract class _HeaderItem extends StatelessWidget {
269269
Widget build(BuildContext context) {
270270
final zulipLocalizations = ZulipLocalizations.of(context);
271271
final designVariables = DesignVariables.of(context);
272-
return Material(
273-
color: collapsed
274-
? designVariables.background // TODO(design) check if this is the right variable
275-
: uncollapsedBackgroundColor(context),
276-
child: InkWell(
277-
// TODO use onRowTap to handle taps that are not on the collapse button.
278-
// Probably we should give the collapse button a 44px or 48px square
279-
// touch target:
280-
// <https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/flutter.3A.20Mark-as-read/near/1680973>
281-
// But that's in tension with the Figma, which gives these header rows
282-
// 40px min height.
283-
onTap: onCollapseButtonTap,
284-
onLongPress: this is _LongPressable
285-
? (this as _LongPressable).onLongPress
286-
: null,
287-
child: Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
288-
Padding(padding: const EdgeInsets.all(10),
289-
child: Icon(size: 20, color: designVariables.sectionCollapseIcon,
290-
collapsed ? ZulipIcons.arrow_right : ZulipIcons.arrow_down)),
291-
Icon(size: 18,
292-
color: collapsed
293-
? collapsedIconColor(context)
294-
: uncollapsedIconColor(context),
295-
icon),
296-
const SizedBox(width: 5),
297-
Expanded(child: Padding(
298-
padding: const EdgeInsets.symmetric(vertical: 4),
299-
child: Text(
300-
style: TextStyle(
301-
fontSize: 17,
302-
height: (20 / 17),
303-
// TODO(design) check if this is the right variable
304-
color: designVariables.labelMenuButton,
305-
).merge(weightVariableTextStyle(context, wght: 600)),
306-
maxLines: 1,
307-
overflow: TextOverflow.ellipsis,
308-
title(zulipLocalizations)))),
309-
const SizedBox(width: 12),
310-
if (hasMention) const _IconMarker(icon: ZulipIcons.at_sign),
311-
Padding(padding: const EdgeInsetsDirectional.only(end: 16),
312-
child: CounterBadge(
313-
// TODO(design) use CounterKind.quantity, following Figma
314-
kind: CounterBadgeKind.unread,
315-
channelIdForBackground: channelId,
316-
count: count)),
317-
])));
272+
return Semantics(
273+
header: true,
274+
child: Material(
275+
color: collapsed
276+
? designVariables.background // TODO(design) check if this is the right variable
277+
: uncollapsedBackgroundColor(context),
278+
child: InkWell(
279+
// TODO use onRowTap to handle taps that are not on the collapse button.
280+
// Probably we should give the collapse button a 44px or 48px square
281+
// touch target:
282+
// <https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/flutter.3A.20Mark-as-read/near/1680973>
283+
// But that's in tension with the Figma, which gives these header rows
284+
// 40px min height.
285+
onTap: onCollapseButtonTap,
286+
onLongPress: this is _LongPressable
287+
? (this as _LongPressable).onLongPress
288+
: null,
289+
child: Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
290+
Padding(padding: const EdgeInsets.all(10),
291+
child: Icon(size: 20, color: designVariables.sectionCollapseIcon,
292+
collapsed ? ZulipIcons.arrow_right : ZulipIcons.arrow_down)),
293+
Icon(size: 18,
294+
color: collapsed
295+
? collapsedIconColor(context)
296+
: uncollapsedIconColor(context),
297+
icon),
298+
const SizedBox(width: 5),
299+
Expanded(child: Padding(
300+
padding: const EdgeInsets.symmetric(vertical: 4),
301+
child: Text(
302+
style: TextStyle(
303+
fontSize: 17,
304+
height: (20 / 17),
305+
// TODO(design) check if this is the right variable
306+
color: designVariables.labelMenuButton,
307+
).merge(weightVariableTextStyle(context, wght: 600)),
308+
maxLines: 1,
309+
overflow: TextOverflow.ellipsis,
310+
title(zulipLocalizations)))),
311+
const SizedBox(width: 12),
312+
if (hasMention) const _IconMarker(icon: ZulipIcons.at_sign),
313+
Padding(padding: const EdgeInsetsDirectional.only(end: 16),
314+
child: CounterBadge(
315+
// TODO(design) use CounterKind.quantity, following Figma
316+
kind: CounterBadgeKind.unread,
317+
channelIdForBackground: channelId,
318+
count: count)),
319+
]))));
318320
}
319321
}
320322

lib/widgets/message_list.dart

Lines changed: 57 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,31 +1904,33 @@ class StreamMessageRecipientHeader extends StatelessWidget {
19041904
store.topicVisibilityPolicy(streamId, topic))),
19051905
]));
19061906

1907-
return GestureDetector(
1908-
// When already in a topic narrow, disable tap interaction that would just
1909-
// push a MessageListPage for the same topic narrow.
1910-
// TODO(#1039) simplify by removing topic-narrow condition if we remove
1911-
// recipient headers in topic narrows
1912-
onTap: narrow is TopicNarrow ? null
1913-
: () => Navigator.push(context,
1914-
MessageListPage.buildRoute(context: context,
1915-
narrow: TopicNarrow.ofMessage(message))),
1916-
onLongPress: () => showTopicActionSheet(context,
1917-
channelId: streamId,
1918-
topic: topic,
1919-
someMessageIdInTopic: message.id),
1920-
child: ColoredBox(
1921-
color: backgroundColor,
1922-
child: Row(
1923-
crossAxisAlignment: CrossAxisAlignment.center,
1924-
children: [
1925-
// TODO(#282): Long stream name will break layout; find a fix.
1926-
streamWidget,
1927-
Expanded(child: topicWidget),
1928-
// TODO topic links?
1929-
// Then web also has edit/resolve/mute buttons. Skip those for mobile.
1930-
RecipientHeaderDate(message: message),
1931-
])));
1907+
return Semantics(
1908+
header: true,
1909+
child: GestureDetector(
1910+
// When already in a topic narrow, disable tap interaction that would just
1911+
// push a MessageListPage for the same topic narrow.
1912+
// TODO(#1039) simplify by removing topic-narrow condition if we remove
1913+
// recipient headers in topic narrows
1914+
onTap: narrow is TopicNarrow ? null
1915+
: () => Navigator.push(context,
1916+
MessageListPage.buildRoute(context: context,
1917+
narrow: TopicNarrow.ofMessage(message))),
1918+
onLongPress: () => showTopicActionSheet(context,
1919+
channelId: streamId,
1920+
topic: topic,
1921+
someMessageIdInTopic: message.id),
1922+
child: ColoredBox(
1923+
color: backgroundColor,
1924+
child: Row(
1925+
crossAxisAlignment: CrossAxisAlignment.center,
1926+
children: [
1927+
// TODO(#282): Long stream name will break layout; find a fix.
1928+
streamWidget,
1929+
Expanded(child: topicWidget),
1930+
// TODO topic links?
1931+
// Then web also has edit/resolve/mute buttons. Skip those for mobile.
1932+
RecipientHeaderDate(message: message),
1933+
]))));
19321934
}
19331935
}
19341936

@@ -1961,34 +1963,36 @@ class DmRecipientHeader extends StatelessWidget {
19611963
final messageListTheme = MessageListTheme.of(context);
19621964
final designVariables = DesignVariables.of(context);
19631965

1964-
return GestureDetector(
1965-
// When already in a DM narrow, disable tap interaction that would just
1966-
// push a MessageListPage for the same DM narrow.
1967-
// TODO(#1244) simplify by removing DM-narrow condition if we remove
1968-
// recipient headers in DM narrows
1969-
onTap: narrow is DmNarrow ? null
1970-
: () => Navigator.push(context,
1971-
MessageListPage.buildRoute(context: context,
1972-
narrow: DmNarrow.ofMessage(message, selfUserId: store.selfUserId))),
1973-
child: ColoredBox(
1974-
color: messageListTheme.dmRecipientHeaderBg,
1975-
child: Padding(
1976-
padding: const EdgeInsets.symmetric(vertical: 11),
1977-
child: Row(
1978-
crossAxisAlignment: CrossAxisAlignment.center,
1979-
children: [
1980-
Padding(
1981-
padding: const EdgeInsets.symmetric(horizontal: 6),
1982-
child: Icon(
1983-
color: designVariables.title,
1984-
size: 16,
1985-
ZulipIcons.two_person)),
1986-
Expanded(
1987-
child: Text(title,
1988-
style: recipientHeaderTextStyle(context),
1989-
overflow: TextOverflow.ellipsis)),
1990-
RecipientHeaderDate(message: message),
1991-
]))));
1966+
return Semantics(
1967+
header: true,
1968+
child: GestureDetector(
1969+
// When already in a DM narrow, disable tap interaction that would just
1970+
// push a MessageListPage for the same DM narrow.
1971+
// TODO(#1244) simplify by removing DM-narrow condition if we remove
1972+
// recipient headers in DM narrows
1973+
onTap: narrow is DmNarrow ? null
1974+
: () => Navigator.push(context,
1975+
MessageListPage.buildRoute(context: context,
1976+
narrow: DmNarrow.ofMessage(message, selfUserId: store.selfUserId))),
1977+
child: ColoredBox(
1978+
color: messageListTheme.dmRecipientHeaderBg,
1979+
child: Padding(
1980+
padding: const EdgeInsets.symmetric(vertical: 11),
1981+
child: Row(
1982+
crossAxisAlignment: CrossAxisAlignment.center,
1983+
children: [
1984+
Padding(
1985+
padding: const EdgeInsets.symmetric(horizontal: 6),
1986+
child: Icon(
1987+
color: designVariables.title,
1988+
size: 16,
1989+
ZulipIcons.two_person)),
1990+
Expanded(
1991+
child: Text(title,
1992+
style: recipientHeaderTextStyle(context),
1993+
overflow: TextOverflow.ellipsis)),
1994+
RecipientHeaderDate(message: message),
1995+
])))));
19921996
}
19931997
}
19941998

0 commit comments

Comments
 (0)