diff --git a/lib/account/widgets/account_page_app_bar.dart b/lib/account/widgets/account_page_app_bar.dart index e469c43dd..6f2463318 100644 --- a/lib/account/widgets/account_page_app_bar.dart +++ b/lib/account/widgets/account_page_app_bar.dart @@ -175,37 +175,40 @@ class AccountAppBarUserActions extends StatelessWidget { ); }, ), - PopupMenuButton( - onOpened: () => HapticFeedback.mediumImpact(), - itemBuilder: (context) => [ - ThunderPopupMenuItem( - icon: Icons.sort, - title: l10n.sortBy, - onTap: () { - showModalBottomSheet( - showDragHandle: true, - context: context, - isScrollControlled: true, - builder: (builderContext) => SortPicker( - title: l10n.sortOptions, - onSelect: (selected) async => feedBloc.add(FeedChangeSortTypeEvent(selected.payload)), - previouslySelected: feedBloc.state.sortType, - minimumVersion: LemmyClient.instance.version, - ), - ); - }, - ), - ThunderPopupMenuItem( - icon: Icons.refresh_rounded, - title: l10n.refresh, - onTap: () => triggerRefresh(context), - ), - ThunderPopupMenuItem( - icon: Icons.share_rounded, - title: l10n.share, - onTap: () => showUserShareSheet(context, feedBloc.state.fullPersonView!.personView), - ), - ], + Semantics( + label: l10n.menu, + child: PopupMenuButton( + onOpened: () => HapticFeedback.mediumImpact(), + itemBuilder: (context) => [ + ThunderPopupMenuItem( + icon: Icons.sort, + title: l10n.sortBy, + onTap: () { + showModalBottomSheet( + showDragHandle: true, + context: context, + isScrollControlled: true, + builder: (builderContext) => SortPicker( + title: l10n.sortOptions, + onSelect: (selected) async => feedBloc.add(FeedChangeSortTypeEvent(selected.payload)), + previouslySelected: feedBloc.state.sortType, + minimumVersion: LemmyClient.instance.version, + ), + ); + }, + ), + ThunderPopupMenuItem( + icon: Icons.refresh_rounded, + title: l10n.refresh, + onTap: () => triggerRefresh(context), + ), + ThunderPopupMenuItem( + icon: Icons.share_rounded, + title: l10n.share, + onTap: () => showUserShareSheet(context, feedBloc.state.fullPersonView!.personView), + ), + ], + ), ), ], ); diff --git a/lib/feed/widgets/feed_page_app_bar.dart b/lib/feed/widgets/feed_page_app_bar.dart index f010f483b..2a3eef121 100644 --- a/lib/feed/widgets/feed_page_app_bar.dart +++ b/lib/feed/widgets/feed_page_app_bar.dart @@ -215,67 +215,70 @@ class FeedAppBarCommunityActions extends StatelessWidget { ); }, ), - PopupMenuButton( - itemBuilder: (context) => [ - ThunderPopupMenuItem( - onTap: () => triggerRefresh(context), - icon: Icons.refresh_rounded, - title: l10n.refresh, - ), - if (_getSubscriptionStatus(context) == SubscribedType.subscribed) + Semantics( + label: l10n.menu, + child: PopupMenuButton( + itemBuilder: (context) => [ ThunderPopupMenuItem( - onTap: () async { - final Community community = context.read().state.fullCommunityView!.communityView.community; - bool isFavorite = _getFavoriteStatus(context); - await toggleFavoriteCommunity(context, community, isFavorite); - }, - icon: _getFavoriteStatus(context) ? Icons.star_rounded : Icons.star_border_rounded, - title: _getFavoriteStatus(context) ? l10n.removeFromFavorites : l10n.addToFavorites, - ), - if (feedBloc.state.fullCommunityView?.communityView.community.actorId != null) - ThunderPopupMenuItem( - onTap: () => showCommunityShareSheet(context, feedBloc.state.fullCommunityView!.communityView), - icon: Icons.share_rounded, - title: l10n.share, + onTap: () => triggerRefresh(context), + icon: Icons.refresh_rounded, + title: l10n.refresh, ), - if (feedBloc.state.fullCommunityView?.communityView != null) + if (_getSubscriptionStatus(context) == SubscribedType.subscribed) + ThunderPopupMenuItem( + onTap: () async { + final Community community = context.read().state.fullCommunityView!.communityView.community; + bool isFavorite = _getFavoriteStatus(context); + await toggleFavoriteCommunity(context, community, isFavorite); + }, + icon: _getFavoriteStatus(context) ? Icons.star_rounded : Icons.star_border_rounded, + title: _getFavoriteStatus(context) ? l10n.removeFromFavorites : l10n.addToFavorites, + ), + if (feedBloc.state.fullCommunityView?.communityView.community.actorId != null) + ThunderPopupMenuItem( + onTap: () => showCommunityShareSheet(context, feedBloc.state.fullCommunityView!.communityView), + icon: Icons.share_rounded, + title: l10n.share, + ), + if (feedBloc.state.fullCommunityView?.communityView != null) + ThunderPopupMenuItem( + onTap: () async { + final ThunderState state = context.read().state; + final bool reduceAnimations = state.reduceAnimations; + final SearchBloc searchBloc = SearchBloc(); + + await Navigator.of(context).push( + SwipeablePageRoute( + transitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : null, + backGestureDetectionWidth: 45, + canOnlySwipeFromEdge: true, + builder: (context) => MultiBlocProvider( + providers: [ + // Create a new SearchBloc so it doesn't conflict with the main one + BlocProvider.value(value: searchBloc), + BlocProvider.value(value: thunderBloc), + ], + child: SearchPage(communityToSearch: feedBloc.state.fullCommunityView!.communityView, isInitiallyFocused: true), + ), + ), + ); + }, + icon: Icons.search_rounded, + title: l10n.search, + ), ThunderPopupMenuItem( onTap: () async { - final ThunderState state = context.read().state; - final bool reduceAnimations = state.reduceAnimations; - final SearchBloc searchBloc = SearchBloc(); - - await Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : null, - backGestureDetectionWidth: 45, - canOnlySwipeFromEdge: true, - builder: (context) => MultiBlocProvider( - providers: [ - // Create a new SearchBloc so it doesn't conflict with the main one - BlocProvider.value(value: searchBloc), - BlocProvider.value(value: thunderBloc), - ], - child: SearchPage(communityToSearch: feedBloc.state.fullCommunityView!.communityView, isInitiallyFocused: true), - ), - ), + await navigateToModlogPage( + context, + feedBloc: feedBloc, + communityId: feedBloc.state.fullCommunityView!.communityView.community.id, ); }, - icon: Icons.search_rounded, - title: l10n.search, + icon: Icons.shield_rounded, + title: l10n.modlog, ), - ThunderPopupMenuItem( - onTap: () async { - await navigateToModlogPage( - context, - feedBloc: feedBloc, - communityId: feedBloc.state.fullCommunityView!.communityView.community.id, - ); - }, - icon: Icons.shield_rounded, - title: l10n.modlog, - ), - ], + ], + ), ), ], ); @@ -311,20 +314,23 @@ class FeedAppBarUserActions extends StatelessWidget { ); }, ), - PopupMenuButton( - itemBuilder: (context) => [ - ThunderPopupMenuItem( - onTap: () => triggerRefresh(context), - icon: Icons.refresh_rounded, - title: l10n.refresh, - ), - if (feedBloc.state.fullPersonView?.personView.person.actorId != null) + Semantics( + label: l10n.menu, + child: PopupMenuButton( + itemBuilder: (context) => [ ThunderPopupMenuItem( - onTap: () => showUserShareSheet(context, feedBloc.state.fullPersonView!.personView), - icon: Icons.share_rounded, - title: l10n.share, + onTap: () => triggerRefresh(context), + icon: Icons.refresh_rounded, + title: l10n.refresh, ), - ], + if (feedBloc.state.fullPersonView?.personView.person.actorId != null) + ThunderPopupMenuItem( + onTap: () => showUserShareSheet(context, feedBloc.state.fullPersonView!.personView), + icon: Icons.share_rounded, + title: l10n.share, + ), + ], + ), ), ], ); @@ -367,18 +373,21 @@ class FeedAppBarGeneralActions extends StatelessWidget { ); }, ), - PopupMenuButton( - onOpened: () => HapticFeedback.mediumImpact(), - itemBuilder: (context) => [ - ThunderPopupMenuItem( - onTap: () async { - HapticFeedback.mediumImpact(); - await navigateToModlogPage(context, feedBloc: feedBloc); - }, - icon: Icons.shield_rounded, - title: l10n.modlog, - ), - ], + Semantics( + label: l10n.menu, + child: PopupMenuButton( + onOpened: () => HapticFeedback.mediumImpact(), + itemBuilder: (context) => [ + ThunderPopupMenuItem( + onTap: () async { + HapticFeedback.mediumImpact(); + await navigateToModlogPage(context, feedBloc: feedBloc); + }, + icon: Icons.shield_rounded, + title: l10n.modlog, + ), + ], + ), ), ], ); diff --git a/lib/inbox/pages/inbox_page.dart b/lib/inbox/pages/inbox_page.dart index aacc93e00..25db90fdb 100644 --- a/lib/inbox/pages/inbox_page.dart +++ b/lib/inbox/pages/inbox_page.dart @@ -136,38 +136,41 @@ class _InboxPageState extends State with SingleTickerProviderStateMix onPressed: () => context.read().add(GetInboxEvent(inboxType: inboxType, reset: true, showAll: showAll)), ), IconButton(onPressed: () => showSortBottomSheet(), icon: Icon(Icons.sort, semanticLabel: l10n.sortBy)), - PopupMenuButton( - onOpened: () => HapticFeedback.mediumImpact(), - itemBuilder: (context) => [ - ThunderPopupMenuItem( - onTap: () async { - HapticFeedback.mediumImpact(); - await showThunderDialog( - context: context, - title: l10n.confirmMarkAllAsReadTitle, - contentText: l10n.confirmMarkAllAsReadBody, - onSecondaryButtonPressed: (dialogContext) => Navigator.of(dialogContext).pop(), - secondaryButtonText: l10n.cancel, - onPrimaryButtonPressed: (dialogContext, _) { - Navigator.of(dialogContext).pop(); - context.read().add(MarkAllAsReadEvent()); - }, - primaryButtonText: l10n.markAllAsRead, - ); - }, - icon: Icons.checklist, - title: l10n.markAllAsRead, - ), - ThunderPopupMenuItem( - onTap: () async { - HapticFeedback.mediumImpact(); - context.read().add(GetInboxEvent(inboxType: inboxType, reset: true, showAll: !showAll)); - setState(() => showAll = !showAll); - }, - icon: showAll ? Icons.mark_as_unread : Icons.all_inbox_rounded, - title: showAll ? l10n.showUnreadOnly : l10n.showAll, - ), - ], + Semantics( + label: l10n.menu, + child: PopupMenuButton( + onOpened: () => HapticFeedback.mediumImpact(), + itemBuilder: (context) => [ + ThunderPopupMenuItem( + onTap: () async { + HapticFeedback.mediumImpact(); + await showThunderDialog( + context: context, + title: l10n.confirmMarkAllAsReadTitle, + contentText: l10n.confirmMarkAllAsReadBody, + onSecondaryButtonPressed: (dialogContext) => Navigator.of(dialogContext).pop(), + secondaryButtonText: l10n.cancel, + onPrimaryButtonPressed: (dialogContext, _) { + Navigator.of(dialogContext).pop(); + context.read().add(MarkAllAsReadEvent()); + }, + primaryButtonText: l10n.markAllAsRead, + ); + }, + icon: Icons.checklist, + title: l10n.markAllAsRead, + ), + ThunderPopupMenuItem( + onTap: () async { + HapticFeedback.mediumImpact(); + context.read().add(GetInboxEvent(inboxType: inboxType, reset: true, showAll: !showAll)); + setState(() => showAll = !showAll); + }, + icon: showAll ? Icons.mark_as_unread : Icons.all_inbox_rounded, + title: showAll ? l10n.showUnreadOnly : l10n.showAll, + ), + ], + ), ), ], bottom: TabBar( diff --git a/lib/instance/pages/instance_page.dart b/lib/instance/pages/instance_page.dart index 6e3d71eca..593c43d2e 100644 --- a/lib/instance/pages/instance_page.dart +++ b/lib/instance/pages/instance_page.dart @@ -181,28 +181,31 @@ class _InstancePageState extends State { ); }, ), - PopupMenuButton( - itemBuilder: (context) => [ - ThunderPopupMenuItem( - onTap: () async { - HapticFeedback.mediumImpact(); - FeedBloc feedBloc = context.read(); - navigateToModlogPage( - context, - feedBloc: feedBloc, - lemmyClient: feedBloc.lemmyClient, - ); - }, - icon: Icons.shield_rounded, - title: l10n.modlog, - ), - if (viewType != SearchType.all) + Semantics( + label: l10n.menu, + child: PopupMenuButton( + itemBuilder: (context) => [ ThunderPopupMenuItem( - onTap: () => handleLink(context, url: widget.getSiteResponse.siteView.site.actorId), - icon: Icons.open_in_browser_rounded, - title: l10n.openInBrowser, + onTap: () async { + HapticFeedback.mediumImpact(); + FeedBloc feedBloc = context.read(); + navigateToModlogPage( + context, + feedBloc: feedBloc, + lemmyClient: feedBloc.lemmyClient, + ); + }, + icon: Icons.shield_rounded, + title: l10n.modlog, ), - ], + if (viewType != SearchType.all) + ThunderPopupMenuItem( + onTap: () => handleLink(context, url: widget.getSiteResponse.siteView.site.actorId), + icon: Icons.open_in_browser_rounded, + title: l10n.openInBrowser, + ), + ], + ), ), ], ), diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 9cc985465..fb94439d0 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1363,6 +1363,10 @@ }, "mention": "{count, plural, zero {Mention} one {Mention} other {Mentions} }", "@mention": {}, + "menu": "Menu", + "@menu": { + "description": "Menu button description" + }, "message": "{count, plural, zero {Message} one {Message} other {Messages} }", "@message": {}, "metadataFontScale": "Metadata Font Scale", diff --git a/lib/post/pages/legacy_post_page.dart b/lib/post/pages/legacy_post_page.dart index 8492aea09..5546c3d60 100644 --- a/lib/post/pages/legacy_post_page.dart +++ b/lib/post/pages/legacy_post_page.dart @@ -208,47 +208,50 @@ class _PostPageState extends State { showSortBottomSheet(context, state); }, ), - PopupMenuButton( - itemBuilder: (context) => [ - ThunderPopupMenuItem( - onTap: () => createCrossPost( - context, - title: widget.postView?.postView.post.name ?? state.postView?.postView.post.name ?? '', - url: widget.postView?.postView.post.url ?? state.postView?.postView.post.url, - text: widget.postView?.postView.post.body ?? state.postView?.postView.post.body, - postUrl: widget.postView?.postView.post.apId ?? state.postView?.postView.post.apId, + Semantics( + label: l10n.menu, + child: PopupMenuButton( + itemBuilder: (context) => [ + ThunderPopupMenuItem( + onTap: () => createCrossPost( + context, + title: widget.postView?.postView.post.name ?? state.postView?.postView.post.name ?? '', + url: widget.postView?.postView.post.url ?? state.postView?.postView.post.url, + text: widget.postView?.postView.post.body ?? state.postView?.postView.post.body, + postUrl: widget.postView?.postView.post.apId ?? state.postView?.postView.post.apId, + ), + icon: Icons.repeat_rounded, + title: l10n.createNewCrossPost, ), - icon: Icons.repeat_rounded, - title: l10n.createNewCrossPost, - ), - ThunderPopupMenuItem( - onTap: () => setState(() => viewSource = !viewSource), - icon: Icons.edit_document, - title: viewSource ? l10n.viewOriginal : l10n.viewPostSource, - ), - ThunderPopupMenuItem( - onTap: () => showSelectableTextModal( - context, - title: widget.postView?.postView.post.name ?? state.postView?.postView.post.name ?? '', - text: widget.postView?.postView.post.body ?? state.postView?.postView.post.body ?? '', + ThunderPopupMenuItem( + onTap: () => setState(() => viewSource = !viewSource), + icon: Icons.edit_document, + title: viewSource ? l10n.viewOriginal : l10n.viewPostSource, ), - icon: Icons.select_all_rounded, - title: l10n.selectText, - ), - if (state.postView?.media.first.mediaType == MediaType.link && state.postView!.media.first.originalUrl?.isNotEmpty == true) ThunderPopupMenuItem( - onTap: () { - handleLinkLongPress( - context, - state.postView!.media.first.originalUrl!, - state.postView!.media.first.originalUrl!, - initialPage: LinkBottomSheetPage.alternateLinks, - ); - }, - icon: Icons.link_rounded, - title: l10n.alternateSources, + onTap: () => showSelectableTextModal( + context, + title: widget.postView?.postView.post.name ?? state.postView?.postView.post.name ?? '', + text: widget.postView?.postView.post.body ?? state.postView?.postView.post.body ?? '', + ), + icon: Icons.select_all_rounded, + title: l10n.selectText, ), - ], + if (state.postView?.media.first.mediaType == MediaType.link && state.postView!.media.first.originalUrl?.isNotEmpty == true) + ThunderPopupMenuItem( + onTap: () { + handleLinkLongPress( + context, + state.postView!.media.first.originalUrl!, + state.postView!.media.first.originalUrl!, + initialPage: LinkBottomSheetPage.alternateLinks, + ); + }, + icon: Icons.link_rounded, + title: l10n.alternateSources, + ), + ], + ), ), ], centerTitle: false, diff --git a/lib/post/widgets/post_page_app_bar.dart b/lib/post/widgets/post_page_app_bar.dart index b2c50b6f7..25ca3dbac 100644 --- a/lib/post/widgets/post_page_app_bar.dart +++ b/lib/post/widgets/post_page_app_bar.dart @@ -173,50 +173,53 @@ class PostAppBarActions extends StatelessWidget { ); }, ), - PopupMenuButton( - itemBuilder: (context) => [ - ThunderPopupMenuItem( - onTap: onCreateCrossPost, - icon: Icons.repeat_rounded, - title: l10n.createNewCrossPost, - ), - ThunderPopupMenuItem( - onTap: () => onViewSource?.call(!viewSource), - icon: Icons.edit_document, - title: viewSource ? l10n.viewOriginal : l10n.viewPostSource, - ), - ThunderPopupMenuItem( - onTap: onSelectText, - icon: Icons.select_all_rounded, - title: l10n.selectText, - ), - ThunderPopupMenuItem( - onTap: () async { - await temporarilySwitchAccount( - context, - profileModalHeading: l10n.viewPostAsDifferentAccount, - onUserChanged: onUserChanged, - postActorId: context.read().state.postView?.postView.post.apId, - onPostChanged: onPostChanged, - ); - }, - icon: Icons.people_alt_rounded, - title: l10n.viewPostAsDifferentAccount, - ), - if (state.postView?.media.first.mediaType == MediaType.link && state.postView!.media.first.originalUrl?.isNotEmpty == true) + Semantics( + label: l10n.menu, + child: PopupMenuButton( + itemBuilder: (context) => [ ThunderPopupMenuItem( - onTap: () { - handleLinkLongPress( + onTap: onCreateCrossPost, + icon: Icons.repeat_rounded, + title: l10n.createNewCrossPost, + ), + ThunderPopupMenuItem( + onTap: () => onViewSource?.call(!viewSource), + icon: Icons.edit_document, + title: viewSource ? l10n.viewOriginal : l10n.viewPostSource, + ), + ThunderPopupMenuItem( + onTap: onSelectText, + icon: Icons.select_all_rounded, + title: l10n.selectText, + ), + ThunderPopupMenuItem( + onTap: () async { + await temporarilySwitchAccount( context, - state.postView!.media.first.originalUrl!, - state.postView!.media.first.originalUrl!, - initialPage: LinkBottomSheetPage.alternateLinks, + profileModalHeading: l10n.viewPostAsDifferentAccount, + onUserChanged: onUserChanged, + postActorId: context.read().state.postView?.postView.post.apId, + onPostChanged: onPostChanged, ); }, - icon: Icons.link_rounded, - title: l10n.alternateSources, + icon: Icons.people_alt_rounded, + title: l10n.viewPostAsDifferentAccount, ), - ], + if (state.postView?.media.first.mediaType == MediaType.link && state.postView!.media.first.originalUrl?.isNotEmpty == true) + ThunderPopupMenuItem( + onTap: () { + handleLinkLongPress( + context, + state.postView!.media.first.originalUrl!, + state.postView!.media.first.originalUrl!, + initialPage: LinkBottomSheetPage.alternateLinks, + ); + }, + icon: Icons.link_rounded, + title: l10n.alternateSources, + ), + ], + ), ), ], ); diff --git a/lib/shared/webview.dart b/lib/shared/webview.dart index 075553368..240a1e851 100644 --- a/lib/shared/webview.dart +++ b/lib/shared/webview.dart @@ -188,43 +188,46 @@ class NavigationControls extends StatelessWidget { ), onPressed: snapshot.hasData && snapshot.data![1] == true ? () async => await webViewController.goForward() : null, ), - PopupMenuButton( - itemBuilder: (BuildContext context) => [ - ThunderPopupMenuItem( - onTap: () async => await webViewController.reload(), - icon: Icons.replay_rounded, - title: l10n.refresh, - ), - ThunderPopupMenuItem( - onTap: () => launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication), - icon: Icons.open_in_browser_rounded, - title: l10n.openInBrowser, - ), - ThunderPopupMenuItem( - onTap: () => Share.share(url), - icon: Icons.share_rounded, - title: l10n.share, - ), - ThunderPopupMenuItem( - onTap: () { - handleLinkLongPress( - context, - url, - url, - initialPage: LinkBottomSheetPage.alternateLinks, - customNavigation: (url) => webViewController.loadRequest(Uri.parse(url)), - ); - }, - icon: Icons.link_rounded, - title: l10n.alternateSources, - ), - ThunderPopupMenuItem( - onTap: onReaderModeToggled, - icon: Icons.menu_book_rounded, - title: l10n.readerMode, - trailing: readerMode ? const Icon(Icons.check_box_rounded) : const Icon(Icons.check_box_outline_blank_rounded), - ), - ], + Semantics( + label: l10n.menu, + child: PopupMenuButton( + itemBuilder: (BuildContext context) => [ + ThunderPopupMenuItem( + onTap: () async => await webViewController.reload(), + icon: Icons.replay_rounded, + title: l10n.refresh, + ), + ThunderPopupMenuItem( + onTap: () => launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication), + icon: Icons.open_in_browser_rounded, + title: l10n.openInBrowser, + ), + ThunderPopupMenuItem( + onTap: () => Share.share(url), + icon: Icons.share_rounded, + title: l10n.share, + ), + ThunderPopupMenuItem( + onTap: () { + handleLinkLongPress( + context, + url, + url, + initialPage: LinkBottomSheetPage.alternateLinks, + customNavigation: (url) => webViewController.loadRequest(Uri.parse(url)), + ); + }, + icon: Icons.link_rounded, + title: l10n.alternateSources, + ), + ThunderPopupMenuItem( + onTap: onReaderModeToggled, + icon: Icons.menu_book_rounded, + title: l10n.readerMode, + trailing: readerMode ? const Icon(Icons.check_box_rounded) : const Icon(Icons.check_box_outline_blank_rounded), + ), + ], + ), ), const SizedBox(width: 8.0), ], diff --git a/lib/utils/video_player/src/thunder_video_player.dart b/lib/utils/video_player/src/thunder_video_player.dart index a5d70d777..b2f4de78f 100644 --- a/lib/utils/video_player/src/thunder_video_player.dart +++ b/lib/utils/video_player/src/thunder_video_player.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:video_player/video_player.dart'; @@ -271,6 +272,8 @@ class _VideoPlayerControlsState extends State { @override Widget build(BuildContext context) { + final AppLocalizations l10n = AppLocalizations.of(context)!; + return Align( alignment: Alignment.bottomCenter, child: Column( @@ -314,22 +317,25 @@ class _VideoPlayerControlsState extends State { color: Colors.white.withValues(alpha: 0.90), ), ), - PopupMenuButton( - itemBuilder: (context) => VideoPlayBackSpeed.values - .map( - (videoPlaybackSpeed) => ThunderPopupMenuItem( - onTap: () { - widget.controller.setPlaybackSpeed(videoPlaybackSpeed.value); - setState(() {}); - }, - icon: Icons.speed_rounded, - title: videoPlaybackSpeed.label, - ), - ) - .toList(), - icon: Icon( - Icons.speed_rounded, - color: Colors.white.withValues(alpha: 0.90), + Semantics( + label: l10n.menu, + child: PopupMenuButton( + itemBuilder: (context) => VideoPlayBackSpeed.values + .map( + (videoPlaybackSpeed) => ThunderPopupMenuItem( + onTap: () { + widget.controller.setPlaybackSpeed(videoPlaybackSpeed.value); + setState(() {}); + }, + icon: Icons.speed_rounded, + title: videoPlaybackSpeed.label, + ), + ) + .toList(), + icon: Icon( + Icons.speed_rounded, + color: Colors.white.withValues(alpha: 0.90), + ), ), ), IconButton(