capacitor-assets icon indicating copy to clipboard operation
capacitor-assets copied to clipboard

Feedback requested: Capacitor Assets Use Cases

Open mlynch opened this issue 3 years ago • 47 comments

Hi everyone,

I am going to be working on getting the Capacitor Assets (formerly cordova-res) tool updated and modernized, to enable developers to more efficiently manage their app icon/splash assets.

I would love to hear what you hope to get out of this tool or how you were using the cordova-res project.

A few goals that we have for the new version of this project:

  • [x] Move to focusing exclusively on Capacitor to simplify and focus the project (thus, dropping Cordova support)
  • [x] Better enable whitelable use cases to make it much easier to swap images and assets out instead of simply generating new ones
  • [x] Integrate with the new @capacitor/configure and @capacitor/project tools to go beyond asset generation to actually configuring and managing your native Capacitor projects with the appropriate assets
  • [x] Be easily incorporated into a cloud build workflow, such as Ionic Appflow for managing assets in a CI/CD pipeline
  • [ ] Support custom icons for notifications/etc.
  • [x] Add support for PWA manifests and PWA assets
  • [x] Support dark mode splashes/icons
  • [x] Add support for new image formats, like SVG
  • [x] Better support for Android Adaptive icons

With this in mind, I'd love feedback and thoughts on the use cases you have for image/asset generation and ideas on how we can make this tool more useful for you.

mlynch avatar Mar 09 '22 19:03 mlynch

Thank you for this! I'm not sure if this is a Capacitor or iOS issue, but I've noticed that my iOS builds are several times larger than my Android ones (~15mb vs ~4mb). It's the same code base so the only difference is I have a lot more app icon and splash icon sizes and formats on iOS. Is there any way to make it so that only the icons that are relevant to the user's device get downloaded? It seems like this would dramatically reduce the download size of apps on iOS. Maybe I'm adding too many icon options and there's a single icon format that would work for all iOS device types. In this case, just making that clearer would be extremely helpful.

alexandermorgan avatar Mar 09 '22 20:03 alexandermorgan

I have not used this tool before, but the most difficult part of shipping on Android is creating a 9 patch splash screen.

As far as I understand it it's supposed to fit on any Android screen, but from my experience it gets squashed no matter what I do 😂

Would love a better way to work around that issue.

Hope that helps!

leo-petrucci avatar Mar 09 '22 20:03 leo-petrucci

@alexandermorgan hard to say without looking at it but either way I think I already cut a number of generated images, I need to see.

The size difference is likely due to embedding Swift libraries. The work Apple did in the App Store means the actual size that users download can be much smaller since it can strip away a lot of that especially in recent versions of Swift.

mlynch avatar Mar 09 '22 20:03 mlynch

@creativiii yea I need to assess where we are with 9 patches, there is definitely work to be done for better Android Adaptive icon support

mlynch avatar Mar 09 '22 20:03 mlynch

Hey boss! I'd love support for PWA manifest images to be included as well. This would fit Ionic's cross-platform/"build once" mantra of supporting web, ios, android out-of-the-box. Other tools do exist to create these though, so it's not a must-have.

dotNetkow avatar Mar 09 '22 21:03 dotNetkow

@dotNetkow great point. IIRC I already added this into my WIP branch a few months ago so this is definitely happening

mlynch avatar Mar 09 '22 21:03 mlynch

It's been a few months since the last time I used cordova-res, but I remember that I had an issue with folders that are missing in Android while I was generating the splash screen & app icon. I'm not sure if it's solved now, so I would already be satisfied if I don't have this problem with Capacitor Assets haha.

I would like that we incorporate notification icon in this new plugin, it is not handled by cordova-res. If I remember well, for iOS, no notification icon is required but for Android, you need to have the same icon than the app icon but in white, the color of the icon is added in the code somewhere in Android config files.

JulienLecoq avatar Mar 10 '22 17:03 JulienLecoq

@JulienLecoq great idea. Seems we should support Notification, Settings, and Spotlight icons at least for iOS, not sure if there are additional ones we should support for Android:

image

https://developer.apple.com/design/human-interface-guidelines/ios/icons-and-images/app-icon/

mlynch avatar Mar 11 '22 16:03 mlynch

The other feature what we need here is the Adaptive Icons support for the Android devices: There are lot of open issues for this:

https://github.com/ionic-team/capacitor-assets/issues/164

https://github.com/ionic-team/capacitor/issues/229

Sampath-Lokuge avatar Mar 11 '22 16:03 Sampath-Lokuge

Yes good point that will be a key focus for this

mlynch avatar Mar 11 '22 16:03 mlynch

Can someone verify my understanding here: on iOS if you want to provide a different icon for notifications and settings, you should modify the smaller sizes of your icons listed here: https://developer.apple.com/design/human-interface-guidelines/ios/icons-and-images/app-icon/

There is no special icon set for notifications/etc. right? They are just taken from your main AppIcons?

In that case I think we'll overwrite those smaller icons if you provide specific notification/settings ones in your assets

mlynch avatar Mar 11 '22 17:03 mlynch

Hey everyone, the first alpha release of @capacitor/assets is ready for testing. It supports generating assets for iOS, Android, and PWA. For Android it supports Adaptive Icons and legacy icons. Both iOS and Android also support generating light and dark mode splash screens.

I know there is still work to be done on the tool, but I would really love some help testing and some feedback on things that are still missing.

To get started, check out the readme for the 1.x branch and I look forward to your feedback:

https://github.com/ionic-team/capacitor-assets/blob/1.x/README.md

mlynch avatar Mar 17 '22 21:03 mlynch

@mlynch thanks a lot for this i just give it a try and some feedback:

  • the script to add in package json is wrong it say to add that
{
  "scripts": {
    "capacitor-assets": "capacitor-assets"
  }
}

but it should be

{
  "scripts": {
    "capacitor-assets": "capacitor-assets generate"
  }
}
  • the readme say it expects resources folder but that wrong it's a assets

I have made a PR for theses : https://github.com/ionic-team/capacitor-assets/pull/296

Otherwise, the tool worked well, and way faster than the old one ! I will love to have this tool also create the notification icon for Android platform.

I good addition i would love to have: A quick generator, most of my app use the logo in centre in the spashscreen background is same in icon and splash. So have a way to generate all from a colour and foreground icon would make our life easier.

riderx avatar Mar 18 '22 03:03 riderx

@riderx for the last addition, meaning you just take a logo and it and generates the other assets for you so you don't have to create the source splash.png etc?

This would be primarily for splash screens?

Seems reasonable

mlynch avatar Mar 21 '22 14:03 mlynch

Yes Exactly :)

riderx avatar Mar 21 '22 18:03 riderx

@riderx Got the iOS side of that done, moving to android + pwa

mlynch avatar Mar 22 '22 14:03 mlynch

@mlynch amazing ! i just try my Android app and all assets got broken link. i think migrate from old asset's system to new one has issue on Android. I'm trying to understand why i get Invalid resource directory name, i event try to remove android folder and add again to see if that come from one of my config but still same issue

riderx avatar Mar 22 '22 14:03 riderx

@riderx 1.0.0-next.2 is out and it supports generating all assets from a single logo file.

Check out the new Easy Mode docs, curious to get your feedback 😄 https://github.com/ionic-team/capacitor-assets/tree/1.x#usage---easy-mode

mlynch avatar Mar 24 '22 22:03 mlynch

Made my day! I just discovered quasar has same kind of features, have a check there lot of interesting stuff! I will check tomorrow :)

riderx avatar Mar 25 '22 00:03 riderx

@mlynch i tryed capacitor-assets generate --iconBackgroundColor '#FFFFFF' --iconBackgroundColorDark '#111111' --splashBackgroundColor '#FFFFFF' --splashBackgroundColorDark '#111111'

with the last version 1.0.0-next.1 and this logo : logo and got some errors:

Unable to generate assets TypeError: Cannot use 'in' operator to search for 'alpha' in true
    at new Color (/Users/martindonadieu/Documents/Projects.nosync/Capacitor/capgo/node_modules/.pnpm/[email protected]/node_modules/color/index.js:77:15)
    at Color (/Users/martindonadieu/Documents/Projects.nosync/Capacitor/capgo/node_modules/.pnpm/[email protected]/node_modules/color/index.js:26:10)
    at Sharp._createInputDescriptor (/Users/martindonadieu/Documents/Projects.nosync/Capacitor/capgo/node_modules/.pnpm/[email protected]/node_modules/sharp/lib/input.js:216:30)
    at new Sharp (/Users/martindonadieu/Documents/Projects.nosync/Capacitor/capgo/node_modules/.pnpm/[email protected]/node_modules/sharp/lib/constructor.js:289:29)
    at Sharp (/Users/martindonadieu/Documents/Projects.nosync/Capacitor/capgo/node_modules/.pnpm/[email protected]/node_modules/sharp/lib/constructor.js:137:12)
    at AndroidAssetGenerator._generateAdaptiveIconsFromLogo (/Users/martindonadieu/Documents/Projects.nosync/Capacitor/capgo/node_modules/.pnpm/@[email protected]_e79e62fe450383fd2d418267dc75e645/node_modules/@capacitor/assets/dist/platforms/android/index.js:81:52)
    at AndroidAssetGenerator.generateFromLogo (/Users/martindonadieu/Documents/Projects.nosync/Capacitor/capgo/node_modules/.pnpm/@[email protected]_e79e62fe450383fd2d418267dc75e645/node_modules/@capacitor/assets/dist/platforms/android/index.js:50:51)
    at AndroidAssetGenerator.generate (/Users/martindonadieu/Documents/Projects.nosync/Capacitor/capgo/node_modules/.pnpm/@[email protected]_e79e62fe450383fd2d418267dc75e645/node_modules/@capacitor/assets/dist/platforms/android/index.js:25:29)
    at InputAsset.generate (/Users/martindonadieu/Documents/Projects.nosync/Capacitor/capgo/node_modules/.pnpm/@[email protected]_e79e62fe450383fd2d418267dc75e645/node_modules/@capacitor/assets/dist/input-asset.js:41:25)
    at /Users/martindonadieu/Documents/Projects.nosync/Capacitor/capgo/node_modules/.pnpm/@[email protected]_e79e62fe450383fd2d418267dc75e645/node_modules/@capacitor/assets/dist/tasks/generate.js:51:63

It seems from the log i cannot have alpha channel in my logo. Edit: i tried to use a logo with background and same issue.

riderx avatar Mar 25 '22 16:03 riderx

Okay thanks for the report will look at this right now @riderx

mlynch avatar Mar 25 '22 16:03 mlynch

@mlynch there a need to change the folder name from ressources to assets ? i see some cordova tools rely on the name of the folder. Maybe we can keep it for compatibility reason ?

riderx avatar Mar 25 '22 19:03 riderx

@riderx haven't fixed that issue yet but will soon once I finish up the pwa splash generation which is the last big task. I can easily support resources or assets

mlynch avatar Mar 26 '22 15:03 mlynch

Thanks to keep me posted 👌

riderx avatar Mar 27 '22 16:03 riderx

@riderx can you try @capacitor/[email protected]@next? I made a bunch of changes and fixed the issue you reported above (I wasn't correctly implementing the command flags).

I added easy mode/logo generation to all platforms and this is just about getting close to a 1.0 release I think

mlynch avatar Mar 29 '22 18:03 mlynch

This go to the end again and seems correct with splash and icon but i'm back with the issue in android.


2: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':app:mergeDebugResources'.
> /Users/martindonadieu/Documents/Projects.nosync/Capacitor/capgo/android/app/src/main/res/drawable-night-port-xhdpi: Error: Invalid resource directory name

* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'.
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:187)
	at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:268)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:185)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:173)
	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:109)
	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:74)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:408)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:395)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:388)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:374)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: com.android.build.gradle.tasks.ResourceException: /Users/martindonadieu/Documents/Projects.nosync/Capacitor/capgo/android/app/src/main/res/drawable-night-port-xhdpi: Error: Invalid resource directory name
	at com.android.build.gradle.tasks.MergeResources.doFullTaskAction(MergeResources.java:312)
Caused by: com.android.build.gradle.tasks.ResourceException: /Users/martindonadieu/Documents/Projects.nosync/Capacitor/capgo/android/app/src/main/res/drawable-night-port-xhdpi: Error: Invalid resource directory name

	at com.android.build.gradle.internal.tasks.IncrementalTask.handleIncrementalInputs(IncrementalTask.kt:110)
	at com.android.build.gradle.internal.tasks.IncrementalTask.access$handleIncrementalInputs(IncrementalTask.kt:65)
	at com.android.build.gradle.internal.tasks.IncrementalTask$taskAction$$inlined$recordTaskAction$1.invoke(BaseTask.kt:62)
	at com.android.build.gradle.internal.tasks.Blocks.recordSpan(Blocks.java:51)
	at com.android.build.gradle.internal.tasks.IncrementalTask.taskAction$gradle_core(IncrementalTask.kt:137)
	at jdk.internal.reflect.GeneratedMethodAccessor722.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:104)
	at org.gradle.api.internal.project.taskfactory.IncrementalTaskInputsTaskAction.doExecute(IncrementalTaskInputsTaskAction.java:47)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51)
	at org.gradle.api.internal.project.taskfactory.AbstractIncrementalTaskAction.execute(AbstractIncrementalTaskAction.java:25)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$2.run(ExecuteActionsTaskExecuter.java:498)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:483)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:466)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$300(ExecuteActionsTaskExecuter.java:105)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.executeWithPreviousOutputFiles(ExecuteActionsTaskExecuter.java:270)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:248)
	at org.gradle.internal.execution.steps.ExecuteStep.executeInternal(ExecuteStep.java:83)
	at org.gradle.internal.execution.steps.ExecuteStep.access$000(ExecuteStep.java:37)
	at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:50)
	at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:47)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:47)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:37)
	at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:68)
	at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:38)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:50)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:36)
	at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:41)
	at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:74)
	at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:55)
	at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:51)
	at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:29)
	at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:54)
	at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:35)
	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:60)
	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:27)
	at org.gradle.internal.execution.steps.BuildCacheStep.executeWithoutCache(BuildCacheStep.java:174)
	at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:74)
	at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:45)
	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:40)
	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:29)
	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:36)
	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:22)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:99)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:92)
	at java.base/java.util.Optional.map(Optional.java:265)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:52)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:36)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:84)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:41)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:37)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:27)
	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:91)
	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:49)
	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:78)
	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:49)
	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:105)
	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:50)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.lambda$execute$2(SkipEmptyWorkStep.java:86)
	at java.base/java.util.Optional.orElseGet(Optional.java:369)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:86)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:32)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
	at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:43)
	at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:31)
	at org.gradle.internal.execution.steps.AssignWorkspaceStep.lambda$execute$0(AssignWorkspaceStep.java:40)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution$2.withWorkspace(ExecuteActionsTaskExecuter.java:283)
	at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:40)
	at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:30)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:37)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:27)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:49)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:35)
	at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:76)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:184)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:173)
	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:109)
	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:74)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:408)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:395)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:388)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:374)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: /Users/martindonadieu/Documents/Projects.nosync/Capacitor/capgo/android/app/src/main/res/drawable-night-port-xhdpi: Error: Invalid resource directory name
	at com.android.ide.common.resources.MergingException.throwIfNonEmpty(MergingException.java:170)
	at com.android.ide.common.resources.DataSet.loadFromFiles(DataSet.java:264)
	at com.android.build.gradle.tasks.MergeResources.lambda$doFullTaskAction$0(MergeResources.java:261)
	at com.android.build.gradle.internal.tasks.Blocks.recordSpan(Blocks.java:51)
	at com.android.build.gradle.tasks.MergeResources.doFullTaskAction(MergeResources.java:255)
Caused by: /Users/martindonadieu/Documents/Projects.nosync/Capacitor/capgo/android/app/src/main/res/drawable-night-port-xhdpi: Error: Invalid resource directory name

	... 133 more

==============================================================================

it's seems there only one issue for drawable-night-port-xhdpi i have try to remove the platform and do it from fresh platform and the issue still happen I really love how fast it is to get the assets !

riderx avatar Mar 29 '22 23:03 riderx

Cool I get the same issue so will fix here shortly. Making progress 🤞

mlynch avatar Mar 30 '22 15:03 mlynch

@riderx 1.0.0-next.5@next should have this fixed

mlynch avatar Mar 30 '22 18:03 mlynch

@mlynch after remove the platform and add again it works! Thanks a lot for this work, a new stone for our mobile app to don't need cordova stuff anymore! I still have a tiny issue related to that, it how the splash look when we start a new Capacitor app:

https://user-images.githubusercontent.com/4084527/160916734-693fc75f-2a47-45e6-85da-a7f863b55a28.mp4

The splash screen doesn't have the appropriate size by default on many phones, and after a few seconds it works. it give a bad feeling of dev who start to use Capacitor.

i know that a matter of settings in Android, but maybe since the tool you did could be added to the capacitor CLI. If you make this setting default, that will improve the feeling of Capacitor is a strong solution ready to go :) You can find a stack overflow post about it here : https://stackoverflow.com/questions/66285483/ionic-capacitor-android-splash-screen-responsiveness

riderx avatar Mar 30 '22 19:03 riderx

@riderx if you follow the steps in that linked solution does it resolve the scaling issue for you?

mlynch avatar Mar 31 '22 18:03 mlynch