2026-04-03 16:56:47 +08:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
|
|
|
|
import '../../../../l10n/app_localizations.dart';
|
|
|
|
|
|
|
|
|
|
String displayLanguageLabel(AppLocalizations l10n, String languageTag) {
|
|
|
|
|
return switch (languageTag) {
|
|
|
|
|
'en-US' => l10n.english,
|
2026-04-13 16:14:28 +08:00
|
|
|
'zh-Hant' => '繁體中文',
|
|
|
|
|
'zh-CN' => '简体中文',
|
|
|
|
|
_ => '简体中文',
|
2026-04-03 16:56:47 +08:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class PreferenceSettings {
|
|
|
|
|
const PreferenceSettings({
|
|
|
|
|
this.interfaceLanguage = 'zh-CN',
|
|
|
|
|
this.aiLanguage = 'zh-CN',
|
|
|
|
|
this.timezone = 'Asia/Shanghai',
|
|
|
|
|
this.country = 'CN',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
final String interfaceLanguage;
|
|
|
|
|
final String aiLanguage;
|
|
|
|
|
final String timezone;
|
|
|
|
|
final String country;
|
|
|
|
|
|
|
|
|
|
PreferenceSettings copyWith({
|
|
|
|
|
String? interfaceLanguage,
|
|
|
|
|
String? aiLanguage,
|
|
|
|
|
String? timezone,
|
|
|
|
|
String? country,
|
|
|
|
|
}) {
|
|
|
|
|
return PreferenceSettings(
|
|
|
|
|
interfaceLanguage: interfaceLanguage ?? this.interfaceLanguage,
|
|
|
|
|
aiLanguage: aiLanguage ?? this.aiLanguage,
|
|
|
|
|
timezone: timezone ?? this.timezone,
|
|
|
|
|
country: country ?? this.country,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 18:43:42 +08:00
|
|
|
class NotificationSettings {
|
|
|
|
|
const NotificationSettings({
|
|
|
|
|
this.allowNotifications = true,
|
|
|
|
|
this.allowVibration = true,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
final bool allowNotifications;
|
|
|
|
|
final bool allowVibration;
|
|
|
|
|
|
|
|
|
|
NotificationSettings copyWith({
|
|
|
|
|
bool? allowNotifications,
|
|
|
|
|
bool? allowVibration,
|
|
|
|
|
}) {
|
|
|
|
|
return NotificationSettings(
|
|
|
|
|
allowNotifications: allowNotifications ?? this.allowNotifications,
|
|
|
|
|
allowVibration: allowVibration ?? this.allowVibration,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-03 16:56:47 +08:00
|
|
|
class ProfileSettingsV1 {
|
|
|
|
|
const ProfileSettingsV1({
|
|
|
|
|
this.version = 1,
|
2026-04-06 01:28:10 +08:00
|
|
|
this.displayName = '',
|
|
|
|
|
this.bio = '',
|
|
|
|
|
this.avatarPath,
|
|
|
|
|
this.avatarUrl,
|
2026-04-03 16:56:47 +08:00
|
|
|
this.preferences = const PreferenceSettings(),
|
|
|
|
|
this.privacy = const <String, Object?>{},
|
2026-04-07 18:43:42 +08:00
|
|
|
this.notification = const NotificationSettings(),
|
2026-04-03 16:56:47 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
final int version;
|
2026-04-06 01:28:10 +08:00
|
|
|
final String displayName;
|
|
|
|
|
final String bio;
|
|
|
|
|
final String? avatarPath;
|
|
|
|
|
final String? avatarUrl;
|
2026-04-03 16:56:47 +08:00
|
|
|
final PreferenceSettings preferences;
|
|
|
|
|
final Map<String, Object?> privacy;
|
2026-04-07 18:43:42 +08:00
|
|
|
final NotificationSettings notification;
|
2026-04-03 16:56:47 +08:00
|
|
|
|
|
|
|
|
ProfileSettingsV1 copyWith({
|
|
|
|
|
int? version,
|
2026-04-06 01:28:10 +08:00
|
|
|
String? displayName,
|
|
|
|
|
String? bio,
|
|
|
|
|
String? avatarPath,
|
|
|
|
|
String? avatarUrl,
|
2026-04-03 16:56:47 +08:00
|
|
|
PreferenceSettings? preferences,
|
|
|
|
|
Map<String, Object?>? privacy,
|
2026-04-07 18:43:42 +08:00
|
|
|
NotificationSettings? notification,
|
2026-04-03 16:56:47 +08:00
|
|
|
}) {
|
|
|
|
|
return ProfileSettingsV1(
|
|
|
|
|
version: version ?? this.version,
|
2026-04-06 01:28:10 +08:00
|
|
|
displayName: displayName ?? this.displayName,
|
|
|
|
|
bio: bio ?? this.bio,
|
|
|
|
|
avatarPath: avatarPath ?? this.avatarPath,
|
|
|
|
|
avatarUrl: avatarUrl ?? this.avatarUrl,
|
2026-04-03 16:56:47 +08:00
|
|
|
preferences: preferences ?? this.preferences,
|
|
|
|
|
privacy: privacy ?? this.privacy,
|
|
|
|
|
notification: notification ?? this.notification,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
factory ProfileSettingsV1.defaultsForLocale(Locale locale) {
|
|
|
|
|
final tag = languageTagFromLocale(locale);
|
|
|
|
|
return ProfileSettingsV1(
|
|
|
|
|
preferences: PreferenceSettings(interfaceLanguage: tag, aiLanguage: tag),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String languageTagFromLocale(Locale locale) {
|
|
|
|
|
switch (locale.languageCode) {
|
|
|
|
|
case 'en':
|
|
|
|
|
return 'en-US';
|
|
|
|
|
case 'zh':
|
2026-04-13 16:14:28 +08:00
|
|
|
if (locale.scriptCode == 'Hant') {
|
|
|
|
|
return 'zh-Hant';
|
|
|
|
|
}
|
|
|
|
|
return 'zh-CN';
|
2026-04-03 16:56:47 +08:00
|
|
|
default:
|
|
|
|
|
return 'zh-CN';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Locale localeFromLanguageTag(String tag) {
|
|
|
|
|
if (tag.toLowerCase().startsWith('en')) {
|
|
|
|
|
return const Locale('en');
|
|
|
|
|
}
|
2026-04-13 16:14:28 +08:00
|
|
|
if (tag == 'zh-Hant') {
|
|
|
|
|
return const Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant');
|
|
|
|
|
}
|
2026-04-03 16:56:47 +08:00
|
|
|
return const Locale('zh');
|
|
|
|
|
}
|