732 lines
32 KiB
Dart
732 lines
32 KiB
Dart
import 'dart:convert';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
|
|
class AppLocalizations {
|
|
final Locale locale;
|
|
late Map<String, dynamic> _localizedStrings;
|
|
|
|
AppLocalizations(this.locale);
|
|
|
|
static AppLocalizations of(BuildContext context) {
|
|
return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
|
|
}
|
|
|
|
// JSON 파일에서 번역 데이터 로드
|
|
Future<void> load() async {
|
|
String jsonString = await rootBundle.loadString('assets/data/text.json');
|
|
Map<String, dynamic> jsonMap = json.decode(jsonString);
|
|
_localizedStrings = jsonMap[locale.languageCode];
|
|
}
|
|
|
|
String get appTitle => _localizedStrings['appTitle'] ?? 'SubManager';
|
|
String get appSubtitle =>
|
|
_localizedStrings['appSubtitle'] ?? 'Manage subscriptions easily';
|
|
String get subscriptionManagement =>
|
|
_localizedStrings['subscriptionManagement'] ?? 'Subscription Management';
|
|
String get addSubscription =>
|
|
_localizedStrings['addSubscription'] ?? 'Add Subscription';
|
|
String get subscriptionName =>
|
|
_localizedStrings['subscriptionName'] ?? 'Service Name';
|
|
String get monthlyCost => _localizedStrings['monthlyCost'] ?? 'Monthly Cost';
|
|
String get billingCycle =>
|
|
_localizedStrings['billingCycle'] ?? 'Billing Cycle';
|
|
String get nextBillingDate =>
|
|
_localizedStrings['nextBillingDate'] ?? 'Next Billing Date';
|
|
String get save => _localizedStrings['save'] ?? 'Save';
|
|
String get cancel => _localizedStrings['cancel'] ?? 'Cancel';
|
|
String get delete => _localizedStrings['delete'] ?? 'Delete';
|
|
String get edit => _localizedStrings['edit'] ?? 'Edit';
|
|
String get totalSubscriptions =>
|
|
_localizedStrings['totalSubscriptions'] ?? 'Total Subscriptions';
|
|
String get totalMonthlyExpense =>
|
|
_localizedStrings['totalMonthlyExpense'] ?? 'Total Monthly Expense';
|
|
String get noSubscriptions =>
|
|
_localizedStrings['noSubscriptions'] ?? 'No subscriptions registered';
|
|
String get addSubscriptionNow =>
|
|
_localizedStrings['addSubscriptionNow'] ?? 'Add Subscription Now';
|
|
String get paymentReminder =>
|
|
_localizedStrings['paymentReminder'] ?? 'Payment Reminder';
|
|
String get expirationReminder =>
|
|
_localizedStrings['expirationReminder'] ?? 'Expiration Reminder';
|
|
String get daysLeft => _localizedStrings['daysLeft'] ?? 'days left';
|
|
String get categoryManagement =>
|
|
_localizedStrings['categoryManagement'] ?? 'Category Management';
|
|
String get categoryName =>
|
|
_localizedStrings['categoryName'] ?? 'Category Name';
|
|
String get selectColor => _localizedStrings['selectColor'] ?? 'Select Color';
|
|
String get selectIcon => _localizedStrings['selectIcon'] ?? 'Select Icon';
|
|
String get addCategory => _localizedStrings['addCategory'] ?? 'Add Category';
|
|
String get settings => _localizedStrings['settings'] ?? 'Settings';
|
|
String get darkMode => _localizedStrings['darkMode'] ?? 'Dark Mode';
|
|
String get language => _localizedStrings['language'] ?? 'Language';
|
|
String get notifications =>
|
|
_localizedStrings['notifications'] ?? 'Notifications';
|
|
String get appLock => _localizedStrings['appLock'] ?? 'App Lock';
|
|
String get paymentCard => _localizedStrings['paymentCard'] ?? 'Payment Card';
|
|
String get paymentCardManagement =>
|
|
_localizedStrings['paymentCardManagement'] ?? 'Payment Card Management';
|
|
String get paymentCardManagementDescription =>
|
|
_localizedStrings['paymentCardManagementDescription'] ??
|
|
'Manage saved cards for subscriptions';
|
|
String get addPaymentCard =>
|
|
_localizedStrings['addPaymentCard'] ?? 'Add Payment Card';
|
|
String get editPaymentCard =>
|
|
_localizedStrings['editPaymentCard'] ?? 'Edit Payment Card';
|
|
String get paymentCardIssuer =>
|
|
_localizedStrings['paymentCardIssuer'] ?? 'Card Name / Issuer';
|
|
String get paymentCardLast4 =>
|
|
_localizedStrings['paymentCardLast4'] ?? 'Last 4 Digits';
|
|
String get paymentCardColor =>
|
|
_localizedStrings['paymentCardColor'] ?? 'Card Color';
|
|
String get paymentCardIcon =>
|
|
_localizedStrings['paymentCardIcon'] ?? 'Card Icon';
|
|
String get setAsDefaultCard =>
|
|
_localizedStrings['setAsDefaultCard'] ?? 'Set as default card';
|
|
String get paymentCardUnassigned =>
|
|
_localizedStrings['paymentCardUnassigned'] ?? 'Unassigned';
|
|
String get detectedPaymentCard =>
|
|
_localizedStrings['detectedPaymentCard'] ?? 'Card detected';
|
|
String detectedPaymentCardDescription(String issuer, String last4) {
|
|
final template = _localizedStrings['detectedPaymentCardDescription'] ??
|
|
'@ was detected from SMS.';
|
|
final label = last4.isNotEmpty ? '$issuer · ****$last4' : issuer;
|
|
return template.replaceAll('@', label);
|
|
}
|
|
|
|
String get addDetectedPaymentCard =>
|
|
_localizedStrings['addDetectedPaymentCard'] ?? 'Add card';
|
|
String get paymentCardUnassignedWarning =>
|
|
_localizedStrings['paymentCardUnassignedWarning'] ??
|
|
'Without a card selection this subscription will be saved as "Unassigned".';
|
|
String get addNewCard => _localizedStrings['addNewCard'] ?? 'Add New Card';
|
|
String get managePaymentCards =>
|
|
_localizedStrings['managePaymentCards'] ?? 'Manage Cards';
|
|
String get choosePaymentCard =>
|
|
_localizedStrings['choosePaymentCard'] ?? 'Choose Payment Card';
|
|
String get analysisCardFilterLabel =>
|
|
_localizedStrings['analysisCardFilterLabel'] ?? 'Filter by payment card';
|
|
String get analysisCardFilterAll =>
|
|
_localizedStrings['analysisCardFilterAll'] ?? 'All cards';
|
|
String get cardDefaultBadge =>
|
|
_localizedStrings['cardDefaultBadge'] ?? 'Default';
|
|
String get noPaymentCards =>
|
|
_localizedStrings['noPaymentCards'] ?? 'No payment cards saved yet.';
|
|
String get areYouSure => _localizedStrings['areYouSure'] ?? 'Are you sure?';
|
|
// SMS 권한 온보딩/설정
|
|
String get smsPermissionTitle =>
|
|
_localizedStrings['smsPermissionTitle'] ?? 'Request SMS Permission';
|
|
String get smsPermissionReasonTitle =>
|
|
_localizedStrings['smsPermissionReasonTitle'] ?? 'Why';
|
|
String get smsPermissionReasonBody =>
|
|
_localizedStrings['smsPermissionReasonBody'] ??
|
|
'We analyze payment-related SMS to auto-detect subscriptions. Processing happens locally only.';
|
|
String get smsPermissionScopeTitle =>
|
|
_localizedStrings['smsPermissionScopeTitle'] ?? 'Scope';
|
|
String get smsPermissionScopeBody =>
|
|
_localizedStrings['smsPermissionScopeBody'] ??
|
|
'We scan only payment-related SMS patterns (service/amount/date) locally; no data leaves your device.';
|
|
String get permanentlyDeniedMessage =>
|
|
_localizedStrings['permanentlyDeniedMessage'] ??
|
|
'Permission is permanently denied. Enable it in Settings.';
|
|
String get openSettings =>
|
|
_localizedStrings['openSettings'] ?? 'Open Settings';
|
|
String get later => _localizedStrings['later'] ?? 'Later';
|
|
String get requesting => _localizedStrings['requesting'] ?? 'Requesting...';
|
|
String get smsPermissionLabel =>
|
|
_localizedStrings['smsPermissionLabel'] ?? 'SMS Permission';
|
|
// 알림 설정
|
|
String get notificationPermission =>
|
|
_localizedStrings['notificationPermission'] ?? 'Notification Permission';
|
|
String get notificationPermissionDesc =>
|
|
_localizedStrings['notificationPermissionDesc'] ??
|
|
'Permission is required to receive notifications';
|
|
String get requestPermission =>
|
|
_localizedStrings['requestPermission'] ?? 'Request Permission';
|
|
String get paymentNotification =>
|
|
_localizedStrings['paymentNotification'] ?? 'Payment Due Notification';
|
|
String get paymentNotificationDesc =>
|
|
_localizedStrings['paymentNotificationDesc'] ??
|
|
'Receive notification on payment due date';
|
|
String get notificationTiming =>
|
|
_localizedStrings['notificationTiming'] ?? 'Notification Timing';
|
|
String get notificationTime =>
|
|
_localizedStrings['notificationTime'] ?? 'Notification Time';
|
|
String get dailyReminder =>
|
|
_localizedStrings['dailyReminder'] ?? 'Daily Reminder';
|
|
String get dailyReminderEnabled =>
|
|
_localizedStrings['dailyReminderEnabled'] ??
|
|
'Receive daily notifications until payment date';
|
|
String get dailyReminderDisabled =>
|
|
_localizedStrings['dailyReminderDisabled'] ??
|
|
'Receive notification @ day(s) before payment';
|
|
String get notificationPermissionDenied =>
|
|
_localizedStrings['notificationPermissionDenied'] ??
|
|
'Notification permission denied';
|
|
// 앱 정보
|
|
String get appInfo => _localizedStrings['appInfo'] ?? 'App Info';
|
|
String get version => _localizedStrings['version'] ?? 'Version';
|
|
String get openStore => _localizedStrings['openStore'] ?? 'Open Store';
|
|
String get appDescription =>
|
|
_localizedStrings['appDescription'] ?? 'Subscription Management App';
|
|
String get developer => _localizedStrings['developer'] ?? 'Developer';
|
|
String get cannotOpenStore =>
|
|
_localizedStrings['cannotOpenStore'] ?? 'Cannot open store';
|
|
// 테마
|
|
String get lightTheme => _localizedStrings['lightTheme'] ?? 'Light';
|
|
String get darkTheme => _localizedStrings['darkTheme'] ?? 'Dark';
|
|
String get oledTheme => _localizedStrings['oledTheme'] ?? 'OLED Black';
|
|
String get systemTheme =>
|
|
_localizedStrings['systemTheme'] ?? 'System Default';
|
|
// 기타 메시지
|
|
String get subscriptionAdded =>
|
|
_localizedStrings['subscriptionAdded'] ?? 'Subscription added';
|
|
// 언어 설정
|
|
String get korean => _localizedStrings['korean'] ?? '한국어';
|
|
String get english => _localizedStrings['english'] ?? 'English';
|
|
String get japanese => _localizedStrings['japanese'] ?? '日本語';
|
|
String get chinese => _localizedStrings['chinese'] ?? '中文';
|
|
// 날짜
|
|
String get oneDayBefore =>
|
|
_localizedStrings['oneDayBefore'] ?? '1 day before';
|
|
String get twoDaysBefore =>
|
|
_localizedStrings['twoDaysBefore'] ?? '2 days before';
|
|
String get threeDaysBefore =>
|
|
_localizedStrings['threeDaysBefore'] ?? '3 days before';
|
|
// 추가 메시지
|
|
String get requiredFieldsError =>
|
|
_localizedStrings['requiredFieldsError'] ??
|
|
'Please fill in all required fields';
|
|
String get subscriptionUpdated =>
|
|
_localizedStrings['subscriptionUpdated'] ??
|
|
'Subscription information has been updated';
|
|
String get officialCancelPageNotFound =>
|
|
_localizedStrings['officialCancelPageNotFound'] ??
|
|
'Official cancellation page not found. Redirecting to Google search.';
|
|
String get cannotOpenWebsite =>
|
|
_localizedStrings['cannotOpenWebsite'] ?? 'Cannot open website';
|
|
String get noWebsiteInfo =>
|
|
_localizedStrings['noWebsiteInfo'] ??
|
|
'No website information available. Please cancel through the website.';
|
|
String get editMode => _localizedStrings['editMode'] ?? 'Edit Mode';
|
|
String get changesAppliedAfterSave =>
|
|
_localizedStrings['changesAppliedAfterSave'] ??
|
|
'Changes will be applied after saving';
|
|
String get saveChanges => _localizedStrings['saveChanges'] ?? 'Save Changes';
|
|
String get monthlyExpense =>
|
|
_localizedStrings['monthlyExpense'] ?? 'Monthly Expense';
|
|
String get websiteUrl => _localizedStrings['websiteUrl'] ?? 'Website URL';
|
|
String get websiteUrlOptional =>
|
|
_localizedStrings['websiteUrlOptional'] ?? 'Website URL (Optional)';
|
|
String get eventPrice => _localizedStrings['eventPrice'] ?? 'Event Price';
|
|
String get eventPriceHint =>
|
|
_localizedStrings['eventPriceHint'] ?? 'Enter discounted price';
|
|
String get eventPriceRequired =>
|
|
_localizedStrings['eventPriceRequired'] ?? 'Please enter event price';
|
|
String get invalidPrice =>
|
|
_localizedStrings['invalidPrice'] ?? 'Please enter a valid price';
|
|
String get smsScanLabel => _localizedStrings['smsScanLabel'] ?? 'SMS';
|
|
String get home => _localizedStrings['home'] ?? 'Home';
|
|
String get analysis => _localizedStrings['analysis'] ?? 'Analysis';
|
|
String get back => _localizedStrings['back'] ?? 'Back';
|
|
String get exitApp => _localizedStrings['exitApp'] ?? 'Exit App';
|
|
String get exitAppConfirm =>
|
|
_localizedStrings['exitAppConfirm'] ??
|
|
'Are you sure you want to exit SubManager?';
|
|
String get exit => _localizedStrings['exit'] ?? 'Exit';
|
|
String get pageNotFound =>
|
|
_localizedStrings['pageNotFound'] ?? 'Page not found';
|
|
String get serviceNameExample =>
|
|
_localizedStrings['serviceNameExample'] ?? 'e.g. Netflix, Spotify';
|
|
String get urlExample =>
|
|
_localizedStrings['urlExample'] ?? 'https://example.com';
|
|
String get appLockDesc =>
|
|
_localizedStrings['appLockDesc'] ??
|
|
'App lock with biometric authentication';
|
|
String get unlockWithBiometric =>
|
|
_localizedStrings['unlockWithBiometric'] ??
|
|
'Unlock with biometric authentication';
|
|
String get authenticationFailed =>
|
|
_localizedStrings['authenticationFailed'] ??
|
|
'Authentication failed. Please try again.';
|
|
String get smsPermissionRequired =>
|
|
_localizedStrings['smsPermissionRequired'] ?? 'SMS permission required';
|
|
String get noSubscriptionSmsFound =>
|
|
_localizedStrings['noSubscriptionSmsFound'] ??
|
|
'No subscription related SMS found';
|
|
String get smsScanError =>
|
|
_localizedStrings['smsScanError'] ?? 'Error occurred during SMS scan';
|
|
String get saveError =>
|
|
_localizedStrings['saveError'] ?? 'Error occurred while saving';
|
|
String get newSubscriptionSmsNotFound =>
|
|
_localizedStrings['newSubscriptionSmsNotFound'] ??
|
|
'No new subscription SMS found';
|
|
String get subscriptionAddError =>
|
|
_localizedStrings['subscriptionAddError'] ?? 'Error adding subscription';
|
|
String get allSubscriptionsProcessed =>
|
|
_localizedStrings['allSubscriptionsProcessed'] ??
|
|
'All subscriptions have been processed.';
|
|
String get websiteUrlExtracted =>
|
|
_localizedStrings['websiteUrlExtracted'] ??
|
|
'Website URL (Auto-extracted)';
|
|
String get startDate => _localizedStrings['startDate'] ?? 'Start Date';
|
|
String get endDate => _localizedStrings['endDate'] ?? 'End Date';
|
|
|
|
// 새로 추가된 항목들
|
|
String get monthlyTotalSubscriptionCost =>
|
|
_localizedStrings['monthlyTotalSubscriptionCost'] ??
|
|
'Total Monthly Subscription Cost';
|
|
String get todaysExchangeRate =>
|
|
_localizedStrings['todaysExchangeRate'] ?? 'Today\'s Exchange Rate';
|
|
String get won => _localizedStrings['won'] ?? 'KRW';
|
|
String get estimatedAnnualCost =>
|
|
_localizedStrings['estimatedAnnualCost'] ?? 'Estimated Annual Cost';
|
|
String get totalSubscriptionServices =>
|
|
_localizedStrings['totalSubscriptionServices'] ??
|
|
'Total Subscription Services';
|
|
String get services => _localizedStrings['services'] ?? 'services';
|
|
String get eventDiscountActive =>
|
|
_localizedStrings['eventDiscountActive'] ?? 'Event Discount Active';
|
|
String get saving => _localizedStrings['saving'] ?? 'Saving';
|
|
String get paymentDueToday =>
|
|
_localizedStrings['paymentDueToday'] ?? 'Payment Due Today';
|
|
String get paymentInfoNeeded =>
|
|
_localizedStrings['paymentInfoNeeded'] ?? 'Payment Info Needed';
|
|
String get event => _localizedStrings['event'] ?? 'Event';
|
|
|
|
// 카테고리 getter들
|
|
String get categoryMusic => _localizedStrings['categoryMusic'] ?? 'Music';
|
|
String get categoryOttVideo =>
|
|
_localizedStrings['categoryOttVideo'] ?? 'OTT(Video)';
|
|
String get categoryStorageCloud =>
|
|
_localizedStrings['categoryStorageCloud'] ?? 'Storage/Cloud';
|
|
String get categoryTelecomInternetTv =>
|
|
_localizedStrings['categoryTelecomInternetTv'] ??
|
|
'Telecom · Internet · TV';
|
|
String get categoryLifestyle =>
|
|
_localizedStrings['categoryLifestyle'] ?? 'Lifestyle';
|
|
String get categoryShoppingEcommerce =>
|
|
_localizedStrings['categoryShoppingEcommerce'] ?? 'Shopping/E-commerce';
|
|
String get categoryProgramming =>
|
|
_localizedStrings['categoryProgramming'] ?? 'Programming';
|
|
String get categoryCollaborationOffice =>
|
|
_localizedStrings['categoryCollaborationOffice'] ??
|
|
'Collaboration/Office';
|
|
String get categoryAiService =>
|
|
_localizedStrings['categoryAiService'] ?? 'AI Service';
|
|
String get categoryOther => _localizedStrings['categoryOther'] ?? 'Other';
|
|
|
|
// 동적 메시지 생성 메서드
|
|
String daysBefore(int days) {
|
|
return '$days${_localizedStrings['daysBefore'] ?? 'day(s) before'}';
|
|
}
|
|
|
|
String dailyReminderDisabledWithDays(int days) {
|
|
final template = _localizedStrings['dailyReminderDisabled'] ??
|
|
'Receive notification @ day(s) before payment';
|
|
return template.replaceAll('@', days.toString());
|
|
}
|
|
|
|
String subscriptionAddedWithName(String serviceName) {
|
|
final template =
|
|
_localizedStrings['subscriptionAddedTemplate'] ?? '@ 구독이 추가되었습니다.';
|
|
return template.replaceAll('@', serviceName);
|
|
}
|
|
|
|
String subscriptionDeleted(String serviceName) {
|
|
final template = _localizedStrings['subscriptionDeleted'] ??
|
|
'@ subscription has been deleted';
|
|
return template.replaceAll('@', serviceName);
|
|
}
|
|
|
|
String totalExpenseCopied(String amount) {
|
|
final template =
|
|
_localizedStrings['totalExpenseCopied'] ?? 'Total expense copied: @';
|
|
return template.replaceAll('@', amount);
|
|
}
|
|
|
|
String serviceRecognized(String serviceName) {
|
|
final template = _localizedStrings['serviceRecognized'] ??
|
|
'@ service has been recognized automatically.';
|
|
return template.replaceAll('@', serviceName);
|
|
}
|
|
|
|
String smsScanErrorWithMessage(String error) {
|
|
final template = _localizedStrings['smsScanError'] ??
|
|
'Error occurred during SMS scan: @';
|
|
return template.replaceAll('@', error);
|
|
}
|
|
|
|
String saveErrorWithMessage(String error) {
|
|
final template =
|
|
_localizedStrings['saveError'] ?? 'Error occurred while saving: @';
|
|
return template.replaceAll('@', error);
|
|
}
|
|
|
|
String subscriptionAddErrorWithMessage(String error) {
|
|
final template = _localizedStrings['subscriptionAddError'] ??
|
|
'Error adding subscription: @';
|
|
return template.replaceAll('@', error);
|
|
}
|
|
|
|
String subscriptionSkipped(String serviceName) {
|
|
final template =
|
|
_localizedStrings['subscriptionSkipped'] ?? '@ subscription skipped.';
|
|
return template.replaceAll('@', serviceName);
|
|
}
|
|
|
|
// 홈화면 관련
|
|
String get mySubscriptions =>
|
|
_localizedStrings['mySubscriptions'] ?? 'My Subscriptions';
|
|
|
|
String subscriptionCount(int count) {
|
|
if (locale.languageCode == 'ko') {
|
|
return '$count개';
|
|
} else if (locale.languageCode == 'ja') {
|
|
return '$count個';
|
|
} else if (locale.languageCode == 'zh') {
|
|
return '$count个';
|
|
} else {
|
|
return count.toString();
|
|
}
|
|
}
|
|
|
|
// 분석화면 관련
|
|
String get monthlyExpenseTitle =>
|
|
_localizedStrings['monthlyExpenseTitle'] ?? 'Monthly Expense Status';
|
|
String get recentSixMonthsTrend =>
|
|
_localizedStrings['recentSixMonthsTrend'] ?? 'Recent 6 months trend';
|
|
String get monthlySubscriptionExpense =>
|
|
_localizedStrings['monthlySubscriptionExpense'] ??
|
|
'Monthly subscription expense';
|
|
String get subscriptionServiceRatio =>
|
|
_localizedStrings['subscriptionServiceRatio'] ??
|
|
'Subscription Service Ratio';
|
|
String get monthlyExpenseBasis =>
|
|
_localizedStrings['monthlyExpenseBasis'] ?? 'Based on monthly expense';
|
|
String get noSubscriptionServices =>
|
|
_localizedStrings['noSubscriptionServices'] ?? 'No subscription services';
|
|
String get totalExpenseSummary =>
|
|
_localizedStrings['totalExpenseSummary'] ?? 'Total Expense Summary';
|
|
String get monthlyTotalAmount =>
|
|
_localizedStrings['monthlyTotalAmount'] ?? 'Monthly Total Amount';
|
|
String get totalExpense =>
|
|
_localizedStrings['totalExpense'] ?? 'Total Expense';
|
|
String get totalServices =>
|
|
_localizedStrings['totalServices'] ?? 'Total Services';
|
|
String get servicesUnit => _localizedStrings['servicesUnit'] ?? 'services';
|
|
String get averageCost => _localizedStrings['averageCost'] ?? 'Average Cost';
|
|
String get eventDiscountStatus =>
|
|
_localizedStrings['eventDiscountStatus'] ?? 'Event Discount Status';
|
|
String get eventDiscountEndsBeforeBilling =>
|
|
_localizedStrings['eventDiscountEndsBeforeBilling'] ??
|
|
'Event discount ends before billing date';
|
|
String get inProgressUnit =>
|
|
_localizedStrings['inProgressUnit'] ?? 'in progress';
|
|
String get monthlySavingAmount =>
|
|
_localizedStrings['monthlySavingAmount'] ?? 'Monthly Saving Amount';
|
|
String get eventsInProgress =>
|
|
_localizedStrings['eventsInProgress'] ?? 'Events in Progress';
|
|
String get discountPercent =>
|
|
_localizedStrings['discountPercent'] ?? '% discount';
|
|
String get currencyWon => _localizedStrings['currencyWon'] ?? 'KRW';
|
|
|
|
// SMS 스캔 관련
|
|
String get scanningMessages =>
|
|
_localizedStrings['scanningMessages'] ?? 'Scanning SMS messages...';
|
|
String get findingSubscriptions =>
|
|
_localizedStrings['findingSubscriptions'] ??
|
|
'Finding subscription services';
|
|
String get subscriptionNotFound =>
|
|
_localizedStrings['subscriptionNotFound'] ??
|
|
'Subscription information not found.';
|
|
String get repeatSubscriptionNotFound =>
|
|
_localizedStrings['repeatSubscriptionNotFound'] ??
|
|
'No repeated subscription information found.';
|
|
String get newSubscriptionNotFound =>
|
|
_localizedStrings['newSubscriptionNotFound'] ??
|
|
'No new subscription SMS found';
|
|
String get findRepeatSubscriptions =>
|
|
_localizedStrings['findRepeatSubscriptions'] ??
|
|
'Find subscriptions paid 2+ times';
|
|
String get scanTextMessages =>
|
|
_localizedStrings['scanTextMessages'] ??
|
|
'Scan text messages to automatically find repeatedly paid subscriptions. Service names and amounts can be extracted for easy subscription addition.';
|
|
String get startScanning =>
|
|
_localizedStrings['startScanning'] ?? 'Start Scanning';
|
|
String get foundSubscription =>
|
|
_localizedStrings['foundSubscription'] ?? 'Found subscription';
|
|
String get serviceName => _localizedStrings['serviceName'] ?? 'Service Name';
|
|
String get latestSmsMessage =>
|
|
_localizedStrings['latestSmsMessage'] ?? 'Latest SMS message';
|
|
String smsDetectedDate(String date) {
|
|
final template = _localizedStrings['smsDetectedDate'] ?? 'Detected on @';
|
|
return template.replaceAll('@', date);
|
|
}
|
|
|
|
String get nextBillingDateLabel =>
|
|
_localizedStrings['nextBillingDateLabel'] ?? 'Next Billing Date';
|
|
String get category => _localizedStrings['category'] ?? 'Category';
|
|
String get websiteUrlAuto =>
|
|
_localizedStrings['websiteUrlAuto'] ?? 'Website URL (Auto-extracted)';
|
|
String get websiteUrlHint =>
|
|
_localizedStrings['websiteUrlHint'] ?? 'Edit website URL or leave empty';
|
|
String get skip => _localizedStrings['skip'] ?? 'Skip';
|
|
String get add => _localizedStrings['add'] ?? 'Add';
|
|
String get nextBillingDateRequired =>
|
|
_localizedStrings['nextBillingDateRequired'] ??
|
|
'Next billing date verification required';
|
|
|
|
String nextBillingDateEstimated(String date, int days) {
|
|
final template = _localizedStrings['nextBillingDateEstimated'] ??
|
|
'Next estimated billing date: @ (# days later)';
|
|
return template.replaceAll('@', date).replaceAll('#', days.toString());
|
|
}
|
|
|
|
String nextBillingDateInfo(String date, int days) {
|
|
final template = _localizedStrings['nextBillingDateInfo'] ??
|
|
'Next billing date: @ (# days later)';
|
|
return template.replaceAll('@', date).replaceAll('#', days.toString());
|
|
}
|
|
|
|
String get nextBillingDatePastRequired =>
|
|
_localizedStrings['nextBillingDatePastRequired'] ??
|
|
'Next billing date verification required (past date)';
|
|
|
|
String formatDate(DateTime date) {
|
|
if (locale.languageCode == 'ko') {
|
|
return '${date.year}년 ${date.month}월 ${date.day}일';
|
|
} else if (locale.languageCode == 'ja') {
|
|
return '${date.year}年${date.month}月${date.day}日';
|
|
} else if (locale.languageCode == 'zh') {
|
|
return '${date.year}年${date.month}月${date.day}日';
|
|
} else {
|
|
final months = [
|
|
'Jan',
|
|
'Feb',
|
|
'Mar',
|
|
'Apr',
|
|
'May',
|
|
'Jun',
|
|
'Jul',
|
|
'Aug',
|
|
'Sep',
|
|
'Oct',
|
|
'Nov',
|
|
'Dec'
|
|
];
|
|
return '${months[date.month - 1]} ${date.day}, ${date.year}';
|
|
}
|
|
}
|
|
|
|
String repeatCountDetected(int count) {
|
|
final template =
|
|
_localizedStrings['repeatCountDetected'] ?? '@ payment(s) detected';
|
|
return template.replaceAll('@', count.toString());
|
|
}
|
|
|
|
String servicesInProgress(int count) {
|
|
if (locale.languageCode == 'ko') {
|
|
return '$count개 진행중';
|
|
} else if (locale.languageCode == 'ja') {
|
|
return '$count個進行中';
|
|
} else if (locale.languageCode == 'zh') {
|
|
return '$count个进行中';
|
|
} else {
|
|
return '$count in progress';
|
|
}
|
|
}
|
|
|
|
// 새로 추가된 동적 메서드들
|
|
String paymentDueInDays(int days) {
|
|
final template =
|
|
_localizedStrings['paymentDueInDays'] ?? 'Payment due in @ days';
|
|
return template.replaceAll('@', days.toString());
|
|
}
|
|
|
|
String daysRemaining(int days) {
|
|
final template = _localizedStrings['daysRemaining'] ?? '@ days remaining';
|
|
return template.replaceAll('@', days.toString());
|
|
}
|
|
|
|
String exchangeRateFormat(String rate) {
|
|
final template =
|
|
_localizedStrings['exchangeRateFormat'] ?? 'Today\'s rate: @';
|
|
return template.replaceAll('@', rate);
|
|
}
|
|
|
|
// 결제 주기 결제 메시지
|
|
String get billingCyclePayment =>
|
|
_localizedStrings['billingCyclePayment'] ?? '@ Payment';
|
|
|
|
// 할인 금액 표시 getter들
|
|
String get discountAmountWon =>
|
|
_localizedStrings['discountAmountWon'] ?? 'Save ₩@';
|
|
String get discountAmountDollar =>
|
|
_localizedStrings['discountAmountDollar'] ?? 'Save \$@';
|
|
String get discountAmountYen =>
|
|
_localizedStrings['discountAmountYen'] ?? 'Save ¥@';
|
|
String get discountAmountYuan =>
|
|
_localizedStrings['discountAmountYuan'] ?? 'Save ¥@';
|
|
|
|
// 결제 주기 관련 getter
|
|
String get monthly => _localizedStrings['monthly'] ?? 'Monthly';
|
|
String get weekly => _localizedStrings['weekly'] ?? 'Weekly';
|
|
String get yearly => _localizedStrings['yearly'] ?? 'Yearly';
|
|
String get billingCycleMonthly =>
|
|
_localizedStrings['billingCycleMonthly'] ?? 'Monthly';
|
|
String get billingCycleQuarterly =>
|
|
_localizedStrings['billingCycleQuarterly'] ?? 'Quarterly';
|
|
String get billingCycleHalfYearly =>
|
|
_localizedStrings['billingCycleHalfYearly'] ?? 'Half-Yearly';
|
|
String get billingCycleYearly =>
|
|
_localizedStrings['billingCycleYearly'] ?? 'Yearly';
|
|
|
|
// 색상 관련 getter
|
|
String get colorBlue => _localizedStrings['colorBlue'] ?? 'Blue';
|
|
String get colorGreen => _localizedStrings['colorGreen'] ?? 'Green';
|
|
String get colorOrange => _localizedStrings['colorOrange'] ?? 'Orange';
|
|
String get colorRed => _localizedStrings['colorRed'] ?? 'Red';
|
|
String get colorPurple => _localizedStrings['colorPurple'] ?? 'Purple';
|
|
|
|
// 날짜 형식 관련 getter
|
|
String get dateFormatFull =>
|
|
_localizedStrings['dateFormatFull'] ?? 'MMM dd, yyyy';
|
|
String get dateFormatShort => _localizedStrings['dateFormatShort'] ?? 'MM/dd';
|
|
|
|
// USD 환율 표시 형식
|
|
String get exchangeRateDisplay =>
|
|
_localizedStrings['exchangeRateDisplay'] ?? '\$1 = @';
|
|
|
|
// 라벨 및 힌트 텍스트
|
|
String get labelServiceName =>
|
|
_localizedStrings['labelServiceName'] ?? 'Service Name';
|
|
String get hintServiceName =>
|
|
_localizedStrings['hintServiceName'] ?? 'e.g. Netflix, Spotify';
|
|
String get labelMonthlyExpense =>
|
|
_localizedStrings['labelMonthlyExpense'] ?? 'Monthly Expense';
|
|
String get labelNextBillingDate =>
|
|
_localizedStrings['labelNextBillingDate'] ?? 'Next Billing Date';
|
|
String get labelWebsiteUrl =>
|
|
_localizedStrings['labelWebsiteUrl'] ?? 'Website URL (Optional)';
|
|
String get hintWebsiteUrl =>
|
|
_localizedStrings['hintWebsiteUrl'] ?? 'https://example.com';
|
|
String get labelEventPrice =>
|
|
_localizedStrings['labelEventPrice'] ?? 'Event Price';
|
|
String get hintEventPrice =>
|
|
_localizedStrings['hintEventPrice'] ?? 'Enter discounted price';
|
|
String get labelCategory => _localizedStrings['labelCategory'] ?? 'Category';
|
|
|
|
// 기타 번역
|
|
String get subscription =>
|
|
_localizedStrings['subscription'] ?? 'Subscription';
|
|
String get movie => _localizedStrings['movie'] ?? 'Movie';
|
|
String get music => _localizedStrings['music'] ?? 'Music';
|
|
String get exercise => _localizedStrings['exercise'] ?? 'Exercise';
|
|
String get shopping => _localizedStrings['shopping'] ?? 'Shopping';
|
|
String get currency => _localizedStrings['currency'] ?? 'Currency';
|
|
String get websiteInfo =>
|
|
_localizedStrings['websiteInfo'] ?? 'Website Information';
|
|
String get cancelGuide =>
|
|
_localizedStrings['cancelGuide'] ?? 'Cancellation Guide';
|
|
String get cancelServiceGuide =>
|
|
_localizedStrings['cancelServiceGuide'] ??
|
|
'To cancel this service, please go to the cancellation page through the link below.';
|
|
String get goToCancelPage =>
|
|
_localizedStrings['goToCancelPage'] ?? 'Go to Cancellation Page';
|
|
String get urlAutoMatchInfo =>
|
|
_localizedStrings['urlAutoMatchInfo'] ??
|
|
'If URL is empty, it will be automatically matched based on the service name';
|
|
String get dateSelect => _localizedStrings['dateSelect'] ?? 'Select';
|
|
|
|
// 새로 추가된 getter들
|
|
String get serviceInfo =>
|
|
_localizedStrings['serviceInfo'] ?? 'Service Information';
|
|
String get newSubscriptionAdd =>
|
|
_localizedStrings['newSubscriptionAdd'] ?? 'Add New Subscription';
|
|
String get enterServiceInfo =>
|
|
_localizedStrings['enterServiceInfo'] ?? 'Enter service information';
|
|
String get addSubscriptionButton =>
|
|
_localizedStrings['addSubscriptionButton'] ?? 'Add Subscription';
|
|
String get serviceNameRequired =>
|
|
_localizedStrings['serviceNameRequired'] ?? 'Please enter service name';
|
|
String get amountRequired =>
|
|
_localizedStrings['amountRequired'] ?? 'Please enter amount';
|
|
String get subscriptionDetail =>
|
|
_localizedStrings['subscriptionDetail'] ?? 'Subscription Detail';
|
|
String get enterAmount => _localizedStrings['enterAmount'] ?? 'Enter amount';
|
|
String get invalidAmount =>
|
|
_localizedStrings['invalidAmount'] ?? 'Please enter a valid amount';
|
|
String get featureComingSoon =>
|
|
_localizedStrings['featureComingSoon'] ?? 'This feature is coming soon';
|
|
|
|
// 결제 주기를 키값으로 변환하여 번역된 이름 반환
|
|
String getBillingCycleName(String billingCycleKey) {
|
|
switch (billingCycleKey) {
|
|
case 'monthly':
|
|
case '월간':
|
|
case '月間':
|
|
case '月付':
|
|
return monthly;
|
|
case 'weekly':
|
|
case '주간':
|
|
case '週間':
|
|
case '周付':
|
|
return weekly;
|
|
case 'yearly':
|
|
case '연간':
|
|
case '年間':
|
|
case '年付':
|
|
return yearly;
|
|
default:
|
|
return billingCycleKey; // 매칭되지 않으면 원본 반환
|
|
}
|
|
}
|
|
|
|
// 카테고리 이름을 키로 변환하여 번역된 이름 반환
|
|
String getCategoryName(String categoryKey) {
|
|
switch (categoryKey) {
|
|
case '음악':
|
|
return categoryMusic;
|
|
case 'OTT(동영상)':
|
|
return categoryOttVideo;
|
|
case '저장/클라우드':
|
|
return categoryStorageCloud;
|
|
case '통신 · 인터넷 · TV':
|
|
return categoryTelecomInternetTv;
|
|
case '생활/라이프스타일':
|
|
return categoryLifestyle;
|
|
case '쇼핑/이커머스':
|
|
return categoryShoppingEcommerce;
|
|
case '프로그래밍':
|
|
return categoryProgramming;
|
|
case '협업/오피스':
|
|
return categoryCollaborationOffice;
|
|
case 'AI 서비스':
|
|
return categoryAiService;
|
|
case '기타':
|
|
return categoryOther;
|
|
default:
|
|
return categoryKey; // 매칭되지 않으면 원본 반환
|
|
}
|
|
}
|
|
}
|
|
|
|
class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
|
|
const AppLocalizationsDelegate();
|
|
|
|
@override
|
|
bool isSupported(Locale locale) =>
|
|
['en', 'ko', 'ja', 'zh'].contains(locale.languageCode);
|
|
|
|
@override
|
|
Future<AppLocalizations> load(Locale locale) async {
|
|
final localizations = AppLocalizations(locale);
|
|
await localizations.load();
|
|
return localizations;
|
|
}
|
|
|
|
@override
|
|
bool shouldReload(AppLocalizationsDelegate old) => false;
|
|
}
|