feat: integrate invite API and improve notification handling

- Add invite code display and binding functionality via API
- Fix notification unread count sync on auth state change
- Improve notification mark read with server state validation
- Add auth state listener to trigger notification refresh
- Add YaoCoinConverter for coin-to-yao type conversion
- Remove YaoLegend from divination screens (UI cleanup)
- Abbreviate relation labels in yao detail view
- Add re-register notice to account delete screen
- Update 'coins' terminology to 'points' in localization
- Fix backend points consumption to only run in CHAT mode
- Add HttpxAuthNoiseFilter to suppress auth endpoint logging
- Fix notification static_schema import path
- Add test coverage for notification bloc error handling
- Update AGENTS.md page header rules and image handling
- Delete deprecated run-dev.sh script
This commit is contained in:
qzl
2026-04-13 14:52:22 +08:00
parent da947f9f08
commit 1e22f27de2
52 changed files with 1419 additions and 307 deletions
@@ -3,6 +3,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import '../../../../core/auth/session_store.dart';
import '../../../../data/network/api_client.dart';
import '../../../divination/presentation/screens/divination_screen.dart';
import '../../../divination/presentation/screens/divination_result_screen.dart';
import '../../../divination/data/apis/divination_api.dart';
@@ -11,8 +12,11 @@ import '../../../divination/data/models/divination_result.dart';
import '../../../notifications/data/repositories/notification_repository.dart';
import '../../../notifications/presentation/bloc/notification_bloc.dart';
import '../../../notifications/presentation/screens/notification_center_screen.dart';
import '../../../settings/data/apis/invite_api.dart';
import '../../../settings/data/models/profile_settings.dart';
import '../../../settings/data/repositories/invite_repository.dart';
import '../../../settings/presentation/screens/settings_screen.dart';
import '../../../../app/di/injection.dart';
import '../../../../l10n/app_localizations.dart';
import '../../../../shared/theme/app_color_palette.dart';
import '../../../../shared/theme/design_tokens.dart';
@@ -68,10 +72,18 @@ class HomeScreen extends StatefulWidget {
class _HomeScreenState extends State<HomeScreen> {
MainTab _currentTab = MainTab.home;
late final InviteRepository _inviteRepository;
@override
void initState() {
super.initState();
final inviteApi = InviteApi(
apiClient: ApiClient(
baseUrl: appDependencies.backendUrl,
tokenProvider: widget.sessionStore.getToken,
),
);
_inviteRepository = InviteRepositoryImpl(inviteApi: inviteApi);
WidgetsBinding.instance.addPostFrameCallback((_) {
_tryShowWelcomeDialog();
});
@@ -120,6 +132,7 @@ class _HomeScreenState extends State<HomeScreen> {
account: widget.account,
settings: widget.profileSettings,
coinBalance: widget.coinBalance,
inviteRepository: _inviteRepository,
onLocaleChanged: widget.onLocaleChanged,
onSettingsChanged: widget.onProfileSettingsChanged,
onSaveProfile: widget.onSaveProfile,
@@ -209,6 +222,11 @@ class _HomeTab extends StatelessWidget {
MaterialPageRoute<void>(
builder: (_) => NotificationCenterScreen(
repository: notificationRepository,
onUnreadCountChanged: () {
return notificationBloc.handleEvent(
RefreshUnreadCount(),
);
},
),
),
);
@@ -532,6 +550,7 @@ class _ProfileTab extends StatelessWidget {
required this.account,
required this.settings,
required this.coinBalance,
required this.inviteRepository,
required this.onLocaleChanged,
required this.onSettingsChanged,
required this.onSaveProfile,
@@ -543,6 +562,7 @@ class _ProfileTab extends StatelessWidget {
final String account;
final ProfileSettingsV1 settings;
final int coinBalance;
final InviteRepository inviteRepository;
final Future<void> Function(String languageTag) onLocaleChanged;
final Future<void> Function(ProfileSettingsV1 settings) onSettingsChanged;
final Future<ProfileSettingsV1> Function(ProfileSettingsV1 updated)
@@ -557,6 +577,7 @@ class _ProfileTab extends StatelessWidget {
account: account,
settings: settings,
coinBalance: coinBalance,
inviteRepository: inviteRepository,
onInterfaceLanguageChanged: onLocaleChanged,
onSettingsChanged: onSettingsChanged,
onSaveProfile: onSaveProfile,