feat: 长辈模式(大字大按钮 + 偏好按账号隔离)+ 语音输入(按住说话 + 实时转写 + 后端代理 DashScope ASR + 患者端专用)+ 健康仪表盘背景渐变
This commit is contained in:
@@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import '../core/app_colors.dart';
|
||||
import '../core/app_design_tokens.dart';
|
||||
import '../core/elder_mode_scope.dart';
|
||||
import '../core/app_module_visuals.dart';
|
||||
import '../core/navigation_provider.dart';
|
||||
import '../providers/auth_provider.dart';
|
||||
@@ -307,11 +308,12 @@ class _MetricTile extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final elderMode = ElderModeScope.enabledOf(context);
|
||||
return InkWell(
|
||||
onTap: onTap,
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
child: Container(
|
||||
height: 100,
|
||||
height: elderMode ? 112 : 100,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withValues(alpha: 0.22),
|
||||
@@ -368,6 +370,7 @@ class _NavigationSection extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final elderMode = ElderModeScope.enabledOf(context);
|
||||
final items = [
|
||||
_NavItem(
|
||||
icon: LucideIcons.folderHeart,
|
||||
@@ -426,15 +429,19 @@ class _NavigationSection extends StatelessWidget {
|
||||
itemCount: items.length,
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 4,
|
||||
mainAxisExtent: 82,
|
||||
mainAxisSpacing: 7,
|
||||
crossAxisSpacing: 8,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: elderMode ? 2 : 4,
|
||||
mainAxisExtent: elderMode ? 82 : 82,
|
||||
mainAxisSpacing: elderMode ? 10 : 7,
|
||||
crossAxisSpacing: elderMode ? 10 : 8,
|
||||
),
|
||||
itemBuilder: (context, index) {
|
||||
final item = items[index];
|
||||
return _NavTile(item: item, onTap: () => pushRoute(ref, item.route));
|
||||
return _NavTile(
|
||||
item: item,
|
||||
elderMode: elderMode,
|
||||
onTap: () => pushRoute(ref, item.route),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
@@ -443,8 +450,13 @@ class _NavigationSection extends StatelessWidget {
|
||||
|
||||
class _NavTile extends StatelessWidget {
|
||||
final _NavItem item;
|
||||
final bool elderMode;
|
||||
final VoidCallback onTap;
|
||||
const _NavTile({required this.item, required this.onTap});
|
||||
const _NavTile({
|
||||
required this.item,
|
||||
required this.elderMode,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
String get _title => switch (item.route) {
|
||||
'healthArchive' => '健康档案',
|
||||
@@ -473,6 +485,54 @@ class _NavTile extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isDevice = item.route == 'devices';
|
||||
if (elderMode) {
|
||||
return InkWell(
|
||||
onTap: onTap,
|
||||
borderRadius: AppRadius.lgBorder,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF8F8FC),
|
||||
borderRadius: AppRadius.lgBorder,
|
||||
border: Border.all(color: const Color(0xFFE7E8F0)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 54,
|
||||
height: 54,
|
||||
decoration: BoxDecoration(
|
||||
color: isDevice ? AppColors.device : null,
|
||||
gradient: isDevice
|
||||
? null
|
||||
: LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: _colors,
|
||||
),
|
||||
borderRadius: AppRadius.mdBorder,
|
||||
),
|
||||
child: Icon(item.icon, color: Colors.white, size: 29),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
_title,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.textPrimary,
|
||||
height: 1.15,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return InkWell(
|
||||
onTap: onTap,
|
||||
borderRadius: AppRadius.mdBorder,
|
||||
@@ -635,23 +695,13 @@ class _HealthDashboardBackgroundPainter extends CustomPainter {
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final rect = Offset.zero & size;
|
||||
canvas.drawRect(rect, Paint()..color = const Color(0xFFBAE6FD));
|
||||
|
||||
void drawGlow(Alignment center, Color color) {
|
||||
final paint = Paint()
|
||||
..shader = RadialGradient(
|
||||
center: center,
|
||||
radius: 1,
|
||||
colors: [color, color.withValues(alpha: 0)],
|
||||
stops: const [0, 0.8],
|
||||
).createShader(rect);
|
||||
canvas.drawRect(rect, paint);
|
||||
}
|
||||
|
||||
drawGlow(Alignment.bottomRight, const Color(0xFF818CF8));
|
||||
drawGlow(const Alignment(0, 0.6), const Color(0xFF60A5FA));
|
||||
drawGlow(const Alignment(0.6, -0.6), const Color(0xFF6366F1));
|
||||
drawGlow(const Alignment(-0.6, -0.6), const Color(0xFF38BDF8));
|
||||
final paint = Paint()
|
||||
..shader = const LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: [Color(0xFF00C6FB), Color(0xFF005BEA)],
|
||||
).createShader(rect);
|
||||
canvas.drawRect(rect, paint);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
Reference in New Issue
Block a user