feat(locale): localize search, library, lyrics, artist with both Bengali and English

This commit is contained in:
Kingkor Roy Tirtho 2023-04-29 10:11:56 +06:00
parent a1cdbad187
commit 11fe9ec744
13 changed files with 172 additions and 69 deletions

View File

@ -4,6 +4,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotify/spotify.dart';
import 'package:spotube/components/shared/image/universal_image.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/hooks/use_breakpoint_value.dart';
import 'package:spotube/hooks/use_brightness_value.dart';
import 'package:spotube/provider/blacklist_provider.dart';
@ -89,9 +90,9 @@ class ArtistCard extends HookConsumerWidget {
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(50)),
child: const Text(
"Artist",
style: TextStyle(
child: Text(
context.l10n.artist,
style: const TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.bold,

View File

@ -8,6 +8,7 @@ import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/components/album/album_card.dart';
import 'package:spotube/components/shared/shimmers/shimmer_playbutton_card.dart';
import 'package:spotube/components/shared/fallbacks/anonymous_fallback.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/hooks/use_breakpoint_value.dart';
import 'package:spotube/provider/authentication_provider.dart';
import 'package:spotube/services/queries/queries.dart';
@ -71,9 +72,9 @@ class UserAlbums extends HookConsumerWidget {
children: [
TextField(
onChanged: (value) => searchText.value = value,
decoration: const InputDecoration(
prefixIcon: Icon(SpotubeIcons.filter),
hintText: 'Filter albums...',
decoration: InputDecoration(
prefixIcon: const Icon(SpotubeIcons.filter),
hintText: context.l10n.filter_albums,
),
),
const SizedBox(height: 20),

View File

@ -9,6 +9,7 @@ import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/components/shared/fallbacks/anonymous_fallback.dart';
import 'package:spotube/components/shared/waypoint.dart';
import 'package:spotube/components/artist/artist_card.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/provider/authentication_provider.dart';
import 'package:spotube/services/queries/queries.dart';
import 'package:tuple/tuple.dart';
@ -62,9 +63,9 @@ class UserArtists extends HookConsumerWidget {
color: theme.scaffoldBackgroundColor,
child: TextField(
onChanged: (value) => searchText.value = value,
decoration: const InputDecoration(
prefixIcon: Icon(SpotubeIcons.filter),
hintText: 'Filter artists...',
decoration: InputDecoration(
prefixIcon: const Icon(SpotubeIcons.filter),
hintText: context.l10n.filter_artist,
),
),
),
@ -76,10 +77,10 @@ class UserArtists extends HookConsumerWidget {
padding: const EdgeInsets.all(20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
CircularProgressIndicator(),
SizedBox(width: 10),
Text("Loading..."),
children: [
const CircularProgressIndicator(),
const SizedBox(width: 10),
Text(context.l10n.loading),
],
),
)

View File

@ -4,6 +4,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotify/spotify.dart';
import 'package:spotube/components/shared/image/universal_image.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/provider/downloader_provider.dart';
import 'package:spotube/utils/type_conversion_utils.dart';
@ -24,7 +25,8 @@ class UserDownloads extends HookConsumerWidget {
children: [
Expanded(
child: AutoSizeText(
"Currently downloading (${downloader.currentlyRunning})",
context.l10n
.currently_downloading(downloader.currentlyRunning),
maxLines: 1,
style: Theme.of(context).textTheme.headlineMedium,
),
@ -38,7 +40,7 @@ class UserDownloads extends HookConsumerWidget {
onPressed: downloader.currentlyRunning > 0
? downloader.cancelAll
: null,
child: const Text("Cancel All"),
child: Text(context.l10n.cancel_all),
),
],
),

View File

@ -19,6 +19,7 @@ import 'package:spotube/components/shared/compact_search.dart';
import 'package:spotube/components/shared/shimmers/shimmer_track_tile.dart';
import 'package:spotube/components/shared/sort_tracks_dropdown.dart';
import 'package:spotube/components/shared/track_table/track_tile.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/hooks/use_async_effect.dart';
import 'package:spotube/models/local_track.dart';
import 'package:spotube/provider/playlist_queue_provider.dart';
@ -175,9 +176,9 @@ class UserLocalTracks extends HookConsumerWidget {
[],
);
var searchbar = CompactSearch(
final searchbar = CompactSearch(
onChanged: (value) => searchText.value = value,
placeholder: "Search local tracks...",
placeholder: context.l10n.search_local_tracks,
);
return Column(
@ -202,7 +203,7 @@ class UserLocalTracks extends HookConsumerWidget {
: null,
child: Row(
children: [
const Text("Play"),
Text(context.l10n.play),
Icon(
isPlaylistPlaying ? SpotubeIcons.stop : SpotubeIcons.play,
)
@ -294,9 +295,9 @@ class UserLocalTracks extends HookConsumerWidget {
ref.refresh(localTracksProvider);
},
padding: EdgeInsets.zero,
child: const ListTile(
leading: Icon(SpotubeIcons.trash),
title: Text("Delete"),
child: ListTile(
leading: const Icon(SpotubeIcons.trash),
title: Text(context.l10n.delete),
),
),
];

View File

@ -10,6 +10,7 @@ import 'package:spotube/components/playlist/playlist_create_dialog.dart';
import 'package:spotube/components/shared/shimmers/shimmer_playbutton_card.dart';
import 'package:spotube/components/shared/fallbacks/anonymous_fallback.dart';
import 'package:spotube/components/playlist/playlist_card.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/hooks/use_breakpoint_value.dart';
import 'package:spotube/hooks/use_breakpoints.dart';
import 'package:spotube/provider/authentication_provider.dart';
@ -33,8 +34,8 @@ class UserPlaylists extends HookConsumerWidget {
final likedTracksPlaylist = useMemoized(
() => PlaylistSimple()
..name = "Liked Tracks"
..description = "All your liked tracks"
..name = context.l10n.liked_tracks
..description = context.l10n.liked_tracks_description
..type = "playlist"
..collaborative = false
..public = false
@ -46,7 +47,7 @@ class UserPlaylists extends HookConsumerWidget {
..url =
"https://t.scdn.co/images/3099b3803ad9496896c43f22fe9be8c4.png"
],
[]);
[context.l10n]);
final playlists = useMemoized(
() {
@ -87,9 +88,9 @@ class UserPlaylists extends HookConsumerWidget {
padding: const EdgeInsets.all(10),
child: TextField(
onChanged: (value) => searchText.value = value,
decoration: const InputDecoration(
hintText: "Filter your playlists...",
prefixIcon: Icon(SpotubeIcons.filter),
decoration: InputDecoration(
hintText: context.l10n.filter_playlists,
prefixIcon: const Icon(SpotubeIcons.filter),
),
),
),

View File

@ -4,6 +4,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/provider/spotify_provider.dart';
class PlaylistCreateDialog extends HookConsumerWidget {
@ -18,7 +19,7 @@ class PlaylistCreateDialog extends HookConsumerWidget {
foregroundColor: Theme.of(context).colorScheme.primary,
),
icon: const Icon(SpotubeIcons.addFilled),
label: const Text("Create Playlist"),
label: Text(context.l10n.create_playlist),
onPressed: () {
showDialog(
context: context,
@ -50,17 +51,17 @@ class PlaylistCreateDialog extends HookConsumerWidget {
}
return AlertDialog(
title: const Text("Create a Playlist"),
title: Text(context.l10n.create_a_playlist),
actions: [
OutlinedButton(
child: const Text("Cancel"),
child: Text(context.l10n.cancel),
onPressed: () {
Navigator.pop(context);
},
),
FilledButton(
onPressed: onCreate,
child: const Text("Create"),
child: Text(context.l10n.create),
),
],
content: Container(
@ -71,29 +72,29 @@ class PlaylistCreateDialog extends HookConsumerWidget {
children: [
TextField(
controller: playlistName,
decoration: const InputDecoration(
hintText: "Name of the playlist",
labelText: "Playlist Name",
decoration: InputDecoration(
hintText: context.l10n.name_of_playlist,
labelText: context.l10n.name_of_playlist,
),
),
const SizedBox(height: 10),
TextField(
controller: description,
decoration: const InputDecoration(
hintText: "Description...",
decoration: InputDecoration(
hintText: context.l10n.description,
),
keyboardType: TextInputType.multiline,
maxLines: 5,
),
const SizedBox(height: 10),
CheckboxListTile(
title: const Text("Public"),
title: Text(context.l10n.public),
value: public.value,
onChanged: (val) => public.value = val ?? false,
),
const SizedBox(height: 10),
CheckboxListTile(
title: const Text("Collaborative"),
title: Text(context.l10n.collaborative),
value: collaborative.value,
onChanged: (val) => collaborative.value = val ?? false,
),

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/components/library/user_local_tracks.dart';
import 'package:spotube/extensions/context.dart';
class SortTracksDropdown extends StatelessWidget {
final SortBy? value;
@ -20,37 +21,37 @@ class SortTracksDropdown extends StatelessWidget {
PopupMenuItem(
value: SortBy.none,
enabled: value != SortBy.none,
child: const Text("None"),
child: Text(context.l10n.none),
),
PopupMenuItem(
value: SortBy.ascending,
enabled: value != SortBy.ascending,
child: const Text("Sort by A-Z"),
child: Text(context.l10n.sort_a_z),
),
PopupMenuItem(
value: SortBy.descending,
enabled: value != SortBy.descending,
child: const Text("Sort by Z-A"),
child: Text(context.l10n.sort_z_a),
),
PopupMenuItem(
value: SortBy.dateAdded,
enabled: value != SortBy.dateAdded,
child: const Text("Sort by Date"),
child: Text(context.l10n.sort_date),
),
PopupMenuItem(
value: SortBy.artist,
enabled: value != SortBy.artist,
child: const Text("Sort by Artist"),
child: Text(context.l10n.sort_artist),
),
PopupMenuItem(
value: SortBy.album,
enabled: value != SortBy.album,
child: const Text("Sort by Album"),
child: Text(context.l10n.sort_album),
),
];
},
onSelected: onChanged,
tooltip: "Sort tracks",
tooltip: context.l10n.sort_tracks,
icon: const Icon(SpotubeIcons.sort),
);
}

View File

@ -16,5 +16,46 @@
"load_more": "আরো লোড করুন",
"playlists": "প্লেলিস্ট",
"artists": "শিল্পী",
"albums": "অ্যালবাম"
"albums": "অ্যালবাম",
"tracks": "গানের ট্র্যাক",
"downloads": "ডাউনলোড",
"filter_playlists": "প্লেলিস্ট অনুসন্ধান করুন...",
"liked_tracks": "পছন্দের গান",
"liked_tracks_description": "আপনার পছন্দের গান সমূহ",
"create_playlist": "প্লেলিস্ট তৈরি করুন",
"create_a_playlist": "একটি প্লেলিস্ট তৈরি করুন",
"create": "তৈরি করুন",
"cancel": "বাতিল করুন",
"playlist_name": "প্লেলিস্টের নাম",
"name_of_playlist": "প্লেলিস্টের নাম",
"description": "বিবরণ",
"public": "পাবলিক",
"collaborative": "সহযোগিতামূলক",
"search_local_tracks": "ডাউনলোডকৃত গান অনুসন্ধান করুন...",
"play": "চালান",
"delete": "মুছে ফেলুন",
"none": "কোনটিই না",
"sort_a_z": "A-Z ক্রমে সাজান",
"sort_z_a": "Z-A ক্রমে সাজান",
"sort_date": "তারিখের ক্রমে সাজান",
"sort_artist": "শিল্পীর ক্রমে সাজান",
"sort_album": "অ্যালবামের ক্রমে সাজান",
"sort_tracks": "গানের ক্রম",
"currently_downloading": "ডাউনলোড করা হচ্ছে ({tracks_length})",
"cancel_all": "সব বাতিল করুন",
"filter_artist": "শিল্পীর অনুসন্ধান করুন...",
"followers": "{followers} অনুসরণকারী",
"add_artist_to_blacklist": "শিল্পীকে ব্ল্যাকলিস্টে যোগ করুন",
"top_tracks": "শীর্ষ গানের ট্র্যাক",
"fans_also_like": "অনুসরণকারীদের পছন্দ",
"loading": "লোড হচ্ছে...",
"artist": "শিল্পী",
"blacklisted": "ব্ল্যাকলিস্টে আছে",
"following": "অনুসরণ করছেন",
"follow": "অনুসরণ করুন",
"artist_url_copied": "শিল্পীর URL কপি করা হয়েছে",
"added_to_queue": "{tracks}টি গানের ট্র্যাক কিউতে যোগ করা হয়েছে",
"filter_albums": "অ্যালবাম অনুসন্ধান করুন...",
"synced": "সময়ের সাথে সুসংগত",
"plain": "অসুসংগত"
}

View File

@ -16,5 +16,46 @@
"load_more": "Load more",
"playlists": "Playlists",
"artists": "Artists",
"albums": "Albums"
"albums": "Albums",
"tracks": "Tracks",
"downloads": "Downloads",
"filter_playlists": "Filter your playlists...",
"liked_tracks": "Liked Tracks",
"liked_tracks_description": "All your liked tracks",
"create_playlist": "Create Playlist",
"create_a_playlist": "Create a playlist",
"create": "Create",
"cancel": "Cancel",
"playlist_name": "Playlist Name",
"name_of_playlist": "Name of the playlist",
"description": "Description",
"public": "Public",
"collaborative": "Collaborative",
"search_local_tracks": "Search local tracks...",
"play": "Play",
"delete": "Delete",
"none": "None",
"sort_a_z": "Sort by A-Z",
"sort_z_a": "Sort by Z-A",
"sort_date": "Sort by date",
"sort_artist": "Sort by Artist",
"sort_album": "Sort by Album",
"sort_tracks": "Sort Tracks",
"currently_downloading": "Currently Downloading ({tracks_length})",
"cancel_all": "Cancel All",
"filter_artist": "Filter artists...",
"followers": "{followers} Followers",
"add_artist_to_blacklist": "Add artist to blacklist",
"top_tracks": "Top Tracks",
"fans_also_like": "Fans also like",
"loading": "Loading...",
"artist": "Artist",
"blacklisted": "Blacklisted",
"following": "Following",
"follow": "Follow",
"artist_url_copied": "Artist URL copied to clipboard",
"added_to_queue": "Added {tracks} tracks to queue",
"filter_albums": "Filter albums...",
"synced": "Synced",
"plain": "Plain"
}

View File

@ -12,6 +12,7 @@ import 'package:spotube/components/shared/track_table/track_tile.dart';
import 'package:spotube/components/shared/image/universal_image.dart';
import 'package:spotube/components/artist/artist_album_list.dart';
import 'package:spotube/components/artist/artist_card.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/hooks/use_breakpoint_value.dart';
import 'package:spotube/hooks/use_breakpoints.dart';
import 'package:spotube/models/logger.dart';
@ -142,7 +143,7 @@ class ArtistPage extends HookConsumerWidget {
borderRadius:
BorderRadius.circular(50)),
child: Text(
"Blacklisted",
context.l10n.blacklisted,
style: chipTextVariant.copyWith(
color: Colors.white,
),
@ -158,7 +159,11 @@ class ArtistPage extends HookConsumerWidget {
: textTheme.headlineMedium,
),
Text(
"${PrimitiveUtils.toReadableNumber(data.followers!.total!.toDouble())} followers",
context.l10n.followers(
PrimitiveUtils.toReadableNumber(
data.followers!.total!.toDouble(),
),
),
style: textTheme.bodyMedium?.copyWith(
fontWeight:
breakpoint.isSm ? null : FontWeight.bold,
@ -211,19 +216,20 @@ class ArtistPage extends HookConsumerWidget {
if (isFollowingQuery.data!) {
return OutlinedButton(
onPressed: followUnfollow,
child: const Text("Following"),
child: Text(context.l10n.following),
);
}
return FilledButton(
onPressed: followUnfollow,
child: const Text("Follow"),
child: Text(context.l10n.follow),
);
},
),
const SizedBox(width: 5),
IconButton(
tooltip: "Add to blacklisted artists",
tooltip:
context.l10n.add_artist_to_blacklist,
icon: Icon(
SpotubeIcons.userRemove,
color: !isBlackListed
@ -263,12 +269,14 @@ class ArtistPage extends HookConsumerWidget {
text: data.externalUrls?.spotify),
);
if (!context.mounted) return;
scaffoldMessenger.showSnackBar(
const SnackBar(
SnackBar(
width: 300,
behavior: SnackBarBehavior.floating,
content: Text(
"Artist URL copied to clipboard",
context.l10n.artist_url_copied,
textAlign: TextAlign.center,
),
),
@ -324,7 +332,7 @@ class ArtistPage extends HookConsumerWidget {
Row(
children: [
Text(
"Top Tracks",
context.l10n.top_tracks,
style: theme.textTheme.headlineSmall,
),
if (!isPlaylistPlaying)
@ -339,7 +347,9 @@ class ArtistPage extends HookConsumerWidget {
width: 300,
behavior: SnackBarBehavior.floating,
content: Text(
"Added ${topTracks.length} tracks to queue",
context.l10n.added_to_queue(
topTracks.length,
),
textAlign: TextAlign.center,
),
),
@ -383,14 +393,14 @@ class ArtistPage extends HookConsumerWidget {
),
const SizedBox(height: 50),
Text(
"Albums",
context.l10n.albums,
style: theme.textTheme.headlineSmall,
),
const SizedBox(height: 10),
ArtistAlbumList(artistId),
const SizedBox(height: 20),
Text(
"Fans also likes",
context.l10n.fans_also_like,
style: theme.textTheme.headlineSmall,
),
const SizedBox(height: 10),

View File

@ -8,12 +8,13 @@ import 'package:spotube/components/library/user_artists.dart';
import 'package:spotube/components/library/user_downloads.dart';
import 'package:spotube/components/library/user_playlists.dart';
import 'package:spotube/components/shared/themed_button_tab_bar.dart';
import 'package:spotube/extensions/context.dart';
class LibraryPage extends HookConsumerWidget {
const LibraryPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, ref) {
return const DefaultTabController(
return DefaultTabController(
length: 5,
child: SafeArea(
bottom: false,
@ -22,16 +23,16 @@ class LibraryPage extends HookConsumerWidget {
centerTitle: true,
leading: ThemedButtonsTabBar(
tabs: [
'Playlists',
'Tracks',
'Downloads',
'Artists',
'Albums',
context.l10n.playlists,
context.l10n.tracks,
context.l10n.downloads,
context.l10n.artists,
context.l10n.albums,
],
),
leadingWidth: double.infinity,
),
body: TabBarView(
body: const TabBarView(
children: [
UserPlaylists(),
UserLocalTracks(),

View File

@ -9,6 +9,7 @@ import 'package:spotube/components/shared/fallbacks/anonymous_fallback.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/themed_button_tab_bar.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/hooks/use_breakpoints.dart';
import 'package:spotube/hooks/use_custom_status_bar_color.dart';
import 'package:spotube/hooks/use_palette_color.dart';
@ -43,10 +44,10 @@ class LyricsPage extends HookConsumerWidget {
noSetBGColor: true,
);
const tabbar = ThemedButtonsTabBar(
final tabbar = ThemedButtonsTabBar(
tabs: [
"Synced",
"Plain",
context.l10n.synced,
context.l10n.plain,
],
);
@ -120,7 +121,7 @@ class LyricsPage extends HookConsumerWidget {
child: Scaffold(
extendBodyBehindAppBar: true,
appBar: !kIsMacOS
? const PageWindowTitleBar(
? PageWindowTitleBar(
backgroundColor: Colors.transparent,
title: tabbar,
)