A proper launcher icon: OxygenHub's mark on night navy (closes #15) 0381bd8af55e
The hub's mark (two joined rings, cyan to blue) at 1.45 times, inside the adaptive icon's 66dp safe zone, on the app's navy with the accent's glow; a monochrome layer for themed icons. The legacy robot bitmaps go: minSdk 31 always uses the adaptive icon. A layoutlib preview renders it as a circle, a squircle and themed (docs/screenshots/launcher-icon.png, in the README); the other screenshots re-rendered, the dashboard now with an avatar. The screenshot hub implements HubApi.avatar.
- Author
- Andy McCall @andymccall <[email protected]>
- via
- agent
agent:claude@andymccall <[email protected]> · keyless, under your grant for changes,refs,seal · key a673739894ab
- When
- · 2026-10-25 11:11 UTC
- Signature
- ◈ sealed by agent:claude@andymccall
- Hash
0381bd8af55eb709088c421e780f985ee20fc553104d576354068b9fb8636ca4- Depends on
- 0a2858c0dad3 1416009b06af 3f3508bd5f16 57c0824300db 9481bfa7c5d0 db00632a61d6 e0e4a1c48a77
- Depended on by
- 4aee5293461d d1f635be9442 e2df27a81e5d
- In bookmarks
- main
- In tags
- v0.1.0 v0.1.1 v0.1.2 v0.1.3 v0.1.4 v0.1.5 v0.1.6 v0.1.7 v0.1.8 v0.1.9
- Edits
- 22 atoms, 17 tree operations, 27 files
Browse the tree at this change
added app/src/main/res/drawable/ic_launcher_monochrome.xml +15 −0
| 1 | + | <?xml version="1.0" encoding="utf-8"?> |
|
| 2 | + | <!-- OxygenHub's mark in one colour, for themed icons: (the hub's assets/icons/mark.svg) at 1.45 times, inside the adaptive icon's 66dp safe zone. --> |
|
| 3 | + | <vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 4 | + | xmlns:aapt="http://schemas.android.com/aapt" |
|
| 5 | + | android:width="108dp" |
|
| 6 | + | android:height="108dp" |
|
| 7 | + | android:viewportWidth="108" |
|
| 8 | + | android:viewportHeight="108"> |
|
| 9 | + | <path android:pathData="M38.05,45.3L69.95,45.3" android:strokeWidth="4.35" android:strokeLineCap="round" android:strokeColor="#FFFFFFFF" android:fillColor="#00000000"/> |
|
| 10 | + | <path android:pathData="M38.05,62.7L69.95,62.7" android:strokeWidth="4.35" android:strokeLineCap="round" android:strokeColor="#FFFFFFFF" android:fillColor="#00000000"/> |
|
| 11 | + | <path android:pathData="M38.05,54m-14.5,0a14.5,14.5 0,1 1,29,0a14.5,14.5 0,1 1,-29,0" android:strokeWidth="4.35" android:strokeLineCap="round" android:strokeColor="#FFFFFFFF" android:fillColor="#00000000"/> |
|
| 12 | + | <path android:pathData="M69.95,54m-14.5,0a14.5,14.5 0,1 1,29,0a14.5,14.5 0,1 1,-29,0" android:strokeWidth="4.35" android:strokeLineCap="round" android:strokeColor="#FFFFFFFF" android:fillColor="#00000000"/> |
|
| 13 | + | <path android:pathData="M38.05,54m-5.075,0a5.075,5.075 0,1 1,10.15,0a5.075,5.075 0,1 1,-10.15,0" android:fillColor="#FFFFFFFF"/> |
|
| 14 | + | <path android:pathData="M69.95,54m-5.075,0a5.075,5.075 0,1 1,10.15,0a5.075,5.075 0,1 1,-10.15,0" android:fillColor="#FFFFFFFF"/> |
|
| 15 | + | </vector> |
added docs/screenshots/launcher-icon.png +0 −0
No line changes.
removed app/src/main/res/mipmap-hdpi +0 −0
No line changes.
removed app/src/main/res/mipmap-hdpi/ic_launcher.webp +0 −0
No line changes.
removed app/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 −0
No line changes.
removed app/src/main/res/mipmap-mdpi +0 −0
No line changes.
removed app/src/main/res/mipmap-mdpi/ic_launcher.webp +0 −0
No line changes.
removed app/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 −0
No line changes.
removed app/src/main/res/mipmap-xhdpi +0 −0
No line changes.
removed app/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 −0
No line changes.
removed app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 −0
No line changes.
removed app/src/main/res/mipmap-xxhdpi +0 −0
No line changes.
removed app/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 −0
No line changes.
removed app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 −0
No line changes.
removed app/src/main/res/mipmap-xxxhdpi +0 −0
No line changes.
removed app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 −0
No line changes.
removed app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 −0
No line changes.
modified CHANGELOG.md +1 −0
| … | 1 unchanged lines |
||
| 2 | 2 | ||
| 3 | 3 | ## Unreleased |
|
| 4 | 4 | ||
| 5 | + | - **A proper launcher icon (#15):** OxygenHub's mark, the hub's two joined rings in its cyan-to-blue gradient, on the app's night navy with a soft glow, as an adaptive icon (any launcher's mask, inside the safe zone) with a monochrome layer for themed icons; the default robot's bitmaps are gone. A rendered preview is in `docs/screenshots/launcher-icon.png`. |
|
| 5 | 6 | - **Your avatar (#13):** the dashboard's greeting and the Account screen show the signed-in account's avatar from the hub's `/avatar/{name}`: an uploaded picture as it is, or the hub's identicon, read from its SVG (hue and cells) and drawn natively, so no SVG library; the initial while there is neither, or the hub cannot be reached. Fetched without the token (it is public), kept for the run, and refreshed with the dashboard. |
|
| 6 | 7 | - **The keyboard no longer comes up on its own on Repositories (#12):** opening Repositories gave the filter focus and brought the keyboard up on every visit (tapping the navigation bar gives the app's view focus, which Compose hands to the screen's first focusable). The filter now takes focus only when it is touched, or reached from a keyboard. Checked on a Pixel 10 Pro Fold. |
|
| 7 | 8 | - **Sign in, the hub's API, navigation and foldable layouts (#2):** sign in with the hub's device flow, as `oh auth login` does (a code to approve on the hub's `/device` page, with the password and second factor there, never in the app), against oxygenhub.io or any hub; the token sealed with a Keystore key, kept out of backups, and revoked on the hub when signing out. A hand-written Kotlin client for the hub's API: the user, repositories, a repository's issues, the inbox and marking it read. A dashboard (greeting, recent repositories, unread count), repositories with their issues side by side from a medium width up (a foldable open, a tablet), and the inbox with a badge; a navigation bar on a phone and a rail when wider; light and dark, in dynamic colour or the hub's own palette; loading, empty and error states with pull to refresh. The placeholder login (username and password) and tabs are gone. Unit tests for the client (against fixtures from hub-api's types) and the view models; README screenshots rendered from Compose previews without an emulator. |
|
| … | 1 unchanged lines |
modified README.md +2 −0
| … | 5 unchanged lines |
||
| 6 | 6 |  |
|
| 7 | 7 |  |
|
| 8 | 8 | ||
| 9 | + | <img src="docs/screenshots/launcher-icon.png" alt="The launcher icon: as a circle, a squircle and a themed icon" width="400"> |
|
| 10 | + | ||
| 9 | 11 | The official native Android client for OxygenHub, designed for modern devices and fully optimized for foldables like the Pixel 10 Pro Fold. |
|
| 10 | 12 | ||
| 11 | 13 | Built with **Kotlin**, **Jetpack Compose**, and deep **Rust interop** (via `uniffi-rs`) to execute native `oxy` commands directly on your device. |
|
| … | 97 unchanged lines |
modified app/src/main/res/drawable/ic_launcher_background.xml +18 −163
| 1 | 1 | <?xml version="1.0" encoding="utf-8"?> |
|
| 2 | + | <!-- The app's night navy, lit from the top left, with the accent's glow behind the mark. --> |
|
| 2 | 3 | <vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 4 | + | xmlns:aapt="http://schemas.android.com/aapt" |
|
| 3 | 5 | android:width="108dp" |
|
| 4 | 6 | android:height="108dp" |
|
| 5 | 7 | android:viewportWidth="108" |
|
| 6 | 8 | android:viewportHeight="108"> |
|
| 7 | - | <path |
|
| 8 | - | android:fillColor="#3DDC84" |
|
| 9 | - | android:pathData="M0,0h108v108h-108z" /> |
|
| 10 | - | <path |
|
| 11 | - | android:fillColor="#00000000" |
|
| 12 | - | android:pathData="M9,0L9,108" |
|
| 13 | - | android:strokeWidth="0.8" |
|
| 14 | - | android:strokeColor="#33FFFFFF" /> |
|
| 15 | - | <path |
|
| 16 | - | android:fillColor="#00000000" |
|
| 17 | - | android:pathData="M19,0L19,108" |
|
| 18 | - | android:strokeWidth="0.8" |
|
| 19 | - | android:strokeColor="#33FFFFFF" /> |
|
| 20 | - | <path |
|
| 21 | - | android:fillColor="#00000000" |
|
| 22 | - | android:pathData="M29,0L29,108" |
|
| 23 | - | android:strokeWidth="0.8" |
|
| 24 | - | android:strokeColor="#33FFFFFF" /> |
|
| 25 | - | <path |
|
| 26 | - | android:fillColor="#00000000" |
|
| 27 | - | android:pathData="M39,0L39,108" |
|
| 28 | - | android:strokeWidth="0.8" |
|
| 29 | - | android:strokeColor="#33FFFFFF" /> |
|
| 30 | - | <path |
|
| 31 | - | android:fillColor="#00000000" |
|
| 32 | - | android:pathData="M49,0L49,108" |
|
| 33 | - | android:strokeWidth="0.8" |
|
| 34 | - | android:strokeColor="#33FFFFFF" /> |
|
| 35 | - | <path |
|
| 36 | - | android:fillColor="#00000000" |
|
| 37 | - | android:pathData="M59,0L59,108" |
|
| 38 | - | android:strokeWidth="0.8" |
|
| 39 | - | android:strokeColor="#33FFFFFF" /> |
|
| 40 | - | <path |
|
| 41 | - | android:fillColor="#00000000" |
|
| 42 | - | android:pathData="M69,0L69,108" |
|
| 43 | - | android:strokeWidth="0.8" |
|
| 44 | - | android:strokeColor="#33FFFFFF" /> |
|
| 45 | - | <path |
|
| 46 | - | android:fillColor="#00000000" |
|
| 47 | - | android:pathData="M79,0L79,108" |
|
| 48 | - | android:strokeWidth="0.8" |
|
| 49 | - | android:strokeColor="#33FFFFFF" /> |
|
| 50 | - | <path |
|
| 51 | - | android:fillColor="#00000000" |
|
| 52 | - | android:pathData="M89,0L89,108" |
|
| 53 | - | android:strokeWidth="0.8" |
|
| 54 | - | android:strokeColor="#33FFFFFF" /> |
|
| 55 | - | <path |
|
| 56 | - | android:fillColor="#00000000" |
|
| 57 | - | android:pathData="M99,0L99,108" |
|
| 58 | - | android:strokeWidth="0.8" |
|
| 59 | - | android:strokeColor="#33FFFFFF" /> |
|
| 60 | - | <path |
|
| 61 | - | android:fillColor="#00000000" |
|
| 62 | - | android:pathData="M0,9L108,9" |
|
| 63 | - | android:strokeWidth="0.8" |
|
| 64 | - | android:strokeColor="#33FFFFFF" /> |
|
| 65 | - | <path |
|
| 66 | - | android:fillColor="#00000000" |
|
| 67 | - | android:pathData="M0,19L108,19" |
|
| 68 | - | android:strokeWidth="0.8" |
|
| 69 | - | android:strokeColor="#33FFFFFF" /> |
|
| 70 | - | <path |
|
| 71 | - | android:fillColor="#00000000" |
|
| 72 | - | android:pathData="M0,29L108,29" |
|
| 73 | - | android:strokeWidth="0.8" |
|
| 74 | - | android:strokeColor="#33FFFFFF" /> |
|
| 75 | - | <path |
|
| 76 | - | android:fillColor="#00000000" |
|
| 77 | - | android:pathData="M0,39L108,39" |
|
| 78 | - | android:strokeWidth="0.8" |
|
| 79 | - | android:strokeColor="#33FFFFFF" /> |
|
| 80 | - | <path |
|
| 81 | - | android:fillColor="#00000000" |
|
| 82 | - | android:pathData="M0,49L108,49" |
|
| 83 | - | android:strokeWidth="0.8" |
|
| 84 | - | android:strokeColor="#33FFFFFF" /> |
|
| 85 | - | <path |
|
| 86 | - | android:fillColor="#00000000" |
|
| 87 | - | android:pathData="M0,59L108,59" |
|
| 88 | - | android:strokeWidth="0.8" |
|
| 89 | - | android:strokeColor="#33FFFFFF" /> |
|
| 90 | - | <path |
|
| 91 | - | android:fillColor="#00000000" |
|
| 92 | - | android:pathData="M0,69L108,69" |
|
| 93 | - | android:strokeWidth="0.8" |
|
| 94 | - | android:strokeColor="#33FFFFFF" /> |
|
| 95 | - | <path |
|
| 96 | - | android:fillColor="#00000000" |
|
| 97 | - | android:pathData="M0,79L108,79" |
|
| 98 | - | android:strokeWidth="0.8" |
|
| 99 | - | android:strokeColor="#33FFFFFF" /> |
|
| 100 | - | <path |
|
| 101 | - | android:fillColor="#00000000" |
|
| 102 | - | android:pathData="M0,89L108,89" |
|
| 103 | - | android:strokeWidth="0.8" |
|
| 104 | - | android:strokeColor="#33FFFFFF" /> |
|
| 105 | - | <path |
|
| 106 | - | android:fillColor="#00000000" |
|
| 107 | - | android:pathData="M0,99L108,99" |
|
| 108 | - | android:strokeWidth="0.8" |
|
| 109 | - | android:strokeColor="#33FFFFFF" /> |
|
| 110 | - | <path |
|
| 111 | - | android:fillColor="#00000000" |
|
| 112 | - | android:pathData="M19,29L89,29" |
|
| 113 | - | android:strokeWidth="0.8" |
|
| 114 | - | android:strokeColor="#33FFFFFF" /> |
|
| 115 | - | <path |
|
| 116 | - | android:fillColor="#00000000" |
|
| 117 | - | android:pathData="M19,39L89,39" |
|
| 118 | - | android:strokeWidth="0.8" |
|
| 119 | - | android:strokeColor="#33FFFFFF" /> |
|
| 120 | - | <path |
|
| 121 | - | android:fillColor="#00000000" |
|
| 122 | - | android:pathData="M19,49L89,49" |
|
| 123 | - | android:strokeWidth="0.8" |
|
| 124 | - | android:strokeColor="#33FFFFFF" /> |
|
| 125 | - | <path |
|
| 126 | - | android:fillColor="#00000000" |
|
| 127 | - | android:pathData="M19,59L89,59" |
|
| 128 | - | android:strokeWidth="0.8" |
|
| 129 | - | android:strokeColor="#33FFFFFF" /> |
|
| 130 | - | <path |
|
| 131 | - | android:fillColor="#00000000" |
|
| 132 | - | android:pathData="M19,69L89,69" |
|
| 133 | - | android:strokeWidth="0.8" |
|
| 134 | - | android:strokeColor="#33FFFFFF" /> |
|
| 135 | - | <path |
|
| 136 | - | android:fillColor="#00000000" |
|
| 137 | - | android:pathData="M19,79L89,79" |
|
| 138 | - | android:strokeWidth="0.8" |
|
| 139 | - | android:strokeColor="#33FFFFFF" /> |
|
| 140 | - | <path |
|
| 141 | - | android:fillColor="#00000000" |
|
| 142 | - | android:pathData="M29,19L29,89" |
|
| 143 | - | android:strokeWidth="0.8" |
|
| 144 | - | android:strokeColor="#33FFFFFF" /> |
|
| 145 | - | <path |
|
| 146 | - | android:fillColor="#00000000" |
|
| 147 | - | android:pathData="M39,19L39,89" |
|
| 148 | - | android:strokeWidth="0.8" |
|
| 149 | - | android:strokeColor="#33FFFFFF" /> |
|
| 150 | - | <path |
|
| 151 | - | android:fillColor="#00000000" |
|
| 152 | - | android:pathData="M49,19L49,89" |
|
| 153 | - | android:strokeWidth="0.8" |
|
| 154 | - | android:strokeColor="#33FFFFFF" /> |
|
| 155 | - | <path |
|
| 156 | - | android:fillColor="#00000000" |
|
| 157 | - | android:pathData="M59,19L59,89" |
|
| 158 | - | android:strokeWidth="0.8" |
|
| 159 | - | android:strokeColor="#33FFFFFF" /> |
|
| 160 | - | <path |
|
| 161 | - | android:fillColor="#00000000" |
|
| 162 | - | android:pathData="M69,19L69,89" |
|
| 163 | - | android:strokeWidth="0.8" |
|
| 164 | - | android:strokeColor="#33FFFFFF" /> |
|
| 165 | - | <path |
|
| 166 | - | android:fillColor="#00000000" |
|
| 167 | - | android:pathData="M79,19L79,89" |
|
| 168 | - | android:strokeWidth="0.8" |
|
| 169 | - | android:strokeColor="#33FFFFFF" /> |
|
| 9 | + | <path android:pathData="M0,0h108v108h-108z"> |
|
| 10 | + | <aapt:attr name="android:fillColor"> |
|
| 11 | + | <gradient android:type="linear" android:startX="0" android:startY="0" android:endX="108" android:endY="108"> |
|
| 12 | + | <item android:offset="0" android:color="#FF0E2A55"/> |
|
| 13 | + | <item android:offset="1" android:color="#FF070C18"/> |
|
| 14 | + | </gradient> |
|
| 15 | + | </aapt:attr> |
|
| 16 | + | </path> |
|
| 17 | + | <path android:pathData="M0,0h108v108h-108z"> |
|
| 18 | + | <aapt:attr name="android:fillColor"> |
|
| 19 | + | <gradient android:type="radial" android:centerX="54" android:centerY="54" android:gradientRadius="40"> |
|
| 20 | + | <item android:offset="0" android:color="#730072FF"/> |
|
| 21 | + | <item android:offset="1" android:color="#000072FF"/> |
|
| 22 | + | </gradient> |
|
| 23 | + | </aapt:attr> |
|
| 24 | + | </path> |
|
| 170 | 25 | </vector> |
modified app/src/main/res/drawable/ic_launcher_foreground.xml +37 −24
| 1 | + | <?xml version="1.0" encoding="utf-8"?> |
|
| 2 | + | <!-- OxygenHub's mark (the hub's assets/icons/mark.svg) at 1.45 times, inside the adaptive icon's 66dp safe zone. --> |
|
| 1 | 3 | <vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 2 | 4 | xmlns:aapt="http://schemas.android.com/aapt" |
|
| 3 | 5 | android:width="108dp" |
|
| 4 | 6 | android:height="108dp" |
|
| 5 | 7 | android:viewportWidth="108" |
|
| 6 | 8 | android:viewportHeight="108"> |
|
| 7 | - | <path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z"> |
|
| 8 | - | <aapt:attr name="android:fillColor"> |
|
| 9 | - | <gradient |
|
| 10 | - | android:endX="85.84757" |
|
| 11 | - | android:endY="92.4963" |
|
| 12 | - | android:startX="42.9492" |
|
| 13 | - | android:startY="49.59793" |
|
| 14 | - | android:type="linear"> |
|
| 15 | - | <item |
|
| 16 | - | android:color="#44000000" |
|
| 17 | - | android:offset="0.0" /> |
|
| 18 | - | <item |
|
| 19 | - | android:color="#00000000" |
|
| 20 | - | android:offset="1.0" /> |
|
| 21 | - | </gradient> |
|
| 22 | - | </aapt:attr> |
|
| 23 | - | </path> |
|
| 24 | - | <path |
|
| 25 | - | android:fillColor="#FFFFFF" |
|
| 26 | - | android:fillType="nonZero" |
|
| 27 | - | android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z" |
|
| 28 | - | android:strokeWidth="1" |
|
| 29 | - | android:strokeColor="#00000000" /> |
|
| 30 | - | </vector> |
|
| 9 | + | <path android:pathData="M38.05,45.3L69.95,45.3" android:strokeWidth="4.35" android:strokeLineCap="round" android:fillColor="#00000000"> |
|
| 10 | + | <aapt:attr name="android:strokeColor"> |
|
| 11 | + | <gradient android:type="linear" android:startX="22.1" android:startY="38.05" android:endX="85.9" android:endY="69.95"> |
|
| 12 | + | <item android:offset="0" android:color="#FF00F0FF"/> |
|
| 13 | + | <item android:offset="1" android:color="#FF0072FF"/> |
|
| 14 | + | </gradient> |
|
| 15 | + | </aapt:attr> |
|
| 16 | + | </path> |
|
| 17 | + | <path android:pathData="M38.05,62.7L69.95,62.7" android:strokeWidth="4.35" android:strokeLineCap="round" android:fillColor="#00000000"> |
|
| 18 | + | <aapt:attr name="android:strokeColor"> |
|
| 19 | + | <gradient android:type="linear" android:startX="22.1" android:startY="38.05" android:endX="85.9" android:endY="69.95"> |
|
| 20 | + | <item android:offset="0" android:color="#FF00F0FF"/> |
|
| 21 | + | <item android:offset="1" android:color="#FF0072FF"/> |
|
| 22 | + | </gradient> |
|
| 23 | + | </aapt:attr> |
|
| 24 | + | </path> |
|
| 25 | + | <path android:pathData="M38.05,54m-14.5,0a14.5,14.5 0,1 1,29,0a14.5,14.5 0,1 1,-29,0" android:strokeWidth="4.35" android:strokeLineCap="round" android:fillColor="#00000000"> |
|
| 26 | + | <aapt:attr name="android:strokeColor"> |
|
| 27 | + | <gradient android:type="linear" android:startX="22.1" android:startY="38.05" android:endX="85.9" android:endY="69.95"> |
|
| 28 | + | <item android:offset="0" android:color="#FF00F0FF"/> |
|
| 29 | + | <item android:offset="1" android:color="#FF0072FF"/> |
|
| 30 | + | </gradient> |
|
| 31 | + | </aapt:attr> |
|
| 32 | + | </path> |
|
| 33 | + | <path android:pathData="M69.95,54m-14.5,0a14.5,14.5 0,1 1,29,0a14.5,14.5 0,1 1,-29,0" android:strokeWidth="4.35" android:strokeLineCap="round" android:fillColor="#00000000"> |
|
| 34 | + | <aapt:attr name="android:strokeColor"> |
|
| 35 | + | <gradient android:type="linear" android:startX="22.1" android:startY="38.05" android:endX="85.9" android:endY="69.95"> |
|
| 36 | + | <item android:offset="0" android:color="#FF00F0FF"/> |
|
| 37 | + | <item android:offset="1" android:color="#FF0072FF"/> |
|
| 38 | + | </gradient> |
|
| 39 | + | </aapt:attr> |
|
| 40 | + | </path> |
|
| 41 | + | <path android:pathData="M38.05,54m-5.075,0a5.075,5.075 0,1 1,10.15,0a5.075,5.075 0,1 1,-10.15,0" android:fillColor="#FF00F0FF"/> |
|
| 42 | + | <path android:pathData="M69.95,54m-5.075,0a5.075,5.075 0,1 1,10.15,0a5.075,5.075 0,1 1,-10.15,0" android:fillColor="#FFFFFFFF"/> |
|
| 43 | + | </vector> |
modified app/src/main/res/mipmap-anydpi/ic_launcher.xml +1 −1
| … | 1 unchanged lines |
||
| 2 | 2 | <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> |
|
| 3 | 3 | <background android:drawable="@drawable/ic_launcher_background" /> |
|
| 4 | 4 | <foreground android:drawable="@drawable/ic_launcher_foreground" /> |
|
| 5 | - | <monochrome android:drawable="@drawable/ic_launcher_foreground" /> |
|
| 5 | + | <monochrome android:drawable="@drawable/ic_launcher_monochrome" /> |
|
| 6 | 6 | </adaptive-icon> |
modified app/src/main/res/mipmap-anydpi/ic_launcher_round.xml +1 −1
| … | 1 unchanged lines |
||
| 2 | 2 | <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> |
|
| 3 | 3 | <background android:drawable="@drawable/ic_launcher_background" /> |
|
| 4 | 4 | <foreground android:drawable="@drawable/ic_launcher_foreground" /> |
|
| 5 | - | <monochrome android:drawable="@drawable/ic_launcher_foreground" /> |
|
| 5 | + | <monochrome android:drawable="@drawable/ic_launcher_monochrome" /> |
|
| 6 | 6 | </adaptive-icon> |
modified app/src/screenshotTest/kotlin/io/oxygenhub/android/Screenshots.kt +47 −0
| 1 | 1 | package io.oxygenhub.android |
|
| 2 | 2 | ||
| 3 | 3 | import android.content.res.Configuration |
|
| 4 | + | import androidx.compose.foundation.Image |
|
| 5 | + | import androidx.compose.foundation.background |
|
| 6 | + | import androidx.compose.foundation.layout.Arrangement |
|
| 7 | + | import androidx.compose.foundation.layout.Box |
|
| 8 | + | import androidx.compose.foundation.layout.Row |
|
| 9 | + | import androidx.compose.foundation.layout.fillMaxSize |
|
| 10 | + | import androidx.compose.foundation.layout.padding |
|
| 11 | + | import androidx.compose.foundation.layout.size |
|
| 12 | + | import androidx.compose.foundation.shape.CircleShape |
|
| 13 | + | import androidx.compose.foundation.shape.RoundedCornerShape |
|
| 14 | + | import androidx.compose.ui.Modifier |
|
| 15 | + | import androidx.compose.ui.draw.clip |
|
| 16 | + | import androidx.compose.ui.graphics.Color |
|
| 17 | + | import androidx.compose.ui.graphics.ColorFilter |
|
| 18 | + | import androidx.compose.ui.res.painterResource |
|
| 19 | + | import androidx.compose.ui.unit.dp |
|
| 4 | 20 | import androidx.compose.runtime.Composable |
|
| 5 | 21 | import androidx.compose.runtime.remember |
|
| 6 | 22 | import androidx.compose.ui.tooling.preview.Preview |
|
| 7 | 23 | import com.android.tools.screenshot.PreviewTest |
|
| 24 | + | import io.oxygenhub.android.api.Avatar |
|
| 8 | 25 | import io.oxygenhub.android.api.DeviceCode |
|
| 9 | 26 | import io.oxygenhub.android.api.HubApi |
|
| 10 | 27 | import io.oxygenhub.android.api.Inbox |
|
| … | 63 unchanged lines |
||
| 74 | 91 | override suspend fun markRead(id: Long) {} |
|
| 75 | 92 | override suspend fun markAllRead() {} |
|
| 76 | 93 | override suspend fun revokeToken() {} |
|
| 94 | + | ||
| 95 | + | // Ada's identicon, as the hub would draw it. |
|
| 96 | + | override suspend fun avatar(name: String) = |
|
| 97 | + | Avatar.Identicon(196, setOf(1 to 1, 5 to 1, 2 to 2, 3 to 2, 4 to 2, 1 to 3, 3 to 3, 5 to 3, 2 to 4, 4 to 4, 1 to 5, 5 to 5)) |
|
| 77 | 98 | } |
|
| 78 | 99 | ||
| 79 | 100 | private val session = Session("https://oxygenhub.io", "ada", "", listOf("repo:read", "user:read")) |
|
| … | 46 unchanged lines |
||
| 126 | 147 | @Preview(name = "inbox-phone-dark", device = PHONE, uiMode = Configuration.UI_MODE_NIGHT_YES) |
|
| 127 | 148 | @Composable |
|
| 128 | 149 | fun InboxPhoneDark() = App(TopLevel.Inbox, dark = true) |
|
| 150 | + | ||
| 151 | + | /** |
|
| 152 | + | * The launcher icon as launchers mask it (a circle, a squircle) and as a |
|
| 153 | + | * themed icon (its monochrome layer, tinted), on the README's page. |
|
| 154 | + | */ |
|
| 155 | + | @PreviewTest |
|
| 156 | + | @Preview(name = "launcher-icon", widthDp = 400, heightDp = 132, backgroundColor = 0xFFF4F7FC, showBackground = true) |
|
| 157 | + | @Composable |
|
| 158 | + | fun LauncherIcon() { |
|
| 159 | + | Row(Modifier.padding(12.dp), horizontalArrangement = Arrangement.spacedBy(16.dp)) { |
|
| 160 | + | for (shape in listOf(CircleShape, RoundedCornerShape(30))) { |
|
| 161 | + | Box(Modifier.size(108.dp).clip(shape)) { |
|
| 162 | + | Image(painterResource(R.drawable.ic_launcher_background), null, Modifier.fillMaxSize()) |
|
| 163 | + | Image(painterResource(R.drawable.ic_launcher_foreground), null, Modifier.fillMaxSize()) |
|
| 164 | + | } |
|
| 165 | + | } |
|
| 166 | + | Box(Modifier.size(108.dp).clip(CircleShape).background(Color(0xFFD3E3FD))) { |
|
| 167 | + | Image( |
|
| 168 | + | painterResource(R.drawable.ic_launcher_monochrome), |
|
| 169 | + | null, |
|
| 170 | + | Modifier.fillMaxSize(), |
|
| 171 | + | colorFilter = ColorFilter.tint(Color(0xFF041E49)), |
|
| 172 | + | ) |
|
| 173 | + | } |
|
| 174 | + | } |
|
| 175 | + | } |
replaced docs/screenshots/dashboard-phone.png +0 −0
No line changes.
replaced docs/screenshots/repositories-foldable.png +0 −0
No line changes.
replaced docs/screenshots/repositories-tablet-dark.png +0 −0
No line changes.