Files
ReelShort/lib/l10n/app_localizations.dart
T
Vicky d7eff4ca59 feat(client): 对接详情/播放/进度续看/收藏(K1 看剧闭环)+ 三态 UI
后端接口从 6 个扩到 13 个,全部走真数据:

- 新增 api:playback_api(/app/episodes/{id}/play)、watch_api(/app/watch/*)、
  library_api(/app/favorites*);票据从 CatalogApi 搬到 PlaybackApi
- 新增 repository:PlaybackRepository(含票据 TTL 缓存,默认 10 分钟,时钟可注入)、
  FavoriteRepository、WatchHistoryRepository 换成服务端模型(每剧一条续看记录,删掉 demoProfileId)
- PlayerLogic:起播前取票(拿不到给三态 UI,失败可重试);accessType 驱动锁定文案,
  不在前端猜;签名地址原样交给播放器(只补 host,不动 path/query);
  进度上报节流 5s → 10s,切集/退出/切后台各补一次,播完带 finished
- 续看定位:服务端记录里的那一集才 seek(其它集从头播),续看位置进详情/播放页时读一次
- FavoriteController:收藏以服务端为准,乐观更新 + 失败回滚;退出登录清空
- UI 三态:详情页(加载/失败可重试/空剧集 + 续看进度条 + 收藏按钮)、
  播放页(票据加载中/失败可重试/后端判定不可播)、我的页(续看失败可重试、收藏三态、最近观看)
- l10n 新增 8 个键(en/zh/id 三份):网络/进度/收藏失败、锁定提示、续看文案等

测试:flutter test 188 全过(存量 27 个测试文件未跑红);新增票据过期重取、进度节流、
续看定位、收藏回滚、签名 query 原样保留、真实后端端到端联调(live_watch_flow)
2026-10-16 17:39:05 +08:00

1231 lines
32 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart' as intl;
import 'app_localizations_en.dart';
import 'app_localizations_id.dart';
import 'app_localizations_zh.dart';
// ignore_for_file: type=lint
/// Callers can lookup localized strings with an instance of AppLocalizations
/// returned by `AppLocalizations.of(context)`.
///
/// Applications need to include `AppLocalizations.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
/// ```dart
/// import 'l10n/app_localizations.dart';
///
/// return MaterialApp(
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
/// supportedLocales: AppLocalizations.supportedLocales,
/// home: MyApplicationHome(),
/// );
/// ```
///
/// ## Update pubspec.yaml
///
/// Please make sure to update your pubspec.yaml to include the following
/// packages:
///
/// ```yaml
/// dependencies:
/// # Internationalization support.
/// flutter_localizations:
/// sdk: flutter
/// intl: any # Use the pinned version from flutter_localizations
///
/// # Rest of dependencies
/// ```
///
/// ## iOS Applications
///
/// iOS applications define key application metadata, including supported
/// locales, in an Info.plist file that is built into the application bundle.
/// To configure the locales supported by your app, you’ll need to edit this
/// file.
///
/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file.
/// Then, in the Project Navigator, open the Info.plist file under the Runner
/// project’s Runner folder.
///
/// Next, select the Information Property List item, select Add Item from the
/// Editor menu, then select Localizations from the pop-up menu.
///
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
/// property.
abstract class AppLocalizations {
AppLocalizations(String locale)
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
static AppLocalizations? of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations);
}
static const LocalizationsDelegate<AppLocalizations> delegate =
_AppLocalizationsDelegate();
/// A list of this localizations delegate along with the default localizations
/// delegates.
///
/// Returns a list of localizations delegates containing this delegate along with
/// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
/// and GlobalWidgetsLocalizations.delegate.
///
/// Additional delegates can be added by appending to this list in
/// MaterialApp. This list does not have to be used at all if a custom list
/// of delegates is preferred or required.
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
<LocalizationsDelegate<dynamic>>[
delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
];
/// A list of this localizations delegate's supported locales.
static const List<Locale> supportedLocales = <Locale>[
Locale('en'),
Locale('id'),
Locale('zh'),
];
/// No description provided for @appName.
///
/// In en, this message translates to:
/// **'FruitShorts'**
String get appName;
/// No description provided for @demo.
///
/// In en, this message translates to:
/// **'DEMO'**
String get demo;
/// No description provided for @homeHeadline.
///
/// In en, this message translates to:
/// **'Watch now'**
String get homeHeadline;
/// No description provided for @homeSubtitle.
///
/// In en, this message translates to:
/// **'Free short drama preview.'**
String get homeSubtitle;
/// No description provided for @mediaNotice.
///
/// In en, this message translates to:
/// **'User-provided local demo video · Free preview'**
String get mediaNotice;
/// No description provided for @featuredDemo.
///
/// In en, this message translates to:
/// **'FEATURED · TECHNICAL DEMO'**
String get featuredDemo;
/// No description provided for @demoTitle.
///
/// In en, this message translates to:
/// **'The Signal'**
String get demoTitle;
/// No description provided for @demoSynopsis.
///
/// In en, this message translates to:
/// **'A short local video preview. More episodes can be added when media is available.'**
String get demoSynopsis;
/// No description provided for @homeTab.
///
/// In en, this message translates to:
/// **'Home'**
String get homeTab;
/// No description provided for @openQuickMenu.
///
/// In en, this message translates to:
/// **'Open quick menu'**
String get openQuickMenu;
/// No description provided for @quickAccess.
///
/// In en, this message translates to:
/// **'Quick access'**
String get quickAccess;
/// No description provided for @currentSeries.
///
/// In en, this message translates to:
/// **'Current series'**
String get currentSeries;
/// No description provided for @discoverTab.
///
/// In en, this message translates to:
/// **'Discover'**
String get discoverTab;
/// No description provided for @searchDiscover.
///
/// In en, this message translates to:
/// **'Search dramas, actors, genres...'**
String get searchDiscover;
/// No description provided for @featured.
///
/// In en, this message translates to:
/// **'Featured'**
String get featured;
/// No description provided for @suspense.
///
/// In en, this message translates to:
/// **'Suspense'**
String get suspense;
/// No description provided for @romance.
///
/// In en, this message translates to:
/// **'Romance'**
String get romance;
/// No description provided for @actionGenre.
///
/// In en, this message translates to:
/// **'Action'**
String get actionGenre;
/// No description provided for @filter.
///
/// In en, this message translates to:
/// **'Filter'**
String get filter;
/// No description provided for @topCharts.
///
/// In en, this message translates to:
/// **'Top Charts'**
String get topCharts;
/// No description provided for @newReleases.
///
/// In en, this message translates to:
/// **'New Releases'**
String get newReleases;
/// No description provided for @trendingMicroDramas.
///
/// In en, this message translates to:
/// **'Trending Micro-Dramas'**
String get trendingMicroDramas;
/// No description provided for @seeAll.
///
/// In en, this message translates to:
/// **'See All'**
String get seeAll;
/// No description provided for @artworkOnly.
///
/// In en, this message translates to:
/// **'Artwork'**
String get artworkOnly;
/// No description provided for @artworkOnlyNotice.
///
/// In en, this message translates to:
/// **'This is a visual catalog item. No video is available yet.'**
String get artworkOnlyNotice;
/// No description provided for @videoPending.
///
/// In en, this message translates to:
/// **'Video pending'**
String get videoPending;
/// No description provided for @watchNow.
///
/// In en, this message translates to:
/// **'Watch free'**
String get watchNow;
/// No description provided for @noSearchResults.
///
/// In en, this message translates to:
/// **'No matching dramas.'**
String get noSearchResults;
/// No description provided for @demoCatalogNotice.
///
/// In en, this message translates to:
/// **'Three demo dramas share the same local video.'**
String get demoCatalogNotice;
/// No description provided for @myTab.
///
/// In en, this message translates to:
/// **'My'**
String get myTab;
/// No description provided for @localViewer.
///
/// In en, this message translates to:
/// **'Local Viewer'**
String get localViewer;
/// No description provided for @localDemoProfile.
///
/// In en, this message translates to:
/// **'Local demo profile'**
String get localDemoProfile;
/// No description provided for @continueWatching.
///
/// In en, this message translates to:
/// **'Continue Watching'**
String get continueWatching;
/// No description provided for @watchedPercent.
///
/// In en, this message translates to:
/// **'Watched {percent}%'**
String watchedPercent(int percent);
/// No description provided for @resume.
///
/// In en, this message translates to:
/// **'Resume'**
String get resume;
/// No description provided for @history.
///
/// In en, this message translates to:
/// **'History'**
String get history;
/// No description provided for @watchlist.
///
/// In en, this message translates to:
/// **'Watchlist'**
String get watchlist;
/// No description provided for @likedTab.
///
/// In en, this message translates to:
/// **'Liked'**
String get likedTab;
/// No description provided for @all.
///
/// In en, this message translates to:
/// **'All'**
String get all;
/// No description provided for @inProgress.
///
/// In en, this message translates to:
/// **'In Progress'**
String get inProgress;
/// No description provided for @completed.
///
/// In en, this message translates to:
/// **'Completed'**
String get completed;
/// No description provided for @noSavedShows.
///
/// In en, this message translates to:
/// **'No shows here yet.'**
String get noSavedShows;
/// No description provided for @preferences.
///
/// In en, this message translates to:
/// **'Preferences'**
String get preferences;
/// No description provided for @appLanguage.
///
/// In en, this message translates to:
/// **'App Language'**
String get appLanguage;
/// No description provided for @followingTab.
///
/// In en, this message translates to:
/// **'Following'**
String get followingTab;
/// No description provided for @animatedTab.
///
/// In en, this message translates to:
/// **'Animated'**
String get animatedTab;
/// No description provided for @recommendedTab.
///
/// In en, this message translates to:
/// **'Recommended'**
String get recommendedTab;
/// No description provided for @noCategoryDramas.
///
/// In en, this message translates to:
/// **'No dramas in this category yet.'**
String get noCategoryDramas;
/// No description provided for @trendingTab.
///
/// In en, this message translates to:
/// **'Trending'**
String get trendingTab;
/// No description provided for @liveActionTab.
///
/// In en, this message translates to:
/// **'Live Action'**
String get liveActionTab;
/// No description provided for @search.
///
/// In en, this message translates to:
/// **'Search'**
String get search;
/// No description provided for @free.
///
/// In en, this message translates to:
/// **'Free'**
String get free;
/// No description provided for @mute.
///
/// In en, this message translates to:
/// **'Mute'**
String get mute;
/// No description provided for @unmute.
///
/// In en, this message translates to:
/// **'Unmute'**
String get unmute;
/// No description provided for @like.
///
/// In en, this message translates to:
/// **'Like'**
String get like;
/// No description provided for @save.
///
/// In en, this message translates to:
/// **'Save'**
String get save;
/// No description provided for @comments.
///
/// In en, this message translates to:
/// **'Comments'**
String get comments;
/// No description provided for @share.
///
/// In en, this message translates to:
/// **'Share'**
String get share;
/// No description provided for @localOnlyComments.
///
/// In en, this message translates to:
/// **'Only visible on this device'**
String get localOnlyComments;
/// No description provided for @noComments.
///
/// In en, this message translates to:
/// **'No comments yet.'**
String get noComments;
/// No description provided for @writeComment.
///
/// In en, this message translates to:
/// **'Write a comment'**
String get writeComment;
/// No description provided for @postComment.
///
/// In en, this message translates to:
/// **'Post'**
String get postComment;
/// No description provided for @shareFailed.
///
/// In en, this message translates to:
/// **'Could not open the share sheet.'**
String get shareFailed;
/// No description provided for @nowPlaying.
///
/// In en, this message translates to:
/// **'Playing now'**
String get nowPlaying;
/// No description provided for @watchFullscreen.
///
/// In en, this message translates to:
/// **'Watch in landscape'**
String get watchFullscreen;
/// No description provided for @exitFullscreen.
///
/// In en, this message translates to:
/// **'Exit fullscreen'**
String get exitFullscreen;
/// No description provided for @pictureInPicture.
///
/// In en, this message translates to:
/// **'Picture in picture'**
String get pictureInPicture;
/// No description provided for @pipUnavailable.
///
/// In en, this message translates to:
/// **'Picture in picture is unavailable on this device'**
String get pipUnavailable;
/// No description provided for @originalTag.
///
/// In en, this message translates to:
/// **'Original'**
String get originalTag;
/// No description provided for @dramaTag.
///
/// In en, this message translates to:
/// **'Short drama'**
String get dramaTag;
/// No description provided for @episodeLabel.
///
/// In en, this message translates to:
/// **'Episode {number}'**
String episodeLabel(int number);
/// No description provided for @exploreSeries.
///
/// In en, this message translates to:
/// **'Explore series'**
String get exploreSeries;
/// No description provided for @episodeCount.
///
/// In en, this message translates to:
/// **'{count} EPISODES'**
String episodeCount(int count);
/// No description provided for @technicalDemoCount.
///
/// In en, this message translates to:
/// **'FREE PREVIEW · {count} EPISODES'**
String technicalDemoCount(int count);
/// No description provided for @episodes.
///
/// In en, this message translates to:
/// **'Episodes'**
String get episodes;
/// No description provided for @watchEpisodeOne.
///
/// In en, this message translates to:
/// **'Watch episode 1'**
String get watchEpisodeOne;
/// No description provided for @continueEpisode.
///
/// In en, this message translates to:
/// **'Continue episode {number}'**
String continueEpisode(int number);
/// No description provided for @freeTestMedia.
///
/// In en, this message translates to:
/// **'Same demo clip · free'**
String get freeTestMedia;
/// No description provided for @lockedStoreUnavailable.
///
/// In en, this message translates to:
/// **'Locked · store unavailable'**
String get lockedStoreUnavailable;
/// No description provided for @freeTestClip.
///
/// In en, this message translates to:
/// **'Free test clip'**
String get freeTestClip;
/// No description provided for @locked.
///
/// In en, this message translates to:
/// **'Locked'**
String get locked;
/// No description provided for @freeSamplesNotice.
///
/// In en, this message translates to:
/// **'Two free samples · store setup pending'**
String get freeSamplesNotice;
/// No description provided for @demoTestMedia.
///
/// In en, this message translates to:
/// **'FREE · SAME DEMO CLIP'**
String get demoTestMedia;
/// No description provided for @episodeProgress.
///
/// In en, this message translates to:
/// **'EPISODE {number} / {total}'**
String episodeProgress(int number, int total);
/// No description provided for @testVideoNotice.
///
/// In en, this message translates to:
/// **'Self-generated technical test video'**
String get testVideoNotice;
/// No description provided for @lockedTitle.
///
/// In en, this message translates to:
/// **'Episode {number} is locked'**
String lockedTitle(int number);
/// No description provided for @lockedBody.
///
/// In en, this message translates to:
/// **'Unlocking will be available after store and verification setup. This demo does not process payments.'**
String get lockedBody;
/// No description provided for @playbackError.
///
/// In en, this message translates to:
/// **'This clip could not be played.'**
String get playbackError;
/// No description provided for @catalogError.
///
/// In en, this message translates to:
/// **'The catalog could not be loaded.'**
String get catalogError;
/// No description provided for @detailError.
///
/// In en, this message translates to:
/// **'The episode list could not be loaded.'**
String get detailError;
/// No description provided for @noMediaNotice.
///
/// In en, this message translates to:
/// **'This episode has no playable media yet.'**
String get noMediaNotice;
/// No description provided for @noStories.
///
/// In en, this message translates to:
/// **'No stories available yet.'**
String get noStories;
/// No description provided for @retry.
///
/// In en, this message translates to:
/// **'Retry'**
String get retry;
/// No description provided for @backToSeries.
///
/// In en, this message translates to:
/// **'Back to series'**
String get backToSeries;
/// No description provided for @nextEpisode.
///
/// In en, this message translates to:
/// **'Next episode'**
String get nextEpisode;
/// No description provided for @pause.
///
/// In en, this message translates to:
/// **'Pause'**
String get pause;
/// No description provided for @play.
///
/// In en, this message translates to:
/// **'Play'**
String get play;
/// No description provided for @seekVideo.
///
/// In en, this message translates to:
/// **'Seek video'**
String get seekVideo;
/// No description provided for @seekFailed.
///
/// In en, this message translates to:
/// **'Could not change playback position.'**
String get seekFailed;
/// No description provided for @captions.
///
/// In en, this message translates to:
/// **'Captions'**
String get captions;
/// No description provided for @captionsOff.
///
/// In en, this message translates to:
/// **'Captions off'**
String get captionsOff;
/// No description provided for @englishCaptions.
///
/// In en, this message translates to:
/// **'English captions'**
String get englishCaptions;
/// No description provided for @chineseCaptions.
///
/// In en, this message translates to:
/// **'Chinese captions'**
String get chineseCaptions;
/// No description provided for @language.
///
/// In en, this message translates to:
/// **'Language'**
String get language;
/// No description provided for @systemLanguage.
///
/// In en, this message translates to:
/// **'System'**
String get systemLanguage;
/// No description provided for @english.
///
/// In en, this message translates to:
/// **'English'**
String get english;
/// No description provided for @simplifiedChinese.
///
/// In en, this message translates to:
/// **'简体中文'**
String get simplifiedChinese;
/// No description provided for @episodeOneTitle.
///
/// In en, this message translates to:
/// **'First Light'**
String get episodeOneTitle;
/// No description provided for @episodeTwoTitle.
///
/// In en, this message translates to:
/// **'A New Frequency'**
String get episodeTwoTitle;
/// No description provided for @episodeThreeTitle.
///
/// In en, this message translates to:
/// **'Crossing Over'**
String get episodeThreeTitle;
/// No description provided for @episodeFourTitle.
///
/// In en, this message translates to:
/// **'After the Echo'**
String get episodeFourTitle;
/// No description provided for @dramaSignalTitle.
///
/// In en, this message translates to:
/// **'The Signal'**
String get dramaSignalTitle;
/// No description provided for @dramaSignalSynopsis.
///
/// In en, this message translates to:
/// **'A demo series for vertical playback. Every episode reuses one local clip.'**
String get dramaSignalSynopsis;
/// No description provided for @dramaCityTitle.
///
/// In en, this message translates to:
/// **'City Lights & Velvet Nights'**
String get dramaCityTitle;
/// No description provided for @dramaCitySynopsis.
///
/// In en, this message translates to:
/// **'A demo romance series. The same local video is used to try switching and resume.'**
String get dramaCitySynopsis;
/// No description provided for @dramaVengeanceTitle.
///
/// In en, this message translates to:
/// **'Vengeance Rising'**
String get dramaVengeanceTitle;
/// No description provided for @dramaVengeanceSynopsis.
///
/// In en, this message translates to:
/// **'A demo action series. The same local video is used to try switching and resume.'**
String get dramaVengeanceSynopsis;
/// No description provided for @dramaEchoesTitle.
///
/// In en, this message translates to:
/// **'Echoes of Fate'**
String get dramaEchoesTitle;
/// No description provided for @genreSuspenseMystery.
///
/// In en, this message translates to:
/// **'Suspense · Mystery'**
String get genreSuspenseMystery;
/// No description provided for @genreUrbanRomance.
///
/// In en, this message translates to:
/// **'Urban Romance'**
String get genreUrbanRomance;
/// No description provided for @genreActionThriller.
///
/// In en, this message translates to:
/// **'Action · Thriller'**
String get genreActionThriller;
/// No description provided for @genreDramaMystery.
///
/// In en, this message translates to:
/// **'Drama · Mystery'**
String get genreDramaMystery;
/// No description provided for @continueWatchingHeading.
///
/// In en, this message translates to:
/// **'CONTINUE WATCHING'**
String get continueWatchingHeading;
/// No description provided for @preferencesHeading.
///
/// In en, this message translates to:
/// **'PREFERENCES'**
String get preferencesHeading;
/// No description provided for @brandMark.
///
/// In en, this message translates to:
/// **'FRUITSHORTS'**
String get brandMark;
/// No description provided for @shareFooter.
///
/// In en, this message translates to:
/// **'FruitShorts'**
String get shareFooter;
/// No description provided for @shortsTab.
///
/// In en, this message translates to:
/// **'Shorts'**
String get shortsTab;
/// No description provided for @myListTab.
///
/// In en, this message translates to:
/// **'My List'**
String get myListTab;
/// No description provided for @watchFull.
///
/// In en, this message translates to:
/// **'Watch Full'**
String get watchFull;
/// No description provided for @swipeForNext.
///
/// In en, this message translates to:
/// **'Swipe up for next'**
String get swipeForNext;
/// No description provided for @clearScreen.
///
/// In en, this message translates to:
/// **'Clear screen'**
String get clearScreen;
/// No description provided for @exitClearScreen.
///
/// In en, this message translates to:
/// **'Exit clear screen'**
String get exitClearScreen;
/// No description provided for @logIn.
///
/// In en, this message translates to:
/// **'Log in'**
String get logIn;
/// No description provided for @logInHint.
///
/// In en, this message translates to:
/// **'Keep your coins and list'**
String get logInHint;
/// No description provided for @rewards.
///
/// In en, this message translates to:
/// **'Rewards'**
String get rewards;
/// No description provided for @forYou.
///
/// In en, this message translates to:
/// **'For You'**
String get forYou;
/// No description provided for @hot.
///
/// In en, this message translates to:
/// **'Hot'**
String get hot;
/// No description provided for @newest.
///
/// In en, this message translates to:
/// **'New'**
String get newest;
/// No description provided for @favorite.
///
/// In en, this message translates to:
/// **'Favorite'**
String get favorite;
/// No description provided for @myAccount.
///
/// In en, this message translates to:
/// **'My account'**
String get myAccount;
/// No description provided for @coins.
///
/// In en, this message translates to:
/// **'Coins'**
String get coins;
/// No description provided for @topUpWallet.
///
/// In en, this message translates to:
/// **'Top Up Wallet'**
String get topUpWallet;
/// No description provided for @vipMembership.
///
/// In en, this message translates to:
/// **'VIP Membership'**
String get vipMembership;
/// No description provided for @notActive.
///
/// In en, this message translates to:
/// **'Not Active'**
String get notActive;
/// No description provided for @joinVip.
///
/// In en, this message translates to:
/// **'Join VIP'**
String get joinVip;
/// No description provided for @earnRewards.
///
/// In en, this message translates to:
/// **'Earn Rewards'**
String get earnRewards;
/// No description provided for @freeBonus.
///
/// In en, this message translates to:
/// **'Get Free Bonus'**
String get freeBonus;
/// No description provided for @watchHistory.
///
/// In en, this message translates to:
/// **'Watch History'**
String get watchHistory;
/// No description provided for @settings.
///
/// In en, this message translates to:
/// **'Settings'**
String get settings;
/// No description provided for @signOut.
///
/// In en, this message translates to:
/// **'Sign Out'**
String get signOut;
/// No description provided for @mockUserName.
///
/// In en, this message translates to:
/// **'Vicky sheng'**
String get mockUserName;
/// No description provided for @mockUserId.
///
/// In en, this message translates to:
/// **'ID: M1CZWVYE'**
String get mockUserId;
/// No description provided for @mockNotice.
///
/// In en, this message translates to:
/// **'Sample data only.'**
String get mockNotice;
/// No description provided for @topBadge.
///
/// In en, this message translates to:
/// **'TOP 1'**
String get topBadge;
/// No description provided for @signIn.
///
/// In en, this message translates to:
/// **'Sign In'**
String get signIn;
/// No description provided for @signUp.
///
/// In en, this message translates to:
/// **'Sign Up'**
String get signUp;
/// No description provided for @authSignInTitle.
///
/// In en, this message translates to:
/// **'Welcome back'**
String get authSignInTitle;
/// No description provided for @authSignUpTitle.
///
/// In en, this message translates to:
/// **'Create your account'**
String get authSignUpTitle;
/// No description provided for @authSubtitle.
///
/// In en, this message translates to:
/// **'Sign in with your email and password.'**
String get authSubtitle;
/// No description provided for @authEmailLabel.
///
/// In en, this message translates to:
/// **'Email'**
String get authEmailLabel;
/// No description provided for @authPasswordLabel.
///
/// In en, this message translates to:
/// **'Password'**
String get authPasswordLabel;
/// No description provided for @authPasswordHint.
///
/// In en, this message translates to:
/// **'At least 8 characters, letters and numbers'**
String get authPasswordHint;
/// No description provided for @authEmailRequired.
///
/// In en, this message translates to:
/// **'Enter your email'**
String get authEmailRequired;
/// No description provided for @authEmailInvalid.
///
/// In en, this message translates to:
/// **'That email doesn\'t look right'**
String get authEmailInvalid;
/// No description provided for @authPasswordRequired.
///
/// In en, this message translates to:
/// **'Enter your password'**
String get authPasswordRequired;
/// No description provided for @authPasswordLength.
///
/// In en, this message translates to:
/// **'Password must be 8-64 characters'**
String get authPasswordLength;
/// No description provided for @authPasswordWeak.
///
/// In en, this message translates to:
/// **'Password needs both letters and numbers'**
String get authPasswordWeak;
/// No description provided for @authNetworkError.
///
/// In en, this message translates to:
/// **'Network error, please try again'**
String get authNetworkError;
/// No description provided for @authSwitchToSignUp.
///
/// In en, this message translates to:
/// **'New here? Create an account'**
String get authSwitchToSignUp;
/// No description provided for @authSwitchToSignIn.
///
/// In en, this message translates to:
/// **'Already have an account? Sign in'**
String get authSwitchToSignIn;
/// No description provided for @authGateTitle.
///
/// In en, this message translates to:
/// **'Sign in to continue'**
String get authGateTitle;
/// No description provided for @authGateMessage.
///
/// In en, this message translates to:
/// **'Favorites and comments need an account.'**
String get authGateMessage;
/// No description provided for @authGateAction.
///
/// In en, this message translates to:
/// **'Sign In'**
String get authGateAction;
/// No description provided for @cancel.
///
/// In en, this message translates to:
/// **'Not now'**
String get cancel;
/// No description provided for @noEpisodesYet.
///
/// In en, this message translates to:
/// **'No playable episodes yet.'**
String get noEpisodesYet;
/// No description provided for @networkError.
///
/// In en, this message translates to:
/// **'Network is unreachable. Please check your connection and retry.'**
String get networkError;
/// No description provided for @progressError.
///
/// In en, this message translates to:
/// **'Your watch position could not be loaded.'**
String get progressError;
/// No description provided for @favoritesError.
///
/// In en, this message translates to:
/// **'Your favorites could not be loaded.'**
String get favoritesError;
/// No description provided for @favoriteToggleFailed.
///
/// In en, this message translates to:
/// **'Could not update favorites. Please retry.'**
String get favoriteToggleFailed;
/// No description provided for @remove.
///
/// In en, this message translates to:
/// **'Remove'**
String get remove;
/// No description provided for @unlockComingSoon.
///
/// In en, this message translates to:
/// **'Unlocking with coins is coming soon.'**
String get unlockComingSoon;
/// No description provided for @resumeProgress.
///
/// In en, this message translates to:
/// **'Resume at {position} / {total}'**
String resumeProgress(Object position, Object total);
}
class _AppLocalizationsDelegate
extends LocalizationsDelegate<AppLocalizations> {
const _AppLocalizationsDelegate();
@override
Future<AppLocalizations> load(Locale locale) {
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
}
@override
bool isSupported(Locale locale) =>
<String>['en', 'id', 'zh'].contains(locale.languageCode);
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
}
AppLocalizations lookupAppLocalizations(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'en':
return AppLocalizationsEn();
case 'id':
return AppLocalizationsId();
case 'zh':
return AppLocalizationsZh();
}
throw FlutterError(
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.',
);
}