From d58083e2a1169e975b3fec5886da5f2b5ce01789 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Wed, 16 Oct 2024 23:45:04 +0200 Subject: [PATCH] add missing accessibility labels --- .gitignore | 9 ++- lib/components/AlbumScreen/delete_button.dart | 1 + .../sync_album_or_playlist_button.dart | 4 ++ .../ArtistScreen/artist_download_button.dart | 2 + .../ArtistScreen/artist_play_button.dart | 7 ++- .../ArtistScreen/artist_shuffle_button.dart | 5 ++ .../PlayerScreen/player_buttons.dart | 14 ++++- lib/l10n/app_en.arb | 56 ++++++++++++++++++- lib/screens/settings_screen.dart | 1 + 9 files changed, 94 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index c140ebe08..6917edaaf 100644 --- a/.gitignore +++ b/.gitignore @@ -82,6 +82,8 @@ unlinked_spec.ds # macOS **/macos/Flutter/GeneratedPluginRegistrant.swift +macos/Flutter/ephemeral/flutter_export_environment.sh +macos/Flutter/ephemeral/Flutter-Generated.xcconfig # Coverage coverage/ @@ -95,4 +97,9 @@ app.*.symbols !**/ios/**/default.pbxuser !**/ios/**/default.perspectivev3 !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages -!/dev/ci/**/Gemfile.lock \ No newline at end of file +!/dev/ci/**/Gemfile.lock + +# Not-yet supported platforms +windows/ +linux/ + diff --git a/lib/components/AlbumScreen/delete_button.dart b/lib/components/AlbumScreen/delete_button.dart index b8f224a92..5619ca3f7 100644 --- a/lib/components/AlbumScreen/delete_button.dart +++ b/lib/components/AlbumScreen/delete_button.dart @@ -44,6 +44,7 @@ class _DeleteButtonState extends State { bool? isOffline = box.get("FinampSettings")?.isOffline; return IconButton( + tooltip: AppLocalizations.of(context)!.deleteFromDevice, icon: const Icon(Icons.delete), // If offline, we don't allow the user to delete items. // If we did, we'd have to implement listeners for MusicScreenTabView so that the user can't delete a parent, go back, and select the same parent. diff --git a/lib/components/AlbumScreen/sync_album_or_playlist_button.dart b/lib/components/AlbumScreen/sync_album_or_playlist_button.dart index d52a20d96..93e560ab4 100644 --- a/lib/components/AlbumScreen/sync_album_or_playlist_button.dart +++ b/lib/components/AlbumScreen/sync_album_or_playlist_button.dart @@ -4,6 +4,7 @@ import 'package:finamp/services/sync_helper.dart'; import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; import 'package:logging/logging.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class SyncAlbumOrPlaylistButton extends StatefulWidget { const SyncAlbumOrPlaylistButton({ @@ -39,6 +40,9 @@ class _SyncAlbumOrPlaylistButtonState Widget build(BuildContext context) { isAlbumDownloaded = _downloadHelper.isAlbumDownloaded(widget.parent.id); return IconButton( + tooltip: isAlbumDownloaded + ? AppLocalizations.of(context)!.sync + : AppLocalizations.of(context)!.download, onPressed: () => syncAlbumOrPlaylist(), icon: isAlbumDownloaded ? const Icon(Icons.sync) : diff --git a/lib/components/ArtistScreen/artist_download_button.dart b/lib/components/ArtistScreen/artist_download_button.dart index f9fe0ea05..c8f97346f 100644 --- a/lib/components/ArtistScreen/artist_download_button.dart +++ b/lib/components/ArtistScreen/artist_download_button.dart @@ -68,6 +68,8 @@ class _ArtistDownloadButtonState extends State { deleteAlbums = undownloadedAlbums.isEmpty; return IconButton( + tooltip: AppLocalizations.of(context)! + .downloadArtist(widget.artist.name ?? "Unknown Artist"), icon: deleteAlbums ? const Icon(Icons.delete) : const Icon(Icons.download), diff --git a/lib/components/ArtistScreen/artist_play_button.dart b/lib/components/ArtistScreen/artist_play_button.dart index 374b44708..4ac7cafa6 100644 --- a/lib/components/ArtistScreen/artist_play_button.dart +++ b/lib/components/ArtistScreen/artist_play_button.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; import 'package:hive/hive.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../../models/jellyfin_models.dart'; @@ -66,6 +67,8 @@ class _ArtistPlayButtonState extends State { }); return IconButton( + tooltip: AppLocalizations.of(context)! + .playArtist(widget.artist.name ?? "Unknown Artist"), onPressed: () async { await _audioServiceHelper .replaceQueueWithItem(itemList: sortedSongs); @@ -87,6 +90,8 @@ class _ArtistPlayButtonState extends State { final List items = snapshot.data!; return IconButton( + tooltip: AppLocalizations.of(context)! + .playArtist(widget.artist.name ?? "Unknown Artist"), onPressed: () async { await _audioServiceHelper .replaceQueueWithItem(itemList: items); @@ -102,4 +107,4 @@ class _ArtistPlayButtonState extends State { }, ); } -} \ No newline at end of file +} diff --git a/lib/components/ArtistScreen/artist_shuffle_button.dart b/lib/components/ArtistScreen/artist_shuffle_button.dart index 95af6d867..28d1f31e6 100644 --- a/lib/components/ArtistScreen/artist_shuffle_button.dart +++ b/lib/components/ArtistScreen/artist_shuffle_button.dart @@ -3,6 +3,7 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; import 'package:hive/hive.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../../models/jellyfin_models.dart'; @@ -55,6 +56,8 @@ class _ArtistShuffleButtonState extends State { } return IconButton( + tooltip: AppLocalizations.of(context)! + .shuffleArtist(widget.artist.name ?? "Unknown Artist"), onPressed: () async { await _audioServiceHelper .replaceQueueWithItem(itemList: artistsSongs, shuffle: true); @@ -76,6 +79,8 @@ class _ArtistShuffleButtonState extends State { final List items = snapshot.data!; return IconButton( + tooltip: AppLocalizations.of(context)! + .shuffleArtist(widget.artist.name ?? "Unknown Artist"), onPressed: () async { await _audioServiceHelper .replaceQueueWithItem(itemList: items, shuffle: true, initialIndex: Random().nextInt(items.length)); diff --git a/lib/components/PlayerScreen/player_buttons.dart b/lib/components/PlayerScreen/player_buttons.dart index 5140aae29..0ec108249 100644 --- a/lib/components/PlayerScreen/player_buttons.dart +++ b/lib/components/PlayerScreen/player_buttons.dart @@ -1,6 +1,7 @@ import 'package:audio_service/audio_service.dart'; import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../../services/music_player_background_task.dart'; @@ -20,6 +21,9 @@ class PlayerButtons extends StatelessWidget { textDirection: TextDirection.ltr, children: [ IconButton( + tooltip: playbackState?.shuffleMode == AudioServiceShuffleMode.all + ? AppLocalizations.of(context)!.playbackOrderShuffledTooltip + : AppLocalizations.of(context)!.playbackOrderLinearTooltip, icon: _getShufflingIcon( playbackState == null ? AudioServiceShuffleMode.none @@ -41,6 +45,7 @@ class PlayerButtons extends StatelessWidget { iconSize: 20, ), IconButton( + tooltip: AppLocalizations.of(context)!.skipToPrevious, icon: const Icon(Icons.skip_previous), onPressed: playbackState != null ? () async => await audioHandler.skipToPrevious() @@ -51,6 +56,7 @@ class PlayerButtons extends StatelessWidget { height: 56, width: 56, child: FloatingActionButton( + tooltip: AppLocalizations.of(context)!.togglePlayback, // We set a heroTag because otherwise the play button on AlbumScreenContent will do hero widget stuff heroTag: "PlayerScreenFAB", backgroundColor: Theme.of(context).colorScheme.primary, @@ -75,12 +81,18 @@ class PlayerButtons extends StatelessWidget { ), ), IconButton( + tooltip: AppLocalizations.of(context)!.skipToNext, icon: const Icon(Icons.skip_next), onPressed: playbackState != null ? () async => audioHandler.skipToNext() : null, iconSize: 36), IconButton( + tooltip: playbackState?.repeatMode == AudioServiceRepeatMode.all + ? AppLocalizations.of(context)!.loopModeAllTooltip + : playbackState?.repeatMode == AudioServiceRepeatMode.one + ? AppLocalizations.of(context)!.loopModeOneTooltip + : AppLocalizations.of(context)!.loopModeNoneTooltip, icon: _getRepeatingIcon( playbackState == null ? AudioServiceRepeatMode.none @@ -131,4 +143,4 @@ class PlayerButtons extends StatelessWidget { return const Icon(Icons.shuffle); } } -} \ No newline at end of file +} diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index a9c39e5d4..0442e7593 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -531,5 +531,57 @@ "@swipeInsertQueueNext": {}, "swipeInsertQueueNextSubtitle": "Enable to insert a song as next item in queue when swiped in song list instead of appending it to the end.", "@swipeInsertQueueNextSubtitle": {}, - "redesignBeta": "Redesign Beta" -} \ No newline at end of file + "redesignBeta": "Try the Beta", + "@redesignBeta": {}, + "playbackOrderShuffledTooltip": "Shuffling. Tap to toggle.", + "@playbackOrderShuffledTooltip": {}, + "playbackOrderLinearTooltip": "Playing in order. Tap to toggle.", + "@playbackOrderLinearTooltip": {}, + "loopModeAllTooltip": "Looping all. Tap to toggle.", + "@loopModeAllTooltip": {}, + "loopModeOneTooltip": "Looping one. Tap to toggle.", + "@loopModeOneTooltip": {}, + "loopModeNoneTooltip": "Not looping. Tap to toggle.", + "@loopModeNoneTooltip": {}, + "skipToPrevious": "Skip to Previous Song", + "@skipToPrevious": {}, + "skipToNext": "Skip to Next Song", + "@skipToNext": {}, + "togglePlayback": "Toggle Playback", + "@togglePlayback": {}, + "playArtist": "Play all albums by {artist}", + "@playArtist": { + "placeholders": { + "artist": { + "type": "String", + "example": "The Beatles" + } + } + }, + "shuffleArtist": "Shuffle all albums by {artist}", + "@shuffleArtist": { + "placeholders": { + "artist": { + "type": "String", + "example": "The Beatles" + } + } + }, + "downloadArtist": "Download all albums by {artist}", + "@downloadArtist": { + "placeholders": { + "artist": { + "type": "String", + "example": "The Beatles" + } + } + }, + "deleteFromDevice": "Delete from Device", + "@deleteFromDevice": {}, + "download": "Download", + "@download": {}, + "sync": "Synchronize with Server", + "@sync": {}, + "about": "About Finamp", + "@about": {} +} diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index 553eeffca..5c63e6902 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -26,6 +26,7 @@ class SettingsScreen extends StatelessWidget { title: Text(AppLocalizations.of(context)!.settings), actions: [ IconButton( + tooltip: AppLocalizations.of(context)!.about, icon: const Icon(Icons.info), onPressed: () async { final applicationLegalese =