diff --git a/README.md b/README.md
index 8f952ad..46b1156 100644
--- a/README.md
+++ b/README.md
@@ -4,40 +4,36 @@
-![CircleCI](https://img.shields.io/circleci/build/github/stonega/tsacdop?token=efe1331861e017144f2abb363acd95197e436dad)
-
-
-
-![GitHub release (latest by date)](https://img.shields.io/github/v/release/stonega/tsacdop) [![GooglePlay](https://img.shields.io/badge/Google-PlayStore-%2323CCC6)](https://play.google.com/store/apps/details?id=com.stonegate.tsacdop)
+![CircleCI](https://img.shields.io/circleci/build/github/stonega/tsacdop?token=efe1331861e017144f2abb363acd95197e436dad) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/stonega/tsacdop) [![GooglePlay](https://img.shields.io/badge/Google-PlayStore-%2323CCC6)](https://play.google.com/store/apps/details?id=com.stonegate.tsacdop)
## About
Enjoy podcasts with Tsacdop.
-Tsacdop is a podcast player developed with flutter, a clean, simply beautiful and friendly app, only support Android right now.
+Tsacdop is a podcast player developed with flutter, a clean, simply beautiful and friendly app, only support Android right now.
-Credit to flutter team and all involved plugins, especially [webfeed](https://github.com/witochandra/webfeed) and [Just_Audio](https://pub.dev/packages/just_audio).
+Credit to flutter team and all involved plugins, especially [webfeed](https://github.com/witochandra/webfeed) and [Just_Audio](https://pub.dev/packages/just_audio).
The podcasts search engine is powered by [ListenNotes](https://listennotes.com).
## Features
-* Podcasts group management
-* Playlist support
-* Sleep timer / Speed setting
-* OMPL file export and import
-* Auto syncing in background
-* Listen and subscribe history record
-* Dark mode / Accent color
-* Download for offline playing
-* Auto download new episodes / Auto delete outdated downloads
+- Podcasts group management
+- Playlist support
+- Sleep timer / Speed setting
+- OMPL file export and import
+- Auto syncing in background
+- Listen and subscribe history record
+- Dark mode / Accent color
+- Download for offline playing
+- Auto download new episodes / Auto delete outdated downloads
More to come...
## Preview
| HomePage | Group | Podcast | Episode | DarkMode |
-|------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|
+| ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| | | | | |
## License
@@ -49,8 +45,8 @@ Tsacdop is licensed under the [GPL V3.0](https://github.com/stonega/tsacdop/blob
Tsacdop is using ListenNotes api 1.0 pro to search podcast, which is not free. So I can not expose the api key in the repo.
If you want to build the app, you need to create a new file named .env.dart in lib folder. Add below code in .env.dart.
-```
-final environment = {"apiKey":"APIKEY", "shareKey":"SHAREKEY"};
+```dart
+final environment = {"apiKey":"APIKEY"};
```
You can get own api key on [ListenNotes](https://www.listennotes.com/api/), basic plan is free to all, and replace "APIKEY" with it.
@@ -58,7 +54,7 @@ If no api key added, the search function in the app won't work. But you can stil
## Known Issue
-* Playlist unstable
+- Playlist unstable
## Getting Started
@@ -66,10 +62,8 @@ This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
-* [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
-* [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
+- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
+- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
For help getting started with Flutter, view our
-[online documentation](https://flutter.dev/docs), which offers tutorials,
-samples, guidance on mobile development, and a full API reference.
-
+[online documentation](https://flutter.dev/docs), which offers tutorials, samples, guidance on mobile development, and a full API reference.
diff --git a/lib/generated/intl/messages_en.dart b/lib/generated/intl/messages_en.dart
index 5c3f786..67255d2 100644
--- a/lib/generated/intl/messages_en.dart
+++ b/lib/generated/intl/messages_en.dart
@@ -19,27 +19,85 @@ typedef String MessageIfAbsent(String messageStr, List args);
class MessageLookup extends MessageLookupByLibrary {
String get localeName => 'en';
+ static m0(groupName, count) => "${Intl.plural(count, zero: '', one: '${count} episode in ${groupName} added to playlist', other: '${count} episodes in ${groupName} added to playlist')}";
+
+ static m1(count) => "${Intl.plural(count, zero: '', one: '${count} episode added to playlist', other: '${count} episodes added to playlist')}";
+
+ static m2(host) => "Hosted on ${host}";
+
+ static m3(count) => "${Intl.plural(count, zero: '', one: '${count} hour', other: '${count} hours')}";
+
+ static m4(count) => "${Intl.plural(count, zero: '', one: '${count} min', other: '${count} mins')}";
+
+ static m5(title) => "Fetch data ${title}";
+
+ static m6(title) => "Subscribe failed, network error ${title}";
+
+ static m7(title) => "Subscribe ${title}";
+
+ static m8(title) => "Subscribe failed, podcast existed ${title}";
+
+ static m9(title) => "Subscribe success ${title}";
+
+ static m10(title) => "Update ${title}";
+
+ static m11(title) => "Update error ${title}";
+
+ static m12(time) => "Last time ${time}";
+
+ static m13(time) => "${time} Left";
+
+ static m14(count) => "${Intl.plural(count, zero: 'No Update', one: 'Updated ${count} Episode', other: 'Updated ${count} Episodes')}";
+
+ static m15(version) => "Version : ${version}";
+
final messages = _notInlinedMessages(_notInlinedMessages);
static _notInlinedMessages(_) => {
+ "add" : MessageLookupByLibrary.simpleMessage("Add"),
+ "addEpisodeGroup" : m0,
+ "addNewEpisodeAll" : m1,
+ "addNewEpisodeTooltip" : MessageLookupByLibrary.simpleMessage("Add new episodes to playlist"),
+ "addSomeGroups" : MessageLookupByLibrary.simpleMessage("Add some groups"),
"all" : MessageLookupByLibrary.simpleMessage("All"),
- "cancel" : MessageLookupByLibrary.simpleMessage("Cancel"),
+ "back" : MessageLookupByLibrary.simpleMessage("Back"),
+ "buffering" : MessageLookupByLibrary.simpleMessage("Buffering"),
+ "cancel" : MessageLookupByLibrary.simpleMessage("CANCEL"),
+ "changeLayout" : MessageLookupByLibrary.simpleMessage("Change layout"),
+ "changelog" : MessageLookupByLibrary.simpleMessage("Changelog"),
"chooseA" : MessageLookupByLibrary.simpleMessage("Choose a"),
+ "clear" : MessageLookupByLibrary.simpleMessage("Clear"),
"color" : MessageLookupByLibrary.simpleMessage("color"),
- "confirm" : MessageLookupByLibrary.simpleMessage("Confirm"),
+ "confirm" : MessageLookupByLibrary.simpleMessage("CONFIRM"),
"darkMode" : MessageLookupByLibrary.simpleMessage("Dark mode"),
"delete" : MessageLookupByLibrary.simpleMessage("Delete"),
+ "developer" : MessageLookupByLibrary.simpleMessage("Developer"),
+ "dismiss" : MessageLookupByLibrary.simpleMessage("Dismiss"),
"download" : MessageLookupByLibrary.simpleMessage("Download"),
+ "downloaded" : MessageLookupByLibrary.simpleMessage("Downloaded"),
"editName" : MessageLookupByLibrary.simpleMessage("Edit name"),
"endOfEpisode" : MessageLookupByLibrary.simpleMessage("End of Episode"),
+ "featureDiscoveryEpisode" : MessageLookupByLibrary.simpleMessage("Episode view"),
+ "featureDiscoveryEpisodeDes" : MessageLookupByLibrary.simpleMessage("You can long tap to play episode or add episode to playlist."),
+ "featureDiscoveryEpisodeTitle" : MessageLookupByLibrary.simpleMessage("Long tap to play episode instantly"),
+ "featureDiscoveryOMPL" : MessageLookupByLibrary.simpleMessage("Tap to import OMPL"),
+ "featureDiscoveryOMPLDes" : MessageLookupByLibrary.simpleMessage("You can import OMPL file, open setting or refresh all podcast at once here."),
+ "featureDiscoveryPlaylist" : MessageLookupByLibrary.simpleMessage("Tap to open playlist"),
+ "featureDiscoveryPlaylistDes" : MessageLookupByLibrary.simpleMessage("You can add episode to playlist by yourself. Episode will be auto removed from playlist when played."),
+ "featureDiscoveryPodcast" : MessageLookupByLibrary.simpleMessage("Podcast view"),
+ "featureDiscoveryPodcastDes" : MessageLookupByLibrary.simpleMessage("You can tap See All to add groups or manage podcasts."),
+ "featureDiscoveryPodcastTitle" : MessageLookupByLibrary.simpleMessage("Scroll vertically to switch groups"),
+ "featureDiscoverySearch" : MessageLookupByLibrary.simpleMessage("Tap to search podcast"),
+ "featureDiscoverySearchDes" : MessageLookupByLibrary.simpleMessage("You can search podcast title , key word or RSS link to subscribe new podcast."),
"feedbackEmail" : MessageLookupByLibrary.simpleMessage("Write to me"),
"feedbackGithub" : MessageLookupByLibrary.simpleMessage("Submit issue"),
"feedbackPlay" : MessageLookupByLibrary.simpleMessage("Rate on Play"),
"feedbackTelegram" : MessageLookupByLibrary.simpleMessage("Join group"),
"from" : MessageLookupByLibrary.simpleMessage("From"),
+ "goodNight" : MessageLookupByLibrary.simpleMessage("Good Night"),
+ "groupFilter" : MessageLookupByLibrary.simpleMessage("Group filter"),
"groups" : MessageLookupByLibrary.simpleMessage("Groups"),
"homeGroupsSeeAll" : MessageLookupByLibrary.simpleMessage("See All"),
"homeMenuPlaylist" : MessageLookupByLibrary.simpleMessage("Playlist"),
- "homeSubMenuDownloaded" : MessageLookupByLibrary.simpleMessage("Downloaded"),
"homeSubMenuLikeData" : MessageLookupByLibrary.simpleMessage("Like Date"),
"homeSubMenuSortBy" : MessageLookupByLibrary.simpleMessage("Sort by"),
"homeSubMenuUpdateDate" : MessageLookupByLibrary.simpleMessage("Update Date"),
@@ -49,29 +107,52 @@ class MessageLookup extends MessageLookupByLibrary {
"homeToprightMenuImportOMPL" : MessageLookupByLibrary.simpleMessage("Import OMPL"),
"homeToprightMenuRefreshAll" : MessageLookupByLibrary.simpleMessage("Refresh all"),
"homeToprightMenuSettings" : MessageLookupByLibrary.simpleMessage("Settings"),
+ "hostedOn" : m2,
+ "hoursCount" : m3,
"later" : MessageLookupByLibrary.simpleMessage("Later"),
"lightMode" : MessageLookupByLibrary.simpleMessage("Light mode"),
"like" : MessageLookupByLibrary.simpleMessage("Like"),
+ "likeDate" : MessageLookupByLibrary.simpleMessage("Like date"),
"liked" : MessageLookupByLibrary.simpleMessage("Liked"),
"listen" : MessageLookupByLibrary.simpleMessage("Listen"),
"listened" : MessageLookupByLibrary.simpleMessage("Listened"),
+ "loadMore" : MessageLookupByLibrary.simpleMessage("Load more"),
+ "markConfirm" : MessageLookupByLibrary.simpleMessage("Mark confirm"),
+ "markConfirmContent" : MessageLookupByLibrary.simpleMessage("Confirm mark all episodes listened?"),
"markListened" : MessageLookupByLibrary.simpleMessage("Mark listened"),
"menu" : MessageLookupByLibrary.simpleMessage("Menu"),
"menuAllPodcasts" : MessageLookupByLibrary.simpleMessage("All podcasts"),
"menuMarkAllListened" : MessageLookupByLibrary.simpleMessage("Mark All Listened"),
- "menuMarkListened" : MessageLookupByLibrary.simpleMessage("Mark Listened"),
"menuViewRSS" : MessageLookupByLibrary.simpleMessage("Visit RSS Feed"),
"menuVisitSite" : MessageLookupByLibrary.simpleMessage("Visit Site"),
+ "minsCount" : m4,
"network" : MessageLookupByLibrary.simpleMessage("Network"),
"newGroup" : MessageLookupByLibrary.simpleMessage("Create new group"),
+ "newestFirst" : MessageLookupByLibrary.simpleMessage("Newest first"),
+ "noEpisodeDownload" : MessageLookupByLibrary.simpleMessage("No episode downloaded yet"),
+ "noEpisodeFavorite" : MessageLookupByLibrary.simpleMessage("No episode collected yet"),
+ "noEpisodeRecent" : MessageLookupByLibrary.simpleMessage("No episode received yet"),
+ "noPodcastGroup" : MessageLookupByLibrary.simpleMessage("No podcast in this group"),
+ "notificaitonFatch" : m5,
+ "notificationNetworkError" : m6,
+ "notificationSubscribe" : m7,
+ "notificationSubscribeExisted" : m8,
+ "notificationSuccess" : m9,
+ "notificationUpdate" : m10,
+ "notificationUpdateError" : m11,
+ "oldestFirst" : MessageLookupByLibrary.simpleMessage("Oldest first"),
"play" : MessageLookupByLibrary.simpleMessage("Play"),
+ "playing" : MessageLookupByLibrary.simpleMessage("Playing"),
+ "podcastSubscribed" : MessageLookupByLibrary.simpleMessage("Podcast subscribed"),
"popupMenuDownloadDes" : MessageLookupByLibrary.simpleMessage("Download episode"),
"popupMenuLaterDes" : MessageLookupByLibrary.simpleMessage("Add episode to playlist"),
"popupMenuLikeDes" : MessageLookupByLibrary.simpleMessage("Add episode to favorite"),
"popupMenuMarkDes" : MessageLookupByLibrary.simpleMessage("Mark episode as listened"),
"popupMenuPlayDes" : MessageLookupByLibrary.simpleMessage("Play the episode"),
+ "privacyPolicy" : MessageLookupByLibrary.simpleMessage("Privacy Policy"),
"remove" : MessageLookupByLibrary.simpleMessage("Remove"),
"schedule" : MessageLookupByLibrary.simpleMessage("Schedule"),
+ "searchInvalidRss" : MessageLookupByLibrary.simpleMessage("Invalid RSS link"),
"searchPodcast" : MessageLookupByLibrary.simpleMessage("Search podcast"),
"settingStorage" : MessageLookupByLibrary.simpleMessage("Storage"),
"settingsAccentColor" : MessageLookupByLibrary.simpleMessage("Accent color"),
@@ -128,9 +209,12 @@ class MessageLookup extends MessageLookupByLibrary {
"settingsTheme" : MessageLookupByLibrary.simpleMessage("Theme"),
"settingsUpdateInterval" : MessageLookupByLibrary.simpleMessage("Update interval"),
"settingsUpdateIntervalDes" : MessageLookupByLibrary.simpleMessage("Default 24 hours"),
+ "size" : MessageLookupByLibrary.simpleMessage("Size"),
"sleepTimer" : MessageLookupByLibrary.simpleMessage("Sleep timer"),
"subscribe" : MessageLookupByLibrary.simpleMessage("Subscribe"),
"systemDefault" : MessageLookupByLibrary.simpleMessage("System default"),
+ "timeLastPlayed" : m12,
+ "timeLeft" : m13,
"to" : MessageLookupByLibrary.simpleMessage("To"),
"toastAddPlaylist" : MessageLookupByLibrary.simpleMessage("Added to playlist"),
"toastDescovery" : MessageLookupByLibrary.simpleMessage("Discovery feature reopened, pleast restart the app"),
@@ -138,7 +222,12 @@ class MessageLookup extends MessageLookupByLibrary {
"toastFileNotVilid" : MessageLookupByLibrary.simpleMessage("File not vilid"),
"toastReadFile" : MessageLookupByLibrary.simpleMessage("Read file successfully"),
"toastRemovePlaylist" : MessageLookupByLibrary.simpleMessage("Removed from playlist"),
+ "understood" : MessageLookupByLibrary.simpleMessage("Understood"),
"unlike" : MessageLookupByLibrary.simpleMessage("Unlike"),
- "unliked" : MessageLookupByLibrary.simpleMessage("Unliked")
+ "unliked" : MessageLookupByLibrary.simpleMessage("Removed from favorite"),
+ "updateDate" : MessageLookupByLibrary.simpleMessage("Update date"),
+ "updateEpisodesCount" : m14,
+ "updateFailed" : MessageLookupByLibrary.simpleMessage("Update failed, network error"),
+ "version" : m15
};
}
diff --git a/lib/generated/intl/messages_zh-Hans.dart b/lib/generated/intl/messages_zh-Hans.dart
index 435ef80..5f95c0b 100644
--- a/lib/generated/intl/messages_zh-Hans.dart
+++ b/lib/generated/intl/messages_zh-Hans.dart
@@ -19,27 +19,85 @@ typedef String MessageIfAbsent(String messageStr, List args);
class MessageLookup extends MessageLookupByLibrary {
String get localeName => 'zh_Hans';
+ static m0(groupName, count) => "{count, plural, zero{} other{{group Name}分组${count}集节目添加到播放列表}}";
+
+ static m1(count) => "${Intl.plural(count, zero: '', other: '${count}集节目添加到播放列表')}";
+
+ static m2(host) => "平台 ${host}";
+
+ static m3(count) => "${Intl.plural(count, zero: '', other: '${count} 小时')}";
+
+ static m4(count) => "${Intl.plural(count, zero: '', other: '${count}分钟')}";
+
+ static m5(title) => "获取数据 ${title}";
+
+ static m6(title) => "订阅失败,网络错误 ${title}";
+
+ static m7(title) => "订阅${title}";
+
+ static m8(title) => "订阅失败,播客已存在 ${title}";
+
+ static m9(title) => "订阅成功 ${title}";
+
+ static m10(title) => "更新 ${title}";
+
+ static m11(title) => "更新失败 ${title}";
+
+ static m12(time) => "上次播放${time}";
+
+ static m13(time) => "剩余 ${time}";
+
+ static m14(count) => "${Intl.plural(count, zero: '未有更新', other: '更新 ${count} 集节目')}";
+
+ static m15(version) => "版本:${version}";
+
final messages = _notInlinedMessages(_notInlinedMessages);
static _notInlinedMessages(_) => {
+ "add" : MessageLookupByLibrary.simpleMessage("订阅"),
+ "addEpisodeGroup" : m0,
+ "addNewEpisodeAll" : m1,
+ "addNewEpisodeTooltip" : MessageLookupByLibrary.simpleMessage("添加更新节目到播放列表"),
+ "addSomeGroups" : MessageLookupByLibrary.simpleMessage("请添加分组"),
"all" : MessageLookupByLibrary.simpleMessage("全部"),
+ "back" : MessageLookupByLibrary.simpleMessage("返回"),
+ "buffering" : MessageLookupByLibrary.simpleMessage("缓冲"),
"cancel" : MessageLookupByLibrary.simpleMessage("取消"),
+ "changeLayout" : MessageLookupByLibrary.simpleMessage("修改布局"),
+ "changelog" : MessageLookupByLibrary.simpleMessage("更新日志"),
"chooseA" : MessageLookupByLibrary.simpleMessage("选择"),
+ "clear" : MessageLookupByLibrary.simpleMessage("清除"),
"color" : MessageLookupByLibrary.simpleMessage("颜色"),
"confirm" : MessageLookupByLibrary.simpleMessage("确认"),
"darkMode" : MessageLookupByLibrary.simpleMessage("夜晚模式"),
"delete" : MessageLookupByLibrary.simpleMessage("删除"),
+ "developer" : MessageLookupByLibrary.simpleMessage("关于我"),
+ "dismiss" : MessageLookupByLibrary.simpleMessage("忽略"),
"download" : MessageLookupByLibrary.simpleMessage("下载"),
+ "downloaded" : MessageLookupByLibrary.simpleMessage("已下载"),
"editName" : MessageLookupByLibrary.simpleMessage("修改组名"),
"endOfEpisode" : MessageLookupByLibrary.simpleMessage("节目结束"),
+ "featureDiscoveryEpisode" : MessageLookupByLibrary.simpleMessage("节目界面"),
+ "featureDiscoveryEpisodeDes" : MessageLookupByLibrary.simpleMessage("您可以长按播放节目或者添加节目到播放列表。"),
+ "featureDiscoveryEpisodeTitle" : MessageLookupByLibrary.simpleMessage("您可以长按快速播放节目"),
+ "featureDiscoveryOMPL" : MessageLookupByLibrary.simpleMessage("点击导入 OMPL"),
+ "featureDiscoveryOMPLDes" : MessageLookupByLibrary.simpleMessage("在这里您可以导入OMPL文件,打开设置页面,或者刷新所有播客。"),
+ "featureDiscoveryPlaylist" : MessageLookupByLibrary.simpleMessage("点击打开播放列表"),
+ "featureDiscoveryPlaylistDes" : MessageLookupByLibrary.simpleMessage("您可以添加节目到播放列表,节目在播放后将会从播放列表自动移除。"),
+ "featureDiscoveryPodcast" : MessageLookupByLibrary.simpleMessage("播客界面"),
+ "featureDiscoveryPodcastDes" : MessageLookupByLibrary.simpleMessage("您可以点击“查看所有”新增或管理分组。"),
+ "featureDiscoveryPodcastTitle" : MessageLookupByLibrary.simpleMessage("您可以通过上下滑动切换分组"),
+ "featureDiscoverySearch" : MessageLookupByLibrary.simpleMessage("点击搜索播客"),
+ "featureDiscoverySearchDes" : MessageLookupByLibrary.simpleMessage("您可以通过搜索播客名称、关键字或者RSS链接订阅播客。"),
"feedbackEmail" : MessageLookupByLibrary.simpleMessage("发送邮件"),
"feedbackGithub" : MessageLookupByLibrary.simpleMessage("提交Issue"),
"feedbackPlay" : MessageLookupByLibrary.simpleMessage("Play评价"),
"feedbackTelegram" : MessageLookupByLibrary.simpleMessage("加入小组"),
"from" : MessageLookupByLibrary.simpleMessage("自"),
+ "goodNight" : MessageLookupByLibrary.simpleMessage("晚安"),
+ "groupFilter" : MessageLookupByLibrary.simpleMessage("分组"),
"groups" : MessageLookupByLibrary.simpleMessage("分组"),
"homeGroupsSeeAll" : MessageLookupByLibrary.simpleMessage("查看全部"),
"homeMenuPlaylist" : MessageLookupByLibrary.simpleMessage("播放列表"),
- "homeSubMenuDownloaded" : MessageLookupByLibrary.simpleMessage("已下载"),
"homeSubMenuLikeData" : MessageLookupByLibrary.simpleMessage("添加日期"),
"homeSubMenuSortBy" : MessageLookupByLibrary.simpleMessage("排序"),
"homeSubMenuUpdateDate" : MessageLookupByLibrary.simpleMessage("更新日期"),
@@ -49,29 +107,52 @@ class MessageLookup extends MessageLookupByLibrary {
"homeToprightMenuImportOMPL" : MessageLookupByLibrary.simpleMessage("导入OMPL"),
"homeToprightMenuRefreshAll" : MessageLookupByLibrary.simpleMessage("全部刷新"),
"homeToprightMenuSettings" : MessageLookupByLibrary.simpleMessage("设置"),
+ "hostedOn" : m2,
+ "hoursCount" : m3,
"later" : MessageLookupByLibrary.simpleMessage("稍后"),
"lightMode" : MessageLookupByLibrary.simpleMessage("明亮模式"),
"like" : MessageLookupByLibrary.simpleMessage("喜欢"),
+ "likeDate" : MessageLookupByLibrary.simpleMessage("收藏日期"),
"liked" : MessageLookupByLibrary.simpleMessage("已收藏"),
"listen" : MessageLookupByLibrary.simpleMessage("收听"),
"listened" : MessageLookupByLibrary.simpleMessage("已收听"),
+ "loadMore" : MessageLookupByLibrary.simpleMessage("加载更多"),
+ "markConfirm" : MessageLookupByLibrary.simpleMessage("确认标记"),
+ "markConfirmContent" : MessageLookupByLibrary.simpleMessage("是否确认标记全部节目为已收听?"),
"markListened" : MessageLookupByLibrary.simpleMessage("标记已收听"),
"menu" : MessageLookupByLibrary.simpleMessage("菜单"),
"menuAllPodcasts" : MessageLookupByLibrary.simpleMessage("所有订阅"),
"menuMarkAllListened" : MessageLookupByLibrary.simpleMessage("标记所有已收听"),
- "menuMarkListened" : MessageLookupByLibrary.simpleMessage("标记已收听"),
"menuViewRSS" : MessageLookupByLibrary.simpleMessage("查看 RSS"),
"menuVisitSite" : MessageLookupByLibrary.simpleMessage("访问网站"),
+ "minsCount" : m4,
"network" : MessageLookupByLibrary.simpleMessage("网络"),
"newGroup" : MessageLookupByLibrary.simpleMessage("创建分组"),
+ "newestFirst" : MessageLookupByLibrary.simpleMessage("由新到旧"),
+ "noEpisodeDownload" : MessageLookupByLibrary.simpleMessage("暂无下载节目"),
+ "noEpisodeFavorite" : MessageLookupByLibrary.simpleMessage("暂无收藏节目"),
+ "noEpisodeRecent" : MessageLookupByLibrary.simpleMessage("暂无节目"),
+ "noPodcastGroup" : MessageLookupByLibrary.simpleMessage("分组无播客"),
+ "notificaitonFatch" : m5,
+ "notificationNetworkError" : m6,
+ "notificationSubscribe" : m7,
+ "notificationSubscribeExisted" : m8,
+ "notificationSuccess" : m9,
+ "notificationUpdate" : m10,
+ "notificationUpdateError" : m11,
+ "oldestFirst" : MessageLookupByLibrary.simpleMessage("由旧到新"),
"play" : MessageLookupByLibrary.simpleMessage("播放"),
+ "playing" : MessageLookupByLibrary.simpleMessage("正在播放"),
+ "podcastSubscribed" : MessageLookupByLibrary.simpleMessage("播客已订阅"),
"popupMenuDownloadDes" : MessageLookupByLibrary.simpleMessage("下载节目"),
"popupMenuLaterDes" : MessageLookupByLibrary.simpleMessage("添加到播放列表"),
"popupMenuLikeDes" : MessageLookupByLibrary.simpleMessage("添加到收藏"),
"popupMenuMarkDes" : MessageLookupByLibrary.simpleMessage("设置为已收听"),
"popupMenuPlayDes" : MessageLookupByLibrary.simpleMessage("播放节目"),
+ "privacyPolicy" : MessageLookupByLibrary.simpleMessage("隐私条款"),
"remove" : MessageLookupByLibrary.simpleMessage("移除"),
"schedule" : MessageLookupByLibrary.simpleMessage("定时"),
+ "searchInvalidRss" : MessageLookupByLibrary.simpleMessage("RSS 链接错误"),
"searchPodcast" : MessageLookupByLibrary.simpleMessage("搜索播客"),
"settingStorage" : MessageLookupByLibrary.simpleMessage("储存空间"),
"settingsAccentColor" : MessageLookupByLibrary.simpleMessage("次要颜色"),
@@ -128,9 +209,12 @@ class MessageLookup extends MessageLookupByLibrary {
"settingsTheme" : MessageLookupByLibrary.simpleMessage("主题"),
"settingsUpdateInterval" : MessageLookupByLibrary.simpleMessage("更新频率"),
"settingsUpdateIntervalDes" : MessageLookupByLibrary.simpleMessage("默认 24 小时"),
+ "size" : MessageLookupByLibrary.simpleMessage("大小"),
"sleepTimer" : MessageLookupByLibrary.simpleMessage("睡眠模式"),
"subscribe" : MessageLookupByLibrary.simpleMessage("订阅"),
"systemDefault" : MessageLookupByLibrary.simpleMessage("系统默认"),
+ "timeLastPlayed" : m12,
+ "timeLeft" : m13,
"to" : MessageLookupByLibrary.simpleMessage("到"),
"toastAddPlaylist" : MessageLookupByLibrary.simpleMessage("添加到播放列表"),
"toastDescovery" : MessageLookupByLibrary.simpleMessage("重启应用后可查看"),
@@ -138,7 +222,12 @@ class MessageLookup extends MessageLookupByLibrary {
"toastFileNotVilid" : MessageLookupByLibrary.simpleMessage("文件错误"),
"toastReadFile" : MessageLookupByLibrary.simpleMessage("读取文件成功"),
"toastRemovePlaylist" : MessageLookupByLibrary.simpleMessage("从播放列表移除"),
+ "understood" : MessageLookupByLibrary.simpleMessage("了解"),
"unlike" : MessageLookupByLibrary.simpleMessage("取消喜欢"),
- "unliked" : MessageLookupByLibrary.simpleMessage("从收藏移除")
+ "unliked" : MessageLookupByLibrary.simpleMessage("从收藏移除"),
+ "updateDate" : MessageLookupByLibrary.simpleMessage("更新日期"),
+ "updateEpisodesCount" : m14,
+ "updateFailed" : MessageLookupByLibrary.simpleMessage("更新失败"),
+ "version" : m15
};
}
diff --git a/lib/generated/l10n.dart b/lib/generated/l10n.dart
index 8928f4c..643066f 100644
--- a/lib/generated/l10n.dart
+++ b/lib/generated/l10n.dart
@@ -33,6 +33,62 @@ class S {
return Localizations.of(context, S);
}
+ /// `Add`
+ String get add {
+ return Intl.message(
+ 'Add',
+ name: 'add',
+ desc: 'Subscribe new podcast',
+ args: [],
+ );
+ }
+
+ /// `{count, plural, zero{} one{{count} episode in {groupName} added to playlist} other{{count} episodes in {groupName} added to playlist}}`
+ String addEpisodeGroup(Object groupName, num count) {
+ return Intl.plural(
+ count,
+ zero: '',
+ one: '$count episode in $groupName added to playlist',
+ other: '$count episodes in $groupName added to playlist',
+ name: 'addEpisodeGroup',
+ desc: '',
+ args: [groupName, count],
+ );
+ }
+
+ /// `{count, plural, zero{} one{{count} episode added to playlist} other{{count} episodes added to playlist}}`
+ String addNewEpisodeAll(num count) {
+ return Intl.plural(
+ count,
+ zero: '',
+ one: '$count episode added to playlist',
+ other: '$count episodes added to playlist',
+ name: 'addNewEpisodeAll',
+ desc: '',
+ args: [count],
+ );
+ }
+
+ /// `Add new episodes to playlist`
+ String get addNewEpisodeTooltip {
+ return Intl.message(
+ 'Add new episodes to playlist',
+ name: 'addNewEpisodeTooltip',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Add some groups`
+ String get addSomeGroups {
+ return Intl.message(
+ 'Add some groups',
+ name: 'addSomeGroups',
+ desc: 'Please add new groups',
+ args: [],
+ );
+ }
+
/// `All`
String get all {
return Intl.message(
@@ -43,16 +99,56 @@ class S {
);
}
- /// `Cancel`
+ /// `Back`
+ String get back {
+ return Intl.message(
+ 'Back',
+ name: 'back',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Buffering`
+ String get buffering {
+ return Intl.message(
+ 'Buffering',
+ name: 'buffering',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `CANCEL`
String get cancel {
return Intl.message(
- 'Cancel',
+ 'CANCEL',
name: 'cancel',
desc: '',
args: [],
);
}
+ /// `Change layout`
+ String get changeLayout {
+ return Intl.message(
+ 'Change layout',
+ name: 'changeLayout',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Changelog`
+ String get changelog {
+ return Intl.message(
+ 'Changelog',
+ name: 'changelog',
+ desc: '',
+ args: [],
+ );
+ }
+
/// `Choose a`
String get chooseA {
return Intl.message(
@@ -63,6 +159,16 @@ class S {
);
}
+ /// `Clear`
+ String get clear {
+ return Intl.message(
+ 'Clear',
+ name: 'clear',
+ desc: '',
+ args: [],
+ );
+ }
+
/// `color`
String get color {
return Intl.message(
@@ -73,10 +179,10 @@ class S {
);
}
- /// `Confirm`
+ /// `CONFIRM`
String get confirm {
return Intl.message(
- 'Confirm',
+ 'CONFIRM',
name: 'confirm',
desc: '',
args: [],
@@ -103,6 +209,26 @@ class S {
);
}
+ /// `Developer`
+ String get developer {
+ return Intl.message(
+ 'Developer',
+ name: 'developer',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Dismiss`
+ String get dismiss {
+ return Intl.message(
+ 'Dismiss',
+ name: 'dismiss',
+ desc: '',
+ args: [],
+ );
+ }
+
/// `Download`
String get download {
return Intl.message(
@@ -113,6 +239,16 @@ class S {
);
}
+ /// `Downloaded`
+ String get downloaded {
+ return Intl.message(
+ 'Downloaded',
+ name: 'downloaded',
+ desc: '',
+ args: [],
+ );
+ }
+
/// `Edit name`
String get editName {
return Intl.message(
@@ -133,6 +269,126 @@ class S {
);
}
+ /// `Episode view`
+ String get featureDiscoveryEpisode {
+ return Intl.message(
+ 'Episode view',
+ name: 'featureDiscoveryEpisode',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `You can long tap to play episode or add episode to playlist.`
+ String get featureDiscoveryEpisodeDes {
+ return Intl.message(
+ 'You can long tap to play episode or add episode to playlist.',
+ name: 'featureDiscoveryEpisodeDes',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Long tap to play episode instantly`
+ String get featureDiscoveryEpisodeTitle {
+ return Intl.message(
+ 'Long tap to play episode instantly',
+ name: 'featureDiscoveryEpisodeTitle',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Tap to import OMPL`
+ String get featureDiscoveryOMPL {
+ return Intl.message(
+ 'Tap to import OMPL',
+ name: 'featureDiscoveryOMPL',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `You can import OMPL file, open setting or refresh all podcast at once here.`
+ String get featureDiscoveryOMPLDes {
+ return Intl.message(
+ 'You can import OMPL file, open setting or refresh all podcast at once here.',
+ name: 'featureDiscoveryOMPLDes',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Tap to open playlist`
+ String get featureDiscoveryPlaylist {
+ return Intl.message(
+ 'Tap to open playlist',
+ name: 'featureDiscoveryPlaylist',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `You can add episode to playlist by yourself. Episode will be auto removed from playlist when played.`
+ String get featureDiscoveryPlaylistDes {
+ return Intl.message(
+ 'You can add episode to playlist by yourself. Episode will be auto removed from playlist when played.',
+ name: 'featureDiscoveryPlaylistDes',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Podcast view`
+ String get featureDiscoveryPodcast {
+ return Intl.message(
+ 'Podcast view',
+ name: 'featureDiscoveryPodcast',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `You can tap See All to add groups or manage podcasts.`
+ String get featureDiscoveryPodcastDes {
+ return Intl.message(
+ 'You can tap See All to add groups or manage podcasts.',
+ name: 'featureDiscoveryPodcastDes',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Scroll vertically to switch groups`
+ String get featureDiscoveryPodcastTitle {
+ return Intl.message(
+ 'Scroll vertically to switch groups',
+ name: 'featureDiscoveryPodcastTitle',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Tap to search podcast`
+ String get featureDiscoverySearch {
+ return Intl.message(
+ 'Tap to search podcast',
+ name: 'featureDiscoverySearch',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `You can search podcast title , key word or RSS link to subscribe new podcast.`
+ String get featureDiscoverySearchDes {
+ return Intl.message(
+ 'You can search podcast title , key word or RSS link to subscribe new podcast.',
+ name: 'featureDiscoverySearchDes',
+ desc: '',
+ args: [],
+ );
+ }
+
/// `Write to me`
String get feedbackEmail {
return Intl.message(
@@ -183,6 +439,26 @@ class S {
);
}
+ /// `Good Night`
+ String get goodNight {
+ return Intl.message(
+ 'Good Night',
+ name: 'goodNight',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Group filter`
+ String get groupFilter {
+ return Intl.message(
+ 'Group filter',
+ name: 'groupFilter',
+ desc: '',
+ args: [],
+ );
+ }
+
/// `Groups`
String get groups {
return Intl.message(
@@ -213,16 +489,6 @@ class S {
);
}
- /// `Downloaded`
- String get homeSubMenuDownloaded {
- return Intl.message(
- 'Downloaded',
- name: 'homeSubMenuDownloaded',
- desc: '',
- args: [],
- );
- }
-
/// `Like Date`
String get homeSubMenuLikeData {
return Intl.message(
@@ -313,6 +579,29 @@ class S {
);
}
+ /// `Hosted on {host}`
+ String hostedOn(Object host) {
+ return Intl.message(
+ 'Hosted on $host',
+ name: 'hostedOn',
+ desc: '',
+ args: [host],
+ );
+ }
+
+ /// `{count, plural, zero{} one{{count} hour} other{{count} hours}}`
+ String hoursCount(num count) {
+ return Intl.plural(
+ count,
+ zero: '',
+ one: '$count hour',
+ other: '$count hours',
+ name: 'hoursCount',
+ desc: '',
+ args: [count],
+ );
+ }
+
/// `Later`
String get later {
return Intl.message(
@@ -353,6 +642,16 @@ class S {
);
}
+ /// `Like date`
+ String get likeDate {
+ return Intl.message(
+ 'Like date',
+ name: 'likeDate',
+ desc: '',
+ args: [],
+ );
+ }
+
/// `Listen`
String get listen {
return Intl.message(
@@ -373,6 +672,36 @@ class S {
);
}
+ /// `Load more`
+ String get loadMore {
+ return Intl.message(
+ 'Load more',
+ name: 'loadMore',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Mark confirm`
+ String get markConfirm {
+ return Intl.message(
+ 'Mark confirm',
+ name: 'markConfirm',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Confirm mark all episodes listened?`
+ String get markConfirmContent {
+ return Intl.message(
+ 'Confirm mark all episodes listened?',
+ name: 'markConfirmContent',
+ desc: '',
+ args: [],
+ );
+ }
+
/// `Mark listened`
String get markListened {
return Intl.message(
@@ -413,16 +742,6 @@ class S {
);
}
- /// `Mark Listened`
- String get menuMarkListened {
- return Intl.message(
- 'Mark Listened',
- name: 'menuMarkListened',
- desc: '',
- args: [],
- );
- }
-
/// `Visit RSS Feed`
String get menuViewRSS {
return Intl.message(
@@ -443,6 +762,19 @@ class S {
);
}
+ /// `{count, plural, zero{} one{{count} min} other{{count} mins}}`
+ String minsCount(num count) {
+ return Intl.plural(
+ count,
+ zero: '',
+ one: '$count min',
+ other: '$count mins',
+ name: 'minsCount',
+ desc: '',
+ args: [count],
+ );
+ }
+
/// `Network`
String get network {
return Intl.message(
@@ -453,6 +785,16 @@ class S {
);
}
+ /// `Newest first`
+ String get newestFirst {
+ return Intl.message(
+ 'Newest first',
+ name: 'newestFirst',
+ desc: '',
+ args: [],
+ );
+ }
+
/// `Create new group`
String get newGroup {
return Intl.message(
@@ -463,6 +805,126 @@ class S {
);
}
+ /// `No episode downloaded yet`
+ String get noEpisodeDownload {
+ return Intl.message(
+ 'No episode downloaded yet',
+ name: 'noEpisodeDownload',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `No episode collected yet`
+ String get noEpisodeFavorite {
+ return Intl.message(
+ 'No episode collected yet',
+ name: 'noEpisodeFavorite',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `No episode received yet`
+ String get noEpisodeRecent {
+ return Intl.message(
+ 'No episode received yet',
+ name: 'noEpisodeRecent',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `No podcast in this group`
+ String get noPodcastGroup {
+ return Intl.message(
+ 'No podcast in this group',
+ name: 'noPodcastGroup',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Fetch data {title}`
+ String notificaitonFatch(Object title) {
+ return Intl.message(
+ 'Fetch data $title',
+ name: 'notificaitonFatch',
+ desc: '',
+ args: [title],
+ );
+ }
+
+ /// `Subscribe failed, network error {title}`
+ String notificationNetworkError(Object title) {
+ return Intl.message(
+ 'Subscribe failed, network error $title',
+ name: 'notificationNetworkError',
+ desc: '',
+ args: [title],
+ );
+ }
+
+ /// `Subscribe {title}`
+ String notificationSubscribe(Object title) {
+ return Intl.message(
+ 'Subscribe $title',
+ name: 'notificationSubscribe',
+ desc: '',
+ args: [title],
+ );
+ }
+
+ /// `Subscribe failed, podcast existed {title}`
+ String notificationSubscribeExisted(Object title) {
+ return Intl.message(
+ 'Subscribe failed, podcast existed $title',
+ name: 'notificationSubscribeExisted',
+ desc: '',
+ args: [title],
+ );
+ }
+
+ /// `Subscribe success {title}`
+ String notificationSuccess(Object title) {
+ return Intl.message(
+ 'Subscribe success $title',
+ name: 'notificationSuccess',
+ desc: '',
+ args: [title],
+ );
+ }
+
+ /// `Update {title}`
+ String notificationUpdate(Object title) {
+ return Intl.message(
+ 'Update $title',
+ name: 'notificationUpdate',
+ desc: '',
+ args: [title],
+ );
+ }
+
+ /// `Update error {title}`
+ String notificationUpdateError(Object title) {
+ return Intl.message(
+ 'Update error $title',
+ name: 'notificationUpdateError',
+ desc: '',
+ args: [title],
+ );
+ }
+
+ /// `Oldest first`
+ String get oldestFirst {
+ return Intl.message(
+ 'Oldest first',
+ name: 'oldestFirst',
+ desc: '',
+ args: [],
+ );
+ }
+
/// `Play`
String get play {
return Intl.message(
@@ -473,6 +935,26 @@ class S {
);
}
+ /// `Playing`
+ String get playing {
+ return Intl.message(
+ 'Playing',
+ name: 'playing',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Podcast subscribed`
+ String get podcastSubscribed {
+ return Intl.message(
+ 'Podcast subscribed',
+ name: 'podcastSubscribed',
+ desc: '',
+ args: [],
+ );
+ }
+
/// `Download episode`
String get popupMenuDownloadDes {
return Intl.message(
@@ -523,6 +1005,16 @@ class S {
);
}
+ /// `Privacy Policy`
+ String get privacyPolicy {
+ return Intl.message(
+ 'Privacy Policy',
+ name: 'privacyPolicy',
+ desc: '',
+ args: [],
+ );
+ }
+
/// `Remove`
String get remove {
return Intl.message(
@@ -543,6 +1035,16 @@ class S {
);
}
+ /// `Invalid RSS link`
+ String get searchInvalidRss {
+ return Intl.message(
+ 'Invalid RSS link',
+ name: 'searchInvalidRss',
+ desc: '',
+ args: [],
+ );
+ }
+
/// `Search podcast`
String get searchPodcast {
return Intl.message(
@@ -1103,6 +1605,16 @@ class S {
);
}
+ /// `Size`
+ String get size {
+ return Intl.message(
+ 'Size',
+ name: 'size',
+ desc: '',
+ args: [],
+ );
+ }
+
/// `Sleep timer`
String get sleepTimer {
return Intl.message(
@@ -1133,6 +1645,26 @@ class S {
);
}
+ /// `Last time {time}`
+ String timeLastPlayed(Object time) {
+ return Intl.message(
+ 'Last time $time',
+ name: 'timeLastPlayed',
+ desc: '',
+ args: [time],
+ );
+ }
+
+ /// `{time} Left`
+ String timeLeft(Object time) {
+ return Intl.message(
+ '$time Left',
+ name: 'timeLeft',
+ desc: '',
+ args: [time],
+ );
+ }
+
/// `To`
String get to {
return Intl.message(
@@ -1203,6 +1735,16 @@ class S {
);
}
+ /// `Understood`
+ String get understood {
+ return Intl.message(
+ 'Understood',
+ name: 'understood',
+ desc: '',
+ args: [],
+ );
+ }
+
/// `Unlike`
String get unlike {
return Intl.message(
@@ -1213,15 +1755,58 @@ class S {
);
}
- /// `Unliked`
+ /// `Removed from favorite`
String get unliked {
return Intl.message(
- 'Unliked',
+ 'Removed from favorite',
name: 'unliked',
desc: '',
args: [],
);
}
+
+ /// `Update date`
+ String get updateDate {
+ return Intl.message(
+ 'Update date',
+ name: 'updateDate',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `{count, plural, zero{No Update} one{Updated {count} Episode} other{Updated {count} Episodes}}`
+ String updateEpisodesCount(num count) {
+ return Intl.plural(
+ count,
+ zero: 'No Update',
+ one: 'Updated $count Episode',
+ other: 'Updated $count Episodes',
+ name: 'updateEpisodesCount',
+ desc: '',
+ args: [count],
+ );
+ }
+
+ /// `Update failed, network error`
+ String get updateFailed {
+ return Intl.message(
+ 'Update failed, network error',
+ name: 'updateFailed',
+ desc: '',
+ args: [],
+ );
+ }
+
+ /// `Version : {version}`
+ String version(Object version) {
+ return Intl.message(
+ 'Version : $version',
+ name: 'version',
+ desc: '',
+ args: [version],
+ );
+ }
}
class AppLocalizationDelegate extends LocalizationsDelegate {
diff --git a/lib/home/about.dart b/lib/home/about.dart
index 0fbc23f..a0751ab 100644
--- a/lib/home/about.dart
+++ b/lib/home/about.dart
@@ -63,6 +63,7 @@ class AboutApp extends StatelessWidget {
);
}
+ final s = context.s;
return AnnotatedRegion(
value: SystemUiOverlayStyle(
statusBarIconBrightness: Theme.of(context).accentColorBrightness,
@@ -73,7 +74,7 @@ class AboutApp extends StatelessWidget {
child: Scaffold(
backgroundColor: Theme.of(context).primaryColor,
appBar: AppBar(
- title: Text('About'),
+ title: Text(s.homeToprightMenuAbout),
),
body: SafeArea(
child: SingleChildScrollView(
@@ -95,7 +96,7 @@ class AboutApp extends StatelessWidget {
image: AssetImage('assets/logo.png'),
height: 80,
),
- Text('Version: $version'),
+ Text(s.version(version)),
],
),
),
@@ -113,7 +114,7 @@ class AboutApp extends StatelessWidget {
FlatButton(
onPressed: () => _launchUrl(
'https://tsacdop.stonegate.me/#/privacy'),
- child: Text('Privacy Policy',
+ child: Text(s.privacyPolicy,
style: TextStyle(color: context.accentColor)),
),
Container(
@@ -127,7 +128,7 @@ class AboutApp extends StatelessWidget {
FlatButton(
onPressed: () => _launchUrl(
'https://tsacdop.stonegate.me/#/changelog'),
- child: Text('Changelog',
+ child: Text(s.changelog,
style: TextStyle(color: context.accentColor)),
),
],
@@ -152,7 +153,7 @@ class AboutApp extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
- 'Developer',
+ s.developer,
style: TextStyle(
color: Theme.of(context).accentColor,
fontWeight: FontWeight.bold),
diff --git a/lib/home/addpodcast.dart b/lib/home/addpodcast.dart
index 51fd1f2..e9b31e5 100644
--- a/lib/home/addpodcast.dart
+++ b/lib/home/addpodcast.dart
@@ -25,21 +25,6 @@ class MyHomePageDelegate extends SearchDelegate {
searchFieldLabel: searchFieldLabel,
);
- //static Future getList(String searchText) async {
- // String apiKey = environment['apiKey'];
- // String url =
- // "https://listennotes.p.rapidapi.com/api/v1/search?only_in=title%2Cdescription&q=" +
- // "$searchText&type=podcast";
- // Response response = await Dio().get(url,
- // options: Options(headers: {
- // 'X-RapidAPI-Key': "$apiKey",
- // 'Accept': "application/json"
- // }));
- // Map searchResultMap = jsonDecode(response.toString());
- // var searchResult = SearchPodcast.fromJson(searchResultMap);
- // return searchResult.results;
- //}
-
static Future getRss(String url) async {
try {
BaseOptions options = new BaseOptions(
@@ -60,10 +45,10 @@ class MyHomePageDelegate extends SearchDelegate {
}
RegExp rssExp = RegExp(r'^(https?):\/\/(.*)');
- Widget invalidRss() => Container(
+ Widget invalidRss(BuildContext context) => Container(
height: 50,
alignment: Alignment.center,
- child: Text('Invalid rss link'),
+ child: Text(context.s.searchInvalidRss),
);
@override
@@ -72,7 +57,7 @@ class MyHomePageDelegate extends SearchDelegate {
@override
Widget buildLeading(BuildContext context) {
return IconButton(
- tooltip: 'Back',
+ tooltip: context.s.back,
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
@@ -145,7 +130,7 @@ class MyHomePageDelegate extends SearchDelegate {
Center()
else
IconButton(
- tooltip: 'Clear',
+ tooltip: context.s.clear,
icon: const Icon(Icons.clear),
onPressed: () {
query = '';
@@ -174,7 +159,7 @@ class MyHomePageDelegate extends SearchDelegate {
future: getRss(rssExp.stringMatch(query)),
builder: (context, snapshot) {
if (snapshot.hasError)
- return invalidRss();
+ return invalidRss(context);
else if (snapshot.hasData)
return SearchResult(
onlinePodcast: snapshot.data,
@@ -297,7 +282,7 @@ class _SearchListState extends State {
child: CircularProgressIndicator(
strokeWidth: 2,
))
- : Text('Load more'),
+ : Text(context.s.loadMore),
onPressed: () => _loading
? null
: setState(() {
@@ -362,7 +347,7 @@ class _SearchResultState extends State
@override
Widget build(BuildContext context) {
var subscribeWorker = Provider.of(context, listen: false);
-
+ final s = context.s;
savePodcast(OnlinePodcast podcast) {
SubscribeItem item =
SubscribeItem(podcast.rss, podcast.title, imgUrl: podcast.image);
@@ -437,14 +422,14 @@ class _SearchResultState extends State
? OutlineButton(
highlightedBorderColor: context.accentColor,
splashColor: context.accentColor.withOpacity(0.8),
- child: Text('Subscribe',
+ child: Text(s.subscribe,
style: TextStyle(
color: Theme.of(context).accentColor)),
onPressed: () {
savePodcast(widget.onlinePodcast);
setState(() => _issubscribe = true);
Fluttertoast.showToast(
- msg: 'Podcast subscribed',
+ msg: s.podcastSubscribed,
gravity: ToastGravity.BOTTOM,
);
})
@@ -452,7 +437,7 @@ class _SearchResultState extends State
color: context.accentColor.withOpacity(0.8),
highlightedBorderColor: Colors.grey[500],
disabledTextColor: Colors.grey[500],
- child: Text('Subscribe'),
+ child: Text(s.subscribe),
disabledBorderColor: Colors.grey[500],
onPressed: () {}),
),
diff --git a/lib/home/audioplayer.dart b/lib/home/audioplayer.dart
index c4c43b9..332e7ec 100644
--- a/lib/home/audioplayer.dart
+++ b/lib/home/audioplayer.dart
@@ -77,7 +77,7 @@ class _PlayerWidgetState extends State {
// color: context.primaryColorDark,
alignment: Alignment.centerLeft,
child: Text(
- 'Playlist',
+ context.s.homeMenuPlaylist,
style: TextStyle(
color: Theme.of(context).accentColor,
fontWeight: FontWeight.bold,
@@ -389,6 +389,7 @@ class _PlayerWidgetState extends State {
Widget _miniPanel(double width, BuildContext context) {
var audio = Provider.of(context, listen: false);
+ final s = context.s;
return Container(
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
@@ -459,13 +460,13 @@ class _PlayerWidgetState extends State {
BasicPlaybackState.skippingToNext ||
data.item1 == BasicPlaybackState.stopped
? Text(
- 'Buffering...',
+ s.buffering,
style: TextStyle(
color: Theme.of(context).accentColor),
)
: Text(
- (_stringForSeconds(data.item2) ?? '') +
- ' Left',
+ s.timeLeft(
+ _stringForSeconds(data.item2) ?? ''),
maxLines: 2,
),
);
@@ -582,6 +583,7 @@ class _LastPositionState extends State {
@override
Widget build(BuildContext context) {
+ final s = context.s;
var audio = Provider.of(context, listen: false);
return Selector(
selector: (_, audio) => audio.episode,
@@ -605,7 +607,7 @@ class _LastPositionState extends State {
.color),
borderRadius:
BorderRadius.all(Radius.circular(10.0))),
- child: Text('Played before'))
+ child: Text(s.listened))
: snapshot.data.seconds < 10
? Center()
: Material(
@@ -628,8 +630,9 @@ class _LastPositionState extends State {
.color),
borderRadius: BorderRadius.all(
Radius.circular(10.0))),
- child: Text('Last time ' +
- _stringForSeconds(snapshot.data.seconds)),
+ child: Text(s.timeLastPlayed(
+ _stringForSeconds(
+ snapshot.data.seconds))),
),
),
)
@@ -851,6 +854,7 @@ class SleepModeState extends State
@override
Widget build(BuildContext context) {
+ final s = context.s;
final ColorTween _colorTween =
ColorTween(begin: context.primaryColor, end: Colors.black);
var audio = Provider.of(context, listen: false);
@@ -976,7 +980,7 @@ class SleepModeState extends State
width: 120,
child: Center(
child: Text(
- 'End of episode',
+ s.endOfEpisode,
style: TextStyle(
// fontWeight: FontWeight.bold,
// fontSize: 20,
@@ -1059,7 +1063,7 @@ class SleepModeState extends State
width: 200,
child: Container(
alignment: Alignment.center,
- child: Text('Good Night',
+ child: Text(s.goodNight,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
@@ -1072,7 +1076,7 @@ class SleepModeState extends State
width: 200,
child: Container(
alignment: Alignment.center,
- child: Text('Sleep Timer',
+ child: Text(s.sleepTimer,
style:
TextStyle(fontWeight: FontWeight.bold, fontSize: 20)),
),
@@ -1223,7 +1227,7 @@ class _ControlPanelState extends State
data.audioState ==
BasicPlaybackState
.skippingToNext
- ? 'Buffring...'
+ ? context.s.buffering
: '',
style: TextStyle(
color: Theme.of(context)
diff --git a/lib/home/home.dart b/lib/home/home.dart
index b50797b..7e210e9 100644
--- a/lib/home/home.dart
+++ b/lib/home/home.dart
@@ -42,10 +42,6 @@ class Home extends StatefulWidget {
}
class _HomeState extends State with SingleTickerProviderStateMixin {
- final MyHomePageDelegate _delegate = MyHomePageDelegate(
- searchFieldLabel: 'Search podcast',
- );
-
final GlobalKey _scaffoldKey = GlobalKey();
TabController _controller;
Decoration _getIndicator(BuildContext context) {
@@ -140,8 +136,8 @@ class _HomeState extends State with SingleTickerProviderStateMixin {
featureId: addFeature,
tapTarget:
Icon(Icons.add_circle_outline),
- title: const Text(
- 'Tap to search podcast'),
+ title:
+ Text(s.featureDiscoverySearch),
backgroundColor: Colors.cyan[600],
overflowMode: feature1OverflowMode,
onDismiss: () {
@@ -151,13 +147,13 @@ class _HomeState extends State with SingleTickerProviderStateMixin {
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
- const Text(
- 'You can search podcast title , key word or RSS link to subscribe new podcast.'),
+ Text(s
+ .featureDiscoverySearchDes),
FlatButton(
color: Colors.cyan[500],
padding:
const EdgeInsets.all(0),
- child: Text('Understood',
+ child: Text(s.understood,
style: Theme.of(context)
.textTheme
.button
@@ -173,7 +169,7 @@ class _HomeState extends State with SingleTickerProviderStateMixin {
color: Colors.cyan[500],
padding:
const EdgeInsets.all(0),
- child: Text('Dismiss',
+ child: Text(s.dismiss,
style: Theme.of(context)
.textTheme
.button
@@ -187,13 +183,15 @@ class _HomeState extends State with SingleTickerProviderStateMixin {
],
),
child: IconButton(
- tooltip: 'Add',
+ tooltip: s.add,
icon: const Icon(
Icons.add_circle_outline),
onPressed: () async {
await showSearch(
context: context,
- delegate: _delegate,
+ delegate: MyHomePageDelegate(
+ searchFieldLabel:
+ s.searchPodcast),
);
},
),
@@ -213,19 +211,19 @@ class _HomeState extends State with SingleTickerProviderStateMixin {
backgroundColor: Colors.cyan[500],
onDismiss: () =>
Future.value(true),
- title: const Text(
- 'Tap to import OMPL'),
+ title:
+ Text(s.featureDiscoveryOMPL),
description: Column(
crossAxisAlignment:
CrossAxisAlignment.end,
children: [
- const Text(
- 'You can import OMPL file, open setting or refresh all podcast at once here.'),
+ Text(s
+ .featureDiscoveryOMPLDes),
FlatButton(
color: Colors.cyan[600],
padding:
const EdgeInsets.all(0),
- child: Text('Understood',
+ child: Text(s.understood,
style: Theme.of(context)
.textTheme
.button
@@ -241,7 +239,7 @@ class _HomeState extends State with SingleTickerProviderStateMixin {
color: Colors.cyan[600],
padding:
const EdgeInsets.all(0),
- child: Text('Dismiss',
+ child: Text(s.dismiss,
style: Theme.of(context)
.textTheme
.button
@@ -270,27 +268,26 @@ class _HomeState extends State with SingleTickerProviderStateMixin {
featureId: groupsFeature,
tapTarget: Center(
child: Text(
- 'Podcast View',
+ s.featureDiscoveryPodcast,
textAlign: TextAlign.center,
)),
backgroundColor: Colors.cyan[500],
enablePulsingAnimation: false,
onDismiss: () => Future.value(true),
- title: const Text(
- 'Scroll vertically to switch groups'),
+ title:
+ Text(s.featureDiscoveryPodcastTitle),
description: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
- const Text(
- 'You can tap See All to add groups or manage podcasts.'),
+ Text(s.featureDiscoveryPodcastDes),
Row(
children: [
FlatButton(
color: Colors.cyan[600],
padding:
const EdgeInsets.all(0),
- child: Text('Understood',
+ child: Text(s.understood,
style: Theme.of(context)
.textTheme
.button
@@ -309,7 +306,7 @@ class _HomeState extends State with SingleTickerProviderStateMixin {
color: Colors.cyan[600],
padding:
const EdgeInsets.all(0),
- child: Text('Dismiss',
+ child: Text(s.dismiss,
style: Theme.of(context)
.textTheme
.button
@@ -365,26 +362,25 @@ class _HomeState extends State with SingleTickerProviderStateMixin {
Key('tab0'),
DescribedFeatureOverlay(
featureId: podcastFeature,
- tapTarget: Text('Episode View',
+ tapTarget: Text(s.featureDiscoveryEpisode,
textAlign: TextAlign.center),
backgroundColor: Colors.cyan[500],
enablePulsingAnimation: false,
onDismiss: () => Future.value(true),
- title: const Text(
- 'Long tap to play episode instantly'),
+ title:
+ Text(s.featureDiscoveryEpisodeTitle),
description: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
- const Text(
- 'You can long tap to play episode or add episode to playlist.'),
+ Text(s.featureDiscoveryEpisodeDes),
Row(
children: [
FlatButton(
color: Colors.cyan[600],
padding:
const EdgeInsets.all(0),
- child: Text('Understood',
+ child: Text(s.understood,
style: Theme.of(context)
.textTheme
.button
@@ -403,7 +399,7 @@ class _HomeState extends State with SingleTickerProviderStateMixin {
color: Colors.cyan[600],
padding:
const EdgeInsets.all(0),
- child: Text('Dismiss',
+ child: Text(s.dismiss,
style: Theme.of(context)
.textTheme
.button
@@ -457,6 +453,7 @@ class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
+ final s = context.s;
return Container(
color: Theme.of(context).scaffoldBackgroundColor,
child: Column(
@@ -471,17 +468,16 @@ class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
featureId: playlistFeature,
tapTarget: Icon(Icons.playlist_play),
backgroundColor: Colors.cyan[500],
- title: const Text('Tap to open playlist'),
+ title: Text(s.featureDiscoveryPlaylist),
onDismiss: () => Future.value(true),
description: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
- const Text(
- 'You can add episode to playlist by yourself. Episode will be auto removed from playlist when played.'),
+ Text(s.featureDiscoveryPlaylistDes),
FlatButton(
color: Colors.cyan[600],
padding: const EdgeInsets.all(0),
- child: Text('Understood',
+ child: Text(s.understood,
style: Theme.of(context)
.textTheme
.button
@@ -492,7 +488,7 @@ class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
FlatButton(
color: Colors.cyan[600],
padding: const EdgeInsets.all(0),
- child: Text('Dismiss',
+ child: Text(s.dismiss,
style: Theme.of(context)
.textTheme
.button
@@ -554,7 +550,7 @@ class PlaylistButtonState extends State {
borderRadius: BorderRadius.all(Radius.circular(10))),
elevation: 1,
icon: Icon(Icons.playlist_play),
- tooltip: "Menu",
+ tooltip: s.menu,
itemBuilder: (context) => [
MyPopupMenuItem(
height: 50,
@@ -749,7 +745,7 @@ class _RecentUpdateState extends State<_RecentUpdate>
Padding(
padding: EdgeInsets.symmetric(vertical: 10)),
Text(
- 'No episode received yet',
+ s.noEpisodeRecent,
style: TextStyle(color: Colors.grey[500]),
)
],
@@ -792,7 +788,7 @@ class _RecentUpdateState extends State<_RecentUpdate>
Radius.circular(
10))),
elevation: 1,
- tooltip: 'Groups fliter',
+ tooltip: s.groupFilter,
child: Container(
padding:
EdgeInsets.symmetric(
@@ -863,8 +859,8 @@ class _RecentUpdateState extends State<_RecentUpdate>
color: Colors
.transparent,
child: IconButton(
- tooltip:
- 'Add new episodes to playlist',
+ tooltip: s
+ .addNewEpisodeTooltip,
icon:
// Icon(Icons.playlist_add),
SizedBox(
@@ -886,8 +882,13 @@ class _RecentUpdateState extends State<_RecentUpdate>
.showToast(
msg: _groupName ==
'All'
- ? '${snapshot.data} episode added to playlist'
- : '${snapshot.data} episode in $_groupName added to playlist',
+ ? s.addNewEpisodeAll(
+ snapshot
+ .data)
+ : s.addEpisodeGroup(
+ _groupName,
+ snapshot
+ .data),
gravity:
ToastGravity
.BOTTOM,
@@ -898,8 +899,8 @@ class _RecentUpdateState extends State<_RecentUpdate>
color: Colors
.transparent,
child: IconButton(
- tooltip:
- 'Add new episodes to playlist',
+ tooltip: s
+ .addNewEpisodeTooltip,
icon:
// Icon(Icons.playlist_add),
SizedBox(
@@ -923,7 +924,7 @@ class _RecentUpdateState extends State<_RecentUpdate>
Material(
color: Colors.transparent,
child: IconButton(
- tooltip: 'Change layout',
+ tooltip: s.changeLayout,
padding: EdgeInsets.zero,
onPressed: () {
if (_layout == Layout.three)
@@ -1073,7 +1074,7 @@ class _MyFavoriteState extends State<_MyFavorite>
Padding(
padding: EdgeInsets.symmetric(vertical: 10)),
Text(
- 'No episode collected yet',
+ s.noEpisodeFavorite,
style: TextStyle(color: Colors.grey[500]),
)
],
@@ -1103,7 +1104,7 @@ class _MyFavoriteState extends State<_MyFavorite>
borderRadius: BorderRadius.all(
Radius.circular(10))),
elevation: 1,
- tooltip: 'Sort By',
+ tooltip: s.homeSubMenuSortBy,
child: Container(
height: 50,
padding: EdgeInsets.symmetric(
@@ -1131,11 +1132,11 @@ class _MyFavoriteState extends State<_MyFavorite>
itemBuilder: (context) => [
PopupMenuItem(
value: 0,
- child: Text('Update Date'),
+ child: Text(s.updateDate),
),
PopupMenuItem(
value: 1,
- child: Text('Like Date'),
+ child: Text(s.likeDate),
)
],
onSelected: (value) {
@@ -1278,7 +1279,7 @@ class _MyDownloadState extends State<_MyDownload>
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 20),
- child: Text(s.homeSubMenuDownloaded)),
+ child: Text(s.downloaded)),
Spacer(),
Material(
color: Colors.transparent,
@@ -1349,7 +1350,7 @@ class _MyDownloadState extends State<_MyDownload>
size: 80, color: Colors.grey[500]),
Padding(padding: EdgeInsets.symmetric(vertical: 10)),
Text(
- 'No episode downloaded yet',
+ s.noEpisodeDownload,
style: TextStyle(color: Colors.grey[500]),
)
],
diff --git a/lib/home/home_groups.dart b/lib/home/home_groups.dart
index da75f80..13f1eb7 100644
--- a/lib/home/home_groups.dart
+++ b/lib/home/home_groups.dart
@@ -56,6 +56,7 @@ class _ScrollPodcastsState extends State {
@override
Widget build(BuildContext context) {
double _width = MediaQuery.of(context).size.width;
+ final s = context.s;
return Consumer(builder: (_, groupList, __) {
var groups = groupList.groups;
bool isLoading = groupList.isLoading;
@@ -75,7 +76,7 @@ class _ScrollPodcastsState extends State {
if (event.primaryVelocity > 200) {
if (groups.length == 1) {
Fluttertoast.showToast(
- msg: 'Add some groups',
+ msg: s.addSomeGroups,
gravity: ToastGravity.BOTTOM,
);
} else {
@@ -89,7 +90,7 @@ class _ScrollPodcastsState extends State {
} else if (event.primaryVelocity < -200) {
if (groups.length == 1) {
Fluttertoast.showToast(
- msg: 'Add some groups',
+ msg: s.addSomeGroups,
gravity: ToastGravity.BOTTOM,
);
} else {
@@ -136,7 +137,7 @@ class _ScrollPodcastsState extends State {
height: 30,
padding: EdgeInsets.all(5.0),
child: Text(
- 'See All',
+ s.homeGroupsSeeAll,
style: Theme.of(context)
.textTheme
.bodyText1
@@ -189,7 +190,7 @@ class _ScrollPodcastsState extends State {
TextSpan(text: ' to subscribe podcasts')
],
))
- : Text('No podcast in this group',
+ : Text(s.noPodcastGroup,
style: TextStyle(
color: context.textTheme.bodyText2.color
.withOpacity(0.5)))),
@@ -208,7 +209,7 @@ class _ScrollPodcastsState extends State {
if (event.primaryVelocity > 200) {
if (groups.length == 1) {
Fluttertoast.showToast(
- msg: 'Add some groups',
+ msg: s.addSomeGroups,
gravity: ToastGravity.BOTTOM,
);
} else {
@@ -222,7 +223,7 @@ class _ScrollPodcastsState extends State {
} else if (event.primaryVelocity < -200) {
if (groups.length == 1) {
Fluttertoast.showToast(
- msg: 'Add some groups',
+ msg: s.addSomeGroups,
gravity: ToastGravity.BOTTOM,
);
} else {
@@ -268,7 +269,7 @@ class _ScrollPodcastsState extends State {
height: 30,
padding: EdgeInsets.all(5.0),
child: Text(
- 'See All',
+ s.homeGroupsSeeAll,
style: Theme.of(context)
.textTheme
.bodyText1
@@ -441,7 +442,7 @@ class PodcastPreview extends StatelessWidget {
selector: (_, audio) => audio.playerRunning,
builder: (_, playerRunning, __) => IconButton(
icon: Icon(Icons.arrow_forward),
- tooltip: 'See All',
+ tooltip: context.s.homeGroupsSeeAll,
onPressed: () {
Navigator.push(
context,
@@ -471,19 +472,19 @@ class PodcastPreview extends StatelessWidget {
class ShowEpisode extends StatelessWidget {
final List episodes;
final PodcastLocal podcastLocal;
- List _menuList = [];
ShowEpisode({Key key, this.episodes, this.podcastLocal}) : super(key: key);
String _stringForSeconds(double seconds) {
if (seconds == null) return null;
return '${(seconds ~/ 60)}:${(seconds.truncate() % 60).toString().padLeft(2, '0')}';
}
- Future> _initData(EpisodeBrief episode) async {
+ Future>> _initData(
+ EpisodeBrief episode) async {
int listened = await _isListened(episode);
bool liked = await _isLiked(episode);
bool downloaded = await _isDownloaded(episode);
- _menuList = await _getEpisodeMenu();
- return Tuple3(listened, liked, downloaded);
+ List menuList = await _getEpisodeMenu();
+ return Tuple4(listened, liked, downloaded, menuList);
}
Future _isListened(EpisodeBrief episode) async {
@@ -697,9 +698,9 @@ class ShowEpisode extends StatelessWidget {
@override
Widget build(BuildContext context) {
double _width = context.width;
+ final s = context.s;
var downloader = Provider.of(context, listen: false);
var audio = Provider.of(context, listen: false);
- Offset offset;
return CustomScrollView(
physics: NeverScrollableScrollPhysics(),
primary: false,
@@ -727,14 +728,15 @@ class ShowEpisode extends StatelessWidget {
.toList(),
),
builder: (_, data, __) => FutureBuilder<
- Tuple3>(
+ Tuple4>>(
future: _initData(episodes[index]),
- initialData: Tuple3(0, false, false),
+ initialData: Tuple4(0, false, false, []),
builder:
(BuildContext context, AsyncSnapshot snapshot) {
int isListened = snapshot.data.item1;
bool isLiked = snapshot.data.item2;
bool isDownloaded = snapshot.data.item3;
+ List menuList = snapshot.data.item4;
return Container(
decoration: BoxDecoration(
borderRadius:
@@ -742,24 +744,7 @@ class ShowEpisode extends StatelessWidget {
color: Theme.of(context).scaffoldBackgroundColor,
),
alignment: Alignment.center,
- child:
- // InkWell(
- // borderRadius:
- // BorderRadius.all(Radius.circular(5.0)),
- // onTapDown: (details) => offset = Offset(
- // details.globalPosition.dx,
- // details.globalPosition.dy),
- // onLongPress: () => _showPopupMenu(
- // offset,
- // episodes[index],
- // context,
- // data.item1 == episodes[index],
- // data.item2.contains(
- // episodes[index].enclosureUrl)),
- // onTap: () {
- //
- // },
- FocusedMenuHolder(
+ child: FocusedMenuHolder(
blurSize: 0.0,
menuItemExtent: 45,
menuBoxDecoration: BoxDecoration(
@@ -782,8 +767,8 @@ class ShowEpisode extends StatelessWidget {
? context.primaryColor
: context.scaffoldBackgroundColor,
title: Text(data.item1 != episodes[index]
- ? "Play"
- : "Playing"),
+ ? s.play
+ : s.playing),
trailingIcon: Icon(
LineIcons.play_circle_solid,
color: Theme.of(context).accentColor,
@@ -792,7 +777,7 @@ class ShowEpisode extends StatelessWidget {
if (data.item1 != episodes[index])
audio.episodeLoad(episodes[index]);
}),
- _menuList.contains(1)
+ menuList.contains(1)
? FocusedMenuItem(
backgroundColor: context.brightness ==
Brightness.light
@@ -800,8 +785,8 @@ class ShowEpisode extends StatelessWidget {
: context.scaffoldBackgroundColor,
title: data.item2.contains(
episodes[index].enclosureUrl)
- ? Text("Remove")
- : Text("Later"),
+ ? Text(s.remove)
+ : Text(s.later),
trailingIcon: Icon(
LineIcons.clock_solid,
color: Colors.cyan,
@@ -812,28 +797,28 @@ class ShowEpisode extends StatelessWidget {
audio
.addToPlaylist(episodes[index]);
Fluttertoast.showToast(
- msg: 'Added to playlist',
+ msg: s.toastAddPlaylist,
gravity: ToastGravity.BOTTOM,
);
} else {
audio.delFromPlaylist(
episodes[index]);
Fluttertoast.showToast(
- msg: 'Removed from playlist',
+ msg: s.toastRemovePlaylist,
gravity: ToastGravity.BOTTOM,
);
}
})
: null,
- _menuList.contains(2)
+ menuList.contains(2)
? FocusedMenuItem(
backgroundColor: context.brightness ==
Brightness.light
? context.primaryColor
: context.scaffoldBackgroundColor,
title: isLiked
- ? Text("Unlike")
- : Text("Like"),
+ ? Text(s.unlike)
+ : Text(s.like),
trailingIcon: Icon(LineIcons.heart,
color: Colors.red, size: 21),
onPressed: () async {
@@ -842,7 +827,7 @@ class ShowEpisode extends StatelessWidget {
episodes[index].enclosureUrl);
audio.setEpisodeState = true;
Fluttertoast.showToast(
- msg: 'Unliked',
+ msg: s.unliked,
gravity: ToastGravity.BOTTOM,
);
} else {
@@ -850,25 +835,25 @@ class ShowEpisode extends StatelessWidget {
episodes[index].enclosureUrl);
audio.setEpisodeState = true;
Fluttertoast.showToast(
- msg: 'Liked',
+ msg: s.liked,
gravity: ToastGravity.BOTTOM,
);
}
})
: null,
- _menuList.contains(3)
+ menuList.contains(3)
? FocusedMenuItem(
backgroundColor: context.brightness ==
Brightness.light
? context.primaryColor
: context.scaffoldBackgroundColor,
title: isListened > 0
- ? Text('Listened',
+ ? Text(s.listened,
style: TextStyle(
color: context.textColor
.withOpacity(0.5)))
: Text(
- 'Mark Listened',
+ s.markListened,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
@@ -886,24 +871,24 @@ class ShowEpisode extends StatelessWidget {
episodes[index]);
audio.setEpisodeState = true;
Fluttertoast.showToast(
- msg: 'Mark listened',
+ msg: s.markListened,
gravity: ToastGravity.BOTTOM,
);
}
})
: null,
- _menuList.contains(4)
+ menuList.contains(4)
? FocusedMenuItem(
backgroundColor: context.brightness ==
Brightness.light
? context.primaryColor
: context.scaffoldBackgroundColor,
title: isDownloaded
- ? Text('Downloaded',
+ ? Text(s.downloaded,
style: TextStyle(
color: context.textColor
.withOpacity(0.5)))
- : Text('Download'),
+ : Text(s.download),
trailingIcon: Icon(
LineIcons.download_solid,
color: Colors.green),
diff --git a/lib/home/importompl.dart b/lib/home/importompl.dart
index 1b0950b..4b802e5 100644
--- a/lib/home/importompl.dart
+++ b/lib/home/importompl.dart
@@ -56,6 +56,7 @@ class Import extends StatelessWidget {
@override
Widget build(BuildContext context) {
+ final s = context.s;
GroupList groupList = Provider.of(context, listen: false);
return Column(
children: [
@@ -64,20 +65,21 @@ class Import extends StatelessWidget {
SubscribeItem item = subscribeWorker.currentSubscribeItem;
switch (item.subscribeState) {
case SubscribeState.start:
- return importColumn("Subscribe ${item.title}", context);
+ return importColumn(
+ s.notificationSubscribe(item.title), context);
case SubscribeState.subscribe:
- return importColumn("Fetch data ${item.title}", context);
+ return importColumn(s.notificaitonFatch(item.title), context);
case SubscribeState.fetch:
groupList.subscribeNewPodcast(item.id);
// groupList.updatePodcast(item.id);
- return importColumn("Subscribe success ${item.title}", context);
+ return importColumn(s.notificationSuccess(item.title), context);
case SubscribeState.exist:
//groupList.subscribeNewPodcast(item.id);
return importColumn(
- "Subscribe failed, podcast existed ${item.title}", context);
+ s.notificationSubscribeExisted(item.title), context);
case SubscribeState.error:
return importColumn(
- "Subscribe failed, network error ${item.title}", context);
+ s.notificationNetworkError(item.title), context);
default:
return Center();
}
@@ -92,9 +94,10 @@ class Import extends StatelessWidget {
}
switch (item.refreshState) {
case RefreshState.fetch:
- return importColumn("Update ${item.title}", context);
+ return importColumn(s.notificationUpdate(item.title), context);
case RefreshState.error:
- return importColumn("Update error ${item.title}", context);
+ return importColumn(
+ s.notificationUpdateError(item.title), context);
default:
return Center();
}
diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb
index 554e53d..1d6e73c 100644
--- a/lib/l10n/intl_en.arb
+++ b/lib/l10n/intl_en.arb
@@ -1,25 +1,83 @@
{
"@@locale": "en",
+ "add": "Add",
+ "@add": {
+ "description": "Subscribe new podcast"
+ },
+ "addEpisodeGroup": "{count, plural, zero{} one{{count} episode in {groupName} added to playlist} other{{count} episodes in {groupName} added to playlist}}",
+ "@addEpisodeGroup": {
+ "placeholders": {
+ "groupName": {}
+ }
+ },
+ "addNewEpisodeAll": "{count, plural, zero{} one{{count} episode added to playlist} other{{count} episodes added to playlist}}",
+ "@addNewEpisodeAll": {},
+ "addNewEpisodeTooltip": "Add new episodes to playlist",
+ "@addNewEpisodeTooltip": {},
+ "addSomeGroups": "Add some groups",
+ "@addSomeGroups": {
+ "description": "Please add new groups"
+ },
"all": "All",
"@all": {},
- "cancel": "Cancel",
+ "back": "Back",
+ "@back": {},
+ "buffering": "Buffering",
+ "@buffering": {},
+ "cancel": "CANCEL",
"@cancel": {},
+ "changeLayout": "Change layout",
+ "@changeLayout": {},
+ "changelog": "Changelog",
+ "@changelog": {},
"chooseA": "Choose a",
"@chooseA": {},
+ "clear": "Clear",
+ "@clear": {},
"color": "color",
"@color": {},
- "confirm": "Confirm",
+ "confirm": "CONFIRM",
"@confirm": {},
"darkMode": "Dark mode",
"@darkMode": {},
"delete": "Delete",
"@delete": {},
+ "developer": "Developer",
+ "@developer": {},
+ "dismiss": "Dismiss",
+ "@dismiss": {},
"download": "Download",
"@download": {},
+ "downloaded": "Downloaded",
+ "@downloaded": {},
"editName": "Edit name",
"@editName": {},
"endOfEpisode": "End of Episode",
"@endOfEpisode": {},
+ "featureDiscoveryEpisode": "Episode view",
+ "@featureDiscoveryEpisode": {},
+ "featureDiscoveryEpisodeDes": "You can long tap to play episode or add episode to playlist.",
+ "@featureDiscoveryEpisodeDes": {},
+ "featureDiscoveryEpisodeTitle": "Long tap to play episode instantly",
+ "@featureDiscoveryEpisodeTitle": {},
+ "featureDiscoveryOMPL": "Tap to import OMPL",
+ "@featureDiscoveryOMPL": {},
+ "featureDiscoveryOMPLDes": "You can import OMPL file, open setting or refresh all podcast at once here.",
+ "@featureDiscoveryOMPLDes": {},
+ "featureDiscoveryPlaylist": "Tap to open playlist",
+ "@featureDiscoveryPlaylist": {},
+ "featureDiscoveryPlaylistDes": "You can add episode to playlist by yourself. Episode will be auto removed from playlist when played.",
+ "@featureDiscoveryPlaylistDes": {},
+ "featureDiscoveryPodcast": "Podcast view",
+ "@featureDiscoveryPodcast": {},
+ "featureDiscoveryPodcastDes": "You can tap See All to add groups or manage podcasts.",
+ "@featureDiscoveryPodcastDes": {},
+ "featureDiscoveryPodcastTitle": "Scroll vertically to switch groups",
+ "@featureDiscoveryPodcastTitle": {},
+ "featureDiscoverySearch": "Tap to search podcast",
+ "@featureDiscoverySearch": {},
+ "featureDiscoverySearchDes": "You can search podcast title , key word or RSS link to subscribe new podcast.",
+ "@featureDiscoverySearchDes": {},
"feedbackEmail": "Write to me",
"@feedbackEmail": {},
"feedbackGithub": "Submit issue",
@@ -30,14 +88,16 @@
"@feedbackTelegram": {},
"from": "From",
"@from": {},
+ "goodNight": "Good Night",
+ "@goodNight": {},
+ "groupFilter": "Group filter",
+ "@groupFilter": {},
"groups": "Groups",
"@groups": {},
"homeGroupsSeeAll": "See All",
"@homeGroupsSeeAll": {},
"homeMenuPlaylist": "Playlist",
"@homeMenuPlaylist": {},
- "homeSubMenuDownloaded": "Downloaded",
- "@homeSubMenuDownloaded": {},
"homeSubMenuLikeData": "Like Date",
"@homeSubMenuLikeData": {},
"homeSubMenuSortBy": "Sort by",
@@ -56,6 +116,14 @@
"@homeToprightMenuRefreshAll": {},
"homeToprightMenuSettings": "Settings",
"@homeToprightMenuSettings": {},
+ "hostedOn": "Hosted on {host}",
+ "@hostedOn": {
+ "placeholders": {
+ "host": {}
+ }
+ },
+ "hoursCount": "{count, plural, zero{} one{{count} hour} other{{count} hours}}",
+ "@hoursCount": {},
"later": "Later",
"@later": {},
"lightMode": "Light mode",
@@ -64,10 +132,18 @@
"@like": {},
"liked": "Liked",
"@liked": {},
+ "likeDate": "Like date",
+ "@likeDate": {},
"listen": "Listen",
"@listen": {},
"listened": "Listened",
"@listened": {},
+ "loadMore": "Load more",
+ "@loadMore": {},
+ "markConfirm": "Mark confirm",
+ "@markConfirm": {},
+ "markConfirmContent": "Confirm mark all episodes listened?",
+ "@markConfirmContent": {},
"markListened": "Mark listened",
"@markListened": {},
"menu": "Menu",
@@ -76,18 +152,72 @@
"@menuAllPodcasts": {},
"menuMarkAllListened": "Mark All Listened",
"@menuMarkAllListened": {},
- "menuMarkListened": "Mark Listened",
- "@menuMarkListened": {},
"menuViewRSS": "Visit RSS Feed",
"@menuViewRSS": {},
"menuVisitSite": "Visit Site",
"@menuVisitSite": {},
+ "minsCount": "{count, plural, zero{} one{{count} min} other{{count} mins}}",
+ "@minsCount": {},
"network": "Network",
"@network": {},
+ "newestFirst": "Newest first",
+ "@newestFirst": {},
"newGroup": "Create new group",
"@newGroup": {},
+ "noEpisodeDownload": "No episode downloaded yet",
+ "@noEpisodeDownload": {},
+ "noEpisodeFavorite": "No episode collected yet",
+ "@noEpisodeFavorite": {},
+ "noEpisodeRecent": "No episode received yet",
+ "@noEpisodeRecent": {},
+ "noPodcastGroup": "No podcast in this group",
+ "@noPodcastGroup": {},
+ "notificaitonFatch": "Fetch data {title}",
+ "@notificaitonFatch": {},
+ "notificationNetworkError": "Subscribe failed, network error {title}",
+ "@notificationNetworkError": {
+ "placeholders": {
+ "title": {}
+ }
+ },
+ "notificationSubscribe": "Subscribe {title}",
+ "@notificationSubscribe": {
+ "placeholders": {
+ "title": {}
+ }
+ },
+ "notificationSubscribeExisted": "Subscribe failed, podcast existed {title}",
+ "@notificationSubscribeExisted": {
+ "placeholders": {
+ "title": {}
+ }
+ },
+ "notificationSuccess": "Subscribe success {title}",
+ "@notificationSuccess": {
+ "placeholders": {
+ "title": {}
+ }
+ },
+ "notificationUpdate": "Update {title}",
+ "@notificationUpdate": {
+ "placeholders": {
+ "title": {}
+ }
+ },
+ "notificationUpdateError": "Update error {title}",
+ "@notificationUpdateError": {
+ "placeholders": {
+ "title": {}
+ }
+ },
+ "oldestFirst": "Oldest first",
+ "@oldestFirst": {},
"play": "Play",
"@play": {},
+ "playing": "Playing",
+ "@playing": {},
+ "podcastSubscribed": "Podcast subscribed",
+ "@podcastSubscribed": {},
"popupMenuDownloadDes": "Download episode",
"@popupMenuDownloadDes": {},
"popupMenuLaterDes": "Add episode to playlist",
@@ -98,10 +228,14 @@
"@popupMenuMarkDes": {},
"popupMenuPlayDes": "Play the episode",
"@popupMenuPlayDes": {},
+ "privacyPolicy": "Privacy Policy",
+ "@privacyPolicy": {},
"remove": "Remove",
"@remove": {},
"schedule": "Schedule",
"@schedule": {},
+ "searchInvalidRss": "Invalid RSS link",
+ "@searchInvalidRss": {},
"searchPodcast": "Search podcast",
"@searchPodcast": {},
"settingsAccentColor": "Accent color",
@@ -214,12 +348,26 @@
"@settingsUpdateInterval": {},
"settingsUpdateIntervalDes": "Default 24 hours",
"@settingsUpdateIntervalDes": {},
+ "size": "Size",
+ "@size": {},
"sleepTimer": "Sleep timer",
"@sleepTimer": {},
"subscribe": "Subscribe",
"@subscribe": {},
"systemDefault": "System default",
"@systemDefault": {},
+ "timeLastPlayed": "Last time {time}",
+ "@timeLastPlayed": {
+ "placeholders": {
+ "time": {}
+ }
+ },
+ "timeLeft": "{time} Left",
+ "@timeLeft": {
+ "placeholders": {
+ "time": {}
+ }
+ },
"to": "To",
"@to": {},
"toastAddPlaylist": "Added to playlist",
@@ -234,8 +382,22 @@
"@toastReadFile": {},
"toastRemovePlaylist": "Removed from playlist",
"@toastRemovePlaylist": {},
+ "understood": "Understood",
+ "@understood": {},
"unlike": "Unlike",
"@unlike": {},
- "unliked": "Unliked",
- "@unliked": {}
+ "unliked": "Removed from favorite",
+ "@unliked": {},
+ "updateDate": "Update date",
+ "@updateDate": {},
+ "updateEpisodesCount": "{count, plural, zero{No Update} one{Updated {count} Episode} other{Updated {count} Episodes}}",
+ "@updateEpisodesCount": {},
+ "updateFailed": "Update failed, network error",
+ "@updateFailed": {},
+ "version": "Version : {version}",
+ "@version": {
+ "placeholders": {
+ "version": {}
+ }
+ }
}
\ No newline at end of file
diff --git a/lib/l10n/intl_zh_Hans.arb b/lib/l10n/intl_zh_Hans.arb
index f76a377..0f0cdb1 100644
--- a/lib/l10n/intl_zh_Hans.arb
+++ b/lib/l10n/intl_zh_Hans.arb
@@ -1,11 +1,39 @@
{
"@@locale": "zh-Hans",
+ "add": "订阅",
+ "@add": {
+ "description": "Subscribe new podcast"
+ },
+ "addEpisodeGroup": "{count, plural, zero{} other{{group Name}分组{count}集节目添加到播放列表}}",
+ "@addEpisodeGroup": {
+ "placeholders": {
+ "groupName": {}
+ }
+ },
+ "addNewEpisodeAll": "{count, plural, zero{} other{{count}集节目添加到播放列表}}",
+ "@addNewEpisodeAll": {},
+ "addNewEpisodeTooltip": "添加更新节目到播放列表",
+ "@addNewEpisodeTooltip": {},
+ "addSomeGroups": "请添加分组",
+ "@addSomeGroups": {
+ "description": "Please add new groups"
+ },
"all": "全部",
"@all": {},
+ "back": "返回",
+ "@back": {},
+ "buffering": "缓冲",
+ "@buffering": {},
"cancel": "取消",
"@cancel": {},
+ "changeLayout": "修改布局",
+ "@changeLayout": {},
+ "changelog": "更新日志",
+ "@changelog": {},
"chooseA": "选择",
"@chooseA": {},
+ "clear": "清除",
+ "@clear": {},
"color": "颜色",
"@color": {},
"confirm": "确认",
@@ -14,12 +42,42 @@
"@darkMode": {},
"delete": "删除",
"@delete": {},
+ "developer": "关于我",
+ "@developer": {},
+ "dismiss": "忽略",
+ "@dismiss": {},
"download": "下载",
"@download": {},
+ "downloaded": "已下载",
+ "@downloaded": {},
"editName": "修改组名",
"@editName": {},
"endOfEpisode": "节目结束",
"@endOfEpisode": {},
+ "featureDiscoveryEpisode": "节目界面",
+ "@featureDiscoveryEpisode": {},
+ "featureDiscoveryEpisodeDes": "您可以长按播放节目或者添加节目到播放列表。",
+ "@featureDiscoveryEpisodeDes": {},
+ "featureDiscoveryEpisodeTitle": "您可以长按快速播放节目",
+ "@featureDiscoveryEpisodeTitle": {},
+ "featureDiscoveryOMPL": "点击导入 OMPL",
+ "@featureDiscoveryOMPL": {},
+ "featureDiscoveryOMPLDes": "在这里您可以导入OMPL文件,打开设置页面,或者刷新所有播客。",
+ "@featureDiscoveryOMPLDes": {},
+ "featureDiscoveryPlaylist": "点击打开播放列表",
+ "@featureDiscoveryPlaylist": {},
+ "featureDiscoveryPlaylistDes": "您可以添加节目到播放列表,节目在播放后将会从播放列表自动移除。",
+ "@featureDiscoveryPlaylistDes": {},
+ "featureDiscoveryPodcast": "播客界面",
+ "@featureDiscoveryPodcast": {},
+ "featureDiscoveryPodcastDes": "您可以点击“查看所有”新增或管理分组。",
+ "@featureDiscoveryPodcastDes": {},
+ "featureDiscoveryPodcastTitle": "您可以通过上下滑动切换分组",
+ "@featureDiscoveryPodcastTitle": {},
+ "featureDiscoverySearch": "点击搜索播客",
+ "@featureDiscoverySearch": {},
+ "featureDiscoverySearchDes": "您可以通过搜索播客名称、关键字或者RSS链接订阅播客。",
+ "@featureDiscoverySearchDes": {},
"feedbackEmail": "发送邮件",
"@feedbackEmail": {},
"feedbackGithub": "提交Issue",
@@ -30,14 +88,16 @@
"@feedbackTelegram": {},
"from": "自",
"@from": {},
+ "goodNight": "晚安",
+ "@goodNight": {},
+ "groupFilter": "分组",
+ "@groupFilter": {},
"groups": "分组",
"@groups": {},
"homeGroupsSeeAll": "查看全部",
"@homeGroupsSeeAll": {},
"homeMenuPlaylist": "播放列表",
"@homeMenuPlaylist": {},
- "homeSubMenuDownloaded": "已下载",
- "@homeSubMenuDownloaded": {},
"homeSubMenuLikeData": "添加日期",
"@homeSubMenuLikeData": {},
"homeSubMenuSortBy": "排序",
@@ -56,6 +116,14 @@
"@homeToprightMenuRefreshAll": {},
"homeToprightMenuSettings": "设置",
"@homeToprightMenuSettings": {},
+ "hostedOn": "平台 {host}",
+ "@hostedOn": {
+ "placeholders": {
+ "host": {}
+ }
+ },
+ "hoursCount": "{count, plural, zero{} other{{count} 小时}}",
+ "@hoursCount": {},
"later": "稍后",
"@later": {},
"lightMode": "明亮模式",
@@ -64,10 +132,18 @@
"@like": {},
"liked": "已收藏",
"@liked": {},
+ "likeDate": "收藏日期",
+ "@likeDate": {},
"listen": "收听",
"@listen": {},
"listened": "已收听",
"@listened": {},
+ "loadMore": "加载更多",
+ "@loadMore": {},
+ "markConfirm": "确认标记",
+ "@markConfirm": {},
+ "markConfirmContent": "是否确认标记全部节目为已收听?",
+ "@markConfirmContent": {},
"markListened": "标记已收听",
"@markListened": {},
"menu": "菜单",
@@ -76,18 +152,72 @@
"@menuAllPodcasts": {},
"menuMarkAllListened": "标记所有已收听",
"@menuMarkAllListened": {},
- "menuMarkListened": "标记已收听",
- "@menuMarkListened": {},
"menuViewRSS": "查看 RSS",
"@menuViewRSS": {},
"menuVisitSite": "访问网站",
"@menuVisitSite": {},
+ "minsCount": "{count, plural, zero{} other{{count}分钟}}",
+ "@minsCount": {},
"network": "网络",
"@network": {},
+ "newestFirst": "由新到旧",
+ "@newestFirst": {},
"newGroup": "创建分组",
"@newGroup": {},
+ "noEpisodeDownload": "暂无下载节目",
+ "@noEpisodeDownload": {},
+ "noEpisodeFavorite": "暂无收藏节目",
+ "@noEpisodeFavorite": {},
+ "noEpisodeRecent": "暂无节目",
+ "@noEpisodeRecent": {},
+ "noPodcastGroup": "分组无播客",
+ "@noPodcastGroup": {},
+ "notificaitonFatch": "获取数据 {title}",
+ "@notificaitonFatch": {},
+ "notificationNetworkError": "订阅失败,网络错误 {title}",
+ "@notificationNetworkError": {
+ "placeholders": {
+ "title": {}
+ }
+ },
+ "notificationSubscribe": "订阅{title}",
+ "@notificationSubscribe": {
+ "placeholders": {
+ "title": {}
+ }
+ },
+ "notificationSubscribeExisted": "订阅失败,播客已存在 {title}",
+ "@notificationSubscribeExisted": {
+ "placeholders": {
+ "title": {}
+ }
+ },
+ "notificationSuccess": "订阅成功 {title}",
+ "@notificationSuccess": {
+ "placeholders": {
+ "title": {}
+ }
+ },
+ "notificationUpdate": "更新 {title}",
+ "@notificationUpdate": {
+ "placeholders": {
+ "title": {}
+ }
+ },
+ "notificationUpdateError": "更新失败 {title}",
+ "@notificationUpdateError": {
+ "placeholders": {
+ "title": {}
+ }
+ },
+ "oldestFirst": "由旧到新",
+ "@oldestFirst": {},
"play": "播放",
"@play": {},
+ "playing": "正在播放",
+ "@playing": {},
+ "podcastSubscribed": "播客已订阅",
+ "@podcastSubscribed": {},
"popupMenuDownloadDes": "下载节目",
"@popupMenuDownloadDes": {},
"popupMenuLaterDes": "添加到播放列表",
@@ -98,10 +228,14 @@
"@popupMenuMarkDes": {},
"popupMenuPlayDes": "播放节目",
"@popupMenuPlayDes": {},
+ "privacyPolicy": "隐私条款",
+ "@privacyPolicy": {},
"remove": "移除",
"@remove": {},
"schedule": "定时",
"@schedule": {},
+ "searchInvalidRss": "RSS 链接错误",
+ "@searchInvalidRss": {},
"searchPodcast": "搜索播客",
"@searchPodcast": {},
"settingsAccentColor": "次要颜色",
@@ -214,12 +348,26 @@
"@settingsUpdateInterval": {},
"settingsUpdateIntervalDes": "默认 24 小时",
"@settingsUpdateIntervalDes": {},
+ "size": "大小",
+ "@size": {},
"sleepTimer": "睡眠模式",
"@sleepTimer": {},
"subscribe": "订阅",
"@subscribe": {},
"systemDefault": "系统默认",
"@systemDefault": {},
+ "timeLastPlayed": "上次播放{time}",
+ "@timeLastPlayed": {
+ "placeholders": {
+ "time": {}
+ }
+ },
+ "timeLeft": "剩余 {time}",
+ "@timeLeft": {
+ "placeholders": {
+ "time": {}
+ }
+ },
"to": "到",
"@to": {},
"toastAddPlaylist": "添加到播放列表",
@@ -234,8 +382,22 @@
"@toastReadFile": {},
"toastRemovePlaylist": "从播放列表移除",
"@toastRemovePlaylist": {},
+ "understood": "了解",
+ "@understood": {},
"unlike": "取消喜欢",
"@unlike": {},
"unliked": "从收藏移除",
- "@unliked": {}
+ "@unliked": {},
+ "updateDate": "更新日期",
+ "@updateDate": {},
+ "updateEpisodesCount": "{count, plural, zero{未有更新} other{更新 {count} 集节目}}",
+ "@updateEpisodesCount": {},
+ "updateFailed": "更新失败",
+ "@updateFailed": {},
+ "version": "版本:{version}",
+ "@version": {
+ "placeholders": {
+ "version": {}
+ }
+ }
}
\ No newline at end of file
diff --git a/lib/podcasts/podcastdetail.dart b/lib/podcasts/podcastdetail.dart
index a26e76e..f2e8703 100644
--- a/lib/podcasts/podcastdetail.dart
+++ b/lib/podcasts/podcastdetail.dart
@@ -44,7 +44,7 @@ class _PodcastDetailState extends State {
int _episodeCount;
Layout _layout;
bool _scroll;
- Future _updateRssItem(PodcastLocal podcastLocal) async {
+ Future _updateRssItem(BuildContext context, PodcastLocal podcastLocal) async {
var dbHelper = DBHelper();
final result = await dbHelper.updatePodcastRss(podcastLocal);
if (result == 0) {
@@ -54,7 +54,7 @@ class _PodcastDetailState extends State {
);
} else if (result > 0) {
Fluttertoast.showToast(
- msg: 'Updated $result Episodes',
+ msg: context.s.updateEpisodesCount(result),
gravity: ToastGravity.TOP,
);
@@ -85,7 +85,7 @@ class _PodcastDetailState extends State {
}
} else {
Fluttertoast.showToast(
- msg: 'Update failed, network error',
+ msg: context.s.updateFailed,
gravity: ToastGravity.TOP,
);
}
@@ -226,15 +226,15 @@ class _PodcastDetailState extends State {
_confirmMarkListened(BuildContext context) => generalDialog(
context,
- title: Text('Mark confirm'),
- content: Text('Confirm mark all episodes listened?'),
+ title: Text(context.s.markConfirm),
+ content: Text(context.s.markConfirmContent),
actions: [
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
- 'CANCEL',
+ context.s.cancel,
style: TextStyle(color: Colors.grey[600]),
),
),
@@ -244,7 +244,7 @@ class _PodcastDetailState extends State {
await _markListened(widget.podcastLocal.id);
},
child: Text(
- 'CONFIRM',
+ context.s.confirm,
style: TextStyle(color: context.accentColor),
),
)
@@ -293,7 +293,7 @@ class _PodcastDetailState extends State {
key: _refreshIndicatorKey,
color: Theme.of(context).accentColor,
onRefresh: () async {
- await _updateRssItem(widget.podcastLocal);
+ await _updateRssItem(context, widget.podcastLocal);
// audio.addNewEpisode(widget.podcastLocal.id);
},
child: Stack(
@@ -346,7 +346,7 @@ class _PodcastDetailState extends State {
borderRadius: BorderRadius.all(
Radius.circular(10))),
elevation: 2,
- tooltip: 'Menu',
+ tooltip: s.menu,
itemBuilder: (context) => [
widget.podcastLocal.link != null
? PopupMenuItem(
@@ -494,10 +494,9 @@ class _PodcastDetailState extends State {
widget.podcastLocal.provider
.isNotEmpty
? Text(
- 'Hosted on ' +
- widget
- .podcastLocal
- .provider,
+ s.hostedOn(widget
+ .podcastLocal
+ .provider),
maxLines: 1,
style: TextStyle(
color: Colors
@@ -588,12 +587,12 @@ class _PodcastDetailState extends State {
PopupMenuItem(
value: 0,
child:
- Text('Newest first'),
+ Text(s.newestFirst),
),
PopupMenuItem(
value: 1,
child:
- Text('Oldest first'),
+ Text(s.oldestFirst),
)
],
onSelected: (value) {
diff --git a/lib/settings/theme.dart b/lib/settings/theme.dart
index 1f7249c..0994bad 100644
--- a/lib/settings/theme.dart
+++ b/lib/settings/theme.dart
@@ -91,7 +91,7 @@ class ThemeSetting extends StatelessWidget {
Navigator.of(context).pop();
}),
RadioListTile(
- title: Text('Dark mode'),
+ title: Text(s.darkMode),
value: ThemeMode.dark,
groupValue: settings.theme,
onChanged: (value) {
@@ -99,7 +99,7 @@ class ThemeSetting extends StatelessWidget {
Navigator.of(context).pop();
}),
RadioListTile(
- title: Text('Light mode'),
+ title: Text(s.lightMode),
value: ThemeMode.light,
groupValue: settings.theme,
onChanged: (value) {
@@ -140,9 +140,9 @@ class ThemeSetting extends StatelessWidget {
ListTile(
onTap: () => generalDialog(
context,
- title: Text.rich(TextSpan(text: 'Choose a ', children: [
+ title: Text.rich(TextSpan(text: s.chooseA, children: [
TextSpan(
- text: 'color',
+ text: s.color,
style: TextStyle(
fontWeight: FontWeight.bold,
color: context.accentColor))
diff --git a/lib/state/subscribe_podcast.dart b/lib/state/subscribe_podcast.dart
index 359a9d3..98b116c 100644
--- a/lib/state/subscribe_podcast.dart
+++ b/lib/state/subscribe_podcast.dart
@@ -205,7 +205,7 @@ Future subIsolateEntryPoint(SendPort sendPort) async {
print(e);
}
}
- int count = await dbHelper.savePodcastRss(p, uuid);
+ await dbHelper.savePodcastRss(p, uuid);
sendPort.send([item.title, item.url, 3, uuid]);
diff --git a/lib/util/episodegrid.dart b/lib/util/episodegrid.dart
index 7e3fbe3..69be382 100644
--- a/lib/util/episodegrid.dart
+++ b/lib/util/episodegrid.dart
@@ -46,20 +46,18 @@ class EpisodeGrid extends StatelessWidget {
this.reverse,
}) : super(key: key);
- List _menuList = [];
-
Future _isListened(EpisodeBrief episode) async {
DBHelper dbHelper = DBHelper();
- _menuList = await _getEpisodeMenu();
return await dbHelper.isListened(episode.enclosureUrl);
}
- Future> _initData(EpisodeBrief episode) async {
+ Future>> _initData(
+ EpisodeBrief episode) async {
int listened = await _isListened(episode);
bool liked = await _isLiked(episode);
bool downloaded = await _isDownloaded(episode);
- _menuList = await _getEpisodeMenu();
- return Tuple3(listened, liked, downloaded);
+ List menuList = await _getEpisodeMenu();
+ return Tuple4(listened, liked, downloaded, menuList);
}
Future _isLiked(EpisodeBrief episode) async {
@@ -431,13 +429,14 @@ class EpisodeGrid extends StatelessWidget {
builder: (_, data, __) => OpenContainerWrapper(
episode: episodes[index],
closedBuilder: (context, action, boo) => FutureBuilder<
- Tuple3>(
+ Tuple4>>(
future: _initData(episodes[index]),
- initialData: Tuple3(0, false, false),
+ initialData: Tuple4(0, false, false, []),
builder: (BuildContext context, AsyncSnapshot snapshot) {
int isListened = snapshot.data.item1;
bool isLiked = snapshot.data.item2;
bool isDownloaded = snapshot.data.item3;
+ List menuList = snapshot.data.item4;
return Container(
decoration: BoxDecoration(
borderRadius:
@@ -457,21 +456,6 @@ class EpisodeGrid extends StatelessWidget {
),
]),
alignment: Alignment.center,
- // InkWell(
- // borderRadius:
- // BorderRadius.all(Radius.circular(5.0)),
- // onTapDown: (details) => _offset = Offset(
- // details.globalPosition.dx,
- // details.globalPosition.dy),
- // onLongPress: () => _showPopupMenu(
- // _offset,
- // episodes[index],
- // context,
- // isPlaying: data.item1 == episodes[index],
- // isInPlaylist: data.item2
- // .contains(episodes[index].enclosureUrl),
- // ),
- // onTap: action,
child: Container(
decoration: BoxDecoration(
borderRadius:
@@ -507,7 +491,7 @@ class EpisodeGrid extends StatelessWidget {
: context.scaffoldBackgroundColor,
title: Text(data.item1 != episodes[index]
? s.play
- : "Playing"),
+ : s.playing),
trailingIcon: Icon(
LineIcons.play_circle_solid,
color: Theme.of(context).accentColor,
@@ -516,7 +500,7 @@ class EpisodeGrid extends StatelessWidget {
if (data.item1 != episodes[index])
audio.episodeLoad(episodes[index]);
}),
- _menuList.contains(1)
+ menuList.contains(1)
? FocusedMenuItem(
backgroundColor:
context.brightness == Brightness.light
@@ -524,7 +508,7 @@ class EpisodeGrid extends StatelessWidget {
: context.scaffoldBackgroundColor,
title: data.item2.contains(
episodes[index].enclosureUrl)
- ? Text("Remove")
+ ? Text(s.remove)
: Text(s.later),
trailingIcon: Icon(
LineIcons.clock_solid,
@@ -535,20 +519,20 @@ class EpisodeGrid extends StatelessWidget {
episodes[index].enclosureUrl)) {
audio.addToPlaylist(episodes[index]);
Fluttertoast.showToast(
- msg: 'Added to playlist',
+ msg: s.toastAddPlaylist,
gravity: ToastGravity.BOTTOM,
);
} else {
audio
.delFromPlaylist(episodes[index]);
Fluttertoast.showToast(
- msg: 'Removed from playlist',
+ msg: s.toastRemovePlaylist,
gravity: ToastGravity.BOTTOM,
);
}
})
: null,
- _menuList.contains(2)
+ menuList.contains(2)
? FocusedMenuItem(
backgroundColor:
context.brightness == Brightness.light
@@ -565,7 +549,7 @@ class EpisodeGrid extends StatelessWidget {
episodes[index].enclosureUrl);
audio.setEpisodeState = true;
Fluttertoast.showToast(
- msg: 'Unliked',
+ msg: s.unliked,
gravity: ToastGravity.BOTTOM,
);
} else {
@@ -573,20 +557,20 @@ class EpisodeGrid extends StatelessWidget {
episodes[index].enclosureUrl);
audio.setEpisodeState = true;
Fluttertoast.showToast(
- msg: 'Liked',
+ msg: s.liked,
gravity: ToastGravity.BOTTOM,
);
}
})
: null,
- _menuList.contains(3)
+ menuList.contains(3)
? FocusedMenuItem(
backgroundColor:
context.brightness == Brightness.light
? context.primaryColor
: context.scaffoldBackgroundColor,
title: isListened > 0
- ? Text('Listened',
+ ? Text(s.listened,
style: TextStyle(
color: context.textColor
.withOpacity(0.5)))
@@ -614,14 +598,14 @@ class EpisodeGrid extends StatelessWidget {
}
})
: null,
- _menuList.contains(4)
+ menuList.contains(4)
? FocusedMenuItem(
backgroundColor:
context.brightness == Brightness.light
? context.primaryColor
: context.scaffoldBackgroundColor,
title: isDownloaded
- ? Text(s.homeSubMenuDownloaded,
+ ? Text(s.downloaded,
style: TextStyle(
color: context.textColor
.withOpacity(0.5)))