diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 9b109a2..afde5c6 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -317,3 +317,24 @@ and commit the regenerated native drawables and license. Run `./gradlew :app:testDebugUnitTest --tests '*AdaptiveFilesTest'` for adaptive selection, saved-state, and rendering checks. Rendering captures are written under `app/build/outputs/design/`; these use Robolectric native graphics, not a device. + +## Brand icons + +The Feiya mark combines an F with two swept wings, using plum, off-white, and lime. +`res/drawable/ic_launcher_foreground.xml` is the color vector source; keep its shape +within the adaptive safe circle. `ic_launcher_monochrome.xml` supplies themed icons, +and `ic_notification.xml` uses an opaque white silhouette on transparency at 24 dp. +Both foreground-service notification builders must use the notification drawable. +The splash screen shares the adaptive foreground and background color. + +After editing the vectors or `values/ic_launcher_background.xml`, regenerate legacy +launcher density PNGs and the in-app logo: + +```sh +python3 -m venv /tmp/feiya-icons-venv +/tmp/feiya-icons-venv/bin/pip install CairoSVG==2.9.1 +/tmp/feiya-icons-venv/bin/python scripts/update-brand-icons.py +./gradlew :app:processDebugResources +``` + +CairoSVG requires the native Cairo library. diff --git a/app/src/main/java/com/storyteller_f/feiya/service/AppService.kt b/app/src/main/java/com/storyteller_f/feiya/service/AppService.kt index de8c3b1..3353112 100644 --- a/app/src/main/java/com/storyteller_f/feiya/service/AppService.kt +++ b/app/src/main/java/com/storyteller_f/feiya/service/AppService.kt @@ -125,7 +125,7 @@ class AppService : LifecycleService() { private fun postForegroundNotify(message: String) { // Foreground promotion is required even when notification permission is denied. val notification = NotificationCompat.Builder(this, FOREGROUND_CHANNEL_ID) - .setSmallIcon(R.mipmap.ic_launcher) + .setSmallIcon(R.drawable.ic_notification) .setContentTitle(getString(R.string.app_name)) .setContentText(message) .setOngoing(true) @@ -139,7 +139,7 @@ class AppService : LifecycleService() { if (managerCompat.areNotificationsEnabled()) { val notification = NotificationCompat.Builder(this, DEFAULT_CHANNEL_ID) - .setSmallIcon(R.mipmap.ic_launcher) + .setSmallIcon(R.drawable.ic_notification) .setContentTitle(getString(R.string.app_name)) .setContentText(message) .build() diff --git a/app/src/main/res/drawable-nodpi/feiya_logo.png b/app/src/main/res/drawable-nodpi/feiya_logo.png index 6947bc4..ebb8bc7 100644 Binary files a/app/src/main/res/drawable-nodpi/feiya_logo.png and b/app/src/main/res/drawable-nodpi/feiya_logo.png differ diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml index 07d5da9..7821864 100644 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -1,170 +1,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:width="108dp" android:height="108dp" + android:viewportWidth="108" android:viewportHeight="108"> + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml index a9c5358..ff15e37 100644 --- a/app/src/main/res/drawable/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -2,19 +2,11 @@ - - - - - - - - \ No newline at end of file + android:viewportWidth="108" + android:viewportHeight="108"> + + + + diff --git a/app/src/main/res/drawable/ic_launcher_monochrome.xml b/app/src/main/res/drawable/ic_launcher_monochrome.xml new file mode 100644 index 0000000..9f6b34a --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_monochrome.xml @@ -0,0 +1,9 @@ + + + + diff --git a/app/src/main/res/drawable/ic_notification.xml b/app/src/main/res/drawable/ic_notification.xml new file mode 100644 index 0000000..24bacda --- /dev/null +++ b/app/src/main/res/drawable/ic_notification.xml @@ -0,0 +1,9 @@ + + + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 7353dbd..10bc7a5 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -2,4 +2,5 @@ - \ No newline at end of file + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index 7353dbd..10bc7a5 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -2,4 +2,5 @@ - \ No newline at end of file + + diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png index a1ccbad..a238141 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png index 40fd740..0c85300 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png index 598acdb..d2c80fd 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png index eb3395f..292b884 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 76d9133..032ec14 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png index 42462ab..4257a7d 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 362cce4..7146bf3 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png index cc21c1b..f93bde7 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index fc94e9d..7fb8ce1 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png index 050302e..56e0d32 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml index f4a86db..63f012e 100644 --- a/app/src/main/res/values/ic_launcher_background.xml +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -1,4 +1,4 @@ - #86D483 - \ No newline at end of file + #48245C + diff --git a/scripts/update-brand-icons.py b/scripts/update-brand-icons.py new file mode 100644 index 0000000..48b16b9 --- /dev/null +++ b/scripts/update-brand-icons.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +"""Render Feiya's VectorDrawable brand source. Requires CairoSVG 2.9.1.""" +from pathlib import Path +import xml.etree.ElementTree as ET +import cairosvg + +ROOT = Path(__file__).resolve().parent.parent +RES = ROOT / 'app/src/main/res' +A = '{http://schemas.android.com/apk/res/android}' +BACKGROUND = ET.parse(RES / 'values/ic_launcher_background.xml').find('color').text + + +def paths(name): + vector = ET.parse(RES / f'drawable/{name}.xml').getroot() + return ''.join(f'' + for p in vector.findall('path')) + + +def svg(content, size=108): + return f'{content}' + + +mark = paths('ic_launcher_foreground') +for density, pixels in [('mdpi', 48), ('hdpi', 72), ('xhdpi', 96), ('xxhdpi', 144), ('xxxhdpi', 192)]: + for suffix, background in [('', f''), + ('_round', f'')]: + # Legacy launchers do not apply the adaptive layer inset. + art = svg(background + f'{mark}') + cairosvg.svg2png(bytestring=art.encode(), write_to=str(RES / f'mipmap-{density}/ic_launcher{suffix}.png'), + output_width=pixels, output_height=pixels) + +logo = svg(f'' + mark) +cairosvg.svg2png(bytestring=logo.encode(), write_to=str(RES / 'drawable-nodpi/feiya_logo.png'), + output_width=512, output_height=512)