feat(notification): 通知标题和正文支持多语言
- 通知静态配置支持 title/body i18n - 前端通知列表和详情页展示本地化内容 - 新增数据库迁移脚本 - 更新通知协议文档
This commit is contained in:
@@ -15,6 +15,7 @@ class NotificationState {
|
||||
this.unreadCount = 0,
|
||||
this.hasMore = false,
|
||||
this.nextCursor,
|
||||
this.isLoadingMore = false,
|
||||
this.errorMessage,
|
||||
});
|
||||
|
||||
@@ -23,6 +24,7 @@ class NotificationState {
|
||||
final int unreadCount;
|
||||
final bool hasMore;
|
||||
final String? nextCursor;
|
||||
final bool isLoadingMore;
|
||||
final String? errorMessage;
|
||||
|
||||
NotificationState copyWith({
|
||||
@@ -31,6 +33,7 @@ class NotificationState {
|
||||
int? unreadCount,
|
||||
bool? hasMore,
|
||||
String? nextCursor,
|
||||
bool? isLoadingMore,
|
||||
String? errorMessage,
|
||||
}) {
|
||||
return NotificationState(
|
||||
@@ -39,6 +42,7 @@ class NotificationState {
|
||||
unreadCount: unreadCount ?? this.unreadCount,
|
||||
hasMore: hasMore ?? this.hasMore,
|
||||
nextCursor: nextCursor ?? this.nextCursor,
|
||||
isLoadingMore: isLoadingMore ?? this.isLoadingMore,
|
||||
errorMessage: errorMessage ?? this.errorMessage,
|
||||
);
|
||||
}
|
||||
@@ -81,10 +85,13 @@ final class NotificationRevokedEvent extends NotificationEvent {
|
||||
}
|
||||
|
||||
class NotificationBloc extends ChangeNotifier {
|
||||
NotificationBloc({required NotificationRepository repository})
|
||||
: _repository = repository;
|
||||
NotificationBloc({
|
||||
required NotificationRepository repository,
|
||||
this.locale = 'zh',
|
||||
}) : _repository = repository;
|
||||
|
||||
final NotificationRepository _repository;
|
||||
final String locale;
|
||||
final Logger _logger = getLogger('features.notifications.bloc');
|
||||
NotificationState _state = const NotificationState();
|
||||
|
||||
@@ -119,7 +126,10 @@ class NotificationBloc extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final result = await _repository.listNotifications(limit: 20);
|
||||
final result = await _repository.listNotifications(
|
||||
limit: 20,
|
||||
locale: locale,
|
||||
);
|
||||
_state = _state.copyWith(
|
||||
status: NotificationStatus.loaded,
|
||||
items: result.items,
|
||||
@@ -143,7 +153,10 @@ class NotificationBloc extends ChangeNotifier {
|
||||
|
||||
Future<void> _refreshNotifications() async {
|
||||
try {
|
||||
final result = await _repository.listNotifications(limit: 20);
|
||||
final result = await _repository.listNotifications(
|
||||
limit: 20,
|
||||
locale: locale,
|
||||
);
|
||||
_state = _state.copyWith(
|
||||
status: NotificationStatus.loaded,
|
||||
items: result.items,
|
||||
@@ -161,18 +174,25 @@ class NotificationBloc extends ChangeNotifier {
|
||||
}
|
||||
|
||||
Future<void> _loadMore() async {
|
||||
if (!_state.hasMore || _state.nextCursor == null) return;
|
||||
if (_state.isLoadingMore || !_state.hasMore || _state.nextCursor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
_state = _state.copyWith(isLoadingMore: true);
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final result = await _repository.listNotifications(
|
||||
limit: 20,
|
||||
cursor: _state.nextCursor,
|
||||
locale: locale,
|
||||
);
|
||||
final allItems = [..._state.items, ...result.items];
|
||||
_state = _state.copyWith(
|
||||
items: allItems,
|
||||
hasMore: result.hasMore,
|
||||
nextCursor: result.nextCursor,
|
||||
isLoadingMore: false,
|
||||
);
|
||||
notifyListeners();
|
||||
} catch (error, stackTrace) {
|
||||
@@ -181,6 +201,8 @@ class NotificationBloc extends ChangeNotifier {
|
||||
error: error,
|
||||
stackTrace: stackTrace,
|
||||
);
|
||||
_state = _state.copyWith(isLoadingMore: false);
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,6 +219,7 @@ class NotificationBloc extends ChangeNotifier {
|
||||
try {
|
||||
final updated = await _repository.markRead(
|
||||
notificationId: notificationId,
|
||||
locale: locale,
|
||||
);
|
||||
final targetIndex = _state.items.indexWhere(
|
||||
(item) => item.id == updated.id,
|
||||
|
||||
Reference in New Issue
Block a user