feat(locale): player, playlist view, track tile bengali and english translations

This commit is contained in:
Kingkor Roy Tirtho 2023-04-29 11:01:16 +06:00
parent 11fe9ec744
commit c55133dc8b
9 changed files with 173 additions and 59 deletions

View File

@ -8,6 +8,7 @@ import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/components/player/player_queue.dart';
import 'package:spotube/components/player/sibling_tracks_sheet.dart';
import 'package:spotube/components/shared/heart_button.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/models/local_track.dart';
import 'package:spotube/models/logger.dart';
import 'package:spotube/provider/authentication_provider.dart';
@ -55,7 +56,7 @@ class PlayerActions extends HookConsumerWidget {
children: [
IconButton(
icon: const Icon(SpotubeIcons.queue),
tooltip: 'Queue',
tooltip: context.l10n.queue,
onPressed: playlist != null
? () {
showModalBottomSheet(
@ -81,7 +82,7 @@ class PlayerActions extends HookConsumerWidget {
if (!isLocalTrack)
IconButton(
icon: const Icon(SpotubeIcons.alternativeRoute),
tooltip: "Alternative Track Sources",
tooltip: context.l10n.alternative_track_sources,
onPressed: playlist?.activeTrack != null
? () {
showModalBottomSheet(
@ -115,7 +116,7 @@ class PlayerActions extends HookConsumerWidget {
)
else
IconButton(
tooltip: 'Download track',
tooltip: context.l10n.download_track,
icon: Icon(
isDownloaded ? SpotubeIcons.done : SpotubeIcons.download,
),

View File

@ -6,6 +6,7 @@ import 'package:palette_generator/palette_generator.dart';
import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/collections/intents.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/hooks/use_progress.dart';
import 'package:spotube/models/logger.dart';
import 'package:spotube/provider/playlist_queue_provider.dart';
@ -133,7 +134,7 @@ class PlayerControls extends HookConsumerWidget {
return Column(
children: [
Tooltip(
message: "Slide to seek forward or backward",
message: context.l10n.slide_to_seek,
child: Slider(
// cannot divide by zero
// there's an edge case for value being bigger
@ -181,8 +182,8 @@ class PlayerControls extends HookConsumerWidget {
children: [
IconButton(
tooltip: playlist?.isShuffled == true
? "Unshuffle playlist"
: "Shuffle playlist",
? context.l10n.unshuffle_playlist
: context.l10n.shuffle_playlist,
icon: const Icon(SpotubeIcons.shuffle),
style: playlist?.isShuffled == true
? activeButtonStyle
@ -198,13 +199,15 @@ class PlayerControls extends HookConsumerWidget {
},
),
IconButton(
tooltip: "Previous track",
tooltip: context.l10n.previous_track,
icon: const Icon(SpotubeIcons.skipBack),
style: buttonStyle,
onPressed: playlistNotifier.previous,
),
IconButton(
tooltip: playing ? "Pause playback" : "Resume playback",
tooltip: playing
? context.l10n.pause_playback
: context.l10n.resume_playback,
icon: playlist?.isLoading == true
? SizedBox(
height: 20,
@ -224,15 +227,15 @@ class PlayerControls extends HookConsumerWidget {
),
),
IconButton(
tooltip: "Next track",
tooltip: context.l10n.next_track,
icon: const Icon(SpotubeIcons.skipForward),
style: buttonStyle,
onPressed: playlistNotifier.next,
),
IconButton(
tooltip: playlist?.isLooping != true
? "Loop Track"
: "Repeat playlist",
? context.l10n.loop_track
: context.l10n.repeat_playlist,
icon: Icon(
playlist?.isLooping == true
? SpotubeIcons.repeatOne

View File

@ -12,6 +12,7 @@ import 'package:spotube/components/player/player_actions.dart';
import 'package:spotube/components/player/player_overlay.dart';
import 'package:spotube/components/player/player_track_details.dart';
import 'package:spotube/components/player/player_controls.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/hooks/use_breakpoints.dart';
import 'package:spotube/hooks/use_brightness_value.dart';
import 'package:spotube/models/logger.dart';
@ -130,7 +131,7 @@ class BottomPlayer extends HookConsumerWidget {
PlayerActions(
extraActions: [
IconButton(
tooltip: 'Mini Player',
tooltip: context.l10n.mini_player,
icon: const Icon(SpotubeIcons.miniPlayer),
onPressed: () async {
await DesktopTools.window.setMinimumSize(

View File

@ -4,6 +4,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotify/spotify.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/hooks/use_palette_color.dart';
import 'package:spotube/provider/authentication_provider.dart';
import 'package:spotube/services/mutations/mutations.dart';
@ -120,7 +121,9 @@ class TrackHeartButton extends HookConsumerWidget {
}
return HeartButton(
tooltip: toggler.item1 ? "Remove from Favorite" : "Add to Favorite",
tooltip: toggler.item1
? context.l10n.remove_from_favorites
: context.l10n.save_as_favorite,
isLiked: toggler.item1,
onPressed: savedTracks.hasData
? () {
@ -174,8 +177,8 @@ class PlaylistHeartButton extends HookConsumerWidget {
return HeartButton(
isLiked: isLikedQuery.data ?? false,
tooltip: isLikedQuery.data ?? false
? "Remove from Favorite"
: "Add to Favorite",
? context.l10n.remove_from_favorites
: context.l10n.save_as_favorite,
color: color?.titleTextColor,
onPressed: isLikedQuery.hasData
? () {
@ -216,7 +219,9 @@ class AlbumHeartButton extends HookConsumerWidget {
return HeartButton(
isLiked: isLiked,
tooltip: isLiked ? "Remove from Favorite" : "Add to Favorite",
tooltip: isLiked
? context.l10n.remove_from_favorites
: context.l10n.save_as_favorite,
onPressed: albumIsSaved.hasData
? () {
toggleAlbumLike.mutate(isLiked);

View File

@ -13,6 +13,7 @@ import 'package:spotube/components/shared/shimmers/shimmer_track_tile.dart';
import 'package:spotube/components/shared/page_window_title_bar.dart';
import 'package:spotube/components/shared/image/universal_image.dart';
import 'package:spotube/components/shared/track_table/tracks_table_view.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/hooks/use_custom_status_bar_color.dart';
import 'package:spotube/hooks/use_palette_color.dart';
import 'package:spotube/models/logger.dart';
@ -80,7 +81,7 @@ class TrackCollectionView<T> extends HookConsumerWidget {
),
if (heartBtn != null && auth != null) heartBtn!,
IconButton(
tooltip: "Shuffle",
tooltip: context.l10n.shuffle,
icon: Icon(
SpotubeIcons.shuffle,
color: color?.titleTextColor,
@ -166,7 +167,7 @@ class TrackCollectionView<T> extends HookConsumerWidget {
onChanged: (value) => searchText.value = value,
style: TextStyle(color: color?.titleTextColor),
decoration: InputDecoration(
hintText: "Search tracks...",
hintText: context.l10n.search_tracks,
hintStyle: TextStyle(color: color?.titleTextColor),
border: theme.inputDecorationTheme.border?.copyWith(
borderSide: BorderSide(
@ -211,7 +212,7 @@ class TrackCollectionView<T> extends HookConsumerWidget {
if (kIsMobile)
CompactSearch(
onChanged: (value) => searchText.value = value,
placeholder: "Search tracks...",
placeholder: context.l10n.search_tracks,
iconColor: color?.titleTextColor,
),
if (collapsed.value) ...buttons,
@ -287,7 +288,7 @@ class TrackCollectionView<T> extends HookConsumerWidget {
),
if (album != null)
Text(
"${AlbumType.from(album?.albumType).formatted}Released${DateTime.tryParse(
"${AlbumType.from(album?.albumType).formatted}${context.l10n.released}${DateTime.tryParse(
album?.releaseDate ?? "",
)?.year}",
style:
@ -325,7 +326,10 @@ class TrackCollectionView<T> extends HookConsumerWidget {
return const ShimmerTrackTile();
} else if (tracksSnapshot.hasError) {
return SliverToBoxAdapter(
child: Text("Error ${tracksSnapshot.error}"));
child: Text(
context.l10n.error(tracksSnapshot.error ?? ""),
),
);
}
return TracksTableView(

View File

@ -10,6 +10,7 @@ import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/components/shared/heart_button.dart';
import 'package:spotube/components/shared/links/link_text.dart';
import 'package:spotube/components/shared/image/universal_image.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/hooks/use_breakpoints.dart';
import 'package:spotube/models/logger.dart';
import 'package:spotube/provider/authentication_provider.dart';
@ -90,7 +91,7 @@ class TrackTile extends HookConsumerWidget {
width: 300,
behavior: SnackBarBehavior.floating,
content: Text(
"Copied $data to clipboard",
context.l10n.copied_to_clipboard(data),
textAlign: TextAlign.center,
),
),
@ -114,7 +115,8 @@ class TrackTile extends HookConsumerWidget {
final playlistsCheck = useState(<String, bool>{});
return AlertDialog(
title: Text(
"Add `${track.value.name}` to following Playlists",
context.l10n
.add_to_following_playlists(track.value.name!),
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
@ -122,11 +124,11 @@ class TrackTile extends HookConsumerWidget {
),
actions: [
OutlinedButton(
child: const Text("Cancel"),
child: Text(context.l10n.cancel),
onPressed: () => Navigator.pop(context),
),
FilledButton(
child: const Text("Add"),
child: Text(context.l10n.add),
onPressed: () async {
final selectedPlaylists = playlistsCheck
.value.entries
@ -263,7 +265,7 @@ class TrackTile extends HookConsumerWidget {
if (isBlackListed) ...[
const SizedBox(width: 5),
Text(
"Blacklisted",
context.l10n.blacklisted,
style: TextStyle(
color: Colors.red[400],
fontSize: 12,
@ -307,7 +309,7 @@ class TrackTile extends HookConsumerWidget {
PopupMenuButton(
icon: const Icon(SpotubeIcons.moreHorizontal),
position: PopupMenuPosition.under,
tooltip: "More options",
tooltip: context.l10n.more_actions,
itemBuilder: (context) {
return [
if (!playlistQueueNotifier.isTrackOnQueue(track.value)) ...[
@ -318,14 +320,15 @@ class TrackTile extends HookConsumerWidget {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
"Added ${track.value.name} to queue",
context.l10n
.added_track_to_queue(track.value.name!),
),
),
);
},
child: const ListTile(
leading: Icon(SpotubeIcons.queueAdd),
title: Text("Add to Queue"),
child: ListTile(
leading: const Icon(SpotubeIcons.queueAdd),
title: Text(context.l10n.add_to_queue),
),
),
PopupMenuItem(
@ -334,14 +337,16 @@ class TrackTile extends HookConsumerWidget {
playlistQueueNotifier.playNext([track.value]);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content:
Text("${track.value.name} will play next"),
content: Text(
context.l10n
.track_will_play_next(track.value.name!),
),
),
);
},
child: const ListTile(
leading: Icon(SpotubeIcons.lightning),
title: Text("Play next"),
child: ListTile(
leading: const Icon(SpotubeIcons.lightning),
title: Text(context.l10n.play_next),
),
),
] else
@ -354,14 +359,17 @@ class TrackTile extends HookConsumerWidget {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
"Removed ${track.value.name} from queue"),
context.l10n.removed_track_from_queue(
track.value.name!,
),
),
),
);
},
enabled: playlist?.activeTrack.id != track.value.id,
child: const ListTile(
leading: Icon(SpotubeIcons.queueRemove),
title: Text("Remove from queue"),
child: ListTile(
leading: const Icon(SpotubeIcons.queueRemove),
title: Text(context.l10n.remove_from_queue),
),
),
if (toggler.item3.hasData)
@ -378,7 +386,9 @@ class TrackTile extends HookConsumerWidget {
)
: const Icon(SpotubeIcons.heart),
title: Text(
"${toggler.item1 ? "Remove from" : "Save as "} favorite",
toggler.item1
? context.l10n.remove_from_favorites
: context.l10n.save_as_favorite,
),
),
),
@ -386,9 +396,9 @@ class TrackTile extends HookConsumerWidget {
PopupMenuItem(
padding: EdgeInsets.zero,
onTap: actionAddToPlaylist,
child: const ListTile(
leading: Icon(SpotubeIcons.playlistAdd),
title: Text("Add To playlist"),
child: ListTile(
leading: const Icon(SpotubeIcons.playlistAdd),
title: Text(context.l10n.add_to_playlist),
),
),
if (userPlaylist && auth != null)
@ -406,7 +416,7 @@ class TrackTile extends HookConsumerWidget {
child: CircularProgressIndicator(),
)
: const Icon(SpotubeIcons.removeFilled),
title: const Text("Remove from playlist"),
title: Text(context.l10n.remove_from_playlist),
),
),
PopupMenuItem(
@ -429,7 +439,9 @@ class TrackTile extends HookConsumerWidget {
iconColor: !isBlackListed ? Colors.red[400] : null,
textColor: !isBlackListed ? Colors.red[400] : null,
title: Text(
"${isBlackListed ? "Remove from" : "Add to"} blacklist",
isBlackListed
? context.l10n.remove_from_blacklist
: context.l10n.add_to_blacklist,
),
),
),
@ -438,9 +450,9 @@ class TrackTile extends HookConsumerWidget {
onTap: () {
actionShare(track.value);
},
child: const ListTile(
leading: Icon(SpotubeIcons.share),
title: Text("Share"),
child: ListTile(
leading: const Icon(SpotubeIcons.share),
title: Text(context.l10n.share),
),
)
];

View File

@ -10,6 +10,7 @@ import 'package:spotube/components/shared/fallbacks/not_found.dart';
import 'package:spotube/components/shared/sort_tracks_dropdown.dart';
import 'package:spotube/components/shared/track_table/track_tile.dart';
import 'package:spotube/components/library/user_local_tracks.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/hooks/use_breakpoints.dart';
import 'package:spotube/provider/blacklist_provider.dart';
import 'package:spotube/provider/downloader_provider.dart';
@ -96,7 +97,7 @@ class TracksTableView extends HookConsumerWidget {
child: Row(
children: [
Text(
"Title",
context.l10n.title,
style: tableHeadStyle,
overflow: TextOverflow.ellipsis,
),
@ -110,7 +111,7 @@ class TracksTableView extends HookConsumerWidget {
child: Row(
children: [
Text(
"Album",
context.l10n.album,
overflow: TextOverflow.ellipsis,
style: tableHeadStyle,
),
@ -120,7 +121,7 @@ class TracksTableView extends HookConsumerWidget {
],
if (!breakpoint.isSm) ...[
const SizedBox(width: 10),
Text("Time", style: tableHeadStyle),
Text(context.l10n.time, style: tableHeadStyle),
const SizedBox(width: 10),
],
SortTracksDropdown(
@ -133,7 +134,7 @@ class TracksTableView extends HookConsumerWidget {
},
),
PopupMenuButton(
tooltip: "More Actions",
tooltip: context.l10n.more_actions,
itemBuilder: (context) {
return [
PopupMenuItem(
@ -144,7 +145,8 @@ class TracksTableView extends HookConsumerWidget {
const Icon(SpotubeIcons.download),
const SizedBox(width: 5),
Text(
"Download ${selectedTracks.isNotEmpty ? "(${selectedTracks.length})" : ""}",
context.l10n
.download_count(selectedTracks.length),
),
],
),
@ -158,7 +160,9 @@ class TracksTableView extends HookConsumerWidget {
const Icon(SpotubeIcons.playlistAdd),
const SizedBox(width: 5),
Text(
"Add (${selectedTracks.length}) to Playlist",
context.l10n.add_count_to_playlist(
selectedTracks.length,
),
),
],
),
@ -171,7 +175,8 @@ class TracksTableView extends HookConsumerWidget {
const Icon(SpotubeIcons.queueAdd),
const SizedBox(width: 5),
Text(
"Add (${selectedTracks.length}) to Queue",
context.l10n
.add_count_to_queue(selectedTracks.length),
),
],
),
@ -184,7 +189,8 @@ class TracksTableView extends HookConsumerWidget {
const Icon(SpotubeIcons.lightning),
const SizedBox(width: 5),
Text(
"Play (${selectedTracks.length}) Next",
context.l10n
.play_count_next(selectedTracks.length),
),
],
),

View File

@ -57,5 +57,46 @@
"added_to_queue": "{tracks}টি গানের ট্র্যাক কিউতে যোগ করা হয়েছে",
"filter_albums": "অ্যালবাম অনুসন্ধান করুন...",
"synced": "সময়ের সাথে সুসংগত",
"plain": "অসুসংগত"
"plain": "অসুসংগত",
"shuffle": "অদলবদল",
"search_tracks": "গান অনুসন্ধান করুন...",
"released": "প্রকাশিত হয়েছে",
"error": "ত্রুটি {error}",
"title": "শিরোনাম",
"time": "সময়",
"more_actions": "আরও অপশন",
"download_count": "ডাউনলোড ({count}টি)",
"add_count_to_playlist": "প্লেলিস্টে যোগ করুন ({count}টি)",
"add_count_to_queue": "কিউতে যোগ করুন ({count}টি)",
"play_count_next": "পরবর্তীতে চালান ({count}টি)",
"album": "অ্যালবাম",
"copied_to_clipboard": "{data} ক্লিপবোর্ডে কপি করা হয়েছে",
"add_to_following_playlists": "নিম্নলিখিত প্লেলিস্টে {track} যোগ করুন",
"add": "যোগ করুন",
"added_track_to_queue": "কিউতে {track} যোগ করা হয়েছে",
"add_to_queue": "কিউতে যোগ করুন",
"track_will_play_next": "{track} পরবর্তীতে চালানো হবে",
"play_next": "পরবর্তীতে চালান",
"removed_track_from_queue": "কিউ থেকে {track} সরিয়ে নেওয়া হয়েছে",
"remove_from_queue": "কিউ থেকে সরান",
"remove_from_favorites": "পছন্দের তালিকা থেকে অপসারণ করুন",
"save_as_favorite": "পছন্দের তালিকায় সংরক্ষণ করুন",
"add_to_playlist": "প্লেলিস্টে যোগ করুন",
"remove_from_playlist": "প্লেলিস্ট থেকে সরান",
"add_to_blacklist": "ব্ল্যাকলিস্টে যোগ করুন",
"remove_from_blacklist": "ব্ল্যাকলিস্ট থেকে সরান",
"share": "শেয়ার করুন",
"mini_player": "মিনি প্লেয়ার",
"slide_to_seek": "গান সামনে বা পিছনে নিতে স্লাইড করুন",
"shuffle_playlist": "প্লেলিস্ট এলোমেলো করুন",
"unshuffle_playlist": "প্লেলিস্ট আগের মতো করুন",
"previous_track": "আগের গানের ট্র্যাক",
"next_track": "পরের গানের ট্র্যাক",
"pause_playback": "গান বন্ধ করুন",
"resume_playback": "গান চালু করুন",
"loop_track": "গান শেষে পুনরায় চালান",
"repeat_playlist": "প্লেলিস্ট শেষে পুনরায় চালান",
"queue": "গানের কিউ",
"alternative_track_sources": "বিকল্প গানের উৎস",
"download_track": "গান ডাউনলোড করুন"
}

View File

@ -57,5 +57,46 @@
"added_to_queue": "Added {tracks} tracks to queue",
"filter_albums": "Filter albums...",
"synced": "Synced",
"plain": "Plain"
"plain": "Plain",
"shuffle": "Shuffle",
"search_tracks": "Search tracks...",
"released": "Released",
"error": "Error {error}",
"title": "Title",
"time": "Time",
"more_actions": "More actions",
"download_count": "Download ({count})",
"add_count_to_playlist": "Add ({count}) to Playlist",
"add_count_to_queue": "Add ({count}) to Queue",
"play_count_next": "Play ({count}) next",
"album": "Album",
"copied_to_clipboard": "Copied {data} to clipboard",
"add_to_following_playlists": "Add {track} to following Playlists",
"add": "Add",
"added_track_to_queue": "Added {track} to queue",
"add_to_queue": "Add to queue",
"track_will_play_next": "{track} will play next",
"play_next": "Play next",
"removed_track_from_queue": "Removed {track} from queue",
"remove_from_queue": "Remove from queue",
"remove_from_favorites": "Remove from favorites",
"save_as_favorite": "Save as favorite",
"add_to_playlist": "Add to playlist",
"remove_from_playlist": "Remove from playlist",
"add_to_blacklist": "Add to blacklist",
"remove_from_blacklist": "Remove from blacklist",
"share": "Share",
"mini_player": "Mini Player",
"slide_to_seek": "Slide to seek forward or backward",
"shuffle_playlist": "Shuffle playlist",
"unshuffle_playlist": "Unshuffle playlist",
"previous_track": "Previous track",
"next_track": "Next track",
"pause_playback": "Pause Playback",
"resume_playback": "Resume Playback",
"loop_track": "Loop track",
"repeat_playlist": "Repeat playlist",
"queue": "Queue",
"alternative_track_sources": "Alternative track sources",
"download_track": "Download track"
}