feat: 发布v5.3.0正式版本,完善跨平台适配与功能优化

本次更新包含多项核心改进:
1. 新增统一跨平台导航扩展,替换原有GoRouter调用,适配鸿蒙平台路由逻辑
2. 重构状态初始化逻辑,使用Future.microtask避免BuildContext异常
3. 完善Linux桌面端支持,添加桌面文件、AppData配置与WSL构建脚本
4. 修复鸿蒙平台动画渲染异常问题,移除平台特判逻辑
5. 优化NFC配对扫描参数,精简不必要的配置项
6. 更新依赖版本与项目版本号
7. 修复Drift数据库缓存问题,移除冗余的表检测逻辑
8. 添加路由观察者日志,优化鸿蒙端路由调试体验
9. 完善签到与文章发布后的用户数据刷新逻辑
10. 删除冗余的子模块与日志文件,清理项目结构
This commit is contained in:
Developer
2026-05-18 08:58:36 +08:00
parent 1bca322600
commit a60957cc0e
94 changed files with 3957 additions and 5358 deletions

View File

@@ -1,9 +1,9 @@
// ============================================================
// 闲言APP — 应用布局壳
// 创建时间: 2026-04-20
// 更新时间: 2026-05-17
// 更新时间: 2026-05-18
// 作用: ShellRoute 布局壳,包含底部 GlassBottomBar 导航 + 发现小红点
// 上次更新: 鸿蒙白屏调试 — 恢复GlassBottomBar+CupertinoTabBar鸿蒙降级方案
// 上次更新: 恢复鸿蒙端液态玻璃效果统一使用GlassBottomBar
// ============================================================
import 'package:badges/badges.dart' as badges;
@@ -17,9 +17,12 @@ import 'package:liquid_glass_widgets/liquid_glass_widgets.dart';
import '../theme/app_theme.dart';
import '../utils/interaction_animations.dart';
import '../utils/logger.dart';
import '../../features/inspiration/providers/chat_provider.dart';
import '../../features/settings/providers/theme_settings_provider.dart';
import '../../shared/widgets/tab_icon_sprite.dart';
import '../../main.dart' show liquidGlassReady;
import '../../shared/widgets/glass_bottom_nav_bar.dart';
class AppShell extends ConsumerWidget {
const AppShell({super.key, required this.child});
@@ -32,6 +35,11 @@ class AppShell extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final ext = AppTheme.ext(context);
final int currentIndex = child.currentIndex;
if (_isOhos) {
Log.i(
'🟢 [OHOS] AppShell.build() — currentIndex=$currentIndex isDark=${ext.isDark}',
);
}
final unreadCount = ref.watch(chatProvider).unreadCount;
final settings = ref.watch(themeSettingsProvider);
final expressionStyle = settings.tabExpressionStyle;
@@ -58,8 +66,8 @@ class AppShell extends ConsumerWidget {
);
}
Widget bottomBar = _isOhos
? _buildCupertinoNavBar(context, currentIndex, ext)
final Widget bottomBar = (_isOhos && !liquidGlassReady)
? _buildFallbackNavBar(context, currentIndex, ext, settings, ref)
: GlassBottomBar(
tabs: [
GlassBottomBarTab(
@@ -164,9 +172,7 @@ class AppShell extends ConsumerWidget {
statusBarIconBrightness: ext.isDark
? Brightness.light
: Brightness.dark,
statusBarBrightness: ext.isDark
? Brightness.dark
: Brightness.light,
statusBarBrightness: ext.isDark ? Brightness.dark : Brightness.light,
systemNavigationBarColor: Colors.transparent,
systemNavigationBarIconBrightness: ext.isDark
? Brightness.light
@@ -192,32 +198,34 @@ class AppShell extends ConsumerWidget {
child.goBranch(index, initialLocation: index == child.currentIndex);
}
Widget _buildCupertinoNavBar(
Widget _buildFallbackNavBar(
BuildContext context,
int currentIndex,
AppThemeExtension ext,
ThemeSettingsState settings,
WidgetRef ref,
) {
return CupertinoTabBar(
items: const [
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.house_fill),
label: '闲言',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.compass_fill),
final expressionStyle = settings.tabExpressionStyle;
final characterId = settings.tabCharacterStyleId;
final animIntensity = settings.animationIntensity.durationMultiplier;
final unreadCount = ref.watch(chatProvider).unreadCount;
return GlassBottomNavBar(
items: [
const GlassBottomNavBarItem(spriteType: TabSpriteType.home, label: '闲言'),
GlassBottomNavBarItem(
spriteType: TabSpriteType.discover,
label: '发现',
badgeCount: unreadCount,
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.person_fill),
label: '我的',
),
const GlassBottomNavBarItem(spriteType: TabSpriteType.profile, label: '我的'),
],
currentIndex: currentIndex,
onTap: (index) => _onTabTap(context, index),
activeColor: ext.accent,
backgroundColor: ext.isDark
? const Color(0xFF1C1C1E)
: CupertinoColors.systemBackground,
selectedIndex: currentIndex,
onTabSelected: (index) => _onTabTap(context, index),
ext: ext,
animationIntensity: animIntensity,
expressionStyle: expressionStyle,
characterId: characterId,
);
}
}

View File

@@ -0,0 +1,254 @@
/// ============================================================
/// 闲言APP — 鸿蒙端专用布局壳
/// 创建时间: 2026-05-18
/// 更新时间: 2026-05-18
/// 作用: 鸿蒙端使用 Scaffold+GlassBottomBar 替代 GoRouter+StatefulShellRoute
/// 上次更新: 恢复液态玻璃效果+TabIconSprite精灵动画仅阉割路由
/// ============================================================
///
/// 根因: 鸿蒙端 Flutter 引擎中 MaterialApp.router + 额外包导入 = 白屏
/// 方案: 鸿蒙端仅阉割路由(GoRouter),保留液态玻璃效果
import 'package:badges/badges.dart' as badges;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:liquid_glass_widgets/liquid_glass_widgets.dart';
import '../../core/theme/app_theme.dart';
import '../../core/utils/interaction_animations.dart';
import '../../core/utils/logger.dart';
import '../../core/utils/platform_utils.dart' show OhosDeviceCapabilities;
import '../../features/inspiration/providers/chat_provider.dart';
import '../../features/inspiration/presentation/pages/home/inspiration_page.dart';
import '../../features/home/presentation/home_page.dart';
import '../../features/profile/presentation/profile_page.dart';
import '../../features/settings/providers/theme_settings_provider.dart';
import '../../main.dart' show liquidGlassReady;
import '../../shared/widgets/glass_bottom_nav_bar.dart';
import '../../shared/widgets/tab_icon_sprite.dart';
class OhosAppShell extends ConsumerStatefulWidget {
const OhosAppShell({super.key});
@override
ConsumerState<OhosAppShell> createState() => _OhosAppShellState();
}
class _OhosAppShellState extends ConsumerState<OhosAppShell> {
int _currentIndex = 0;
static const List<Widget> _tabPages = [
HomePage(),
InspirationPage(),
ProfilePage(),
];
@override
Widget build(BuildContext context) {
OhosDeviceCapabilities.init(context);
final ext = AppTheme.ext(context);
final unreadCount = ref.watch(chatProvider).unreadCount;
final settings = ref.watch(themeSettingsProvider);
final expressionStyle = settings.tabExpressionStyle;
final characterId = settings.tabCharacterStyleId;
final animIntensity = settings.animationIntensity.durationMultiplier;
Log.i(
'🟢 [OHOS] OhosAppShell.build() — currentIndex=$_currentIndex liquidGlass=$liquidGlassReady',
);
final Widget bottomBar = liquidGlassReady
? _buildGlassBottomBar(
ext: ext,
unreadCount: unreadCount,
expressionStyle: expressionStyle,
characterId: characterId,
animIntensity: animIntensity,
)
: _buildFallbackNavBar(
ext: ext,
unreadCount: unreadCount,
expressionStyle: expressionStyle,
characterId: characterId,
animIntensity: animIntensity,
);
return CelebrationOverlay(
child: AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: ext.isDark
? Brightness.light
: Brightness.dark,
statusBarBrightness: ext.isDark ? Brightness.dark : Brightness.light,
systemNavigationBarColor: Colors.transparent,
systemNavigationBarIconBrightness: ext.isDark
? Brightness.light
: Brightness.dark,
systemNavigationBarDividerColor: Colors.transparent,
),
child: PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, _) {
if (didPop) return;
},
child: Scaffold(
extendBody: true,
body: IndexedStack(index: _currentIndex, children: _tabPages),
bottomNavigationBar: bottomBar,
),
),
),
);
}
/// GPU Shader 液态玻璃底部导航栏 (LiquidGlassWidgets 可用时)
Widget _buildGlassBottomBar({
required AppThemeExtension ext,
required int unreadCount,
required TabExpressionStyleOption expressionStyle,
required String characterId,
required double animIntensity,
}) {
int adjacentFor(int index) {
if (index == _currentIndex) return 0;
if (index < _currentIndex) return -1;
return 1;
}
Widget buildSpriteIcon(TabSpriteType type, int index, String label) {
return TabIconSprite(
type: type,
label: label,
isSelected: index == _currentIndex,
adjacentDirection: adjacentFor(index),
animationIntensity: animIntensity,
characterId: characterId,
eyeScale: expressionStyle.eyeScale,
mouthCurve: expressionStyle.mouthCurve,
bounceMultiplier: expressionStyle.bounceMultiplier,
);
}
return GlassBottomBar(
tabs: [
GlassBottomBarTab(
label: '',
icon: buildSpriteIcon(TabSpriteType.home, 0, '闲言'),
activeIcon: buildSpriteIcon(TabSpriteType.home, 0, '闲言'),
glowColor: const Color(0xFFE8E8ED),
),
GlassBottomBarTab(
label: '',
icon: _buildBadgeIcon(
unreadCount: unreadCount,
child: buildSpriteIcon(TabSpriteType.discover, 1, '发现'),
),
activeIcon: _buildBadgeIcon(
unreadCount: unreadCount,
child: buildSpriteIcon(TabSpriteType.discover, 1, '发现'),
),
glowColor: const Color(0xFFE8E8ED),
),
GlassBottomBarTab(
label: '',
icon: buildSpriteIcon(TabSpriteType.profile, 2, '我的'),
activeIcon: buildSpriteIcon(TabSpriteType.profile, 2, '我的'),
glowColor: const Color(0xFFE8E8ED),
),
],
selectedIndex: _currentIndex,
onTabSelected: (index) => setState(() => _currentIndex = index),
quality: GlassQuality.premium,
selectedIconColor: ext.isDark ? Colors.white : ext.accent,
unselectedIconColor: ext.isDark
? Colors.white38
: const Color(0xFFAEAEB2),
barHeight: 68,
barBorderRadius: 34,
horizontalPadding: 16,
verticalPadding: 16,
indicatorColor: ext.isDark
? Colors.white.withValues(alpha: 0.08)
: Colors.black.withValues(alpha: 0.04),
indicatorSettings: LiquidGlassSettings(
thickness: 40,
blur: 25,
refractiveIndex: 1.8,
chromaticAberration: 1.2,
lightIntensity: 3.5,
ambientStrength: 1.2,
glassColor: ext.isDark
? const Color.from(alpha: 0.18, red: 1, green: 1, blue: 1)
: const Color.from(alpha: 0.12, red: 1, green: 1, blue: 1),
),
glassSettings: LiquidGlassSettings(
thickness: 30,
blur: 1.5,
refractiveIndex: 1.5,
chromaticAberration: 0.8,
lightIntensity: 1.2,
saturation: 1.0,
ambientStrength: 0.6,
glassColor: ext.isDark
? const Color.from(alpha: 0.08, red: 1, green: 1, blue: 1)
: const Color.from(alpha: 0.05, red: 1, green: 1, blue: 1),
),
magnification: 1.12,
innerBlur: 1.5,
glowOpacity: 0.4,
glowBlurRadius: 24,
glowSpreadRadius: 4,
);
}
/// 纯Dart BackdropFilter 液态玻璃底部导航栏 (降级方案)
Widget _buildFallbackNavBar({
required AppThemeExtension ext,
required int unreadCount,
required TabExpressionStyleOption expressionStyle,
required String characterId,
required double animIntensity,
}) {
return GlassBottomNavBar(
items: [
const GlassBottomNavBarItem(spriteType: TabSpriteType.home, label: '闲言'),
GlassBottomNavBarItem(
spriteType: TabSpriteType.discover,
label: '发现',
badgeCount: unreadCount,
),
const GlassBottomNavBarItem(spriteType: TabSpriteType.profile, label: '我的'),
],
selectedIndex: _currentIndex,
onTabSelected: (index) => setState(() => _currentIndex = index),
ext: ext,
animationIntensity: animIntensity,
expressionStyle: expressionStyle,
characterId: characterId,
);
}
Widget _buildBadgeIcon({required int unreadCount, required Widget child}) {
if (unreadCount <= 0) return child;
return badges.Badge(
badgeContent: Text(
'$unreadCount',
style: const TextStyle(
color: Colors.white,
fontSize: 9,
fontWeight: FontWeight.bold,
),
),
badgeStyle: const badges.BadgeStyle(
badgeColor: CupertinoColors.systemRed,
padding: EdgeInsets.all(3),
),
position: badges.BadgePosition.topEnd(top: -4, end: -6),
child: child,
);
}
}