Commit 0710e7eb3996308d0a89b299ad52a0c00f66b9dd

Authored by 常守达
1 parent 59bcf064

feat(my): 我的表盘

@@ -2,9 +2,11 @@ import 'package:cached_network_image/cached_network_image.dart'; @@ -2,9 +2,11 @@ import 'package:cached_network_image/cached_network_image.dart';
2 import 'package:doublefeel_flutter/app/models/input_dialog_meta_data.dart'; 2 import 'package:doublefeel_flutter/app/models/input_dialog_meta_data.dart';
3 import 'package:doublefeel_flutter/app/modules/home/controllers/my_controller.dart'; 3 import 'package:doublefeel_flutter/app/modules/home/controllers/my_controller.dart';
4 import 'package:doublefeel_flutter/app/modules/home/widgets/my/account_setting_view.dart'; 4 import 'package:doublefeel_flutter/app/modules/home/widgets/my/account_setting_view.dart';
  5 +import 'package:doublefeel_flutter/app/modules/watch_theme/models/watch_theme_models.dart';
5 import 'package:doublefeel_flutter/app/routes/app_pages.dart'; 6 import 'package:doublefeel_flutter/app/routes/app_pages.dart';
6 import 'package:doublefeel_flutter/app/utils/dialog_utils.dart'; 7 import 'package:doublefeel_flutter/app/utils/dialog_utils.dart';
7 import 'package:doublefeel_flutter/core/theme/app_theme.dart'; 8 import 'package:doublefeel_flutter/core/theme/app_theme.dart';
  9 +import 'package:doublefeel_flutter/core/util/size_extensions.dart';
8 import 'package:doublefeel_flutter/data/local/user_preferences_storage.dart'; 10 import 'package:doublefeel_flutter/data/local/user_preferences_storage.dart';
9 import 'package:doublefeel_flutter/data/models/local/user_preferences.dart'; 11 import 'package:doublefeel_flutter/data/models/local/user_preferences.dart';
10 import 'package:doublefeel_flutter/data/models/user/user_models.dart'; 12 import 'package:doublefeel_flutter/data/models/user/user_models.dart';
@@ -12,6 +14,8 @@ import 'package:flutter/foundation.dart'; @@ -12,6 +14,8 @@ import 'package:flutter/foundation.dart';
12 import 'package:flutter/material.dart'; 14 import 'package:flutter/material.dart';
13 import 'package:get/get.dart'; 15 import 'package:get/get.dart';
14 16
  17 +import '../../../../../core/theme/app_colors.dart';
  18 +
15 class MyTab extends GetView<MyController> { 19 class MyTab extends GetView<MyController> {
16 const MyTab({super.key}); 20 const MyTab({super.key});
17 21
@@ -46,7 +50,12 @@ class MyTab extends GetView<MyController> { @@ -46,7 +50,12 @@ class MyTab extends GetView<MyController> {
46 const SizedBox(height: 28), 50 const SizedBox(height: 28),
47 _ProCard(vipInfo: vipInfo), 51 _ProCard(vipInfo: vipInfo),
48 const SizedBox(height: 12), 52 const SizedBox(height: 12),
49 - const _WatchThemeCard(), 53 + _WatchThemeCard(
  54 + onTap: () => Get.toNamed(
  55 + Routes.WATCH_THEME,
  56 + arguments: {'isPremium': false, 'hasCustomThemes': false},
  57 + ),
  58 + ),
50 const SizedBox(height: 12), 59 const SizedBox(height: 12),
51 _SettingsRow( 60 _SettingsRow(
52 title: '账号信息', 61 title: '账号信息',
@@ -73,6 +82,51 @@ class MyTab extends GetView<MyController> { @@ -73,6 +82,51 @@ class MyTab extends GetView<MyController> {
73 ); 82 );
74 } 83 }
75 } 84 }
  85 +class _SettingsRow extends StatelessWidget {
  86 + const _SettingsRow({required this.title, required this.onTap});
  87 +
  88 + final String title;
  89 + final VoidCallback onTap;
  90 +
  91 + @override
  92 + Widget build(BuildContext context) {
  93 + return GestureDetector(
  94 + behavior: HitTestBehavior.opaque,
  95 + onTap: onTap,
  96 + child: Container(
  97 + height: 56,
  98 + padding: const EdgeInsets.symmetric(horizontal: 20),
  99 + decoration: BoxDecoration(
  100 + color: Colors.white,
  101 + borderRadius: BorderRadius.circular(16),
  102 + ),
  103 + child: Row(
  104 + children: [
  105 + Expanded(
  106 + child: Text(
  107 + title,
  108 + maxLines: 1,
  109 + overflow: TextOverflow.ellipsis,
  110 + style: TextStyle(
  111 + color: context.colors.textPrimary,
  112 + fontSize: 14,
  113 + fontWeight: FontWeight.w400,
  114 + height: 1.4,
  115 + ),
  116 + ),
  117 + ),
  118 + Image.asset(
  119 + 'assets/images/common/ic_more_gray.png',
  120 + width: 16,
  121 + height: 16,
  122 + ),
  123 + ],
  124 + ),
  125 + ),
  126 + );
  127 + }
  128 +}
  129 +
76 130
77 class _ProfileHeader extends StatelessWidget { 131 class _ProfileHeader extends StatelessWidget {
78 const _ProfileHeader({required this.user}); 132 const _ProfileHeader({required this.user});
@@ -303,59 +357,94 @@ class _ProCard extends StatelessWidget { @@ -303,59 +357,94 @@ class _ProCard extends StatelessWidget {
303 } 357 }
304 } 358 }
305 359
306 -class _WatchThemeCard extends StatelessWidget {  
307 - const _WatchThemeCard(); 360 +// class _WatchThemeCard extends StatelessWidget {
  361 +// const _WatchThemeCard();
  362 +//
  363 +// @override
  364 +// Widget build(BuildContext context) {
  365 +// return Container(
  366 +// height: 145,
  367 +// decoration: BoxDecoration(
  368 +// color: Colors.white,
  369 +// borderRadius: BorderRadius.circular(16),
  370 +// ),
  371 +// child: Image.asset('assets/images/my/ic_my_watch_theme.png'),
  372 +// );
  373 +// }
  374 +// }
308 375
309 - @override  
310 - Widget build(BuildContext context) {  
311 - return Container(  
312 - height: 145,  
313 - decoration: BoxDecoration(  
314 - color: Colors.white,  
315 - borderRadius: BorderRadius.circular(16),  
316 - ),  
317 - child: Image.asset('assets/images/my/ic_my_watch_theme.png'),  
318 - );  
319 - }  
320 -}  
321 -  
322 -class _SettingsRow extends StatelessWidget {  
323 - const _SettingsRow({required this.title, required this.onTap}); 376 +class _WatchThemeCard extends StatelessWidget {
  377 + const _WatchThemeCard({required this.onTap});
324 378
325 - final String title;  
326 final VoidCallback onTap; 379 final VoidCallback onTap;
327 380
  381 + final double _itemSize = 64;
  382 + final double _overlap = 8;
  383 +
328 @override 384 @override
329 Widget build(BuildContext context) { 385 Widget build(BuildContext context) {
330 return GestureDetector( 386 return GestureDetector(
331 behavior: HitTestBehavior.opaque, 387 behavior: HitTestBehavior.opaque,
332 onTap: onTap, 388 onTap: onTap,
333 child: Container( 389 child: Container(
334 - height: 56,  
335 - padding: const EdgeInsets.symmetric(horizontal: 20), 390 + padding: EdgeInsets.fromLTRB(20.dp, 20.dp, 20.dp, 18.dp),
336 decoration: BoxDecoration( 391 decoration: BoxDecoration(
337 color: Colors.white, 392 color: Colors.white,
338 - borderRadius: BorderRadius.circular(16), 393 + borderRadius: BorderRadius.circular(16.dp),
339 ), 394 ),
340 - child: Row( 395 + child: Column(
  396 + crossAxisAlignment: CrossAxisAlignment.start,
341 children: [ 397 children: [
342 - Expanded(  
343 - child: Text(  
344 - title,  
345 - maxLines: 1,  
346 - overflow: TextOverflow.ellipsis,  
347 - style: TextStyle(  
348 - color: context.colors.textPrimary,  
349 - fontSize: 14,  
350 - fontWeight: FontWeight.w400,  
351 - height: 1.4, 398 + Row(
  399 + children: [
  400 + Text(
  401 + 'Watch主题',
  402 + style: TextStyle(
  403 + color: AppColors.textPrimary,
  404 + fontSize: 16.dp,
  405 + fontWeight: FontWeight.w600,
  406 + height: 1.25,
  407 + ),
  408 + ),
  409 + const Spacer(),
  410 + Icon(
  411 + Icons.chevron_right,
  412 + color: AppColors.textTertiary,
  413 + size: 20.dp,
352 ), 414 ),
  415 + ],
  416 + ),
  417 + SizedBox(height: 17.dp),
  418 + SizedBox(
  419 + height: _itemSize,
  420 + child: ListView.builder(
  421 + scrollDirection: Axis.horizontal,
  422 + clipBehavior: Clip.none,
  423 + itemCount: officialThemes.length,
  424 + itemBuilder: (context, index) {
  425 + return Transform.translate(
  426 + offset: Offset(index == 0 ? 0 : -_overlap * index, 0),
  427 + child: _ThemeBubble(
  428 + size: _itemSize,
  429 + assetPath: officialThemes[index]
  430 + .infoList
  431 + .firstOrNull
  432 + ?.assetPath ??
  433 + '',
  434 + ));
  435 + },
  436 +
353 ), 437 ),
354 ), 438 ),
355 - Image.asset(  
356 - 'assets/images/common/ic_more_gray.png',  
357 - width: 16,  
358 - height: 16, 439 + SizedBox(height: 10.dp),
  440 + Text(
  441 + '支持自定义创作主题哦~',
  442 + style: TextStyle(
  443 + color: AppColors.primary,
  444 + fontSize: 12.dp,
  445 + fontWeight: FontWeight.w500,
  446 + height: 1.25,
  447 + ),
359 ), 448 ),
360 ], 449 ],
361 ), 450 ),
@@ -363,3 +452,29 @@ class _SettingsRow extends StatelessWidget { @@ -363,3 +452,29 @@ class _SettingsRow extends StatelessWidget {
363 ); 452 );
364 } 453 }
365 } 454 }
  455 +class _ThemeBubble extends StatelessWidget {
  456 + const _ThemeBubble({required this.size, required this.assetPath});
  457 +
  458 + final double size;
  459 + final String assetPath;
  460 +
  461 + @override
  462 + Widget build(BuildContext context) {
  463 + return Container(
  464 + width: size,
  465 + height: size,
  466 + decoration: BoxDecoration(
  467 + color: const Color(0xFFEDE8FF),
  468 + shape: BoxShape.circle,
  469 + border: Border.all(color: Colors.white, width: 4),
  470 + ),
  471 + alignment: Alignment.center,
  472 + child: Image.asset(
  473 + assetPath,
  474 + width: 36,
  475 + height: 36,
  476 + fit: BoxFit.fill,
  477 + ),
  478 + );
  479 + }
  480 +}