Showing
15 changed files
with
92 additions
and
46 deletions
| @@ -3,9 +3,7 @@ import 'package:doublefeel_flutter/core/network/api/friend_api.dart'; | @@ -3,9 +3,7 @@ import 'package:doublefeel_flutter/core/network/api/friend_api.dart'; | ||
| 3 | import 'package:doublefeel_flutter/core/network/api/health_api.dart'; | 3 | import 'package:doublefeel_flutter/core/network/api/health_api.dart'; |
| 4 | import 'package:doublefeel_flutter/core/network/api/pay_api.dart'; | 4 | import 'package:doublefeel_flutter/core/network/api/pay_api.dart'; |
| 5 | import 'package:doublefeel_flutter/core/network/api/vip_api.dart'; | 5 | import 'package:doublefeel_flutter/core/network/api/vip_api.dart'; |
| 6 | -import 'package:doublefeel_flutter/core/services/health_kit_upload_service.dart'; | ||
| 7 | import 'package:doublefeel_flutter/core/services/user_state_service.dart'; | 6 | import 'package:doublefeel_flutter/core/services/user_state_service.dart'; |
| 8 | -import 'package:doublefeel_flutter/app/apple_health_upload/apple_health_upload_tool.dart'; | ||
| 9 | import 'package:doublefeel_flutter/data/models/friend/friend_models.dart'; | 7 | import 'package:doublefeel_flutter/data/models/friend/friend_models.dart'; |
| 10 | import 'package:get/get.dart'; | 8 | import 'package:get/get.dart'; |
| 11 | 9 | ||
| @@ -20,8 +18,6 @@ class FriendHomeBinding extends Bindings { | @@ -20,8 +18,6 @@ class FriendHomeBinding extends Bindings { | ||
| 20 | Get.find<HealthApi>(), | 18 | Get.find<HealthApi>(), |
| 21 | Get.find<FriendApi>(), | 19 | Get.find<FriendApi>(), |
| 22 | Get.find<UserStateService>(), | 20 | Get.find<UserStateService>(), |
| 23 | - Get.find<HealthKitUploadService>(), | ||
| 24 | - Get.find<AppleHealthUploadTool>(), | ||
| 25 | friendInfo: args, | 21 | friendInfo: args, |
| 26 | ), | 22 | ), |
| 27 | tag: 'friend_${args.friendUserId}', // 动态 tag,支持多个好友同时在路由栈中 | 23 | tag: 'friend_${args.friendUserId}', // 动态 tag,支持多个好友同时在路由栈中 |
| @@ -12,6 +12,7 @@ import 'package:doublefeel_flutter/core/util/app_toast.dart'; | @@ -12,6 +12,7 @@ import 'package:doublefeel_flutter/core/util/app_toast.dart'; | ||
| 12 | import 'package:doublefeel_flutter/data/models/health/health_v2_models.dart'; | 12 | import 'package:doublefeel_flutter/data/models/health/health_v2_models.dart'; |
| 13 | import 'package:doublefeel_flutter/l10n/l10n_extensions.dart'; | 13 | import 'package:doublefeel_flutter/l10n/l10n_extensions.dart'; |
| 14 | import 'package:doublefeel_flutter/pigeon/platform_api.g.dart'; | 14 | import 'package:doublefeel_flutter/pigeon/platform_api.g.dart'; |
| 15 | +import 'package:doublefeel_flutter/pigeon/wear_engine_api.g.dart'; | ||
| 15 | import 'package:get/get.dart'; | 16 | import 'package:get/get.dart'; |
| 16 | 17 | ||
| 17 | import '../data/friends_repository.dart'; | 18 | import '../data/friends_repository.dart'; |
| @@ -28,7 +29,7 @@ class FriendsController extends GetxController { | @@ -28,7 +29,7 @@ class FriendsController extends GetxController { | ||
| 28 | _selfHealthRepository = selfHealthRepository ?? | 29 | _selfHealthRepository = selfHealthRepository ?? |
| 29 | SelfHealthRepositoryImpl(Get.find<HealthApi>()), | 30 | SelfHealthRepositoryImpl(Get.find<HealthApi>()), |
| 30 | _updateWatchOtherUserInfo = updateWatchOtherUserInfo ?? | 31 | _updateWatchOtherUserInfo = updateWatchOtherUserInfo ?? |
| 31 | - ((info) => PlatformHostApi().refreshWatchAppAndWidgets()); | 32 | + ((info) => WearEngineHostApi().sendWatchSyncPayload('')); |
| 32 | 33 | ||
| 33 | static const maxFriends = 10; | 34 | static const maxFriends = 10; |
| 34 | 35 |
| @@ -42,6 +42,10 @@ class SelectFriendLogic { | @@ -42,6 +42,10 @@ class SelectFriendLogic { | ||
| 42 | if (index < 0 || index >= friends.length) return null; | 42 | if (index < 0 || index >= friends.length) return null; |
| 43 | 43 | ||
| 44 | final selectedFriend = friends[index]; | 44 | final selectedFriend = friends[index]; |
| 45 | + if (selectedFriend.isOnWatchFace) { | ||
| 46 | + return null; | ||
| 47 | + } | ||
| 48 | + | ||
| 45 | final userId = selectedFriend.userId; | 49 | final userId = selectedFriend.userId; |
| 46 | if (userId == null) return null; | 50 | if (userId == null) return null; |
| 47 | 51 |
| @@ -95,7 +95,7 @@ class _SelectFriendViewState extends State<SelectFriendView> { | @@ -95,7 +95,7 @@ class _SelectFriendViewState extends State<SelectFriendView> { | ||
| 95 | 95 | ||
| 96 | Future<void> _syncSelectedFriend() async { | 96 | Future<void> _syncSelectedFriend() async { |
| 97 | final selectedFriend = await _logic.syncSelectedFriendToWatchFace(); | 97 | final selectedFriend = await _logic.syncSelectedFriendToWatchFace(); |
| 98 | - if (selectedFriend != null) Get.back(result: selectedFriend); | 98 | + Get.back(result: selectedFriend); |
| 99 | } | 99 | } |
| 100 | } | 100 | } |
| 101 | 101 |
| @@ -26,8 +26,6 @@ class HomeBinding extends Bindings { | @@ -26,8 +26,6 @@ class HomeBinding extends Bindings { | ||
| 26 | Get.find<HealthApi>(), | 26 | Get.find<HealthApi>(), |
| 27 | Get.find<FriendApi>(), | 27 | Get.find<FriendApi>(), |
| 28 | Get.find<UserStateService>(), | 28 | Get.find<UserStateService>(), |
| 29 | - Get.find<HealthKitUploadService>(), | ||
| 30 | - Get.find<AppleHealthUploadTool>(), | ||
| 31 | ), | 29 | ), |
| 32 | fenix: true, | 30 | fenix: true, |
| 33 | ); | 31 | ); |
| 1 | import 'dart:async'; | 1 | import 'dart:async'; |
| 2 | import 'dart:math'; | 2 | import 'dart:math'; |
| 3 | 3 | ||
| 4 | -import 'package:doublefeel_flutter/app/apple_health_upload/apple_health_upload_tool.dart'; | ||
| 5 | import 'package:doublefeel_flutter/app/modules/friends/controllers/friend_trend_controller.dart'; | 4 | import 'package:doublefeel_flutter/app/modules/friends/controllers/friend_trend_controller.dart'; |
| 6 | import 'package:doublefeel_flutter/app/modules/home/controllers/home_controller.dart'; | 5 | import 'package:doublefeel_flutter/app/modules/home/controllers/home_controller.dart'; |
| 7 | import 'package:doublefeel_flutter/app/modules/home/controllers/trend/trend_controller.dart'; | 6 | import 'package:doublefeel_flutter/app/modules/home/controllers/trend/trend_controller.dart'; |
| @@ -14,7 +13,6 @@ import 'package:doublefeel_flutter/core/network/api/health_api.dart'; | @@ -14,7 +13,6 @@ import 'package:doublefeel_flutter/core/network/api/health_api.dart'; | ||
| 14 | import 'package:doublefeel_flutter/core/network/api/pay_api.dart'; | 13 | import 'package:doublefeel_flutter/core/network/api/pay_api.dart'; |
| 15 | import 'package:doublefeel_flutter/core/network/api/vip_api.dart'; | 14 | import 'package:doublefeel_flutter/core/network/api/vip_api.dart'; |
| 16 | import 'package:doublefeel_flutter/core/result/app_result.dart'; | 15 | import 'package:doublefeel_flutter/core/result/app_result.dart'; |
| 17 | -import 'package:doublefeel_flutter/core/services/health_kit_upload_service.dart'; | ||
| 18 | import 'package:doublefeel_flutter/core/services/user_state_service.dart'; | 16 | import 'package:doublefeel_flutter/core/services/user_state_service.dart'; |
| 19 | import 'package:doublefeel_flutter/core/util/app_toast.dart'; | 17 | import 'package:doublefeel_flutter/core/util/app_toast.dart'; |
| 20 | import 'package:doublefeel_flutter/data/local/user_account_storage.dart'; | 18 | import 'package:doublefeel_flutter/data/local/user_account_storage.dart'; |
| @@ -59,9 +57,7 @@ class TodayController extends GetMaterialController { | @@ -59,9 +57,7 @@ class TodayController extends GetMaterialController { | ||
| 59 | this._vipApi, | 57 | this._vipApi, |
| 60 | this._healthApi, | 58 | this._healthApi, |
| 61 | this._friendApi, | 59 | this._friendApi, |
| 62 | - this._userStateService, | ||
| 63 | - this._healthKitUploadService, | ||
| 64 | - this._appleHealthUploadTool, { | 60 | + this._userStateService, { |
| 65 | FriendItem? friendInfo, // null = 自己,非 null = 好友 | 61 | FriendItem? friendInfo, // null = 自己,非 null = 好友 |
| 66 | }) : _initialFriendInfo = friendInfo; | 62 | }) : _initialFriendInfo = friendInfo; |
| 67 | 63 | ||
| @@ -70,8 +66,6 @@ class TodayController extends GetMaterialController { | @@ -70,8 +66,6 @@ class TodayController extends GetMaterialController { | ||
| 70 | final HealthApi _healthApi; | 66 | final HealthApi _healthApi; |
| 71 | final FriendApi _friendApi; | 67 | final FriendApi _friendApi; |
| 72 | final UserStateService _userStateService; | 68 | final UserStateService _userStateService; |
| 73 | - final HealthKitUploadService _healthKitUploadService; | ||
| 74 | - final AppleHealthUploadTool _appleHealthUploadTool; | ||
| 75 | final HealthKitHostApi _hostApi = HealthKitHostApi(); | 69 | final HealthKitHostApi _hostApi = HealthKitHostApi(); |
| 76 | 70 | ||
| 77 | /// 好友的信息;null 表示查看自己的数据,非 null 表示查看好友的数据。 | 71 | /// 好友的信息;null 表示查看自己的数据,非 null 表示查看好友的数据。 |
| @@ -265,7 +259,7 @@ class TodayController extends GetMaterialController { | @@ -265,7 +259,7 @@ class TodayController extends GetMaterialController { | ||
| 265 | Future<void> _performDataUpload() async { | 259 | Future<void> _performDataUpload() async { |
| 266 | try { | 260 | try { |
| 267 | final result = | 261 | final result = |
| 268 | - await _appleHealthUploadTool.uploadAllNewDataFromHealthKit(); | 262 | + await _hostApi.performHealthUpload(); |
| 269 | // AppLogger.i( | 263 | // AppLogger.i( |
| 270 | // 'Apple Health upload finished: ' | 264 | // 'Apple Health upload finished: ' |
| 271 | // 'common=${result.commonUploadSuccess}(${result.commonCount}), ' | 265 | // 'common=${result.commonUploadSuccess}(${result.commonCount}), ' |
| @@ -54,7 +54,7 @@ class MyTab extends GetView<MyController> { | @@ -54,7 +54,7 @@ class MyTab extends GetView<MyController> { | ||
| 54 | : _UnlockPremiumCard(controller), | 54 | : _UnlockPremiumCard(controller), |
| 55 | const SizedBox(height: 12), | 55 | const SizedBox(height: 12), |
| 56 | _WatchThemeCard( | 56 | _WatchThemeCard( |
| 57 | - themes: controller.officialWatchThemes, | 57 | + themes: controller.watchThemeItems, |
| 58 | isLoading: controller.isLoadingWatchThemes.value, | 58 | isLoading: controller.isLoadingWatchThemes.value, |
| 59 | onTap: () => controller.goWatchThemePage(), | 59 | onTap: () => controller.goWatchThemePage(), |
| 60 | ), | 60 | ), |
| @@ -213,6 +213,7 @@ class CreateWatchThemeController extends GetxController { | @@ -213,6 +213,7 @@ class CreateWatchThemeController extends GetxController { | ||
| 213 | ), | 213 | ), |
| 214 | barrierDismissible: true, | 214 | barrierDismissible: true, |
| 215 | ); | 215 | ); |
| 216 | + Get.back(); | ||
| 216 | if (abandon == true) { | 217 | if (abandon == true) { |
| 217 | Get.back(); | 218 | Get.back(); |
| 218 | } | 219 | } |
| @@ -259,7 +260,7 @@ class CreateWatchThemeController extends GetxController { | @@ -259,7 +260,7 @@ class CreateWatchThemeController extends GetxController { | ||
| 259 | } | 260 | } |
| 260 | 261 | ||
| 261 | final createdTheme = await _loadCreatedTheme(); | 262 | final createdTheme = await _loadCreatedTheme(); |
| 262 | - await Get.toNamed( | 263 | + await Get.offAndToNamed( |
| 263 | Routes.WATCH_THEME_CUSTOM_PREVIEW, | 264 | Routes.WATCH_THEME_CUSTOM_PREVIEW, |
| 264 | arguments: { | 265 | arguments: { |
| 265 | 'theme': createdTheme ?? _buildThemeItem(uploadedImageUrls), | 266 | 'theme': createdTheme ?? _buildThemeItem(uploadedImageUrls), |
| @@ -4,10 +4,13 @@ import 'dart:convert'; | @@ -4,10 +4,13 @@ import 'dart:convert'; | ||
| 4 | import 'package:doublefeel_flutter/core/network/api/theme_api.dart'; | 4 | import 'package:doublefeel_flutter/core/network/api/theme_api.dart'; |
| 5 | import 'package:doublefeel_flutter/core/result/app_result.dart'; | 5 | import 'package:doublefeel_flutter/core/result/app_result.dart'; |
| 6 | import 'package:doublefeel_flutter/core/util/app_toast.dart'; | 6 | import 'package:doublefeel_flutter/core/util/app_toast.dart'; |
| 7 | +import 'package:doublefeel_flutter/pigeon/platform_api.g.dart'; | ||
| 7 | import 'package:doublefeel_flutter/pigeon/wear_engine_api.g.dart'; | 8 | import 'package:doublefeel_flutter/pigeon/wear_engine_api.g.dart'; |
| 8 | import 'package:flutter/material.dart'; | 9 | import 'package:flutter/material.dart'; |
| 9 | import 'package:get/get.dart'; | 10 | import 'package:get/get.dart'; |
| 10 | 11 | ||
| 12 | +import '../../friends/models/friend_health_data.dart'; | ||
| 13 | +import '../../friends/views/select_friend_view.dart'; | ||
| 11 | import '../models/watch_theme_models.dart'; | 14 | import '../models/watch_theme_models.dart'; |
| 12 | import '../widgets/watch_theme_dialogs.dart'; | 15 | import '../widgets/watch_theme_dialogs.dart'; |
| 13 | import '../widgets/watch_theme_no_watch_dialog.dart'; | 16 | import '../widgets/watch_theme_no_watch_dialog.dart'; |
| @@ -108,8 +111,25 @@ class CustomWatchThemePreviewController extends GetxController { | @@ -108,8 +111,25 @@ class CustomWatchThemePreviewController extends GetxController { | ||
| 108 | } | 111 | } |
| 109 | } | 112 | } |
| 110 | 113 | ||
| 111 | - void changeFriend() { | ||
| 112 | - //TODO: - bottomSheet 的方式展示出 SelectFriendView | 114 | + Future<void> changeFriend() async { |
| 115 | + final selectedFriend = await Get.bottomSheet<FriendHealthData>( | ||
| 116 | + SizedBox( | ||
| 117 | + height: Get.height * 0.9, | ||
| 118 | + child: const SelectFriendView(), | ||
| 119 | + ), | ||
| 120 | + ignoreSafeArea: false, | ||
| 121 | + isScrollControlled: true, | ||
| 122 | + backgroundColor: Colors.transparent, | ||
| 123 | + barrierColor: const Color(0xB3000000), | ||
| 124 | + ); | ||
| 125 | + if (selectedFriend == null) return; | ||
| 126 | + | ||
| 127 | + await loadFriendTheme(); | ||
| 128 | + try { | ||
| 129 | + await WearEngineHostApi().sendWatchSyncPayload(''); | ||
| 130 | + } catch (_) { | ||
| 131 | + // The selected friend is saved on the server; native refresh can retry. | ||
| 132 | + } | ||
| 113 | } | 133 | } |
| 114 | 134 | ||
| 115 | Future<void> addWatchFace() async { | 135 | Future<void> addWatchFace() async { |
| @@ -120,20 +140,20 @@ class CustomWatchThemePreviewController extends GetxController { | @@ -120,20 +140,20 @@ class CustomWatchThemePreviewController extends GetxController { | ||
| 120 | device = null; | 140 | device = null; |
| 121 | } | 141 | } |
| 122 | if (device == null) { | 142 | if (device == null) { |
| 123 | - await Get.dialog<void>( | 143 | + await Get.bottomSheet<void>( |
| 124 | const WatchThemeNoWatchDialog(), | 144 | const WatchThemeNoWatchDialog(), |
| 125 | - barrierDismissible: true, | 145 | + backgroundColor: Colors.transparent, |
| 126 | barrierColor: const Color(0xB3000000), | 146 | barrierColor: const Color(0xB3000000), |
| 127 | ); | 147 | ); |
| 128 | return; | 148 | return; |
| 129 | } | 149 | } |
| 130 | 150 | ||
| 131 | - await Get.dialog<void>( | 151 | + await Get.bottomSheet<void>( |
| 132 | WatchThemeSyncDialog( | 152 | WatchThemeSyncDialog( |
| 133 | themeImageUrl: themeItem.energeticImage, | 153 | themeImageUrl: themeItem.energeticImage, |
| 134 | onSync: applyAndSyncWatchFace, | 154 | onSync: applyAndSyncWatchFace, |
| 135 | ), | 155 | ), |
| 136 | - barrierDismissible: false, | 156 | + backgroundColor: Colors.transparent, |
| 137 | barrierColor: const Color(0xB3000000), | 157 | barrierColor: const Color(0xB3000000), |
| 138 | ); | 158 | ); |
| 139 | } | 159 | } |
| @@ -4,10 +4,13 @@ import 'dart:convert'; | @@ -4,10 +4,13 @@ import 'dart:convert'; | ||
| 4 | import 'package:doublefeel_flutter/core/network/api/theme_api.dart'; | 4 | import 'package:doublefeel_flutter/core/network/api/theme_api.dart'; |
| 5 | import 'package:doublefeel_flutter/core/result/app_result.dart'; | 5 | import 'package:doublefeel_flutter/core/result/app_result.dart'; |
| 6 | import 'package:doublefeel_flutter/core/util/app_toast.dart'; | 6 | import 'package:doublefeel_flutter/core/util/app_toast.dart'; |
| 7 | +import 'package:doublefeel_flutter/pigeon/platform_api.g.dart'; | ||
| 7 | import 'package:doublefeel_flutter/pigeon/wear_engine_api.g.dart'; | 8 | import 'package:doublefeel_flutter/pigeon/wear_engine_api.g.dart'; |
| 8 | import 'package:flutter/material.dart'; | 9 | import 'package:flutter/material.dart'; |
| 9 | import 'package:get/get.dart'; | 10 | import 'package:get/get.dart'; |
| 10 | 11 | ||
| 12 | +import '../../friends/models/friend_health_data.dart'; | ||
| 13 | +import '../../friends/views/select_friend_view.dart'; | ||
| 11 | import '../models/watch_theme_models.dart'; | 14 | import '../models/watch_theme_models.dart'; |
| 12 | import '../widgets/watch_theme_no_watch_dialog.dart'; | 15 | import '../widgets/watch_theme_no_watch_dialog.dart'; |
| 13 | import '../widgets/watch_theme_sync_dialog.dart'; | 16 | import '../widgets/watch_theme_sync_dialog.dart'; |
| @@ -86,26 +89,43 @@ class WatchThemePreviewController extends GetxController { | @@ -86,26 +89,43 @@ class WatchThemePreviewController extends GetxController { | ||
| 86 | device = null; | 89 | device = null; |
| 87 | } | 90 | } |
| 88 | if (device == null) { | 91 | if (device == null) { |
| 89 | - await Get.dialog<void>( | 92 | + await Get.bottomSheet<void>( |
| 90 | const WatchThemeNoWatchDialog(), | 93 | const WatchThemeNoWatchDialog(), |
| 91 | - barrierDismissible: true, | 94 | + backgroundColor: Colors.transparent, |
| 92 | barrierColor: const Color(0xB3000000), | 95 | barrierColor: const Color(0xB3000000), |
| 93 | ); | 96 | ); |
| 94 | return; | 97 | return; |
| 95 | } | 98 | } |
| 96 | 99 | ||
| 97 | - await Get.dialog<void>( | 100 | + await Get.bottomSheet<void>( |
| 98 | WatchThemeSyncDialog( | 101 | WatchThemeSyncDialog( |
| 99 | themeImageUrl: themeItem.energeticImage, | 102 | themeImageUrl: themeItem.energeticImage, |
| 100 | onSync: applyAndSyncWatchFace, | 103 | onSync: applyAndSyncWatchFace, |
| 101 | ), | 104 | ), |
| 102 | - barrierDismissible: false, | 105 | + backgroundColor: Colors.transparent, |
| 103 | barrierColor: const Color(0xB3000000), | 106 | barrierColor: const Color(0xB3000000), |
| 104 | ); | 107 | ); |
| 105 | } | 108 | } |
| 106 | 109 | ||
| 107 | - void changeFriend() { | ||
| 108 | - //TODO: - bottomSheet 的方式展示出 SelectFriendView | 110 | + Future<void> changeFriend() async { |
| 111 | + final selectedFriend = await Get.bottomSheet<FriendHealthData>( | ||
| 112 | + SizedBox( | ||
| 113 | + height: Get.height * 0.9, | ||
| 114 | + child: const SelectFriendView(), | ||
| 115 | + ), | ||
| 116 | + ignoreSafeArea: false, | ||
| 117 | + isScrollControlled: true, | ||
| 118 | + backgroundColor: Colors.transparent, | ||
| 119 | + barrierColor: const Color(0xB3000000), | ||
| 120 | + ); | ||
| 121 | + if (selectedFriend == null) return; | ||
| 122 | + | ||
| 123 | + await loadFriendTheme(); | ||
| 124 | + try { | ||
| 125 | + await WearEngineHostApi().sendWatchSyncPayload(''); | ||
| 126 | + } catch (_) { | ||
| 127 | + // The selected friend is saved on the server; native refresh can retry. | ||
| 128 | + } | ||
| 109 | } | 129 | } |
| 110 | 130 | ||
| 111 | Future<bool> applyAndSyncWatchFace() async { | 131 | Future<bool> applyAndSyncWatchFace() async { |
| @@ -124,7 +124,7 @@ class _EditorCard extends StatelessWidget { | @@ -124,7 +124,7 @@ class _EditorCard extends StatelessWidget { | ||
| 124 | ), | 124 | ), |
| 125 | SizedBox(height: 4), | 125 | SizedBox(height: 4), |
| 126 | Text( | 126 | Text( |
| 127 | - '支持上传图片、视频、Live图、Gif、最长5秒', | 127 | + '仅支持上传图片', |
| 128 | style: TextStyle( | 128 | style: TextStyle( |
| 129 | color: WatchThemeColors.textSecondary, | 129 | color: WatchThemeColors.textSecondary, |
| 130 | fontSize: 12, | 130 | fontSize: 12, |
| @@ -63,9 +63,9 @@ class CustomWatchThemePreviewView | @@ -63,9 +63,9 @@ class CustomWatchThemePreviewView | ||
| 63 | style: TextStyle( | 63 | style: TextStyle( |
| 64 | color: const Color(0xFFFC4447), | 64 | color: const Color(0xFFFC4447), |
| 65 | fontSize: 14, | 65 | fontSize: 14, |
| 66 | - fontWeight: FontWeight.w500, | 66 | + fontWeight: FontWeight.w600, |
| 67 | ), | 67 | ), |
| 68 | - ), | 68 | + ).paddingOnly(left: 4, right: 4, top: 4, bottom: 4), |
| 69 | ), | 69 | ), |
| 70 | ), | 70 | ), |
| 71 | Expanded( | 71 | Expanded( |
| @@ -88,6 +88,7 @@ class CustomWatchThemePreviewView | @@ -88,6 +88,7 @@ class CustomWatchThemePreviewView | ||
| 88 | controller.themeItem.energeticImage, | 88 | controller.themeItem.energeticImage, |
| 89 | themeImageUrl2: | 89 | themeImageUrl2: |
| 90 | controller.friendThemeItem.value?.normalImage, | 90 | controller.friendThemeItem.value?.normalImage, |
| 91 | + switchFriend: controller.changeFriend, | ||
| 91 | ); | 92 | ); |
| 92 | }), | 93 | }), |
| 93 | ], | 94 | ], |
| @@ -73,6 +73,7 @@ class WatchThemePreviewView extends GetView<WatchThemePreviewController> { | @@ -73,6 +73,7 @@ class WatchThemePreviewView extends GetView<WatchThemePreviewController> { | ||
| 73 | controller.themeItem.energeticImage, | 73 | controller.themeItem.energeticImage, |
| 74 | themeImageUrl2: controller | 74 | themeImageUrl2: controller |
| 75 | .friendThemeItem.value?.normalImage, | 75 | .friendThemeItem.value?.normalImage, |
| 76 | + switchFriend: controller.changeFriend, | ||
| 76 | ); | 77 | ); |
| 77 | }, | 78 | }, |
| 78 | ), | 79 | ), |
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 2 | +import 'package:get/utils.dart'; | ||
| 2 | 3 | ||
| 3 | import '../models/watch_theme_models.dart'; | 4 | import '../models/watch_theme_models.dart'; |
| 4 | import 'watch_theme_character_avatar.dart'; | 5 | import 'watch_theme_character_avatar.dart'; |
| @@ -47,24 +48,30 @@ class CustomThemeCard extends StatelessWidget { | @@ -47,24 +48,30 @@ class CustomThemeCard extends StatelessWidget { | ||
| 47 | ), | 48 | ), |
| 48 | SizedBox(height: 14), | 49 | SizedBox(height: 14), |
| 49 | _CreateThemeButton(onTap: onCreateTap), | 50 | _CreateThemeButton(onTap: onCreateTap), |
| 50 | - if (customThemes.isEmpty) ...[ | ||
| 51 | - SizedBox(height: 12), | ||
| 52 | - Row( | ||
| 53 | - children: [ | ||
| 54 | - for (var index = 0; index < customThemes.length; index++) ...[ | ||
| 55 | - _CustomThemeItem( | 51 | + customThemes.isEmpty |
| 52 | + ? SizedBox(height: 0) | ||
| 53 | + : SizedBox( | ||
| 54 | + height: 112, | ||
| 55 | + child: ListView.separated( | ||
| 56 | + scrollDirection: Axis.horizontal, | ||
| 57 | + padding: EdgeInsets.zero, | ||
| 58 | + itemBuilder: (context, index) { | ||
| 59 | + return _CustomThemeItem( | ||
| 56 | item: customThemes[index], | 60 | item: customThemes[index], |
| 57 | selected: customThemes[index].id != null && | 61 | selected: customThemes[index].id != null && |
| 58 | customThemes[index].id == activeThemeId, | 62 | customThemes[index].id == activeThemeId, |
| 59 | onTap: onThemeTap == null | 63 | onTap: onThemeTap == null |
| 60 | ? null | 64 | ? null |
| 61 | : () => onThemeTap!(customThemes[index]), | 65 | : () => onThemeTap!(customThemes[index]), |
| 62 | - ), | ||
| 63 | - if (index != customThemes.length - 1) SizedBox(width: 20), | ||
| 64 | - ], | ||
| 65 | - ], | ||
| 66 | - ), | ||
| 67 | - ], | 66 | + ); |
| 67 | + }, | ||
| 68 | + separatorBuilder: (context, index) { | ||
| 69 | + return SizedBox( | ||
| 70 | + width: 20, | ||
| 71 | + ); | ||
| 72 | + }, | ||
| 73 | + itemCount: customThemes.length), | ||
| 74 | + ).paddingOnly(top: 12), | ||
| 68 | ], | 75 | ], |
| 69 | ), | 76 | ), |
| 70 | ); | 77 | ); |
| @@ -9,11 +9,13 @@ class DialPreviewCard extends StatelessWidget { | @@ -9,11 +9,13 @@ class DialPreviewCard extends StatelessWidget { | ||
| 9 | bool showFriend; | 9 | bool showFriend; |
| 10 | final String? themeImageUrl; | 10 | final String? themeImageUrl; |
| 11 | final String? themeImageUrl2; | 11 | final String? themeImageUrl2; |
| 12 | + final Function()? switchFriend; | ||
| 12 | DialPreviewCard( | 13 | DialPreviewCard( |
| 13 | {super.key, | 14 | {super.key, |
| 14 | required this.showFriend, | 15 | required this.showFriend, |
| 15 | this.themeImageUrl, | 16 | this.themeImageUrl, |
| 16 | - this.themeImageUrl2}); | 17 | + this.themeImageUrl2, |
| 18 | + this.switchFriend}); | ||
| 17 | 19 | ||
| 18 | @override | 20 | @override |
| 19 | Widget build(BuildContext context) { | 21 | Widget build(BuildContext context) { |
| @@ -41,6 +43,7 @@ class DialPreviewCard extends StatelessWidget { | @@ -41,6 +43,7 @@ class DialPreviewCard extends StatelessWidget { | ||
| 41 | type: WatchFacePreviewType.coupleSmall, | 43 | type: WatchFacePreviewType.coupleSmall, |
| 42 | themeImageUrl: themeImageUrl, | 44 | themeImageUrl: themeImageUrl, |
| 43 | themeImageUrl2: themeImageUrl2, | 45 | themeImageUrl2: themeImageUrl2, |
| 46 | + switchFriend: switchFriend, | ||
| 44 | ); | 47 | ); |
| 45 | } | 48 | } |
| 46 | return WatchFacePreview( | 49 | return WatchFacePreview( |
-
Please register or login to post a comment