Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/add-mobile-app-icon-selection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
default: minor
---

Add selectable app icons on Android and iOS.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
"postinstall": "node scripts/install-knope.js",
"setup:knope": "node scripts/install-knope.js",
"setup:tauri-icons": "node scripts/icons/symlink.js",
"generate:app-icons:android": "node node_modules/tauri-plugin-app-icon-api/scripts/generate-android.mjs --config src-tauri/app-icons.json && pnpm setup:tauri-icons --write --force",
"generate:app-icons:ios": "node node_modules/tauri-plugin-app-icon-api/scripts/generate-ios.mjs --config src-tauri/app-icons.json",
"lint:normalize-imports": "node scripts/normalize-imports.js"
},
"dependencies": {
Expand Down Expand Up @@ -122,6 +124,7 @@
"workbox-precaching": "^7.4.1"
},
"devDependencies": {
"tauri-plugin-app-icon-api": "github:SableClient/tauri-plugin-app-icon#9248a3370dca5c9b1640b20806002fe59d25fa57",
"@cloudflare/vite-plugin": "^1.42.4",
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
"@faker-js/faker": "^10.5.0",
Expand Down
11 changes: 11 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 19 additions & 2 deletions scripts/icons/symlink.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ import path from 'node:path';
import process from 'node:process';
import { createTextHelpers } from '../utils/console-style.js';

const ROOT = process.cwd();
const appIconsPath = path.join(ROOT, 'src-tauri', 'app-icons.json');
const appIcons = fs.existsSync(appIconsPath)
? JSON.parse(fs.readFileSync(appIconsPath, 'utf8')).icons
: [];

const ANDROID_ICONS = [
'mipmap-hdpi',
'mipmap-mdpi',
Expand All @@ -22,7 +28,19 @@ const ANDROID_ICONS = [
`${dir}/ic_notification.png`,
])
.concat(['mipmap-anydpi-v26/ic_launcher.xml', 'values/ic_launcher_background.xml'])
.concat(['drawable/ic_notification.xml', 'drawable/notification_icon.xml']);
.concat(['drawable/ic_notification.xml', 'drawable/notification_icon.xml'])
.concat(
appIcons.flatMap(({ id }) => [
...['mipmap-hdpi', 'mipmap-mdpi', 'mipmap-xhdpi', 'mipmap-xxhdpi', 'mipmap-xxxhdpi'].flatMap(
(dir) => [
`${dir}/ic_launcher_${id}.png`,
`${dir}/ic_launcher_${id}_round.png`,
`${dir}/ic_launcher_${id}_foreground.png`,
]
),
`mipmap-anydpi-v26/ic_launcher_${id}.xml`,
])
);

const IOS_ICONS = [
'AppIcon-20x20@1x.png',
Expand Down Expand Up @@ -133,7 +151,6 @@ function processGroup(label, srcDir, destDir, files, write, force, helpers) {
}

function main() {
const ROOT = process.cwd();
const { write, force } = parseArgs(process.argv.slice(2));
const helpers = createTextHelpers();

Expand Down
12 changes: 12 additions & 0 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ tauri-plugin-notifications = { git = "https://github.com/SableClient/tauri-plugi
] }
tauri-plugin-edge-to-edge = { git = "https://github.com/SableClient/tauri-plugin-edge-to-edge.git", rev = "33c6116c27be28c06df5a9d02231ecc5fdeb93c5" }
tauri-plugin-sharekit = { git = "https://github.com/Choochmeque/tauri-plugin-sharekit", rev = "9f2b4c5d8a4f0ab910d900ba234ed8bae0ab854b" }
tauri-plugin-app-icon = { git = "https://github.com/SableClient/tauri-plugin-app-icon", rev = "9248a3370dca5c9b1640b20806002fe59d25fa57" }

[target.'cfg(target_os = "ios")'.dependencies]
objc2 = "0.6"
Expand Down
15 changes: 15 additions & 0 deletions src-tauri/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,20 @@
<string>Sable needs camera access for video calls.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Sable needs microphone access for voice and video calls.</string>
<!-- APP-ICON ALTERNATES START -->
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>propeler</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIconPropeler</string>
</array>
</dict>
</dict>
</dict>
<!-- APP-ICON ALTERNATES END -->
</dict>
</plist>
17 changes: 17 additions & 0 deletions src-tauri/app-icons.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"android": {
"mainActivity": ".MainActivity",
"resourcesDirectory": "icons/android",
"manifest": "gen/android/app/src/main/AndroidManifest.xml"
},
"ios": {
"assetsDirectory": "icons/ios/AppIcons.xcassets",
"infoPlist": "Info.plist"
},
"icons": [
{
"id": "propeler",
"source": "icons/app-icons/propeler.png"
}
]
}
1 change: 1 addition & 0 deletions src-tauri/capabilities/mobile.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"windows": ["main"],
"permissions": [
"core:window:allow-set-badge-count",
"app-icon:default",
"deep-link:default",
"edge-to-edge:default",
"notifications:default",
Expand Down
46 changes: 39 additions & 7 deletions src-tauri/gen/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,6 @@
android:label="@string/main_activity_title"
android:name="moe.sable.client.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<!-- AndroidTV support -->
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>

<!-- Inbound share targets — receive text, images, videos, and files from other apps.
Mirrors the iOS share extension activation rules. -->
<intent-filter>
Expand Down Expand Up @@ -120,6 +113,45 @@
<!-- DEEP LINK PLUGIN. AUTO-GENERATED. DO NOT REMOVE. -->
</activity>

<!-- APP-ICON ALIASES START -->
<activity-alias
android:name=".AppIconDefault"
android:targetActivity=".MainActivity"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:enabled="true"
android:exported="true">
<meta-data
android:name="tauri-plugin-app-icon-id"
android:value="default" />
<meta-data
android:name="tauri-plugin-app-icon-default"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity-alias>

<activity-alias
android:name=".AppIconPropeler"
android:targetActivity=".MainActivity"
android:icon="@mipmap/ic_launcher_propeler"
android:roundIcon="@mipmap/ic_launcher_propeler_round"
android:enabled="false"
android:exported="true">
<meta-data
android:name="tauri-plugin-app-icon-id"
android:value="propeler" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity-alias>
<!-- APP-ICON ALIASES END -->

<service
android:name="moe.sable.client.CallForegroundService"
android:exported="false"
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<foreground android:drawable="@mipmap/ic_launcher_propeler_foreground"/>
<background>
<color android:color="#fff"/>
</background>
</adaptive-icon>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src-tauri/icons/app-icons/propeler.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading