Commit 6650b9effc2c303d0502707c995105fb7e7fa12b

Authored by 权海
1 parent fbfb0bc5

feat(ui):优化主题应用

... ... @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 77;
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
... ...
... ... @@ -190,8 +190,7 @@ class CustomWatchThemePreviewController extends GetxController {
WatchThemeSyncDialog(
themeImageUrl: themeItem.energeticImage,
onSync: () async {
if (device?.isPaired != true ||
device?.isWatchAppInstalled != true) {
if (device?.isPaired != true || device?.isWatchAppInstalled != true) {
Get.back();
await Get.dialog<void>(
const WatchThemeNoWatchDialog(),
... ... @@ -217,10 +216,20 @@ class CustomWatchThemePreviewController extends GetxController {
isApplying.value = true;
WatchTransformTheme? downloadedTheme;
if (themeItem.isDefaultTheme != 1) {
try {
downloadedTheme = await _syncPayloadBuilder.build(themeItem);
} catch (e) {
AppToast.show(l10n.watchThemeImageDownloadFailed(e.toString()));
isApplying.value = false;
return false;
}
}
var syncSuccess = true;
try {
final payload = await _syncPayloadBuilder.build(themeItem);
final success = await WearEngineHostApi().syncWatchTheme(payload);
final success = await WearEngineHostApi().syncWatchTheme(downloadedTheme);
if (success) {
final result = await _themeApi.applyTheme(themeId);
if (result is! AppSuccess<void>) {
... ...
... ... @@ -161,8 +161,7 @@ class WatchThemePreviewController extends GetxController {
WatchThemeSyncDialog(
themeImageUrl: themeItem.energeticImage,
onSync: () async {
if (device?.isPaired != true ||
device?.isWatchAppInstalled != true) {
if (device?.isPaired != true || device?.isWatchAppInstalled != true) {
Get.back();
await Get.dialog<void>(
const WatchThemeNoWatchDialog(),
... ... @@ -188,10 +187,20 @@ class WatchThemePreviewController extends GetxController {
isApplying.value = true;
WatchTransformTheme? downloadedTheme;
if (themeItem.isDefaultTheme != 1) {
try {
downloadedTheme = await _syncPayloadBuilder.build(themeItem);
} catch (e) {
AppToast.show(l10n.watchThemeImageDownloadFailed(e.toString()));
isApplying.value = false;
return false;
}
}
var syncSuccess = true;
try {
final payload = await _syncPayloadBuilder.build(themeItem);
final success = await WearEngineHostApi().syncWatchTheme(payload);
final success = await WearEngineHostApi().syncWatchTheme(downloadedTheme);
if (success) {
final result = await _themeApi.applyTheme(themeId);
if (result is! AppSuccess<void>) {
... ...
import 'dart:io';
import 'dart:typed_data';
import 'package:doublefeel_flutter/app/modules/watch_theme/models/watch_theme_models.dart';
import 'package:doublefeel_flutter/pigeon/wear_engine_api.g.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
class WatchThemeSyncPayloadBuilder {
... ... @@ -46,18 +46,37 @@ class WatchThemeSyncPayloadBuilder {
}
Future<Uint8List?> _downloadImage(Uri uri) async {
final client = HttpClient();
try {
final request = await client.getUrl(uri);
final response = await request.close();
if (response.statusCode < 200 || response.statusCode >= 300) {
return null;
const maxAttempts = 3;
for (var attempt = 0; attempt < maxAttempts; attempt += 1) {
final client = HttpClient()
..connectionTimeout = const Duration(seconds: 15)
..idleTimeout = const Duration(seconds: 5);
try {
final request = await client.getUrl(uri);
request.headers.set(HttpHeaders.acceptHeader, 'image/*,*/*');
request.headers.set(HttpHeaders.connectionHeader, 'close');
request.headers.set(
HttpHeaders.userAgentHeader,
'doublefeel_flutter/watch_theme',
);
final response = await request.close();
if (response.statusCode < 200 || response.statusCode >= 300) {
return null;
}
final builder = BytesBuilder(copy: false);
await for (final chunk in response) {
builder.add(chunk);
}
return builder.takeBytes();
} catch (_) {
if (attempt == maxAttempts - 1) {
return null;
}
await Future<void>.delayed(Duration(milliseconds: 150 * (attempt + 1)));
} finally {
client.close(force: true);
}
return consolidateHttpClientResponseBytes(response);
} catch (_) {
return null;
} finally {
client.close(force: true);
}
return null;
}
}
... ...
... ... @@ -659,6 +659,15 @@
"watchThemeAbandonMessage": "Your changes won't be saved if you close this page. Discard them?",
"watchThemeContinueEditing": "Continue Editing",
"watchThemeImageUploadFailed": "Image upload failed. Please try again",
"watchThemeImageDownloadFailed": "Failed to download theme images: {error}",
"@watchThemeImageDownloadFailed": {
"description": "Toast shown when watch theme images fail to download",
"placeholders": {
"error": {
"type": "String"
}
}
},
"watchThemeCreateFailed": "Failed to create watch face. Please try again",
"watchThemeDeleteTheme": "Delete Theme",
"watchThemeDeleteMessage": "Deleted themes cannot be restored. Delete this theme?",
... ...
... ... @@ -1038,6 +1038,15 @@
"watchThemeAbandonMessage": "关闭此页面后,已编辑的内容不会保留,是否放弃编辑?",
"watchThemeContinueEditing": "继续编辑",
"watchThemeImageUploadFailed": "图片上传失败,请重试",
"watchThemeImageDownloadFailed": "主题图片下载失败:{error}",
"@watchThemeImageDownloadFailed": {
"description": "表盘主题图片下载失败提示",
"placeholders": {
"error": {
"type": "String"
}
}
},
"watchThemeCreateFailed": "创建表盘失败,请重试",
"watchThemeDeleteTheme": "删除主题",
"watchThemeDeleteMessage": "主题删除后无法恢复,确认删除该主题吗?",
... ...
... ... @@ -3867,6 +3867,12 @@ abstract class AppLocalizations {
/// **'图片上传失败,请重试'**
String get watchThemeImageUploadFailed;
/// 表盘主题图片下载失败提示
///
/// In zh, this message translates to:
/// **'主题图片下载失败:{error}'**
String watchThemeImageDownloadFailed(String error);
/// No description provided for @watchThemeCreateFailed.
///
/// In zh, this message translates to:
... ...
... ... @@ -2169,6 +2169,11 @@ class AppLocalizationsEn extends AppLocalizations {
'Image upload failed. Please try again';
@override
String watchThemeImageDownloadFailed(String error) {
return 'Failed to download theme images: $error';
}
@override
String get watchThemeCreateFailed =>
'Failed to create watch face. Please try again';
... ...
... ... @@ -2061,6 +2061,11 @@ class AppLocalizationsZh extends AppLocalizations {
String get watchThemeImageUploadFailed => '图片上传失败,请重试';
@override
String watchThemeImageDownloadFailed(String error) {
return '主题图片下载失败:$error';
}
@override
String get watchThemeCreateFailed => '创建表盘失败,请重试';
@override
... ...