@maccesar/titools 2.7.2 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -13
- package/lib/config.js +1 -1
- package/package.json +1 -1
- package/skills/purgetss/SKILL.md +25 -0
- package/skills/purgetss/references/EXAMPLES.md +86 -24
- package/skills/purgetss/references/app-branding.md +412 -0
- package/skills/purgetss/references/appearance-module.md +161 -0
- package/skills/purgetss/references/apply-directive.md +87 -31
- package/skills/purgetss/references/arbitrary-values.md +4 -0
- package/skills/purgetss/references/class-categories.md +10 -7
- package/skills/purgetss/references/class-index.md +25 -18
- package/skills/purgetss/references/cli-commands.md +219 -8
- package/skills/purgetss/references/configurable-properties.md +11 -7
- package/skills/purgetss/references/custom-rules.md +7 -3
- package/skills/purgetss/references/customization-deep-dive.md +52 -4
- package/skills/purgetss/references/dynamic-component-creation.md +29 -14
- package/skills/purgetss/references/grid-layout.md +20 -8
- package/skills/purgetss/references/icon-fonts.md +4 -0
- package/skills/purgetss/references/installation-setup.md +3 -8
- package/skills/purgetss/references/ios-large-titles.md +141 -0
- package/skills/purgetss/references/migration-guide.md +162 -25
- package/skills/purgetss/references/multi-density-images.md +363 -0
- package/skills/purgetss/references/opacity-modifier.md +4 -0
- package/skills/purgetss/references/performance-tips.md +5 -0
- package/skills/purgetss/references/platform-modifiers.md +4 -0
- package/skills/purgetss/references/semantic-colors.md +386 -0
- package/skills/purgetss/references/smart-mappings.md +50 -28
- package/skills/purgetss/references/tikit-components.md +3 -1
- package/skills/purgetss/references/titanium-resets.md +46 -15
- package/skills/purgetss/references/ui-ux-design.md +32 -6
- package/skills/ti-branding/SKILL.md +0 -230
- package/skills/ti-branding/assets/ic_launcher.xml +0 -6
- package/skills/ti-branding/references/android-adaptive-icons.md +0 -85
- package/skills/ti-branding/references/cleanup-legacy.md +0 -112
- package/skills/ti-branding/references/ios-appiconset.md +0 -62
- package/skills/ti-branding/references/master-input-guidelines.md +0 -84
- package/skills/ti-branding/references/notification-icons.md +0 -63
- package/skills/ti-branding/references/splash-screen-api.md +0 -81
- package/skills/ti-branding/references/ti-icon-paths.md +0 -84
- package/skills/ti-branding/references/tiapp-xml-snippets.md +0 -92
- package/skills/ti-branding/scripts/lib/cleanup-legacy.sh +0 -230
- package/skills/ti-branding/scripts/lib/deps.sh +0 -58
- package/skills/ti-branding/scripts/lib/gen-android-adaptive.sh +0 -64
- package/skills/ti-branding/scripts/lib/gen-android-legacy.sh +0 -36
- package/skills/ti-branding/scripts/lib/gen-ios.sh +0 -46
- package/skills/ti-branding/scripts/lib/gen-marketplace.sh +0 -55
- package/skills/ti-branding/scripts/lib/gen-notification.sh +0 -46
- package/skills/ti-branding/scripts/lib/gen-splash-icon.sh +0 -31
- package/skills/ti-branding/scripts/lib/prepare-master.sh +0 -48
- package/skills/ti-branding/scripts/lib/validate.sh +0 -67
- package/skills/ti-branding/scripts/ti-branding +0 -546
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
# Splash screens (modern)
|
|
2
|
-
|
|
3
|
-
## Two strategies by platform
|
|
4
|
-
|
|
5
|
-
### iOS — storyboard-driven (iOS 14+)
|
|
6
|
-
|
|
7
|
-
Modern iOS uses `LaunchScreen.storyboard`. Titanium enables this via `tiapp.xml`:
|
|
8
|
-
|
|
9
|
-
```xml
|
|
10
|
-
<ios>
|
|
11
|
-
<enable-launch-screen-storyboard>true</enable-launch-screen-storyboard>
|
|
12
|
-
<default-background-color>#0B1326</default-background-color>
|
|
13
|
-
</ios>
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
The storyboard is a single layout that scales dynamically to any device. No per-device PNG launch images are needed. The `<default-background-color>` sets both the storyboard background AND the gap-color between the storyboard and the first view.
|
|
17
|
-
|
|
18
|
-
This skill does NOT generate iOS launch images. It prints the `<default-background-color>` snippet for the user to paste.
|
|
19
|
-
|
|
20
|
-
### Android 12+ — SplashScreen API (API 31+)
|
|
21
|
-
|
|
22
|
-
Android 12 introduced a system-managed splash that replaces the old "put a PNG in drawable/background.png" approach. It's theme-driven:
|
|
23
|
-
|
|
24
|
-
```xml
|
|
25
|
-
<!-- platform/android/res/values-v31/splash_theme.xml -->
|
|
26
|
-
<resources>
|
|
27
|
-
<style name="Theme.SnapGym.SplashScreen" parent="Theme.SplashScreen">
|
|
28
|
-
<item name="windowSplashScreenBackground">#0B1326</item>
|
|
29
|
-
<item name="windowSplashScreenAnimatedIcon">@drawable/splash_icon</item>
|
|
30
|
-
<item name="postSplashScreenTheme">@style/Theme.AppDerived</item>
|
|
31
|
-
</style>
|
|
32
|
-
</resources>
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
With a matching `AndroidManifest.xml` entry (inside `<application>`):
|
|
36
|
-
|
|
37
|
-
```xml
|
|
38
|
-
<meta-data android:name="io.tidev.titanium.splash.theme"
|
|
39
|
-
android:value="@style/Theme.SnapGym.SplashScreen"/>
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
Critical: **do NOT apply this theme to `<application android:theme>` or to a specific `<activity>`** — it only affects the system SplashScreen via the manifest meta-data. Applying it to the application breaks the ActionBar / TitleBar in every subsequent screen (as SNAP Gym learned the hard way).
|
|
43
|
-
|
|
44
|
-
### Android <12 — fallback to launcher icon
|
|
45
|
-
|
|
46
|
-
On API <31, the system uses the launcher icon as the splash. No extra file needed. The `background.9.png` 9-patch pattern is obsolete in Titanium SDK 13+.
|
|
47
|
-
|
|
48
|
-
## splash_icon.png canvas (Android 12+)
|
|
49
|
-
|
|
50
|
-
The SplashScreen API spec:
|
|
51
|
-
|
|
52
|
-
- Total canvas: **288 dp**
|
|
53
|
-
- Icon safe-zone: **192 dp centered** (≈ 67% of canvas)
|
|
54
|
-
- OS applies a circular mask automatically — keep content centered
|
|
55
|
-
|
|
56
|
-
Density sizes:
|
|
57
|
-
|
|
58
|
-
| Density | Total canvas | Icon area |
|
|
59
|
-
|----------|--------------|-----------|
|
|
60
|
-
| mdpi | 288 | 192 |
|
|
61
|
-
| hdpi | 432 | 288 |
|
|
62
|
-
| xhdpi | 576 | 384 |
|
|
63
|
-
| xxhdpi | 864 | 576 |
|
|
64
|
-
| xxxhdpi | 1152 | 768 |
|
|
65
|
-
|
|
66
|
-
The skill's `gen-splash-icon.sh` places the logo at `192/288 ≈ 67%` of the canvas with transparent padding around it.
|
|
67
|
-
|
|
68
|
-
## Why we don't generate `background.9.png`
|
|
69
|
-
|
|
70
|
-
The old 9-patch splash pattern works like this:
|
|
71
|
-
|
|
72
|
-
- PNG with 1px borders marked as stretchable regions
|
|
73
|
-
- Titanium references it as `background.9.png` in `drawable-*dpi/`
|
|
74
|
-
- SDK pre-13 used it as `windowBackground` for the root activity
|
|
75
|
-
|
|
76
|
-
Titanium 13+ handles splash via the modern SplashScreen API on 12+ and via the launcher icon itself on older versions. `background.9.png` produces worse results on 12+ (competing with the SplashScreen API) and offers no benefit on older versions that the launcher fallback can't provide.
|
|
77
|
-
|
|
78
|
-
## References
|
|
79
|
-
|
|
80
|
-
- Android: [Splash screens](https://developer.android.com/develop/ui/views/launch/splash-screen)
|
|
81
|
-
- Apple: [Configuring your app's launch screen](https://developer.apple.com/documentation/xcode/configuring-your-apps-launch-screen)
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
# Canonical paths — Titanium SDK 13.x
|
|
2
|
-
|
|
3
|
-
## Alloy layout (primary)
|
|
4
|
-
|
|
5
|
-
```
|
|
6
|
-
project-root/
|
|
7
|
-
├── DefaultIcon-ios.png # iOS master (1024² no alpha)
|
|
8
|
-
├── DefaultIcon.png # Generic master (1024² no alpha) — fallback
|
|
9
|
-
├── iTunesConnect.png # 1024² App Store submission
|
|
10
|
-
├── MarketplaceArtwork.png # 512² Google Play submission
|
|
11
|
-
├── tiapp.xml
|
|
12
|
-
└── app/
|
|
13
|
-
├── assets/
|
|
14
|
-
│ ├── iphone/ # (optional) manual iOS appiconset — skill doesn't write here
|
|
15
|
-
│ └── android/
|
|
16
|
-
│ ├── appicon.png # 128² legacy fallback (pre-adaptive)
|
|
17
|
-
│ └── images/ # density-scaled in-app image assets (NOT launcher)
|
|
18
|
-
└── platform/
|
|
19
|
-
└── android/
|
|
20
|
-
└── res/
|
|
21
|
-
├── mipmap-mdpi/
|
|
22
|
-
│ ├── ic_launcher.png # legacy 48²
|
|
23
|
-
│ ├── ic_launcher_foreground.png # adaptive 108²
|
|
24
|
-
│ ├── ic_launcher_background.png # adaptive 108²
|
|
25
|
-
│ └── ic_launcher_monochrome.png # themed 108²
|
|
26
|
-
├── mipmap-hdpi/ # 72 / 162 / 162 / 162
|
|
27
|
-
├── mipmap-xhdpi/ # 96 / 216 / 216 / 216
|
|
28
|
-
├── mipmap-xxhdpi/ # 144 / 324 / 324 / 324
|
|
29
|
-
├── mipmap-xxxhdpi/ # 192 / 432 / 432 / 432
|
|
30
|
-
├── mipmap-anydpi-v26/
|
|
31
|
-
│ └── ic_launcher.xml # binds the 3 adaptive layers
|
|
32
|
-
├── drawable-mdpi/
|
|
33
|
-
│ ├── ic_stat_notify.png # (optional) 24² white+alpha
|
|
34
|
-
│ └── splash_icon.png # (optional) 288² Android 12+ splash
|
|
35
|
-
├── drawable-hdpi/ # 36 / 432
|
|
36
|
-
├── drawable-xhdpi/ # 48 / 576
|
|
37
|
-
├── drawable-xxhdpi/ # 72 / 864
|
|
38
|
-
└── drawable-xxxhdpi/ # 96 / 1152
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Classic layout
|
|
42
|
-
|
|
43
|
-
Same structure, different roots. The skill detects `Resources/` and remaps:
|
|
44
|
-
|
|
45
|
-
| Alloy path | Classic path |
|
|
46
|
-
|---|---|
|
|
47
|
-
| `app/assets/android/appicon.png` | `Resources/android/appicon.png` |
|
|
48
|
-
| `app/platform/android/res/...` | `platform/android/res/...` |
|
|
49
|
-
|
|
50
|
-
Root-level files (`DefaultIcon*.png`, `iTunesConnect.png`, `MarketplaceArtwork.png`) are identical in both layouts.
|
|
51
|
-
|
|
52
|
-
## What Titanium does at build time
|
|
53
|
-
|
|
54
|
-
- **iOS**: reads the root master → writes to `build/iphone/Assets.xcassets/AppIcon.appiconset/` (build directory, regenerated every build, never commited)
|
|
55
|
-
- **Android**: copies `app/platform/android/res/*` verbatim to `build/android/app/src/main/res/`, plus copies `app/assets/android/appicon.png` to `build/.../res/drawable-*dpi/appicon.png` if the legacy path is used
|
|
56
|
-
|
|
57
|
-
Result: anything the skill writes to `app/platform/android/res/` or `app/assets/` survives builds. Nothing the skill generates can be accidentally overwritten by `ti build`.
|
|
58
|
-
|
|
59
|
-
## What the skill writes
|
|
60
|
-
|
|
61
|
-
After confirming with the user, the skill copies from its staging directory to:
|
|
62
|
-
|
|
63
|
-
| Target | Files |
|
|
64
|
-
|---|---|
|
|
65
|
-
| Project root | `DefaultIcon-ios.png`, `iTunesConnect.png`, `MarketplaceArtwork.png` |
|
|
66
|
-
| `app/platform/android/res/mipmap-*/` | Launcher icons (adaptive triplet + legacy flat), 5 densities |
|
|
67
|
-
| `app/platform/android/res/mipmap-anydpi-v26/` | `ic_launcher.xml` |
|
|
68
|
-
| `app/platform/android/res/drawable-*/` (optional) | `ic_stat_notify.png`, `splash_icon.png` |
|
|
69
|
-
|
|
70
|
-
The skill never touches `tiapp.xml`, `config.json`, source code, or anything outside the asset/resource paths above.
|
|
71
|
-
|
|
72
|
-
## Required `tiapp.xml` entry
|
|
73
|
-
|
|
74
|
-
For the adaptive icon to be picked up, `tiapp.xml` must reference it:
|
|
75
|
-
|
|
76
|
-
```xml
|
|
77
|
-
<android>
|
|
78
|
-
<manifest>
|
|
79
|
-
<application android:icon="@mipmap/ic_launcher"/>
|
|
80
|
-
</manifest>
|
|
81
|
-
</android>
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
The skill checks for this and, if missing, prints the snippet — does not edit the file. See `tiapp-xml-snippets.md` for the full set.
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
# tiapp.xml snippets
|
|
2
|
-
|
|
3
|
-
The skill prints these blocks after generating assets. The user reviews and pastes them manually — `tiapp.xml` often contains sensitive info (API keys, signing identities, staging URLs) and automated editing would be fragile.
|
|
4
|
-
|
|
5
|
-
## Block 1 — iOS background color (for storyboard splash)
|
|
6
|
-
|
|
7
|
-
Under the `<ios>` element:
|
|
8
|
-
|
|
9
|
-
```xml
|
|
10
|
-
<ios>
|
|
11
|
-
<enable-launch-screen-storyboard>true</enable-launch-screen-storyboard>
|
|
12
|
-
<default-background-color>#0B1326</default-background-color>
|
|
13
|
-
</ios>
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
Replace `#0B1326` with the user's `--bg-color`.
|
|
17
|
-
|
|
18
|
-
## Block 2 — Android application icon reference
|
|
19
|
-
|
|
20
|
-
Under `<android><manifest><application>`:
|
|
21
|
-
|
|
22
|
-
```xml
|
|
23
|
-
<android>
|
|
24
|
-
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
25
|
-
<application android:icon="@mipmap/ic_launcher"
|
|
26
|
-
android:usesCleartextTraffic="false"/>
|
|
27
|
-
</manifest>
|
|
28
|
-
</android>
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
The `android:icon="@mipmap/ic_launcher"` tells Android to use the adaptive icon XML (via `mipmap-anydpi-v26/ic_launcher.xml` on API 26+) with automatic fallback to the flat `mipmap-*dpi/ic_launcher.png` on older devices.
|
|
32
|
-
|
|
33
|
-
## Block 3 — Android 12+ splash screen (optional, requires `--with-splash-icon`)
|
|
34
|
-
|
|
35
|
-
Requires three changes:
|
|
36
|
-
|
|
37
|
-
### 3a. Splash theme resource
|
|
38
|
-
|
|
39
|
-
Create `app/platform/android/res/values-v31/splash_theme.xml`:
|
|
40
|
-
|
|
41
|
-
```xml
|
|
42
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
43
|
-
<resources>
|
|
44
|
-
<style name="Theme.App.SplashScreen" parent="Theme.SplashScreen">
|
|
45
|
-
<item name="windowSplashScreenBackground">#0B1326</item>
|
|
46
|
-
<item name="windowSplashScreenAnimatedIcon">@drawable/splash_icon</item>
|
|
47
|
-
<item name="postSplashScreenTheme">@style/Theme.AppDerived</item>
|
|
48
|
-
</style>
|
|
49
|
-
</resources>
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### 3b. Manifest meta-data (NOT a theme on `<application>` or `<activity>`)
|
|
53
|
-
|
|
54
|
-
Under `<android><manifest><application>`:
|
|
55
|
-
|
|
56
|
-
```xml
|
|
57
|
-
<meta-data android:name="io.tidev.titanium.splash.theme"
|
|
58
|
-
android:value="@style/Theme.App.SplashScreen"/>
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
### 3c. DO NOT do this
|
|
62
|
-
|
|
63
|
-
Setting `android:theme="@style/Theme.App.SplashScreen"` on `<application>` or `<activity>` will strip the ActionBar / TitleBar from every screen in the app because Titanium's `Theme.AppDerived` inherits from the application theme. The SplashScreen API is designed to work through the manifest meta-data entry above, not through activity theming.
|
|
64
|
-
|
|
65
|
-
## Block 4 — Firebase Cloud Messaging notification icon (optional, requires `--with-notification`)
|
|
66
|
-
|
|
67
|
-
Create `app/platform/android/res/values/colors.xml` (if it doesn't exist) with:
|
|
68
|
-
|
|
69
|
-
```xml
|
|
70
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
71
|
-
<resources>
|
|
72
|
-
<color name="notification_tint">#FDD900</color>
|
|
73
|
-
</resources>
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Then under `<android><manifest><application>`:
|
|
77
|
-
|
|
78
|
-
```xml
|
|
79
|
-
<meta-data android:name="com.google.firebase.messaging.default_notification_icon"
|
|
80
|
-
android:resource="@drawable/ic_stat_notify"/>
|
|
81
|
-
<meta-data android:name="com.google.firebase.messaging.default_notification_color"
|
|
82
|
-
android:resource="@color/notification_tint"/>
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## What the skill reports
|
|
86
|
-
|
|
87
|
-
After generation, the skill prints only the blocks relevant to the flags used and the project's current state:
|
|
88
|
-
|
|
89
|
-
- Always prints Block 2 if `android:icon="@mipmap/ic_launcher"` is missing from tiapp.xml
|
|
90
|
-
- Always prints Block 1 if `<default-background-color>` is missing
|
|
91
|
-
- Prints Block 3 only if `--with-splash-icon` was used
|
|
92
|
-
- Prints Block 4 only if `--with-notification` was used
|
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# cleanup-legacy.sh — context-aware removal of legacy branding artifacts.
|
|
3
|
-
#
|
|
4
|
-
# Reads tiapp.xml to decide what's safe to delete. Categorizes targets into:
|
|
5
|
-
#
|
|
6
|
-
# SAFE always deleted — universally obsolete (dead qualifiers etc.)
|
|
7
|
-
# CONDITIONAL deleted only when project config guarantees they're unused
|
|
8
|
-
# (e.g. iOS legacy launch images when storyboard is enabled)
|
|
9
|
-
# AGGRESSIVE behind --aggressive flag — strongly defensible but some
|
|
10
|
-
# edge cases remain (e.g. ldpi drawables on <1% of devices)
|
|
11
|
-
#
|
|
12
|
-
# Always prints the plan before acting. Respects --dry-run.
|
|
13
|
-
|
|
14
|
-
# Append "path|reason" pair to a named array in a bash-3.2-compatible way.
|
|
15
|
-
_add_target() {
|
|
16
|
-
local array_name="$1"
|
|
17
|
-
local path="$2"
|
|
18
|
-
local reason="$3"
|
|
19
|
-
eval "$array_name+=(\"\$path|\$reason\")"
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
cleanup_legacy() {
|
|
23
|
-
local project_root="$1"
|
|
24
|
-
local project_type="$2"
|
|
25
|
-
local aggressive="$3"
|
|
26
|
-
local dry_run="$4"
|
|
27
|
-
|
|
28
|
-
local tiapp="$project_root/tiapp.xml"
|
|
29
|
-
local storyboard_enabled=0
|
|
30
|
-
local portrait_only=0
|
|
31
|
-
|
|
32
|
-
if [[ -f "$tiapp" ]]; then
|
|
33
|
-
grep -q "<enable-launch-screen-storyboard>true" "$tiapp" && storyboard_enabled=1
|
|
34
|
-
# Portrait-only heuristic: <orientations> block contains UIInterfaceOrientationPortrait
|
|
35
|
-
# for iphone AND no Landscape entries.
|
|
36
|
-
if grep -q '<orientations' "$tiapp" && \
|
|
37
|
-
! grep -iqE 'UIInterfaceOrientationLandscape' "$tiapp"; then
|
|
38
|
-
portrait_only=1
|
|
39
|
-
fi
|
|
40
|
-
fi
|
|
41
|
-
|
|
42
|
-
local android_images=""
|
|
43
|
-
local iphone_dir=""
|
|
44
|
-
local android_assets=""
|
|
45
|
-
case "$project_type" in
|
|
46
|
-
alloy)
|
|
47
|
-
android_images="$project_root/app/assets/android/images"
|
|
48
|
-
iphone_dir="$project_root/app/assets/iphone"
|
|
49
|
-
android_assets="$project_root/app/assets/android"
|
|
50
|
-
;;
|
|
51
|
-
classic)
|
|
52
|
-
android_images="$project_root/Resources/android/images"
|
|
53
|
-
iphone_dir="$project_root/Resources/iphone"
|
|
54
|
-
android_assets="$project_root/Resources/android"
|
|
55
|
-
;;
|
|
56
|
-
esac
|
|
57
|
-
|
|
58
|
-
local has_adaptive=0
|
|
59
|
-
[[ -d "$project_root/app/platform/android/res/mipmap-anydpi-v26" ]] && has_adaptive=1
|
|
60
|
-
[[ -d "$project_root/platform/android/res/mipmap-anydpi-v26" ]] && has_adaptive=1
|
|
61
|
-
|
|
62
|
-
local safe_targets=()
|
|
63
|
-
local cond_targets=()
|
|
64
|
-
local aggressive_targets=()
|
|
65
|
-
|
|
66
|
-
# -------------------------------------------------------------------------
|
|
67
|
-
# SAFE
|
|
68
|
-
# -------------------------------------------------------------------------
|
|
69
|
-
|
|
70
|
-
if [[ -n "$android_images" && -d "$android_images" ]]; then
|
|
71
|
-
local d
|
|
72
|
-
for d in "$android_images"/res-long-* "$android_images"/res-notlong-*; do
|
|
73
|
-
[[ -d "$d" ]] && _add_target safe_targets "$d" "Android long/notlong qualifier (dead since Android 3.0, 2011)"
|
|
74
|
-
done
|
|
75
|
-
fi
|
|
76
|
-
|
|
77
|
-
# -------------------------------------------------------------------------
|
|
78
|
-
# CONDITIONAL
|
|
79
|
-
# -------------------------------------------------------------------------
|
|
80
|
-
|
|
81
|
-
# iOS legacy launch images — only safe with storyboard enabled
|
|
82
|
-
if [[ $storyboard_enabled -eq 1 && -n "$iphone_dir" && -d "$iphone_dir" ]]; then
|
|
83
|
-
local f
|
|
84
|
-
for f in "$iphone_dir"/Default-*.png "$iphone_dir"/Default@2x.png; do
|
|
85
|
-
[[ -f "$f" ]] && _add_target cond_targets "$f" "iOS legacy launch image (storyboard enabled → not consulted)"
|
|
86
|
-
done
|
|
87
|
-
fi
|
|
88
|
-
|
|
89
|
-
# Android landscape-variant folders — safe when app is portrait-only
|
|
90
|
-
if [[ $portrait_only -eq 1 && -n "$android_images" && -d "$android_images" ]]; then
|
|
91
|
-
local d
|
|
92
|
-
for d in "$android_images"/res-*-land-* "$android_images"/res-land-*; do
|
|
93
|
-
[[ -d "$d" ]] && _add_target cond_targets "$d" "Landscape variant (app is portrait-only)"
|
|
94
|
-
done
|
|
95
|
-
fi
|
|
96
|
-
|
|
97
|
-
# Android legacy splash PNG — safe when adaptive icons are in place
|
|
98
|
-
if [[ $has_adaptive -eq 1 && -n "$android_assets" && -f "$android_assets/default.png" ]]; then
|
|
99
|
-
_add_target cond_targets "$android_assets/default.png" "Legacy Android splash PNG (adaptive launcher handles splash now)"
|
|
100
|
-
fi
|
|
101
|
-
|
|
102
|
-
# Android legacy appicon.png — redundant when adaptive icons are in place
|
|
103
|
-
if [[ $has_adaptive -eq 1 && -n "$android_assets" && -f "$android_assets/appicon.png" ]]; then
|
|
104
|
-
_add_target cond_targets "$android_assets/appicon.png" "Legacy appicon.png (adaptive launcher takes precedence)"
|
|
105
|
-
fi
|
|
106
|
-
|
|
107
|
-
# -------------------------------------------------------------------------
|
|
108
|
-
# AGGRESSIVE
|
|
109
|
-
# -------------------------------------------------------------------------
|
|
110
|
-
|
|
111
|
-
if [[ $aggressive -eq 1 ]]; then
|
|
112
|
-
# ldpi everywhere — <1% of active devices globally in 2026
|
|
113
|
-
local d
|
|
114
|
-
if [[ -n "$android_images" && -d "$android_images" ]]; then
|
|
115
|
-
for d in "$android_images"/res-ldpi "$android_images"/res-*-ldpi; do
|
|
116
|
-
[[ -d "$d" ]] && _add_target aggressive_targets "$d" "ldpi density (<1% global market)"
|
|
117
|
-
done
|
|
118
|
-
fi
|
|
119
|
-
for d in "$project_root/app/platform/android/res/drawable-ldpi" \
|
|
120
|
-
"$project_root/app/platform/android/res/values-ldpi" \
|
|
121
|
-
"$project_root/app/platform/android/res/mipmap-ldpi" \
|
|
122
|
-
"$project_root/platform/android/res/drawable-ldpi" \
|
|
123
|
-
"$project_root/platform/android/res/values-ldpi" \
|
|
124
|
-
"$project_root/platform/android/res/mipmap-ldpi"; do
|
|
125
|
-
[[ -d "$d" ]] && _add_target aggressive_targets "$d" "ldpi resource folder (<1% global market)"
|
|
126
|
-
done
|
|
127
|
-
fi
|
|
128
|
-
|
|
129
|
-
# -------------------------------------------------------------------------
|
|
130
|
-
# Print plan
|
|
131
|
-
# -------------------------------------------------------------------------
|
|
132
|
-
|
|
133
|
-
echo
|
|
134
|
-
echo "${C_YELLOW}⚠ WARNING${C_RESET} — --cleanup-legacy deletes files permanently."
|
|
135
|
-
echo " Recommended: commit your project with git before running without --dry-run."
|
|
136
|
-
echo " Provided AS IS under the MIT License. No warranty — use at your own risk."
|
|
137
|
-
echo
|
|
138
|
-
echo "${C_BOLD}Cleanup plan${C_RESET}"
|
|
139
|
-
echo " ${C_DIM}Project: $project_root ($project_type)${C_RESET}"
|
|
140
|
-
echo " ${C_DIM}Storyboard: $([[ $storyboard_enabled -eq 1 ]] && echo "enabled" || echo "disabled")${C_RESET}"
|
|
141
|
-
echo " ${C_DIM}Orientation: $([[ $portrait_only -eq 1 ]] && echo "portrait-only" || echo "landscape allowed")${C_RESET}"
|
|
142
|
-
echo " ${C_DIM}Adaptive icons: $([[ $has_adaptive -eq 1 ]] && echo "present" || echo "not detected")${C_RESET}"
|
|
143
|
-
echo " ${C_DIM}Aggressive mode: $([[ $aggressive -eq 1 ]] && echo "on (includes ldpi)" || echo "off")${C_RESET}"
|
|
144
|
-
|
|
145
|
-
local total=$(( ${#safe_targets[@]} + ${#cond_targets[@]} + ${#aggressive_targets[@]} ))
|
|
146
|
-
|
|
147
|
-
if [[ $total -eq 0 ]]; then
|
|
148
|
-
echo
|
|
149
|
-
log_ok "No legacy artifacts detected. Project is already clean."
|
|
150
|
-
return 0
|
|
151
|
-
fi
|
|
152
|
-
|
|
153
|
-
# bash 3.2 under `set -u` errors on "${empty_array[@]}" — iterate per-bucket
|
|
154
|
-
# with explicit length guards instead of expanding empty arrays into args.
|
|
155
|
-
_print_bucket_safe() {
|
|
156
|
-
local t path reason size
|
|
157
|
-
echo
|
|
158
|
-
echo "${C_GREEN}SAFE — universally obsolete${C_RESET}"
|
|
159
|
-
for t in "${safe_targets[@]}"; do
|
|
160
|
-
path="${t%%|*}"; reason="${t#*|}"
|
|
161
|
-
size=$(du -sk "$path" 2>/dev/null | awk '{print $1}')
|
|
162
|
-
[[ -z "$size" ]] && size=0
|
|
163
|
-
printf " %-6sK %s\n" "$size" "${path#$project_root/}"
|
|
164
|
-
printf " ${C_DIM}%s${C_RESET}\n" "$reason"
|
|
165
|
-
done
|
|
166
|
-
}
|
|
167
|
-
_print_bucket_cond() {
|
|
168
|
-
local t path reason size
|
|
169
|
-
echo
|
|
170
|
-
echo "${C_YELLOW}CONDITIONAL — safe given your project config${C_RESET}"
|
|
171
|
-
for t in "${cond_targets[@]}"; do
|
|
172
|
-
path="${t%%|*}"; reason="${t#*|}"
|
|
173
|
-
size=$(du -sk "$path" 2>/dev/null | awk '{print $1}')
|
|
174
|
-
[[ -z "$size" ]] && size=0
|
|
175
|
-
printf " %-6sK %s\n" "$size" "${path#$project_root/}"
|
|
176
|
-
printf " ${C_DIM}%s${C_RESET}\n" "$reason"
|
|
177
|
-
done
|
|
178
|
-
}
|
|
179
|
-
_print_bucket_aggr() {
|
|
180
|
-
local t path reason size
|
|
181
|
-
echo
|
|
182
|
-
echo "${C_RED}AGGRESSIVE — --aggressive enabled${C_RESET}"
|
|
183
|
-
for t in "${aggressive_targets[@]}"; do
|
|
184
|
-
path="${t%%|*}"; reason="${t#*|}"
|
|
185
|
-
size=$(du -sk "$path" 2>/dev/null | awk '{print $1}')
|
|
186
|
-
[[ -z "$size" ]] && size=0
|
|
187
|
-
printf " %-6sK %s\n" "$size" "${path#$project_root/}"
|
|
188
|
-
printf " ${C_DIM}%s${C_RESET}\n" "$reason"
|
|
189
|
-
done
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
[[ ${#safe_targets[@]} -gt 0 ]] && _print_bucket_safe
|
|
193
|
-
[[ ${#cond_targets[@]} -gt 0 ]] && _print_bucket_cond
|
|
194
|
-
[[ ${#aggressive_targets[@]} -gt 0 ]] && _print_bucket_aggr
|
|
195
|
-
|
|
196
|
-
echo
|
|
197
|
-
echo " ${C_BOLD}Total: $total item(s) to remove${C_RESET}"
|
|
198
|
-
|
|
199
|
-
if [[ $dry_run -eq 1 ]]; then
|
|
200
|
-
echo
|
|
201
|
-
log_info "Dry-run mode — nothing deleted. Re-run without --dry-run to apply."
|
|
202
|
-
return 0
|
|
203
|
-
fi
|
|
204
|
-
|
|
205
|
-
# -------------------------------------------------------------------------
|
|
206
|
-
# Apply
|
|
207
|
-
# -------------------------------------------------------------------------
|
|
208
|
-
|
|
209
|
-
echo
|
|
210
|
-
log_step "Applying cleanup"
|
|
211
|
-
local t path
|
|
212
|
-
if [[ ${#safe_targets[@]} -gt 0 ]]; then
|
|
213
|
-
for t in "${safe_targets[@]}"; do
|
|
214
|
-
path="${t%%|*}"; rm -rf "$path"
|
|
215
|
-
log_ok "Removed ${path#$project_root/}"
|
|
216
|
-
done
|
|
217
|
-
fi
|
|
218
|
-
if [[ ${#cond_targets[@]} -gt 0 ]]; then
|
|
219
|
-
for t in "${cond_targets[@]}"; do
|
|
220
|
-
path="${t%%|*}"; rm -rf "$path"
|
|
221
|
-
log_ok "Removed ${path#$project_root/}"
|
|
222
|
-
done
|
|
223
|
-
fi
|
|
224
|
-
if [[ ${#aggressive_targets[@]} -gt 0 ]]; then
|
|
225
|
-
for t in "${aggressive_targets[@]}"; do
|
|
226
|
-
path="${t%%|*}"; rm -rf "$path"
|
|
227
|
-
log_ok "Removed ${path#$project_root/}"
|
|
228
|
-
done
|
|
229
|
-
fi
|
|
230
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# deps.sh — detect required system tools and guide installation.
|
|
3
|
-
|
|
4
|
-
check_deps() {
|
|
5
|
-
local master="$1"
|
|
6
|
-
local need_rsvg=0
|
|
7
|
-
local missing=()
|
|
8
|
-
|
|
9
|
-
local master_lower
|
|
10
|
-
master_lower=$(printf '%s' "$master" | tr '[:upper:]' '[:lower:]')
|
|
11
|
-
case "$master_lower" in
|
|
12
|
-
*.svg) need_rsvg=1 ;;
|
|
13
|
-
esac
|
|
14
|
-
|
|
15
|
-
if ! command -v magick >/dev/null 2>&1; then
|
|
16
|
-
missing+=("imagemagick")
|
|
17
|
-
fi
|
|
18
|
-
|
|
19
|
-
if [[ $need_rsvg -eq 1 ]] && ! command -v rsvg-convert >/dev/null 2>&1; then
|
|
20
|
-
missing+=("librsvg")
|
|
21
|
-
fi
|
|
22
|
-
|
|
23
|
-
if [[ ${#missing[@]} -eq 0 ]]; then
|
|
24
|
-
log_ok "All dependencies present: $(magick -version | head -1 | awk '{print $2,$3}')"
|
|
25
|
-
[[ $need_rsvg -eq 1 ]] && log_ok "librsvg: $(rsvg-convert --version | head -1)"
|
|
26
|
-
return 0
|
|
27
|
-
fi
|
|
28
|
-
|
|
29
|
-
log_err "Missing required tools: ${missing[*]}"
|
|
30
|
-
echo
|
|
31
|
-
echo "Install with one of:"
|
|
32
|
-
local os="$(uname -s)"
|
|
33
|
-
case "$os" in
|
|
34
|
-
Darwin)
|
|
35
|
-
echo " macOS: brew install ${missing[*]}"
|
|
36
|
-
;;
|
|
37
|
-
Linux)
|
|
38
|
-
if command -v apt >/dev/null 2>&1; then
|
|
39
|
-
local apt_pkgs=()
|
|
40
|
-
for m in "${missing[@]}"; do
|
|
41
|
-
case "$m" in
|
|
42
|
-
imagemagick) apt_pkgs+=("imagemagick") ;;
|
|
43
|
-
librsvg) apt_pkgs+=("librsvg2-bin") ;;
|
|
44
|
-
esac
|
|
45
|
-
done
|
|
46
|
-
echo " Ubuntu: sudo apt install ${apt_pkgs[*]}"
|
|
47
|
-
elif command -v pacman >/dev/null 2>&1; then
|
|
48
|
-
echo " Arch: sudo pacman -S ${missing[*]}"
|
|
49
|
-
elif command -v dnf >/dev/null 2>&1; then
|
|
50
|
-
echo " Fedora: sudo dnf install ${missing[*]}"
|
|
51
|
-
fi
|
|
52
|
-
;;
|
|
53
|
-
esac
|
|
54
|
-
echo " Windows: choco install ${missing[*]}"
|
|
55
|
-
echo
|
|
56
|
-
echo "After installing, re-run this command."
|
|
57
|
-
exit 1
|
|
58
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# gen-android-adaptive.sh — produce the adaptive icon triplet (foreground +
|
|
3
|
-
# background + monochrome) at 5 densities.
|
|
4
|
-
#
|
|
5
|
-
# Android adaptive icon: 108×108dp canvas, 66×66dp safe-zone.
|
|
6
|
-
# Densities: mdpi=108px, hdpi=162, xhdpi=216, xxhdpi=324, xxxhdpi=432.
|
|
7
|
-
#
|
|
8
|
-
# Foreground: logo centered inside safe-zone, transparent outside.
|
|
9
|
-
# Background: solid color (or pattern) filling the full canvas.
|
|
10
|
-
# Monochrome: foreground silhouette in pure white with preserved alpha — Android
|
|
11
|
-
# applies themed tint at runtime on API 31+.
|
|
12
|
-
|
|
13
|
-
gen_android_adaptive() {
|
|
14
|
-
local master="$1"
|
|
15
|
-
local bg="$2"
|
|
16
|
-
local padding="$3" # percent per side
|
|
17
|
-
local res_root="$4" # e.g. /path/app/platform/android/res
|
|
18
|
-
local mono_master="${5:-}" # optional dedicated silhouette master
|
|
19
|
-
|
|
20
|
-
local densities=(mdpi hdpi xhdpi xxhdpi xxxhdpi)
|
|
21
|
-
local sizes=(108 162 216 324 432)
|
|
22
|
-
|
|
23
|
-
for i in "${!densities[@]}"; do
|
|
24
|
-
local d="${densities[$i]}"
|
|
25
|
-
local size="${sizes[$i]}"
|
|
26
|
-
local inner=$(( size * (100 - 2 * padding) / 100 ))
|
|
27
|
-
local dir="$res_root/mipmap-$d"
|
|
28
|
-
mkdir -p "$dir"
|
|
29
|
-
|
|
30
|
-
# Foreground: logo centered, padded, transparent outside
|
|
31
|
-
magick "$master" \
|
|
32
|
-
-resize "${inner}x${inner}" \
|
|
33
|
-
-background none -gravity center -extent "${size}x${size}" \
|
|
34
|
-
-strip \
|
|
35
|
-
"$dir/ic_launcher_foreground.png"
|
|
36
|
-
|
|
37
|
-
# Background: solid color
|
|
38
|
-
magick -size "${size}x${size}" "xc:$bg" \
|
|
39
|
-
-strip \
|
|
40
|
-
"$dir/ic_launcher_background.png"
|
|
41
|
-
|
|
42
|
-
# Monochrome: white silhouette with alpha. If a dedicated mono master was
|
|
43
|
-
# provided, render it fresh with the same padding. Otherwise derive from
|
|
44
|
-
# the colored foreground (naive whitening — may flatten complex logos).
|
|
45
|
-
if [[ -n "$mono_master" ]]; then
|
|
46
|
-
magick "$mono_master" \
|
|
47
|
-
-resize "${inner}x${inner}" \
|
|
48
|
-
-background none -gravity center -extent "${size}x${size}" \
|
|
49
|
-
-channel RGB -fill white -colorize 100 +channel \
|
|
50
|
-
-strip \
|
|
51
|
-
"$dir/ic_launcher_monochrome.png"
|
|
52
|
-
else
|
|
53
|
-
magick "$dir/ic_launcher_foreground.png" \
|
|
54
|
-
-channel RGB -fill white -colorize 100 +channel \
|
|
55
|
-
-strip \
|
|
56
|
-
"$dir/ic_launcher_monochrome.png"
|
|
57
|
-
fi
|
|
58
|
-
done
|
|
59
|
-
|
|
60
|
-
# anydpi-v26 binder directory (XML copied by caller from assets/ic_launcher.xml)
|
|
61
|
-
mkdir -p "$res_root/mipmap-anydpi-v26"
|
|
62
|
-
|
|
63
|
-
log_ok "Adaptive icons: foreground + background + monochrome × 5 densities"
|
|
64
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# gen-android-legacy.sh — produce the flat ic_launcher.png for pre-adaptive Android
|
|
3
|
-
# (API 21–25, ~3% of users in 2026). Composites foreground over background and
|
|
4
|
-
# scales down to the legacy density sizes.
|
|
5
|
-
#
|
|
6
|
-
# Legacy densities: mdpi=48px, hdpi=72, xhdpi=96, xxhdpi=144, xxxhdpi=192.
|
|
7
|
-
|
|
8
|
-
gen_android_legacy() {
|
|
9
|
-
local master="$1"
|
|
10
|
-
local bg="$2"
|
|
11
|
-
local padding="$3"
|
|
12
|
-
local res_root="$4"
|
|
13
|
-
|
|
14
|
-
local densities=(mdpi hdpi xhdpi xxhdpi xxxhdpi)
|
|
15
|
-
local sizes=(48 72 96 144 192)
|
|
16
|
-
|
|
17
|
-
for i in "${!densities[@]}"; do
|
|
18
|
-
local d="${densities[$i]}"
|
|
19
|
-
local size="${sizes[$i]}"
|
|
20
|
-
# Legacy icons are displayed as-drawn (no adaptive mask), so we can fill more of
|
|
21
|
-
# the canvas. Reduce the padding by ~40% for the legacy composite.
|
|
22
|
-
local legacy_padding=$(( padding * 60 / 100 ))
|
|
23
|
-
local inner=$(( size * (100 - 2 * legacy_padding) / 100 ))
|
|
24
|
-
local dir="$res_root/mipmap-$d"
|
|
25
|
-
mkdir -p "$dir"
|
|
26
|
-
|
|
27
|
-
# Compose: solid bg + logo centered
|
|
28
|
-
magick -size "${size}x${size}" "xc:$bg" \
|
|
29
|
-
\( "$master" -resize "${inner}x${inner}" \) \
|
|
30
|
-
-gravity center -composite \
|
|
31
|
-
-strip \
|
|
32
|
-
"$dir/ic_launcher.png"
|
|
33
|
-
done
|
|
34
|
-
|
|
35
|
-
log_ok "Legacy ic_launcher.png × 5 densities (fallback for Android <8)"
|
|
36
|
-
}
|