Commit 8a108a53bff922d0ac4002b278a554ff06aaa124

Authored by 权海
1 parent 9956ee47

feat(ui):手表自定义主题支持

@@ -134,6 +134,7 @@ private open class WearEngineApiPigeonCodec : StandardMessageCodec() { @@ -134,6 +134,7 @@ private open class WearEngineApiPigeonCodec : StandardMessageCodec() {
134 } 134 }
135 } 135 }
136 136
  137 +
137 /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ 138 /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
138 interface WearEngineHostApi { 139 interface WearEngineHostApi {
139 fun hasAvailableDevices(): Boolean 140 fun hasAvailableDevices(): Boolean
@@ -145,7 +146,7 @@ interface WearEngineHostApi { @@ -145,7 +146,7 @@ interface WearEngineHostApi {
145 * Opens the system photo picker and returns a local PNG file path after 146 * Opens the system photo picker and returns a local PNG file path after
146 * removing the image background on the host platform. 147 * removing the image background on the host platform.
147 */ 148 */
148 - fun pickImageAndRemoveBackground(): String? 149 + fun removeBackground(originImagePath: String, callback: (Result<String?>) -> Unit)
149 150
150 companion object { 151 companion object {
151 /** The codec used by WearEngineHostApi. */ 152 /** The codec used by WearEngineHostApi. */
@@ -236,15 +237,20 @@ interface WearEngineHostApi { @@ -236,15 +237,20 @@ interface WearEngineHostApi {
236 } 237 }
237 } 238 }
238 run { 239 run {
239 - val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.doublefeel_flutter.WearEngineHostApi.pickImageAndRemoveBackground$separatedMessageChannelSuffix", codec) 240 + val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.doublefeel_flutter.WearEngineHostApi.removeBackground$separatedMessageChannelSuffix", codec)
240 if (api != null) { 241 if (api != null) {
241 - channel.setMessageHandler { _, reply ->  
242 - val wrapped: List<Any?> = try {  
243 - listOf(api.pickImageAndRemoveBackground())  
244 - } catch (exception: Throwable) {  
245 - WearEngineApiPigeonUtils.wrapError(exception) 242 + channel.setMessageHandler { message, reply ->
  243 + val args = message as List<Any?>
  244 + val originImagePathArg = args[0] as String
  245 + api.removeBackground(originImagePathArg) { result: Result<String?> ->
  246 + val error = result.exceptionOrNull()
  247 + if (error != null) {
  248 + reply.reply(WearEngineApiPigeonUtils.wrapError(error))
  249 + } else {
  250 + val data = result.getOrNull()
  251 + reply.reply(WearEngineApiPigeonUtils.wrapResult(data))
  252 + }
246 } 253 }
247 - reply.reply(wrapped)  
248 } 254 }
249 } else { 255 } else {
250 channel.setMessageHandler(null) 256 channel.setMessageHandler(null)
@@ -7,16 +7,16 @@ @@ -7,16 +7,16 @@
7 objects = { 7 objects = {
8 8
9 /* Begin PBXBuildFile section */ 9 /* Begin PBXBuildFile section */
10 - 0798E27DB95F2A823881D75A /* Pods_Runner_Watch_App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A488EFC0BD642ED604C4E43 /* Pods_Runner_Watch_App.framework */; };  
11 - 20A3C4994C9B0F60D1F3BCBE /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E8DC48B3736B7FEB548D0E65 /* Pods_Runner.framework */; }; 10 + 36345731C945926C4A5BD632 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CEEADFA95177019D949C8D0 /* Pods_Runner.framework */; };
12 66FB19002FDBC80100F515B4 /* DFWatchFigmaTokens.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66FB19032FDBC80100F515B4 /* DFWatchFigmaTokens.swift */; }; 11 66FB19002FDBC80100F515B4 /* DFWatchFigmaTokens.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66FB19032FDBC80100F515B4 /* DFWatchFigmaTokens.swift */; };
13 66FB19012FDBC80100F515B4 /* DFWatchFigmaHomeViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66FB19042FDBC80100F515B4 /* DFWatchFigmaHomeViews.swift */; }; 12 66FB19012FDBC80100F515B4 /* DFWatchFigmaHomeViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66FB19042FDBC80100F515B4 /* DFWatchFigmaHomeViews.swift */; };
14 66FB19022FDBC80100F515B4 /* DFWatchFigmaDetailViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66FB19052FDBC80100F515B4 /* DFWatchFigmaDetailViews.swift */; }; 13 66FB19022FDBC80100F515B4 /* DFWatchFigmaDetailViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66FB19052FDBC80100F515B4 /* DFWatchFigmaDetailViews.swift */; };
15 66FBE58C2FDA4F0F00F515B4 /* Runner Watch App.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 66FBE58B2FDA4F0F00F515B4 /* Runner Watch App.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 14 66FBE58C2FDA4F0F00F515B4 /* Runner Watch App.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 66FBE58B2FDA4F0F00F515B4 /* Runner Watch App.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
  15 + D0E7FB41C5122A32579199E1 /* Pods_Runner_Watch_App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 32675A83AFB845DC8CA3467C /* Pods_Runner_Watch_App.framework */; };
16 /* End PBXBuildFile section */ 16 /* End PBXBuildFile section */
17 17
18 /* Begin PBXContainerItemProxy section */ 18 /* Begin PBXContainerItemProxy section */
19 - 66FBE58D2FDA4F0F00F515B4 /* PBXContainerItemProxy */ = { 19 + 66569B6E2FE27D0400B7E33C /* PBXContainerItemProxy */ = {
20 isa = PBXContainerItemProxy; 20 isa = PBXContainerItemProxy;
21 containerPortal = 66FBE5762FDA4F0E00F515B4 /* Project object */; 21 containerPortal = 66FBE5762FDA4F0E00F515B4 /* Project object */;
22 proxyType = 1; 22 proxyType = 1;
@@ -50,10 +50,12 @@ @@ -50,10 +50,12 @@
50 /* End PBXCopyFilesBuildPhase section */ 50 /* End PBXCopyFilesBuildPhase section */
51 51
52 /* Begin PBXFileReference section */ 52 /* Begin PBXFileReference section */
53 - 276A214460495EB498491851 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };  
54 - 27E4D5A8995AB1EC91E7330E /* Pods-Runner Watch App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner Watch App.debug.xcconfig"; path = "Target Support Files/Pods-Runner Watch App/Pods-Runner Watch App.debug.xcconfig"; sourceTree = "<group>"; }; 53 + 0B1A5890F53172BA3C93CF69 /* Pods-Runner Watch App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner Watch App.release.xcconfig"; path = "Target Support Files/Pods-Runner Watch App/Pods-Runner Watch App.release.xcconfig"; sourceTree = "<group>"; };
  54 + 32675A83AFB845DC8CA3467C /* Pods_Runner_Watch_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner_Watch_App.framework; sourceTree = BUILT_PRODUCTS_DIR; };
55 4A9B7C102FDB0A1200F515B4 /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; }; 55 4A9B7C102FDB0A1200F515B4 /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
56 4A9B7C112FDB0A1200F515B4 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; }; 56 4A9B7C112FDB0A1200F515B4 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
  57 + 5CEEADFA95177019D949C8D0 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
  58 + 6291BE76A39C6E31BC18338B /* Pods-Runner Watch App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner Watch App.debug.xcconfig"; path = "Target Support Files/Pods-Runner Watch App/Pods-Runner Watch App.debug.xcconfig"; sourceTree = "<group>"; };
57 66FB19032FDBC80100F515B4 /* DFWatchFigmaTokens.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Runner Watch App/FigmaHome/DFWatchFigmaTokens.swift"; sourceTree = "<group>"; }; 59 66FB19032FDBC80100F515B4 /* DFWatchFigmaTokens.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Runner Watch App/FigmaHome/DFWatchFigmaTokens.swift"; sourceTree = "<group>"; };
58 66FB19042FDBC80100F515B4 /* DFWatchFigmaHomeViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Runner Watch App/FigmaHome/DFWatchFigmaHomeViews.swift"; sourceTree = "<group>"; }; 60 66FB19042FDBC80100F515B4 /* DFWatchFigmaHomeViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Runner Watch App/FigmaHome/DFWatchFigmaHomeViews.swift"; sourceTree = "<group>"; };
59 66FB19052FDBC80100F515B4 /* DFWatchFigmaDetailViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Runner Watch App/FigmaHome/DFWatchFigmaDetailViews.swift"; sourceTree = "<group>"; }; 61 66FB19052FDBC80100F515B4 /* DFWatchFigmaDetailViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Runner Watch App/FigmaHome/DFWatchFigmaDetailViews.swift"; sourceTree = "<group>"; };
@@ -62,10 +64,8 @@ @@ -62,10 +64,8 @@
62 66FBE5A72FDA518C00F515B4 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; 64 66FBE5A72FDA518C00F515B4 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
63 66FBE5A92FDA518C00F515B4 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; 65 66FBE5A92FDA518C00F515B4 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
64 66FBE5BF2FDA51A300F515B4 /* doublefeel-watch-app-extensionExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "doublefeel-watch-app-extensionExtension.entitlements"; sourceTree = "<group>"; }; 66 66FBE5BF2FDA51A300F515B4 /* doublefeel-watch-app-extensionExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "doublefeel-watch-app-extensionExtension.entitlements"; sourceTree = "<group>"; };
65 - 6F3AFF2C02DF9B5A3593F751 /* Pods-Runner Watch App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner Watch App.release.xcconfig"; path = "Target Support Files/Pods-Runner Watch App/Pods-Runner Watch App.release.xcconfig"; sourceTree = "<group>"; };  
66 - 7A488EFC0BD642ED604C4E43 /* Pods_Runner_Watch_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner_Watch_App.framework; sourceTree = BUILT_PRODUCTS_DIR; };  
67 - B245A68D9E1E49A7A1C5C57A /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };  
68 - E8DC48B3736B7FEB548D0E65 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 67 + 7845C91D0615F45450905891 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
  68 + 9D4354F0FB273F6846CD38C3 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
69 /* End PBXFileReference section */ 69 /* End PBXFileReference section */
70 70
71 /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ 71 /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
@@ -109,7 +109,7 @@ @@ -109,7 +109,7 @@
109 isa = PBXFrameworksBuildPhase; 109 isa = PBXFrameworksBuildPhase;
110 buildActionMask = 2147483647; 110 buildActionMask = 2147483647;
111 files = ( 111 files = (
112 - 20A3C4994C9B0F60D1F3BCBE /* Pods_Runner.framework in Frameworks */, 112 + 36345731C945926C4A5BD632 /* Pods_Runner.framework in Frameworks */,
113 ); 113 );
114 runOnlyForDeploymentPostprocessing = 0; 114 runOnlyForDeploymentPostprocessing = 0;
115 }; 115 };
@@ -117,7 +117,7 @@ @@ -117,7 +117,7 @@
117 isa = PBXFrameworksBuildPhase; 117 isa = PBXFrameworksBuildPhase;
118 buildActionMask = 2147483647; 118 buildActionMask = 2147483647;
119 files = ( 119 files = (
120 - 0798E27DB95F2A823881D75A /* Pods_Runner_Watch_App.framework in Frameworks */, 120 + D0E7FB41C5122A32579199E1 /* Pods_Runner_Watch_App.framework in Frameworks */,
121 ); 121 );
122 runOnlyForDeploymentPostprocessing = 0; 122 runOnlyForDeploymentPostprocessing = 0;
123 }; 123 };
@@ -171,8 +171,8 @@ @@ -171,8 +171,8 @@
171 children = ( 171 children = (
172 66FBE5A72FDA518C00F515B4 /* WidgetKit.framework */, 172 66FBE5A72FDA518C00F515B4 /* WidgetKit.framework */,
173 66FBE5A92FDA518C00F515B4 /* SwiftUI.framework */, 173 66FBE5A92FDA518C00F515B4 /* SwiftUI.framework */,
174 - E8DC48B3736B7FEB548D0E65 /* Pods_Runner.framework */,  
175 - 7A488EFC0BD642ED604C4E43 /* Pods_Runner_Watch_App.framework */, 174 + 5CEEADFA95177019D949C8D0 /* Pods_Runner.framework */,
  175 + 32675A83AFB845DC8CA3467C /* Pods_Runner_Watch_App.framework */,
176 ); 176 );
177 name = Frameworks; 177 name = Frameworks;
178 sourceTree = "<group>"; 178 sourceTree = "<group>";
@@ -180,10 +180,10 @@ @@ -180,10 +180,10 @@
180 C9C45D06AF94828256154164 /* Pods */ = { 180 C9C45D06AF94828256154164 /* Pods */ = {
181 isa = PBXGroup; 181 isa = PBXGroup;
182 children = ( 182 children = (
183 - 276A214460495EB498491851 /* Pods-Runner.debug.xcconfig */,  
184 - B245A68D9E1E49A7A1C5C57A /* Pods-Runner.release.xcconfig */,  
185 - 27E4D5A8995AB1EC91E7330E /* Pods-Runner Watch App.debug.xcconfig */,  
186 - 6F3AFF2C02DF9B5A3593F751 /* Pods-Runner Watch App.release.xcconfig */, 183 + 9D4354F0FB273F6846CD38C3 /* Pods-Runner.debug.xcconfig */,
  184 + 7845C91D0615F45450905891 /* Pods-Runner.release.xcconfig */,
  185 + 6291BE76A39C6E31BC18338B /* Pods-Runner Watch App.debug.xcconfig */,
  186 + 0B1A5890F53172BA3C93CF69 /* Pods-Runner Watch App.release.xcconfig */,
187 ); 187 );
188 path = Pods; 188 path = Pods;
189 sourceTree = "<group>"; 189 sourceTree = "<group>";
@@ -195,20 +195,20 @@ @@ -195,20 +195,20 @@
195 isa = PBXNativeTarget; 195 isa = PBXNativeTarget;
196 buildConfigurationList = 66FBE59C2FDA4F1000F515B4 /* Build configuration list for PBXNativeTarget "Runner" */; 196 buildConfigurationList = 66FBE59C2FDA4F1000F515B4 /* Build configuration list for PBXNativeTarget "Runner" */;
197 buildPhases = ( 197 buildPhases = (
198 - 650BBC2B60529BD5A359701D /* [CP] Check Pods Manifest.lock */, 198 + 90A53D3C4EC7070BDEF1286D /* [CP] Check Pods Manifest.lock */,
199 66FBE57A2FDA4F0E00F515B4 /* Sources */, 199 66FBE57A2FDA4F0E00F515B4 /* Sources */,
200 66FBE57B2FDA4F0E00F515B4 /* Frameworks */, 200 66FBE57B2FDA4F0E00F515B4 /* Frameworks */,
201 66FBE57C2FDA4F0E00F515B4 /* Resources */, 201 66FBE57C2FDA4F0E00F515B4 /* Resources */,
202 66FBE59B2FDA4F1000F515B4 /* Embed Watch Content */, 202 66FBE59B2FDA4F1000F515B4 /* Embed Watch Content */,
203 66FB07192FDAA64500F515B4 /* ShellScript */, 203 66FB07192FDAA64500F515B4 /* ShellScript */,
204 66FB071A2FDAA65C00F515B4 /* Thin Binary */, 204 66FB071A2FDAA65C00F515B4 /* Thin Binary */,
205 - AEED982AFD101BCEF5E9554C /* [CP] Embed Pods Frameworks */,  
206 - 4F50D89F3617C0F6FEFA4C4F /* [CP] Copy Pods Resources */, 205 + 4348DC7B38CB739C4ABA7DAC /* [CP] Embed Pods Frameworks */,
  206 + E68ABE0C79927AE95370205A /* [CP] Copy Pods Resources */,
207 ); 207 );
208 buildRules = ( 208 buildRules = (
209 ); 209 );
210 dependencies = ( 210 dependencies = (
211 - 66FBE58E2FDA4F0F00F515B4 /* PBXTargetDependency */, 211 + 66569B6F2FE27D0400B7E33C /* PBXTargetDependency */,
212 ); 212 );
213 fileSystemSynchronizedGroups = ( 213 fileSystemSynchronizedGroups = (
214 66FBE5802FDA4F0E00F515B4 /* Runner */, 214 66FBE5802FDA4F0E00F515B4 /* Runner */,
@@ -222,12 +222,12 @@ @@ -222,12 +222,12 @@
222 isa = PBXNativeTarget; 222 isa = PBXNativeTarget;
223 buildConfigurationList = 66FBE5982FDA4F1000F515B4 /* Build configuration list for PBXNativeTarget "Runner Watch App" */; 223 buildConfigurationList = 66FBE5982FDA4F1000F515B4 /* Build configuration list for PBXNativeTarget "Runner Watch App" */;
224 buildPhases = ( 224 buildPhases = (
225 - F7289009DDDC1ECAC786520D /* [CP] Check Pods Manifest.lock */, 225 + BA66C644AE443BFC9EB5FA40 /* [CP] Check Pods Manifest.lock */,
226 66FBE5872FDA4F0F00F515B4 /* Sources */, 226 66FBE5872FDA4F0F00F515B4 /* Sources */,
227 66FBE5882FDA4F0F00F515B4 /* Frameworks */, 227 66FBE5882FDA4F0F00F515B4 /* Frameworks */,
228 66FBE5892FDA4F0F00F515B4 /* Resources */, 228 66FBE5892FDA4F0F00F515B4 /* Resources */,
229 66FBE5BE2FDA518D00F515B4 /* Embed Foundation Extensions */, 229 66FBE5BE2FDA518D00F515B4 /* Embed Foundation Extensions */,
230 - DFE431650B789D7B2379EBFD /* [CP] Embed Pods Frameworks */, 230 + 1F69C09D185F42507815E3C2 /* [CP] Embed Pods Frameworks */,
231 ); 231 );
232 buildRules = ( 232 buildRules = (
233 ); 233 );
@@ -297,43 +297,38 @@ @@ -297,43 +297,38 @@
297 /* End PBXResourcesBuildPhase section */ 297 /* End PBXResourcesBuildPhase section */
298 298
299 /* Begin PBXShellScriptBuildPhase section */ 299 /* Begin PBXShellScriptBuildPhase section */
300 - 4F50D89F3617C0F6FEFA4C4F /* [CP] Copy Pods Resources */ = { 300 + 1F69C09D185F42507815E3C2 /* [CP] Embed Pods Frameworks */ = {
301 isa = PBXShellScriptBuildPhase; 301 isa = PBXShellScriptBuildPhase;
302 buildActionMask = 2147483647; 302 buildActionMask = 2147483647;
303 files = ( 303 files = (
304 ); 304 );
305 inputFileListPaths = ( 305 inputFileListPaths = (
306 - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", 306 + "${PODS_ROOT}/Target Support Files/Pods-Runner Watch App/Pods-Runner Watch App-frameworks-${CONFIGURATION}-input-files.xcfilelist",
307 ); 307 );
308 - name = "[CP] Copy Pods Resources"; 308 + name = "[CP] Embed Pods Frameworks";
309 outputFileListPaths = ( 309 outputFileListPaths = (
310 - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", 310 + "${PODS_ROOT}/Target Support Files/Pods-Runner Watch App/Pods-Runner Watch App-frameworks-${CONFIGURATION}-output-files.xcfilelist",
311 ); 311 );
312 runOnlyForDeploymentPostprocessing = 0; 312 runOnlyForDeploymentPostprocessing = 0;
313 shellPath = /bin/sh; 313 shellPath = /bin/sh;
314 - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; 314 + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner Watch App/Pods-Runner Watch App-frameworks.sh\"\n";
315 showEnvVarsInLog = 0; 315 showEnvVarsInLog = 0;
316 }; 316 };
317 - 650BBC2B60529BD5A359701D /* [CP] Check Pods Manifest.lock */ = { 317 + 4348DC7B38CB739C4ABA7DAC /* [CP] Embed Pods Frameworks */ = {
318 isa = PBXShellScriptBuildPhase; 318 isa = PBXShellScriptBuildPhase;
319 buildActionMask = 2147483647; 319 buildActionMask = 2147483647;
320 files = ( 320 files = (
321 ); 321 );
322 inputFileListPaths = ( 322 inputFileListPaths = (
  323 + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
323 ); 324 );
324 - inputPaths = (  
325 - "${PODS_PODFILE_DIR_PATH}/Podfile.lock",  
326 - "${PODS_ROOT}/Manifest.lock",  
327 - );  
328 - name = "[CP] Check Pods Manifest.lock"; 325 + name = "[CP] Embed Pods Frameworks";
329 outputFileListPaths = ( 326 outputFileListPaths = (
330 - );  
331 - outputPaths = (  
332 - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 327 + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
333 ); 328 );
334 runOnlyForDeploymentPostprocessing = 0; 329 runOnlyForDeploymentPostprocessing = 0;
335 shellPath = /bin/sh; 330 shellPath = /bin/sh;
336 - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 331 + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
337 showEnvVarsInLog = 0; 332 showEnvVarsInLog = 0;
338 }; 333 };
339 66FB07192FDAA64500F515B4 /* ShellScript */ = { 334 66FB07192FDAA64500F515B4 /* ShellScript */ = {
@@ -371,60 +366,65 @@ @@ -371,60 +366,65 @@
371 shellPath = /bin/sh; 366 shellPath = /bin/sh;
372 shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; 367 shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n";
373 }; 368 };
374 - AEED982AFD101BCEF5E9554C /* [CP] Embed Pods Frameworks */ = { 369 + 90A53D3C4EC7070BDEF1286D /* [CP] Check Pods Manifest.lock */ = {
375 isa = PBXShellScriptBuildPhase; 370 isa = PBXShellScriptBuildPhase;
376 buildActionMask = 2147483647; 371 buildActionMask = 2147483647;
377 files = ( 372 files = (
378 ); 373 );
379 inputFileListPaths = ( 374 inputFileListPaths = (
380 - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",  
381 ); 375 );
382 - name = "[CP] Embed Pods Frameworks"; 376 + inputPaths = (
  377 + "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
  378 + "${PODS_ROOT}/Manifest.lock",
  379 + );
  380 + name = "[CP] Check Pods Manifest.lock";
383 outputFileListPaths = ( 381 outputFileListPaths = (
384 - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", 382 + );
  383 + outputPaths = (
  384 + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
385 ); 385 );
386 runOnlyForDeploymentPostprocessing = 0; 386 runOnlyForDeploymentPostprocessing = 0;
387 shellPath = /bin/sh; 387 shellPath = /bin/sh;
388 - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 388 + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
389 showEnvVarsInLog = 0; 389 showEnvVarsInLog = 0;
390 }; 390 };
391 - DFE431650B789D7B2379EBFD /* [CP] Embed Pods Frameworks */ = { 391 + BA66C644AE443BFC9EB5FA40 /* [CP] Check Pods Manifest.lock */ = {
392 isa = PBXShellScriptBuildPhase; 392 isa = PBXShellScriptBuildPhase;
393 buildActionMask = 2147483647; 393 buildActionMask = 2147483647;
394 files = ( 394 files = (
395 ); 395 );
396 inputFileListPaths = ( 396 inputFileListPaths = (
397 - "${PODS_ROOT}/Target Support Files/Pods-Runner Watch App/Pods-Runner Watch App-frameworks-${CONFIGURATION}-input-files.xcfilelist",  
398 ); 397 );
399 - name = "[CP] Embed Pods Frameworks"; 398 + inputPaths = (
  399 + "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
  400 + "${PODS_ROOT}/Manifest.lock",
  401 + );
  402 + name = "[CP] Check Pods Manifest.lock";
400 outputFileListPaths = ( 403 outputFileListPaths = (
401 - "${PODS_ROOT}/Target Support Files/Pods-Runner Watch App/Pods-Runner Watch App-frameworks-${CONFIGURATION}-output-files.xcfilelist", 404 + );
  405 + outputPaths = (
  406 + "$(DERIVED_FILE_DIR)/Pods-Runner Watch App-checkManifestLockResult.txt",
402 ); 407 );
403 runOnlyForDeploymentPostprocessing = 0; 408 runOnlyForDeploymentPostprocessing = 0;
404 shellPath = /bin/sh; 409 shellPath = /bin/sh;
405 - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner Watch App/Pods-Runner Watch App-frameworks.sh\"\n"; 410 + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
406 showEnvVarsInLog = 0; 411 showEnvVarsInLog = 0;
407 }; 412 };
408 - F7289009DDDC1ECAC786520D /* [CP] Check Pods Manifest.lock */ = { 413 + E68ABE0C79927AE95370205A /* [CP] Copy Pods Resources */ = {
409 isa = PBXShellScriptBuildPhase; 414 isa = PBXShellScriptBuildPhase;
410 buildActionMask = 2147483647; 415 buildActionMask = 2147483647;
411 files = ( 416 files = (
412 ); 417 );
413 inputFileListPaths = ( 418 inputFileListPaths = (
  419 + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
414 ); 420 );
415 - inputPaths = (  
416 - "${PODS_PODFILE_DIR_PATH}/Podfile.lock",  
417 - "${PODS_ROOT}/Manifest.lock",  
418 - );  
419 - name = "[CP] Check Pods Manifest.lock"; 421 + name = "[CP] Copy Pods Resources";
420 outputFileListPaths = ( 422 outputFileListPaths = (
421 - );  
422 - outputPaths = (  
423 - "$(DERIVED_FILE_DIR)/Pods-Runner Watch App-checkManifestLockResult.txt", 423 + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
424 ); 424 );
425 runOnlyForDeploymentPostprocessing = 0; 425 runOnlyForDeploymentPostprocessing = 0;
426 shellPath = /bin/sh; 426 shellPath = /bin/sh;
427 - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 427 + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
428 showEnvVarsInLog = 0; 428 showEnvVarsInLog = 0;
429 }; 429 };
430 /* End PBXShellScriptBuildPhase section */ 430 /* End PBXShellScriptBuildPhase section */
@@ -450,10 +450,10 @@ @@ -450,10 +450,10 @@
450 /* End PBXSourcesBuildPhase section */ 450 /* End PBXSourcesBuildPhase section */
451 451
452 /* Begin PBXTargetDependency section */ 452 /* Begin PBXTargetDependency section */
453 - 66FBE58E2FDA4F0F00F515B4 /* PBXTargetDependency */ = { 453 + 66569B6F2FE27D0400B7E33C /* PBXTargetDependency */ = {
454 isa = PBXTargetDependency; 454 isa = PBXTargetDependency;
455 target = 66FBE58A2FDA4F0F00F515B4 /* Runner Watch App */; 455 target = 66FBE58A2FDA4F0F00F515B4 /* Runner Watch App */;
456 - targetProxy = 66FBE58D2FDA4F0F00F515B4 /* PBXContainerItemProxy */; 456 + targetProxy = 66569B6E2FE27D0400B7E33C /* PBXContainerItemProxy */;
457 }; 457 };
458 /* End PBXTargetDependency section */ 458 /* End PBXTargetDependency section */
459 459
@@ -576,7 +576,7 @@ @@ -576,7 +576,7 @@
576 }; 576 };
577 66FBE5992FDA4F1000F515B4 /* Debug */ = { 577 66FBE5992FDA4F1000F515B4 /* Debug */ = {
578 isa = XCBuildConfiguration; 578 isa = XCBuildConfiguration;
579 - baseConfigurationReference = 27E4D5A8995AB1EC91E7330E /* Pods-Runner Watch App.debug.xcconfig */; 579 + baseConfigurationReference = 6291BE76A39C6E31BC18338B /* Pods-Runner Watch App.debug.xcconfig */;
580 buildSettings = { 580 buildSettings = {
581 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 581 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
582 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 582 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
@@ -613,7 +613,7 @@ @@ -613,7 +613,7 @@
613 }; 613 };
614 66FBE59A2FDA4F1000F515B4 /* Release */ = { 614 66FBE59A2FDA4F1000F515B4 /* Release */ = {
615 isa = XCBuildConfiguration; 615 isa = XCBuildConfiguration;
616 - baseConfigurationReference = 6F3AFF2C02DF9B5A3593F751 /* Pods-Runner Watch App.release.xcconfig */; 616 + baseConfigurationReference = 0B1A5890F53172BA3C93CF69 /* Pods-Runner Watch App.release.xcconfig */;
617 buildSettings = { 617 buildSettings = {
618 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 618 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
619 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 619 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
@@ -181,6 +181,7 @@ class WearEngineApiPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable @@ -181,6 +181,7 @@ class WearEngineApiPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable
181 static let shared = WearEngineApiPigeonCodec(readerWriter: WearEngineApiPigeonCodecReaderWriter()) 181 static let shared = WearEngineApiPigeonCodec(readerWriter: WearEngineApiPigeonCodecReaderWriter())
182 } 182 }
183 183
  184 +
184 /// Generated protocol from Pigeon that represents a handler of messages from Flutter. 185 /// Generated protocol from Pigeon that represents a handler of messages from Flutter.
185 protocol WearEngineHostApi { 186 protocol WearEngineHostApi {
186 func hasAvailableDevices() throws -> Bool 187 func hasAvailableDevices() throws -> Bool
@@ -190,7 +191,7 @@ protocol WearEngineHostApi { @@ -190,7 +191,7 @@ protocol WearEngineHostApi {
190 func sendWatchSyncPayload(jsonPayload: String) throws -> Bool 191 func sendWatchSyncPayload(jsonPayload: String) throws -> Bool
191 /// Opens the system photo picker and returns a local PNG file path after 192 /// Opens the system photo picker and returns a local PNG file path after
192 /// removing the image background on the host platform. 193 /// removing the image background on the host platform.
193 - func pickImageAndRemoveBackground() throws -> String? 194 + func removeBackground(originImagePath: String, completion: @escaping (Result<String?, Error>) -> Void)
194 } 195 }
195 196
196 /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. 197 /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
@@ -270,18 +271,22 @@ class WearEngineHostApiSetup { @@ -270,18 +271,22 @@ class WearEngineHostApiSetup {
270 } 271 }
271 /// Opens the system photo picker and returns a local PNG file path after 272 /// Opens the system photo picker and returns a local PNG file path after
272 /// removing the image background on the host platform. 273 /// removing the image background on the host platform.
273 - let pickImageAndRemoveBackgroundChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.WearEngineHostApi.pickImageAndRemoveBackground\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) 274 + let removeBackgroundChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.WearEngineHostApi.removeBackground\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
274 if let api = api { 275 if let api = api {
275 - pickImageAndRemoveBackgroundChannel.setMessageHandler { _, reply in  
276 - do {  
277 - let result = try api.pickImageAndRemoveBackground()  
278 - reply(wrapResult(result))  
279 - } catch {  
280 - reply(wrapError(error)) 276 + removeBackgroundChannel.setMessageHandler { message, reply in
  277 + let args = message as! [Any?]
  278 + let originImagePathArg = args[0] as! String
  279 + api.removeBackground(originImagePath: originImagePathArg) { result in
  280 + switch result {
  281 + case .success(let res):
  282 + reply(wrapResult(res))
  283 + case .failure(let error):
  284 + reply(wrapError(error))
  285 + }
281 } 286 }
282 } 287 }
283 } else { 288 } else {
284 - pickImageAndRemoveBackgroundChannel.setMessageHandler(nil) 289 + removeBackgroundChannel.setMessageHandler(nil)
285 } 290 }
286 } 291 }
287 } 292 }
@@ -3,6 +3,10 @@ import PhotosUI @@ -3,6 +3,10 @@ import PhotosUI
3 import UIKit 3 import UIKit
4 import Vision 4 import Vision
5 5
  6 +enum ImageProcessError: Error{
  7 + case invalidatePath
  8 +}
  9 +
6 final class WearEngineHostApiImpl: WearEngineHostApi { 10 final class WearEngineHostApiImpl: WearEngineHostApi {
7 private let watchService: WatchConnectivityService 11 private let watchService: WatchConnectivityService
8 12
@@ -30,100 +34,21 @@ final class WearEngineHostApiImpl: WearEngineHostApi { @@ -30,100 +34,21 @@ final class WearEngineHostApiImpl: WearEngineHostApi {
30 watchService.syncPayload(jsonPayload: jsonPayload) 34 watchService.syncPayload(jsonPayload: jsonPayload)
31 } 35 }
32 36
33 - func pickImageAndRemoveBackground() throws -> String? {  
34 - if #available(iOS 14.0, *) {  
35 - return WatchThemeImagePicker().pickImageAndRemoveBackground()  
36 - }  
37 - return nil  
38 - }  
39 -}  
40 -  
41 -@available(iOS 14.0, *)  
42 -private final class WatchThemeImagePicker: NSObject, PHPickerViewControllerDelegate {  
43 - private var continuation: CheckedContinuation<String?, Never>?  
44 -  
45 - func pickImageAndRemoveBackground() -> String? {  
46 - if Thread.isMainThread {  
47 - return runOnMain()  
48 - }  
49 -  
50 - var result: String?  
51 - let semaphore = DispatchSemaphore(value: 0)  
52 - DispatchQueue.main.async {  
53 - result = self.runOnMain()  
54 - semaphore.signal()  
55 - }  
56 - semaphore.wait()  
57 - return result  
58 - }  
59 -  
60 - private func runOnMain() -> String? {  
61 - var configuration = PHPickerConfiguration(photoLibrary: .shared())  
62 - configuration.filter = .images  
63 - configuration.selectionLimit = 1  
64 -  
65 - guard let presenter = UIApplication.shared.topMostViewController else {  
66 - return nil  
67 - }  
68 -  
69 - let picker = PHPickerViewController(configuration: configuration)  
70 - picker.delegate = self  
71 -  
72 - return waitForPickerResult(picker: picker, presenter: presenter)  
73 - }  
74 -  
75 - private func waitForPickerResult(  
76 - picker: PHPickerViewController,  
77 - presenter: UIViewController  
78 - ) -> String? {  
79 - var pickedPath: String?  
80 - let semaphore = DispatchSemaphore(value: 0)  
81 -  
82 - Task { @MainActor in  
83 - pickedPath = await withCheckedContinuation { continuation in  
84 - self.continuation = continuation  
85 - presenter.present(picker, animated: true)  
86 - }  
87 - semaphore.signal()  
88 - }  
89 -  
90 - while semaphore.wait(timeout: .now() + 0.05) == .timedOut {  
91 - RunLoop.main.run(mode: .default, before: Date(timeIntervalSinceNow: 0.05))  
92 - }  
93 - return pickedPath  
94 - }  
95 -  
96 - nonisolated func picker(  
97 - _ picker: PHPickerViewController,  
98 - didFinishPicking results: [PHPickerResult]  
99 - ) {  
100 - Task { @MainActor in  
101 - picker.dismiss(animated: true)  
102 -  
103 - guard let provider = results.first?.itemProvider,  
104 - provider.canLoadObject(ofClass: UIImage.self) else {  
105 - continuation?.resume(returning: nil)  
106 - continuation = nil  
107 - return  
108 - }  
109 -  
110 - provider.loadObject(ofClass: UIImage.self) { object, _ in  
111 - Task { @MainActor in  
112 - guard let image = object as? UIImage else {  
113 - self.continuation?.resume(returning: nil)  
114 - self.continuation = nil 37 + func removeBackground(originImagePath: String, completion: @escaping (Result<String?, any Error>) -> Void) {
  38 + // 抠图
  39 + guard let image = UIImage(contentsOfFile: originImagePath) else{
  40 + completion(.failure(ImageProcessError.invalidatePath))
115 return 41 return
116 - }  
117 - let processed = await WatchThemeImageProcessor.removeBackground(from: image)  
118 - let path = WatchThemeImageProcessor.savePNG(processed)  
119 - self.continuation?.resume(returning: path)  
120 - self.continuation = nil  
121 } 42 }
122 - } 43 + Task{
  44 + let processed = await WatchThemeImageProcessor.removeBackground(from: image)
  45 + let path = WatchThemeImageProcessor.savePNG(processed)
  46 + completion(.success(path))
  47 + }
123 } 48 }
124 - }  
125 } 49 }
126 50
  51 +
127 private enum WatchThemeImageProcessor { 52 private enum WatchThemeImageProcessor {
128 static func removeBackground(from image: UIImage) async -> UIImage { 53 static func removeBackground(from image: UIImage) async -> UIImage {
129 guard #available(iOS 17.0, *), 54 guard #available(iOS 17.0, *),
@@ -5,6 +5,7 @@ import 'package:doublefeel_flutter/core/util/app_toast.dart'; @@ -5,6 +5,7 @@ import 'package:doublefeel_flutter/core/util/app_toast.dart';
5 import 'package:doublefeel_flutter/pigeon/wear_engine_api.g.dart'; 5 import 'package:doublefeel_flutter/pigeon/wear_engine_api.g.dart';
6 import 'package:flutter/material.dart'; 6 import 'package:flutter/material.dart';
7 import 'package:get/get.dart'; 7 import 'package:get/get.dart';
  8 +import 'package:image_picker/image_picker.dart';
8 9
9 import '../models/watch_theme_models.dart'; 10 import '../models/watch_theme_models.dart';
10 import '../widgets/watch_theme_dialogs.dart'; 11 import '../widgets/watch_theme_dialogs.dart';
@@ -13,6 +14,7 @@ class CreateWatchThemeController extends GetxController { @@ -13,6 +14,7 @@ class CreateWatchThemeController extends GetxController {
13 CreateWatchThemeController(this._themeApi); 14 CreateWatchThemeController(this._themeApi);
14 15
15 final ThemeApi _themeApi; 16 final ThemeApi _themeApi;
  17 + final WearEngineHostApi _wearEngineHostApi = WearEngineHostApi();
16 18
17 final customThemeName = ''.obs; 19 final customThemeName = ''.obs;
18 final agreedToSubmission = true.obs; 20 final agreedToSubmission = true.obs;
@@ -43,13 +45,11 @@ class CreateWatchThemeController extends GetxController { @@ -43,13 +45,11 @@ class CreateWatchThemeController extends GetxController {
43 customImagePaths.every((path) => path != null && path.isNotEmpty); 45 customImagePaths.every((path) => path != null && path.isNotEmpty);
44 46
45 Future<void> pickCustomImage(int index) async { 47 Future<void> pickCustomImage(int index) async {
46 - try {  
47 - final path = await WearEngineHostApi().pickImageAndRemoveBackground();  
48 - if (path == null || path.isEmpty) {  
49 - return;  
50 - }  
51 - customImagePaths[index] = path;  
52 - } catch (error) { 48 + final picker = ImagePicker();
  49 + final XFile? image = await picker.pickImage(source: ImageSource.gallery);
  50 + if (image != null) {
  51 + customImagePaths[index] = image.path;
  52 + } else {
53 AppToast.show('图片选择失败'); 53 AppToast.show('图片选择失败');
54 } 54 }
55 } 55 }
@@ -95,26 +95,58 @@ class CreateWatchThemeController extends GetxController { @@ -95,26 +95,58 @@ class CreateWatchThemeController extends GetxController {
95 } 95 }
96 96
97 isSaving.value = true; 97 isSaving.value = true;
98 - final result = await _themeApi.createTheme(  
99 - name: customThemeName.value,  
100 - fullOfEnergyName: customStatusNames[0],  
101 - normalName: customStatusNames[1],  
102 - overpressureName: customStatusNames[3],  
103 - fullOfEnergyImage: customImagePaths[0] ?? '',  
104 - normalImage: customImagePaths[1] ?? '',  
105 - overpressureImage: customImagePaths[3] ?? customImagePaths[2] ?? '',  
106 - );  
107 - isSaving.value = false;  
108 98
109 - if (result is! AppSuccess<void>) {  
110 - AppToast.show('主题保存失败');  
111 - return; 99 + var imagePath1 = customImagePaths[0];
  100 + var imagePath2 = customImagePaths[1];
  101 + var imagePath3 = customImagePaths[2];
  102 + var imagePath4 = customImagePaths[3];
  103 +
  104 + if (imagePath1 != null) {
  105 + final path = await _wearEngineHostApi.removeBackground(imagePath1);
  106 + if (path != null) {
  107 + imagePath1 = path;
  108 + }
  109 + }
  110 + if (imagePath2 != null) {
  111 + final path = await _wearEngineHostApi.removeBackground(imagePath2);
  112 + if (path != null) {
  113 + imagePath2 = path;
  114 + }
  115 + }
  116 + if (imagePath3 != null) {
  117 + final path = await _wearEngineHostApi.removeBackground(imagePath3);
  118 + if (path != null) {
  119 + imagePath3 = path;
  120 + }
  121 + }
  122 + if (imagePath4 != null) {
  123 + final path = await _wearEngineHostApi.removeBackground(imagePath4);
  124 + if (path != null) {
  125 + imagePath4 = path;
  126 + }
112 } 127 }
113 128
114 - final createdTheme = await _loadCreatedTheme();  
115 - Get.toNamed(Routes.WATCH_THEME_CUSTOM_PREVIEW, arguments: {  
116 - 'theme': createdTheme ?? _buildThemeItem(),  
117 - }); 129 + //TODO: - 上传图片
  130 +
  131 + // final result = await _themeApi.createTheme(
  132 + // name: customThemeName.value,
  133 + // fullOfEnergyName: customStatusNames[0],
  134 + // normalName: customStatusNames[1],
  135 + // overpressureName: customStatusNames[3],
  136 + // fullOfEnergyImage: customImagePaths[0] ?? '',
  137 + // normalImage: customImagePaths[1] ?? '',
  138 + // overpressureImage: customImagePaths[3] ?? customImagePaths[2] ?? '',
  139 + // );
  140 + isSaving.value = false;
  141 +
  142 + //Test: - 测试抠图结果
  143 + customImagePaths.value = [imagePath1, imagePath2, imagePath3, imagePath4];
  144 + customImagePaths.refresh();
  145 +
  146 + // final createdTheme = await _loadCreatedTheme();
  147 + // Get.toNamed(Routes.WATCH_THEME_CUSTOM_PREVIEW, arguments: {
  148 + // 'theme': createdTheme ?? _buildThemeItem(),
  149 + // });
118 } 150 }
119 151
120 WatchThemeItem _buildThemeItem() { 152 WatchThemeItem _buildThemeItem() {
@@ -258,14 +258,14 @@ class WearEngineHostApi { @@ -258,14 +258,14 @@ class WearEngineHostApi {
258 258
259 /// Opens the system photo picker and returns a local PNG file path after 259 /// Opens the system photo picker and returns a local PNG file path after
260 /// removing the image background on the host platform. 260 /// removing the image background on the host platform.
261 - Future<String?> pickImageAndRemoveBackground() async {  
262 - final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.WearEngineHostApi.pickImageAndRemoveBackground$pigeonVar_messageChannelSuffix'; 261 + Future<String?> removeBackground(String originImagePath) async {
  262 + final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.WearEngineHostApi.removeBackground$pigeonVar_messageChannelSuffix';
263 final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>( 263 final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
264 pigeonVar_channelName, 264 pigeonVar_channelName,
265 pigeonChannelCodec, 265 pigeonChannelCodec,
266 binaryMessenger: pigeonVar_binaryMessenger, 266 binaryMessenger: pigeonVar_binaryMessenger,
267 ); 267 );
268 - final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null); 268 + final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[originImagePath]);
269 final List<Object?>? pigeonVar_replyList = 269 final List<Object?>? pigeonVar_replyList =
270 await pigeonVar_sendFuture as List<Object?>?; 270 await pigeonVar_sendFuture as List<Object?>?;
271 if (pigeonVar_replyList == null) { 271 if (pigeonVar_replyList == null) {
@@ -40,7 +40,9 @@ abstract class WearEngineHostApi { @@ -40,7 +40,9 @@ abstract class WearEngineHostApi {
40 40
41 bool sendWatchSyncPayload(String jsonPayload); 41 bool sendWatchSyncPayload(String jsonPayload);
42 42
  43 +
43 /// Opens the system photo picker and returns a local PNG file path after 44 /// Opens the system photo picker and returns a local PNG file path after
44 /// removing the image background on the host platform. 45 /// removing the image background on the host platform.
45 - String? pickImageAndRemoveBackground(); 46 + @async
  47 + String? removeBackground(String originImagePath);
46 } 48 }