diff --git a/README.md b/README.md index 8ee766b..004a776 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ - **沉浸式首页**:竖屏播放,上下滑切换短剧,左右滑切换内容类别;支持拖动进度、横屏全屏观看。 - **剧集播放**:从详情页进入后按集连续播放,支持选集和本地续看。 - **找剧与个人页**:浏览、搜索和查看剧集详情;在个人页查看观看记录、收藏与喜欢的内容。 -- **互动与多语言**:本地演示评论、系统分享,以及英文和简体中文界面。 +- **互动与多语言**:本地演示评论、系统分享,以及英文、简体中文和印尼语界面。 - **画中画**:Android 接入系统画中画;iOS 画中画尚未实现。 ## 技术实现 @@ -14,7 +14,7 @@ ## 对接后端 -目录数据来自短剧服务的客户端接口(`FruitServer` 的 `reelshort-app-api`,默认 `http://127.0.0.1:8081`): +目录数据来自短剧服务的客户端接口(`FruitServer` 的 `fruitshorts-app-api`,默认 `http://127.0.0.1:8081`): - `GET /app/home/feed`、`GET /app/discover/feed`:轮播 + 分区,一次请求渲染整页。 每张卡片带 `preview`(首个可播免费集),首页竖屏播放可以直接起播; diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 6b90a62..bd2525e 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - Nontonki + FruitShorts CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -15,7 +15,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - Nontonki + FruitShorts CFBundlePackageType APPL CFBundleShortVersionString diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index e9b4cfe..ef8e20c 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1,6 +1,6 @@ { "@@locale": "en", - "appName": "Nontonki", + "appName": "FruitShorts", "demo": "DEMO", "homeHeadline": "Watch now", "homeSubtitle": "Free short drama preview.", @@ -131,8 +131,8 @@ "genreDramaMystery": "Drama · Mystery", "continueWatchingHeading": "CONTINUE WATCHING", "preferencesHeading": "PREFERENCES", - "brandMark": "NONTONKI · DEMO", - "shareFooter": "Nontonki demo", + "brandMark": "FRUITSHORTS", + "shareFooter": "FruitShorts", "shortsTab": "Shorts", "myListTab": "My List", "watchFull": "Watch Full", diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb new file mode 100644 index 0000000..788b6e7 --- /dev/null +++ b/lib/l10n/app_id.arb @@ -0,0 +1,184 @@ +{ + "@@locale": "id", + "appName": "FruitShorts", + "demo": "Demo", + "homeHeadline": "Tonton sekarang", + "homeSubtitle": "Pratinjau drama pendek gratis.", + "mediaNotice": "Video demo lokal dari pengguna · Pratinjau gratis", + "featuredDemo": "UNGGULAN · DEMO TEKNIS", + "demoTitle": "Sinyal", + "demoSynopsis": "Pratinjau video lokal singkat. Episode lain bisa ditambahkan saat medianya tersedia.", + "homeTab": "Beranda", + "openQuickMenu": "Buka menu cepat", + "quickAccess": "Akses cepat", + "currentSeries": "Serial saat ini", + "discoverTab": "Jelajahi", + "searchDiscover": "Cari drama, aktor, genre...", + "featured": "Unggulan", + "suspense": "Thriller", + "romance": "Romantis", + "actionGenre": "Aksi", + "filter": "Filter", + "topCharts": "Peringkat Teratas", + "newReleases": "Rilisan Baru", + "trendingMicroDramas": "Drama Mini Populer", + "seeAll": "Lihat Semua", + "artworkOnly": "Gambar", + "artworkOnlyNotice": "Ini hanya gambar katalog. Videonya belum tersedia.", + "videoPending": "Video belum siap", + "watchNow": "Tonton gratis", + "noSearchResults": "Tidak ada drama yang cocok.", + "demoCatalogNotice": "Tiga drama demo memakai video lokal yang sama.", + "myTab": "Saya", + "localViewer": "Penonton Lokal", + "localDemoProfile": "Profil demo lokal", + "continueWatching": "Lanjut Tonton", + "watchedPercent": "Sudah ditonton {percent}%", + "@watchedPercent": {"placeholders": {"percent": {"type": "int"}}}, + "resume": "Lanjutkan", + "history": "Riwayat", + "watchlist": "Daftar Tonton", + "likedTab": "Disukai", + "all": "Semua", + "inProgress": "Sedang Berjalan", + "completed": "Selesai", + "noSavedShows": "Belum ada tontonan di sini.", + "preferences": "Preferensi", + "appLanguage": "Bahasa Aplikasi", + "followingTab": "Mengikuti", + "animatedTab": "Animasi", + "recommendedTab": "Rekomendasi", + "noCategoryDramas": "Belum ada drama di kategori ini.", + "trendingTab": "Sedang Tren", + "liveActionTab": "Live Action", + "search": "Cari", + "free": "Gratis", + "mute": "Bisukan", + "unmute": "Nyalakan suara", + "like": "Suka", + "save": "Simpan", + "comments": "Komentar", + "share": "Bagikan", + "localOnlyComments": "Hanya terlihat di perangkat ini", + "noComments": "Belum ada komentar.", + "writeComment": "Tulis komentar", + "postComment": "Kirim", + "shareFailed": "Tidak bisa membuka menu berbagi.", + "nowPlaying": "Sedang diputar", + "watchFullscreen": "Tonton mode lanskap", + "exitFullscreen": "Keluar dari layar penuh", + "pictureInPicture": "Gambar dalam gambar", + "pipUnavailable": "Gambar dalam gambar tidak tersedia di perangkat ini", + "originalTag": "Original", + "dramaTag": "Drama pendek", + "episodeLabel": "Episode {number}", + "@episodeLabel": {"placeholders": {"number": {"type": "int"}}}, + "exploreSeries": "Lihat serial", + "episodeCount": "{count} EPISODE", + "@episodeCount": {"placeholders": {"count": {"type": "int"}}}, + "technicalDemoCount": "PRATINJAU GRATIS · {count} EPISODE", + "@technicalDemoCount": {"placeholders": {"count": {"type": "int"}}}, + "episodes": "Episode", + "watchEpisodeOne": "Tonton episode 1", + "continueEpisode": "Lanjut episode {number}", + "@continueEpisode": {"placeholders": {"number": {"type": "int"}}}, + "freeTestMedia": "Klip demo sama · gratis", + "lockedStoreUnavailable": "Terkunci · toko belum tersedia", + "freeTestClip": "Klip uji gratis", + "locked": "Terkunci", + "freeSamplesNotice": "Dua sampel gratis · pengaturan toko belum selesai", + "demoTestMedia": "GRATIS · KLIP DEMO SAMA", + "episodeProgress": "EPISODE {number} / {total}", + "@episodeProgress": {"placeholders": {"number": {"type": "int"}, "total": {"type": "int"}}}, + "testVideoNotice": "Video uji teknis buatan sendiri", + "lockedTitle": "Episode {number} terkunci", + "@lockedTitle": {"placeholders": {"number": {"type": "int"}}}, + "lockedBody": "Pembukaan kunci tersedia setelah toko dan verifikasi disiapkan. Demo ini tidak memproses pembayaran.", + "playbackError": "Klip ini tidak bisa diputar.", + "catalogError": "Katalog gagal dimuat.", + "detailError": "Daftar episode gagal dimuat.", + "noMediaNotice": "Episode ini belum punya media yang bisa diputar.", + "noStories": "Belum ada cerita.", + "retry": "Coba lagi", + "backToSeries": "Kembali ke serial", + "nextEpisode": "Episode berikutnya", + "pause": "Jeda", + "play": "Putar", + "seekVideo": "Geser posisi video", + "seekFailed": "Gagal mengubah posisi putar.", + "captions": "Subtitle", + "captionsOff": "Subtitle nonaktif", + "englishCaptions": "Subtitle bahasa Inggris", + "chineseCaptions": "Subtitle bahasa Mandarin", + "language": "Bahasa", + "systemLanguage": "Sistem", + "english": "English", + "simplifiedChinese": "简体中文", + "episodeOneTitle": "Cahaya Pertama", + "episodeTwoTitle": "Frekuensi Baru", + "episodeThreeTitle": "Menyeberang", + "episodeFourTitle": "Setelah Gema", + "dramaSignalTitle": "Sinyal", + "dramaSignalSynopsis": "Serial demo untuk tontonan vertikal. Setiap episode memakai satu klip lokal yang sama.", + "dramaCityTitle": "Cahaya Kota & Malam Beludru", + "dramaCitySynopsis": "Serial romansa demo. Video lokal yang sama dipakai untuk mencoba pindah episode dan lanjut tonton.", + "dramaVengeanceTitle": "Badai Pembalasan", + "dramaVengeanceSynopsis": "Serial aksi demo. Video lokal yang sama dipakai untuk mencoba pindah episode dan lanjut tonton.", + "dramaEchoesTitle": "Gema Takdir", + "genreSuspenseMystery": "Thriller · Misteri", + "genreUrbanRomance": "Romansa Kota", + "genreActionThriller": "Aksi · Thriller", + "genreDramaMystery": "Drama · Misteri", + "continueWatchingHeading": "LANJUT TONTON", + "preferencesHeading": "PREFERENSI", + "brandMark": "FRUITSHORTS", + "shareFooter": "FruitShorts", + "shortsTab": "Drama Pendek", + "myListTab": "Daftar Saya", + "watchFull": "Tonton Penuh", + "swipeForNext": "Geser ke atas untuk lanjut", + "clearScreen": "Bersihkan layar", + "exitClearScreen": "Keluar dari mode bersih", + "logIn": "Masuk", + "logInHint": "Simpan koin dan daftar kamu", + "rewards": "Hadiah", + "forYou": "Untuk Kamu", + "hot": "Populer", + "newest": "Terbaru", + "favorite": "Favorit", + "myAccount": "Akun saya", + "coins": "Koin", + "topUpWallet": "Isi Ulang Dompet", + "vipMembership": "Keanggotaan VIP", + "notActive": "Tidak Aktif", + "joinVip": "Gabung VIP", + "earnRewards": "Dapatkan Hadiah", + "freeBonus": "Bonus Gratis", + "watchHistory": "Riwayat Tontonan", + "settings": "Pengaturan", + "signOut": "Keluar", + "mockUserName": "Vicky sheng", + "mockUserId": "ID: M1CZWVYE", + "mockNotice": "Hanya data contoh.", + "topBadge": "TOP 1", + "signIn": "Masuk", + "signUp": "Daftar", + "authSignInTitle": "Selamat datang kembali", + "authSignUpTitle": "Buat akun kamu", + "authSubtitle": "Masuk dengan email dan kata sandi.", + "authEmailLabel": "Email", + "authPasswordLabel": "Kata sandi", + "authPasswordHint": "Minimal 8 karakter, berisi huruf dan angka", + "authEmailRequired": "Masukkan email kamu", + "authEmailInvalid": "Email itu sepertinya tidak benar", + "authPasswordRequired": "Masukkan kata sandi kamu", + "authPasswordLength": "Kata sandi harus 8-64 karakter", + "authPasswordWeak": "Kata sandi perlu huruf dan angka", + "authNetworkError": "Jaringan bermasalah, coba lagi", + "authSwitchToSignUp": "Baru di sini? Buat akun", + "authSwitchToSignIn": "Sudah punya akun? Masuk", + "authGateTitle": "Masuk untuk melanjutkan", + "authGateMessage": "Favorit dan komentar perlu akun.", + "authGateAction": "Masuk", + "cancel": "Nanti saja" +} diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 3b0ce7e..fcc3d0e 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -6,6 +6,7 @@ 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 @@ -95,13 +96,14 @@ abstract class AppLocalizations { /// A list of this localizations delegate's supported locales. static const List supportedLocales = [ Locale('en'), + Locale('id'), Locale('zh'), ]; /// No description provided for @appName. /// /// In en, this message translates to: - /// **'Nontonki'** + /// **'FruitShorts'** String get appName; /// No description provided for @demo. @@ -845,13 +847,13 @@ abstract class AppLocalizations { /// No description provided for @brandMark. /// /// In en, this message translates to: - /// **'NONTONKI · DEMO'** + /// **'FRUITSHORTS'** String get brandMark; /// No description provided for @shareFooter. /// /// In en, this message translates to: - /// **'Nontonki demo'** + /// **'FruitShorts'** String get shareFooter; /// No description provided for @shortsTab. @@ -1154,7 +1156,7 @@ class _AppLocalizationsDelegate @override bool isSupported(Locale locale) => - ['en', 'zh'].contains(locale.languageCode); + ['en', 'id', 'zh'].contains(locale.languageCode); @override bool shouldReload(_AppLocalizationsDelegate old) => false; @@ -1165,6 +1167,8 @@ AppLocalizations lookupAppLocalizations(Locale locale) { switch (locale.languageCode) { case 'en': return AppLocalizationsEn(); + case 'id': + return AppLocalizationsId(); case 'zh': return AppLocalizationsZh(); } diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 8b0d272..dbc4e6a 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -9,7 +9,7 @@ class AppLocalizationsEn extends AppLocalizations { AppLocalizationsEn([String locale = 'en']) : super(locale); @override - String get appName => 'Nontonki'; + String get appName => 'FruitShorts'; @override String get demo => 'DEMO'; @@ -403,10 +403,10 @@ class AppLocalizationsEn extends AppLocalizations { String get preferencesHeading => 'PREFERENCES'; @override - String get brandMark => 'NONTONKI · DEMO'; + String get brandMark => 'FRUITSHORTS'; @override - String get shareFooter => 'Nontonki demo'; + String get shareFooter => 'FruitShorts'; @override String get shortsTab => 'Shorts'; diff --git a/lib/l10n/app_localizations_id.dart b/lib/l10n/app_localizations_id.dart new file mode 100644 index 0000000..ebcf54d --- /dev/null +++ b/lib/l10n/app_localizations_id.dart @@ -0,0 +1,556 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for Indonesian (`id`). +class AppLocalizationsId extends AppLocalizations { + AppLocalizationsId([String locale = 'id']) : super(locale); + + @override + String get appName => 'FruitShorts'; + + @override + String get demo => 'Demo'; + + @override + String get homeHeadline => 'Tonton sekarang'; + + @override + String get homeSubtitle => 'Pratinjau drama pendek gratis.'; + + @override + String get mediaNotice => 'Video demo lokal dari pengguna · Pratinjau gratis'; + + @override + String get featuredDemo => 'UNGGULAN · DEMO TEKNIS'; + + @override + String get demoTitle => 'Sinyal'; + + @override + String get demoSynopsis => + 'Pratinjau video lokal singkat. Episode lain bisa ditambahkan saat medianya tersedia.'; + + @override + String get homeTab => 'Beranda'; + + @override + String get openQuickMenu => 'Buka menu cepat'; + + @override + String get quickAccess => 'Akses cepat'; + + @override + String get currentSeries => 'Serial saat ini'; + + @override + String get discoverTab => 'Jelajahi'; + + @override + String get searchDiscover => 'Cari drama, aktor, genre...'; + + @override + String get featured => 'Unggulan'; + + @override + String get suspense => 'Thriller'; + + @override + String get romance => 'Romantis'; + + @override + String get actionGenre => 'Aksi'; + + @override + String get filter => 'Filter'; + + @override + String get topCharts => 'Peringkat Teratas'; + + @override + String get newReleases => 'Rilisan Baru'; + + @override + String get trendingMicroDramas => 'Drama Mini Populer'; + + @override + String get seeAll => 'Lihat Semua'; + + @override + String get artworkOnly => 'Gambar'; + + @override + String get artworkOnlyNotice => + 'Ini hanya gambar katalog. Videonya belum tersedia.'; + + @override + String get videoPending => 'Video belum siap'; + + @override + String get watchNow => 'Tonton gratis'; + + @override + String get noSearchResults => 'Tidak ada drama yang cocok.'; + + @override + String get demoCatalogNotice => + 'Tiga drama demo memakai video lokal yang sama.'; + + @override + String get myTab => 'Saya'; + + @override + String get localViewer => 'Penonton Lokal'; + + @override + String get localDemoProfile => 'Profil demo lokal'; + + @override + String get continueWatching => 'Lanjut Tonton'; + + @override + String watchedPercent(int percent) { + return 'Sudah ditonton $percent%'; + } + + @override + String get resume => 'Lanjutkan'; + + @override + String get history => 'Riwayat'; + + @override + String get watchlist => 'Daftar Tonton'; + + @override + String get likedTab => 'Disukai'; + + @override + String get all => 'Semua'; + + @override + String get inProgress => 'Sedang Berjalan'; + + @override + String get completed => 'Selesai'; + + @override + String get noSavedShows => 'Belum ada tontonan di sini.'; + + @override + String get preferences => 'Preferensi'; + + @override + String get appLanguage => 'Bahasa Aplikasi'; + + @override + String get followingTab => 'Mengikuti'; + + @override + String get animatedTab => 'Animasi'; + + @override + String get recommendedTab => 'Rekomendasi'; + + @override + String get noCategoryDramas => 'Belum ada drama di kategori ini.'; + + @override + String get trendingTab => 'Sedang Tren'; + + @override + String get liveActionTab => 'Live Action'; + + @override + String get search => 'Cari'; + + @override + String get free => 'Gratis'; + + @override + String get mute => 'Bisukan'; + + @override + String get unmute => 'Nyalakan suara'; + + @override + String get like => 'Suka'; + + @override + String get save => 'Simpan'; + + @override + String get comments => 'Komentar'; + + @override + String get share => 'Bagikan'; + + @override + String get localOnlyComments => 'Hanya terlihat di perangkat ini'; + + @override + String get noComments => 'Belum ada komentar.'; + + @override + String get writeComment => 'Tulis komentar'; + + @override + String get postComment => 'Kirim'; + + @override + String get shareFailed => 'Tidak bisa membuka menu berbagi.'; + + @override + String get nowPlaying => 'Sedang diputar'; + + @override + String get watchFullscreen => 'Tonton mode lanskap'; + + @override + String get exitFullscreen => 'Keluar dari layar penuh'; + + @override + String get pictureInPicture => 'Gambar dalam gambar'; + + @override + String get pipUnavailable => + 'Gambar dalam gambar tidak tersedia di perangkat ini'; + + @override + String get originalTag => 'Original'; + + @override + String get dramaTag => 'Drama pendek'; + + @override + String episodeLabel(int number) { + return 'Episode $number'; + } + + @override + String get exploreSeries => 'Lihat serial'; + + @override + String episodeCount(int count) { + return '$count EPISODE'; + } + + @override + String technicalDemoCount(int count) { + return 'PRATINJAU GRATIS · $count EPISODE'; + } + + @override + String get episodes => 'Episode'; + + @override + String get watchEpisodeOne => 'Tonton episode 1'; + + @override + String continueEpisode(int number) { + return 'Lanjut episode $number'; + } + + @override + String get freeTestMedia => 'Klip demo sama · gratis'; + + @override + String get lockedStoreUnavailable => 'Terkunci · toko belum tersedia'; + + @override + String get freeTestClip => 'Klip uji gratis'; + + @override + String get locked => 'Terkunci'; + + @override + String get freeSamplesNotice => + 'Dua sampel gratis · pengaturan toko belum selesai'; + + @override + String get demoTestMedia => 'GRATIS · KLIP DEMO SAMA'; + + @override + String episodeProgress(int number, int total) { + return 'EPISODE $number / $total'; + } + + @override + String get testVideoNotice => 'Video uji teknis buatan sendiri'; + + @override + String lockedTitle(int number) { + return 'Episode $number terkunci'; + } + + @override + String get lockedBody => + 'Pembukaan kunci tersedia setelah toko dan verifikasi disiapkan. Demo ini tidak memproses pembayaran.'; + + @override + String get playbackError => 'Klip ini tidak bisa diputar.'; + + @override + String get catalogError => 'Katalog gagal dimuat.'; + + @override + String get detailError => 'Daftar episode gagal dimuat.'; + + @override + String get noMediaNotice => + 'Episode ini belum punya media yang bisa diputar.'; + + @override + String get noStories => 'Belum ada cerita.'; + + @override + String get retry => 'Coba lagi'; + + @override + String get backToSeries => 'Kembali ke serial'; + + @override + String get nextEpisode => 'Episode berikutnya'; + + @override + String get pause => 'Jeda'; + + @override + String get play => 'Putar'; + + @override + String get seekVideo => 'Geser posisi video'; + + @override + String get seekFailed => 'Gagal mengubah posisi putar.'; + + @override + String get captions => 'Subtitle'; + + @override + String get captionsOff => 'Subtitle nonaktif'; + + @override + String get englishCaptions => 'Subtitle bahasa Inggris'; + + @override + String get chineseCaptions => 'Subtitle bahasa Mandarin'; + + @override + String get language => 'Bahasa'; + + @override + String get systemLanguage => 'Sistem'; + + @override + String get english => 'English'; + + @override + String get simplifiedChinese => '简体中文'; + + @override + String get episodeOneTitle => 'Cahaya Pertama'; + + @override + String get episodeTwoTitle => 'Frekuensi Baru'; + + @override + String get episodeThreeTitle => 'Menyeberang'; + + @override + String get episodeFourTitle => 'Setelah Gema'; + + @override + String get dramaSignalTitle => 'Sinyal'; + + @override + String get dramaSignalSynopsis => + 'Serial demo untuk tontonan vertikal. Setiap episode memakai satu klip lokal yang sama.'; + + @override + String get dramaCityTitle => 'Cahaya Kota & Malam Beludru'; + + @override + String get dramaCitySynopsis => + 'Serial romansa demo. Video lokal yang sama dipakai untuk mencoba pindah episode dan lanjut tonton.'; + + @override + String get dramaVengeanceTitle => 'Badai Pembalasan'; + + @override + String get dramaVengeanceSynopsis => + 'Serial aksi demo. Video lokal yang sama dipakai untuk mencoba pindah episode dan lanjut tonton.'; + + @override + String get dramaEchoesTitle => 'Gema Takdir'; + + @override + String get genreSuspenseMystery => 'Thriller · Misteri'; + + @override + String get genreUrbanRomance => 'Romansa Kota'; + + @override + String get genreActionThriller => 'Aksi · Thriller'; + + @override + String get genreDramaMystery => 'Drama · Misteri'; + + @override + String get continueWatchingHeading => 'LANJUT TONTON'; + + @override + String get preferencesHeading => 'PREFERENSI'; + + @override + String get brandMark => 'FRUITSHORTS'; + + @override + String get shareFooter => 'FruitShorts'; + + @override + String get shortsTab => 'Drama Pendek'; + + @override + String get myListTab => 'Daftar Saya'; + + @override + String get watchFull => 'Tonton Penuh'; + + @override + String get swipeForNext => 'Geser ke atas untuk lanjut'; + + @override + String get clearScreen => 'Bersihkan layar'; + + @override + String get exitClearScreen => 'Keluar dari mode bersih'; + + @override + String get logIn => 'Masuk'; + + @override + String get logInHint => 'Simpan koin dan daftar kamu'; + + @override + String get rewards => 'Hadiah'; + + @override + String get forYou => 'Untuk Kamu'; + + @override + String get hot => 'Populer'; + + @override + String get newest => 'Terbaru'; + + @override + String get favorite => 'Favorit'; + + @override + String get myAccount => 'Akun saya'; + + @override + String get coins => 'Koin'; + + @override + String get topUpWallet => 'Isi Ulang Dompet'; + + @override + String get vipMembership => 'Keanggotaan VIP'; + + @override + String get notActive => 'Tidak Aktif'; + + @override + String get joinVip => 'Gabung VIP'; + + @override + String get earnRewards => 'Dapatkan Hadiah'; + + @override + String get freeBonus => 'Bonus Gratis'; + + @override + String get watchHistory => 'Riwayat Tontonan'; + + @override + String get settings => 'Pengaturan'; + + @override + String get signOut => 'Keluar'; + + @override + String get mockUserName => 'Vicky sheng'; + + @override + String get mockUserId => 'ID: M1CZWVYE'; + + @override + String get mockNotice => 'Hanya data contoh.'; + + @override + String get topBadge => 'TOP 1'; + + @override + String get signIn => 'Masuk'; + + @override + String get signUp => 'Daftar'; + + @override + String get authSignInTitle => 'Selamat datang kembali'; + + @override + String get authSignUpTitle => 'Buat akun kamu'; + + @override + String get authSubtitle => 'Masuk dengan email dan kata sandi.'; + + @override + String get authEmailLabel => 'Email'; + + @override + String get authPasswordLabel => 'Kata sandi'; + + @override + String get authPasswordHint => 'Minimal 8 karakter, berisi huruf dan angka'; + + @override + String get authEmailRequired => 'Masukkan email kamu'; + + @override + String get authEmailInvalid => 'Email itu sepertinya tidak benar'; + + @override + String get authPasswordRequired => 'Masukkan kata sandi kamu'; + + @override + String get authPasswordLength => 'Kata sandi harus 8-64 karakter'; + + @override + String get authPasswordWeak => 'Kata sandi perlu huruf dan angka'; + + @override + String get authNetworkError => 'Jaringan bermasalah, coba lagi'; + + @override + String get authSwitchToSignUp => 'Baru di sini? Buat akun'; + + @override + String get authSwitchToSignIn => 'Sudah punya akun? Masuk'; + + @override + String get authGateTitle => 'Masuk untuk melanjutkan'; + + @override + String get authGateMessage => 'Favorit dan komentar perlu akun.'; + + @override + String get authGateAction => 'Masuk'; + + @override + String get cancel => 'Nanti saja'; +} diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index cc8b39c..91dddb8 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -9,7 +9,7 @@ class AppLocalizationsZh extends AppLocalizations { AppLocalizationsZh([String locale = 'zh']) : super(locale); @override - String get appName => 'Nontonki'; + String get appName => 'FruitShorts'; @override String get demo => '演示'; @@ -395,10 +395,10 @@ class AppLocalizationsZh extends AppLocalizations { String get preferencesHeading => '偏好设置'; @override - String get brandMark => 'NONTONKI · 演示'; + String get brandMark => 'FRUITSHORTS'; @override - String get shareFooter => 'Nontonki 演示'; + String get shareFooter => 'FruitShorts'; @override String get shortsTab => '短剧'; diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index fc54650..6ab8562 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -1,6 +1,6 @@ { "@@locale": "zh", - "appName": "Nontonki", + "appName": "FruitShorts", "demo": "演示", "homeHeadline": "即刻观看", "homeSubtitle": "免费短剧预览。", @@ -126,8 +126,8 @@ "genreDramaMystery": "剧情 · 悬疑", "continueWatchingHeading": "继续观看", "preferencesHeading": "偏好设置", - "brandMark": "NONTONKI · 演示", - "shareFooter": "Nontonki 演示", + "brandMark": "FRUITSHORTS", + "shareFooter": "FruitShorts", "shortsTab": "短剧", "myListTab": "片单", "watchFull": "看全集", diff --git a/lib/pages/auth/auth_view.dart b/lib/pages/auth/auth_view.dart index 7fc1bbf..49dcc70 100644 --- a/lib/pages/auth/auth_view.dart +++ b/lib/pages/auth/auth_view.dart @@ -9,7 +9,7 @@ import 'auth_logic.dart'; /// 登录 / 注册页:邮箱 + 密码。 /// -/// 风格沿用 `nontonki` 现有页面(深色卡片 + 圆角 + 主色蓝),不另起一套视觉。 +/// 风格沿用 FruitShorts 现有页面(深色卡片 + 圆角 + 主色蓝),不另起一套视觉。 class AuthPage extends StatefulWidget { const AuthPage({super.key, this.signUpMode = false}); diff --git a/pubspec.yaml b/pubspec.yaml index 6fedbac..7f4fd45 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ -name: nontonki -description: "Nontonki short-drama playback prototype." +name: fruitshorts +description: "FruitShorts short-drama playback app (Indonesia first)." # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev @@ -103,7 +103,7 @@ flutter: flutter_launcher_icons: android: true ios: true - image_path: assets/icon/nontonki.png + image_path: assets/icon/fruitshorts.png adaptive_icon_background: "#D74A7D" - adaptive_icon_foreground: assets/icon/nontonki.png + adaptive_icon_foreground: assets/icon/fruitshorts.png remove_alpha_ios: true diff --git a/test/auth/auth_controller_test.dart b/test/auth/auth_controller_test.dart index 6ff0c25..cbefd61 100644 --- a/test/auth/auth_controller_test.dart +++ b/test/auth/auth_controller_test.dart @@ -4,11 +4,10 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; -// 包名此刻仍是 nontonki,1-3 改名时会一并替换成 fruitshorts -import 'package:nontonki/core/data/remote/api_client.dart'; -import 'package:nontonki/core/data/remote/auth_api.dart'; -import 'package:nontonki/core/data/services/auth_controller.dart'; -import 'package:nontonki/core/data/services/auth_session_store.dart'; +import 'package:fruitshorts/core/data/remote/api_client.dart'; +import 'package:fruitshorts/core/data/remote/auth_api.dart'; +import 'package:fruitshorts/core/data/services/auth_controller.dart'; +import 'package:fruitshorts/core/data/services/auth_session_store.dart'; import '../support/fake_http_adapter.dart'; diff --git a/test/auth/auth_page_test.dart b/test/auth/auth_page_test.dart index 1ea91c9..61f3aa9 100644 --- a/test/auth/auth_page_test.dart +++ b/test/auth/auth_page_test.dart @@ -4,12 +4,12 @@ import 'package:provider/provider.dart'; import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; -import 'package:nontonki/core/data/remote/auth_api.dart'; -import 'package:nontonki/core/data/remote/api_client.dart'; -import 'package:nontonki/core/data/services/auth_controller.dart'; -import 'package:nontonki/core/data/services/auth_session_store.dart'; -import 'package:nontonki/l10n/app_localizations.dart'; -import 'package:nontonki/pages/auth/auth_view.dart'; +import 'package:fruitshorts/core/data/remote/auth_api.dart'; +import 'package:fruitshorts/core/data/remote/api_client.dart'; +import 'package:fruitshorts/core/data/services/auth_controller.dart'; +import 'package:fruitshorts/core/data/services/auth_session_store.dart'; +import 'package:fruitshorts/l10n/app_localizations.dart'; +import 'package:fruitshorts/pages/auth/auth_view.dart'; import '../support/fake_http_adapter.dart'; diff --git a/test/catalog/catalog_controller_test.dart b/test/catalog/catalog_controller_test.dart index 1b97d6d..471e64c 100644 --- a/test/catalog/catalog_controller_test.dart +++ b/test/catalog/catalog_controller_test.dart @@ -1,9 +1,9 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/models/drama.dart'; -import 'package:nontonki/core/data/models/home_feed.dart'; -import 'package:nontonki/core/data/models/play_ticket.dart'; -import 'package:nontonki/core/data/repositories/catalog_repository.dart'; -import 'package:nontonki/core/data/services/catalog_controller.dart'; +import 'package:fruitshorts/core/data/models/drama.dart'; +import 'package:fruitshorts/core/data/models/home_feed.dart'; +import 'package:fruitshorts/core/data/models/play_ticket.dart'; +import 'package:fruitshorts/core/data/repositories/catalog_repository.dart'; +import 'package:fruitshorts/core/data/services/catalog_controller.dart'; void main() { test('should_distinguish_empty_catalog_from_load_failure_when_retry_succeeds', () async { diff --git a/test/catalog/drama_model_test.dart b/test/catalog/drama_model_test.dart index c3a3653..7b715cb 100644 --- a/test/catalog/drama_model_test.dart +++ b/test/catalog/drama_model_test.dart @@ -1,5 +1,5 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/models/drama.dart'; +import 'package:fruitshorts/core/data/models/drama.dart'; void main() { test('should_carry_one_preview_and_total_count_when_list_card_is_parsed', () { diff --git a/test/config/l10n_id_test.dart b/test/config/l10n_id_test.dart new file mode 100644 index 0000000..c04c29c --- /dev/null +++ b/test/config/l10n_id_test.dart @@ -0,0 +1,48 @@ +// Author: fruit.com.cn + +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:fruitshorts/l10n/app_localizations.dart'; + +/// id-ID 文案接入的可读证据:设备语言是 `id` 时真的拿到印尼语、`id` 在支持列表里、 +/// 并且品牌文案里不再有 demo 标记。 +void main() { + test('should_return_indonesian_copy_when_locale_is_id', () async { + final l10n = await AppLocalizations.delegate.load(const Locale('id')); + + expect(l10n.homeTab, 'Beranda'); + expect(l10n.watchNow, 'Tonton gratis'); + expect(l10n.watchlist, 'Daftar Tonton'); + expect(l10n.coins, 'Koin'); + expect(l10n.signIn, 'Masuk'); + }); + + test('should_include_id_when_supported_locales_are_read', () { + final codes = AppLocalizations.supportedLocales + .map((locale) => locale.languageCode) + .toList(); + + expect(codes, containsAll(['en', 'zh', 'id'])); + }); + + test('should_drop_demo_marker_when_brand_copy_is_loaded', () async { + for (final locale in const [Locale('en'), Locale('zh'), Locale('id')]) { + final l10n = await AppLocalizations.delegate.load(locale); + + expect(l10n.appName, 'FruitShorts', reason: '$locale appName'); + expect(l10n.brandMark, 'FRUITSHORTS', reason: '$locale brandMark'); + expect(l10n.shareFooter, 'FruitShorts', reason: '$locale shareFooter'); + expect(l10n.brandMark.toLowerCase(), isNot(contains('demo'))); + expect(l10n.shareFooter.toLowerCase(), isNot(contains('demo'))); + } + }); + + test('should_keep_placeholders_when_indonesian_copy_renders', () async { + final l10n = await AppLocalizations.delegate.load(const Locale('id')); + + expect(l10n.episodeLabel(3), contains('3')); + expect(l10n.episodeProgress(2, 10), contains('2')); + expect(l10n.episodeProgress(2, 10), contains('10')); + }); +} diff --git a/test/config/locale_controller_test.dart b/test/config/locale_controller_test.dart index b43afaa..cd32c01 100644 --- a/test/config/locale_controller_test.dart +++ b/test/config/locale_controller_test.dart @@ -1,6 +1,6 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/config/locale_controller.dart'; +import 'package:fruitshorts/core/config/locale_controller.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; diff --git a/test/core/android_picture_in_picture_test.dart b/test/core/android_picture_in_picture_test.dart index a2520f3..4dd72a0 100644 --- a/test/core/android_picture_in_picture_test.dart +++ b/test/core/android_picture_in_picture_test.dart @@ -1,7 +1,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/services/android_picture_in_picture.dart'; +import 'package:fruitshorts/core/data/services/android_picture_in_picture.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); diff --git a/test/core/api_client_test.dart b/test/core/api_client_test.dart index 903e231..2b69055 100644 --- a/test/core/api_client_test.dart +++ b/test/core/api_client_test.dart @@ -4,7 +4,7 @@ import 'dart:convert'; import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/remote/api_client.dart'; +import 'package:fruitshorts/core/data/remote/api_client.dart'; import '../support/fake_http_adapter.dart'; diff --git a/test/discover/cover_carousel_test.dart b/test/discover/cover_carousel_test.dart index 2f52609..7d298d2 100644 --- a/test/discover/cover_carousel_test.dart +++ b/test/discover/cover_carousel_test.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/pages/discover/widgets/cover_carousel.dart'; +import 'package:fruitshorts/pages/discover/widgets/cover_carousel.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); diff --git a/test/discover/discover_logic_test.dart b/test/discover/discover_logic_test.dart index cc89799..30daae7 100644 --- a/test/discover/discover_logic_test.dart +++ b/test/discover/discover_logic_test.dart @@ -2,9 +2,9 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/models/drama.dart'; -import 'package:nontonki/l10n/app_localizations.dart'; -import 'package:nontonki/pages/discover/discover_logic.dart'; +import 'package:fruitshorts/core/data/models/drama.dart'; +import 'package:fruitshorts/l10n/app_localizations.dart'; +import 'package:fruitshorts/pages/discover/discover_logic.dart'; import '../support/fake_watch_history.dart'; diff --git a/test/drama_detail/drama_detail_logic_test.dart b/test/drama_detail/drama_detail_logic_test.dart index a2a25c3..248fe9a 100644 --- a/test/drama_detail/drama_detail_logic_test.dart +++ b/test/drama_detail/drama_detail_logic_test.dart @@ -1,7 +1,7 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/models/drama.dart'; -import 'package:nontonki/core/data/remote/api_client.dart'; -import 'package:nontonki/pages/drama_detail/drama_detail_logic.dart'; +import 'package:fruitshorts/core/data/models/drama.dart'; +import 'package:fruitshorts/core/data/remote/api_client.dart'; +import 'package:fruitshorts/pages/drama_detail/drama_detail_logic.dart'; import '../support/fake_watch_history.dart'; diff --git a/test/engagement/engagement_controller_test.dart b/test/engagement/engagement_controller_test.dart index 1e6a9fe..0bba97c 100644 --- a/test/engagement/engagement_controller_test.dart +++ b/test/engagement/engagement_controller_test.dart @@ -1,6 +1,6 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/services/engagement_controller.dart'; -import 'package:nontonki/core/data/repositories/engagement_repository.dart'; +import 'package:fruitshorts/core/data/services/engagement_controller.dart'; +import 'package:fruitshorts/core/data/repositories/engagement_repository.dart'; import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; diff --git a/test/engagement/engagement_repository_test.dart b/test/engagement/engagement_repository_test.dart index 5f6f8c3..c877051 100644 --- a/test/engagement/engagement_repository_test.dart +++ b/test/engagement/engagement_repository_test.dart @@ -1,8 +1,8 @@ import 'dart:convert'; import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/models/engagement_snapshot.dart'; -import 'package:nontonki/core/data/repositories/engagement_repository.dart'; +import 'package:fruitshorts/core/data/models/engagement_snapshot.dart'; +import 'package:fruitshorts/core/data/repositories/engagement_repository.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; diff --git a/test/formatting/localized_content_test.dart b/test/formatting/localized_content_test.dart index e097924..5f05e78 100644 --- a/test/formatting/localized_content_test.dart +++ b/test/formatting/localized_content_test.dart @@ -1,8 +1,8 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/models/drama.dart'; -import 'package:nontonki/core/formatting/localized_content.dart'; -import 'package:nontonki/l10n/app_localizations_en.dart'; -import 'package:nontonki/l10n/app_localizations_zh.dart'; +import 'package:fruitshorts/core/data/models/drama.dart'; +import 'package:fruitshorts/core/formatting/localized_content.dart'; +import 'package:fruitshorts/l10n/app_localizations_en.dart'; +import 'package:fruitshorts/l10n/app_localizations_zh.dart'; Drama _drama({required String id, String title = 'raw', String synopsis = 'raw'}) => Drama( diff --git a/test/home/home_logic_test.dart b/test/home/home_logic_test.dart index 4ac5323..7ba720b 100644 --- a/test/home/home_logic_test.dart +++ b/test/home/home_logic_test.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/models/drama.dart'; -import 'package:nontonki/pages/discover/discover_logic.dart'; -import 'package:nontonki/pages/home/home_logic.dart'; -import 'package:nontonki/pages/mine/mine_logic.dart'; +import 'package:fruitshorts/core/data/models/drama.dart'; +import 'package:fruitshorts/pages/discover/discover_logic.dart'; +import 'package:fruitshorts/pages/home/home_logic.dart'; +import 'package:fruitshorts/pages/mine/mine_logic.dart'; Drama _drama(String id) => Drama( id: id, diff --git a/test/integration/live_auth_test.dart b/test/integration/live_auth_test.dart index 21e0ed7..9fbf452 100644 --- a/test/integration/live_auth_test.dart +++ b/test/integration/live_auth_test.dart @@ -2,8 +2,8 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/remote/api_client.dart'; -import 'package:nontonki/core/data/remote/auth_api.dart'; +import 'package:fruitshorts/core/data/remote/api_client.dart'; +import 'package:fruitshorts/core/data/remote/auth_api.dart'; /// 联调测试:直连本机客户端接口服务(8081)验证 **POST + JSON body + 错误码映射**。 /// diff --git a/test/integration/live_catalog_test.dart b/test/integration/live_catalog_test.dart index 0b79238..0d17476 100644 --- a/test/integration/live_catalog_test.dart +++ b/test/integration/live_catalog_test.dart @@ -1,6 +1,6 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/remote/api_client.dart'; -import 'package:nontonki/core/data/remote/catalog_api.dart'; +import 'package:fruitshorts/core/data/remote/api_client.dart'; +import 'package:fruitshorts/core/data/remote/catalog_api.dart'; /// 联调测试:直连本机客户端接口服务(8081)。 /// 服务没启动时自动跳过,不影响日常 `flutter test`。 diff --git a/test/mine/mine_logic_test.dart b/test/mine/mine_logic_test.dart index 9fb07c8..1bd1f1b 100644 --- a/test/mine/mine_logic_test.dart +++ b/test/mine/mine_logic_test.dart @@ -2,10 +2,10 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/config/locale_controller.dart'; -import 'package:nontonki/core/data/models/drama.dart'; -import 'package:nontonki/l10n/app_localizations.dart'; -import 'package:nontonki/pages/mine/mine_logic.dart'; +import 'package:fruitshorts/core/config/locale_controller.dart'; +import 'package:fruitshorts/core/data/models/drama.dart'; +import 'package:fruitshorts/l10n/app_localizations.dart'; +import 'package:fruitshorts/pages/mine/mine_logic.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; diff --git a/test/playback/playback_preload_test.dart b/test/playback/playback_preload_test.dart index a4f09a8..5b90f72 100644 --- a/test/playback/playback_preload_test.dart +++ b/test/playback/playback_preload_test.dart @@ -1,9 +1,9 @@ import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/models/drama.dart'; -import 'package:nontonki/core/data/services/playback_session.dart'; -import 'package:nontonki/core/data/models/player_port.dart'; +import 'package:fruitshorts/core/data/models/drama.dart'; +import 'package:fruitshorts/core/data/services/playback_session.dart'; +import 'package:fruitshorts/core/data/models/player_port.dart'; void main() { final episodes = List.generate( diff --git a/test/playback/playback_queue_test.dart b/test/playback/playback_queue_test.dart index 1117367..e0fb953 100644 --- a/test/playback/playback_queue_test.dart +++ b/test/playback/playback_queue_test.dart @@ -1,6 +1,6 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/models/drama.dart'; -import 'package:nontonki/core/data/services/playback_queue.dart'; +import 'package:fruitshorts/core/data/models/drama.dart'; +import 'package:fruitshorts/core/data/services/playback_queue.dart'; void main() { test('should_advance_between_dramas_on_home_and_between_episodes_in_series_when_queue_is_built', () { diff --git a/test/playback/playback_session_test.dart b/test/playback/playback_session_test.dart index de700d1..ca292ad 100644 --- a/test/playback/playback_session_test.dart +++ b/test/playback/playback_session_test.dart @@ -1,9 +1,9 @@ import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/models/drama.dart'; -import 'package:nontonki/core/data/services/playback_session.dart'; -import 'package:nontonki/core/data/models/player_port.dart'; +import 'package:fruitshorts/core/data/models/drama.dart'; +import 'package:fruitshorts/core/data/services/playback_session.dart'; +import 'package:fruitshorts/core/data/models/player_port.dart'; void main() { final episodes = List.generate( diff --git a/test/playback/seek_progress_bar_test.dart b/test/playback/seek_progress_bar_test.dart index 137e7db..b2262dc 100644 --- a/test/playback/seek_progress_bar_test.dart +++ b/test/playback/seek_progress_bar_test.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/pages/player/widgets/seek_progress_bar.dart'; +import 'package:fruitshorts/pages/player/widgets/seek_progress_bar.dart'; import 'package:video_player/video_player.dart'; void main() { diff --git a/test/playback/video_player_port_test.dart b/test/playback/video_player_port_test.dart index 5a35138..d40a7f3 100644 --- a/test/playback/video_player_port_test.dart +++ b/test/playback/video_player_port_test.dart @@ -1,7 +1,7 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/config/app_config.dart'; -import 'package:nontonki/core/data/models/drama.dart'; -import 'package:nontonki/core/data/services/video_player_port.dart'; +import 'package:fruitshorts/core/config/app_config.dart'; +import 'package:fruitshorts/core/data/models/drama.dart'; +import 'package:fruitshorts/core/data/services/video_player_port.dart'; Episode _episode(String videoUrl) => Episode( id: '1', diff --git a/test/playback/watch_history_test.dart b/test/playback/watch_history_test.dart index d814deb..bc12aaa 100644 --- a/test/playback/watch_history_test.dart +++ b/test/playback/watch_history_test.dart @@ -1,6 +1,6 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/models/drama.dart'; -import 'package:nontonki/core/data/repositories/watch_history_repository.dart'; +import 'package:fruitshorts/core/data/models/drama.dart'; +import 'package:fruitshorts/core/data/repositories/watch_history_repository.dart'; import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; diff --git a/test/player/player_logic_test.dart b/test/player/player_logic_test.dart index 6a71cbe..1ed2607 100644 --- a/test/player/player_logic_test.dart +++ b/test/player/player_logic_test.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/core/data/models/drama.dart'; -import 'package:nontonki/core/data/models/player_port.dart'; -import 'package:nontonki/core/data/services/android_picture_in_picture.dart'; -import 'package:nontonki/core/data/services/playback_session.dart'; -import 'package:nontonki/pages/player/player_logic.dart'; -import 'package:nontonki/pages/player/player_view.dart'; +import 'package:fruitshorts/core/data/models/drama.dart'; +import 'package:fruitshorts/core/data/models/player_port.dart'; +import 'package:fruitshorts/core/data/services/android_picture_in_picture.dart'; +import 'package:fruitshorts/core/data/services/playback_session.dart'; +import 'package:fruitshorts/pages/player/player_logic.dart'; +import 'package:fruitshorts/pages/player/player_view.dart'; import '../support/fake_watch_history.dart'; diff --git a/test/support/fake_catalog.dart b/test/support/fake_catalog.dart index 393315f..3bfe1d6 100644 --- a/test/support/fake_catalog.dart +++ b/test/support/fake_catalog.dart @@ -1,7 +1,7 @@ -import 'package:nontonki/core/data/models/drama.dart'; -import 'package:nontonki/core/data/models/home_feed.dart'; -import 'package:nontonki/core/data/models/play_ticket.dart'; -import 'package:nontonki/core/data/repositories/catalog_repository.dart'; +import 'package:fruitshorts/core/data/models/drama.dart'; +import 'package:fruitshorts/core/data/models/home_feed.dart'; +import 'package:fruitshorts/core/data/models/play_ticket.dart'; +import 'package:fruitshorts/core/data/repositories/catalog_repository.dart'; /// 测试用目录数据:三部分区里的短剧,标题与后端演示数据保持一致。 class FakeCatalogRepository implements CatalogRepository { diff --git a/test/support/fake_watch_history.dart b/test/support/fake_watch_history.dart index 57f6ad4..9b4d8b1 100644 --- a/test/support/fake_watch_history.dart +++ b/test/support/fake_watch_history.dart @@ -1,4 +1,4 @@ -import 'package:nontonki/core/data/repositories/watch_history_repository.dart'; +import 'package:fruitshorts/core/data/repositories/watch_history_repository.dart'; /// Records every history interaction so tests can assert on the key it used. class FakeWatchHistory implements WatchHistoryRepository { diff --git a/test/support/widget_player.dart b/test/support/widget_player.dart index 6e2ad1d..2d3d81c 100644 --- a/test/support/widget_player.dart +++ b/test/support/widget_player.dart @@ -1,5 +1,5 @@ -import 'package:nontonki/core/data/models/drama.dart'; -import 'package:nontonki/core/data/models/player_port.dart'; +import 'package:fruitshorts/core/data/models/drama.dart'; +import 'package:fruitshorts/core/data/models/player_port.dart'; // Widget tests exercise navigation and scheduling without a native decoder. PlayerPort createWidgetPlayer(Episode episode) => WidgetPlayer(); diff --git a/test/widget_test.dart b/test/widget_test.dart index 28f02e2..9bdae0b 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:nontonki/app.dart'; -import 'package:nontonki/pages/player/player_view.dart'; +import 'package:fruitshorts/app.dart'; +import 'package:fruitshorts/pages/player/player_view.dart'; import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart';