feat(settings): 添加通知偏好设置和后端 API 集成

This commit is contained in:
qzl
2026-04-07 18:43:42 +08:00
parent b18a205bf3
commit b22673ce49
9 changed files with 612 additions and 29 deletions
@@ -36,6 +36,38 @@ class ProfileApi {
return _toSettings(data);
}
Future<ProfileSettingsV1> updateSettings(ProfileSettingsV1 settings) async {
final payload = <String, dynamic>{
'settings': {
'version': settings.version,
'preferences': {
'interface_language': settings.preferences.interfaceLanguage,
'ai_language': settings.preferences.aiLanguage,
'timezone': settings.preferences.timezone,
'country': settings.preferences.country,
},
'privacy': settings.privacy,
'notification': {
'allow_notifications': settings.notification.allowNotifications,
'allow_vibration': settings.notification.allowVibration,
},
},
};
final json = await _apiClient.rawDio.patch<Map<String, dynamic>>(
'/api/v1/users/me/settings',
data: payload,
);
final data = json.data;
if (data is! Map<String, dynamic>) {
throw ApiProblem(
status: 502,
title: 'Invalid settings payload',
detail: 'Expected settings response object',
);
}
return _toSettings(data);
}
Future<ProfileSettingsV1> uploadAvatar(String filePath) async {
final formData = FormData.fromMap({
'file': await MultipartFile.fromFile(filePath),
@@ -71,6 +103,18 @@ class ProfileApi {
)
: const PreferenceSettings();
final notificationRaw = settingsRaw is Map<String, dynamic>
? settingsRaw['notification']
: null;
final notification = notificationRaw is Map<String, dynamic>
? NotificationSettings(
allowNotifications:
(notificationRaw['allow_notifications'] as bool? ?? true),
allowVibration:
(notificationRaw['allow_vibration'] as bool? ?? true),
)
: const NotificationSettings();
return ProfileSettingsV1(
displayName: (json['display_name'] as String?) ?? '',
bio: (json['bio'] as String?) ?? '',
@@ -81,10 +125,7 @@ class ProfileApi {
? (settingsRaw['privacy'] as Map<String, dynamic>? ??
const <String, dynamic>{})
: const <String, dynamic>{},
notification: settingsRaw is Map<String, dynamic>
? (settingsRaw['notification'] as Map<String, dynamic>? ??
const <String, dynamic>{})
: const <String, dynamic>{},
notification: notification,
);
}
}
@@ -37,6 +37,26 @@ class PreferenceSettings {
}
}
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,
);
}
}
class ProfileSettingsV1 {
const ProfileSettingsV1({
this.version = 1,
@@ -46,7 +66,7 @@ class ProfileSettingsV1 {
this.avatarUrl,
this.preferences = const PreferenceSettings(),
this.privacy = const <String, Object?>{},
this.notification = const <String, Object?>{},
this.notification = const NotificationSettings(),
});
final int version;
@@ -56,7 +76,7 @@ class ProfileSettingsV1 {
final String? avatarUrl;
final PreferenceSettings preferences;
final Map<String, Object?> privacy;
final Map<String, Object?> notification;
final NotificationSettings notification;
ProfileSettingsV1 copyWith({
int? version,
@@ -66,7 +86,7 @@ class ProfileSettingsV1 {
String? avatarUrl,
PreferenceSettings? preferences,
Map<String, Object?>? privacy,
Map<String, Object?>? notification,
NotificationSettings? notification,
}) {
return ProfileSettingsV1(
version: version ?? this.version,