From 9c751911274e11da2d5af8a97033b0323f2678b9 Mon Sep 17 00:00:00 2001 From: Iain Date: Tue, 6 Oct 2026 19:16:00 +0100 Subject: [PATCH 1/2] feat: card view by default, with a switch back to the table Every data page now leads with cards that state the facts plainly, and a Cards | Table switch at the top right brings the table back. It's two radios, so it works without JS, and the choice is remembered between pages. - Device pages show the bootloader and stock updates up top, then a card per ROM: Android version, Google apps, build date and patch, relock, what it needs first, what works, and the install guide - Device, brand and ROM pages list devices as cards grouped by brand, with one filter bar driving cards and table alike, plus new ROM and bootloader filters - Wording comes from one place, src/lib/facts.js: inferred answers read "Likely doesn't work", old reports say when they were last checked, and the origin jargon is gone. Unknown features stay off cards, and show in the table - A design system: tokens, base and shared component styles, Lucide icons, and brand and ROM logos (Simple Icons plus the five ROMs' own marks) with initials as the fallback - The API output is unchanged Co-Authored-By: Claude Opus 5.5 --- .github/CONTRIBUTING.md | 4 +- .github/README.md | 2 +- package-lock.json | 10 + package.json | 1 + public/icons/broken.svg | 2 +- public/icons/ended.svg | 2 +- public/icons/na.svg | 2 +- public/icons/note.svg | 2 +- public/icons/partial.svg | 2 +- public/icons/sort-down.svg | 2 +- public/icons/sort-up.svg | 2 +- public/icons/sort.svg | 2 +- public/icons/stale.svg | 2 +- public/icons/unknown.svg | 2 +- public/icons/working.svg | 2 +- src/assets/logos/README.md | 38 ++++ src/assets/logos/brands/asus.svg | 1 + src/assets/logos/brands/fairphone.svg | 1 + src/assets/logos/brands/google.svg | 1 + src/assets/logos/brands/htc.svg | 1 + src/assets/logos/brands/huawei.svg | 1 + src/assets/logos/brands/lenovo.svg | 1 + src/assets/logos/brands/lg.svg | 1 + src/assets/logos/brands/meizu.svg | 1 + src/assets/logos/brands/motorola.svg | 1 + src/assets/logos/brands/nokia.svg | 1 + src/assets/logos/brands/nvidia.svg | 1 + src/assets/logos/brands/oneplus.svg | 1 + src/assets/logos/brands/oppo.svg | 1 + src/assets/logos/brands/razer.svg | 1 + src/assets/logos/brands/samsung.svg | 1 + src/assets/logos/brands/solana.svg | 1 + src/assets/logos/brands/sony.svg | 1 + src/assets/logos/brands/xiaomi.svg | 1 + src/assets/logos/roms/calyxos.svg | 1 + src/assets/logos/roms/crdroid.svg | 1 + src/assets/logos/roms/eos.svg | 1 + src/assets/logos/roms/evolutionx.svg | 1 + src/assets/logos/roms/grapheneos.svg | 1 + src/assets/logos/roms/iodeos.svg | 1 + src/assets/logos/roms/lineageos.svg | 1 + src/assets/logos/roms/pixelos.svg | 1 + src/components/cards/CardGrid.astro | 143 ++++++++++++++ src/components/cards/FeatureList.astro | 70 +++++++ src/components/cards/RomCard.astro | 156 +++++++++++++++ src/components/cards/RomSummary.astro | 74 ++++++++ src/components/layout/Base.astro | 14 +- src/components/layout/Footer.astro | 8 +- src/components/layout/Header.astro | 5 +- src/components/layout/PageHead.astro | 63 ++++++ src/components/table/Cell.astro | 68 ++----- src/components/table/ColumnPicker.astro | 97 ++++++++++ src/components/table/Controls.astro | 158 --------------- src/components/table/Matrix.astro | 45 +---- src/components/ui/DeviceList.astro | 57 ++++++ src/components/ui/DeviceTables.astro | 21 -- src/components/ui/Facts.astro | 73 ++++++- src/components/ui/FilterBar.astro | 153 +++++++++++++++ src/components/ui/Icon.astro | 51 +++-- src/components/ui/Logo.astro | 76 ++++++++ src/components/ui/RomFeatures.astro | 58 ------ src/components/ui/ViewSwitch.astro | 107 +++++++++++ src/lib/cards.js | 50 +++++ src/lib/data/model.js | 4 +- src/lib/dates.js | 15 ++ src/lib/facts.js | 167 ++++++++++++++++ src/lib/table.js | 119 ++++++------ src/lib/text.js | 2 + src/pages/about.astro | 8 +- src/pages/api/[name].json.js | 2 +- src/pages/devices/[brand]/[slug].astro | 236 ++++++++++++++--------- src/pages/devices/[brand]/index.astro | 46 +++-- src/pages/devices/index.astro | 71 +++++-- src/pages/index.astro | 52 +++-- src/pages/roms/[rom].astro | 158 +++++++++------ src/pages/roms/index.astro | 60 ++++-- src/scripts/filter.js | 67 +++++++ src/scripts/matrix.js | 52 +---- src/styles/{global.css => base.css} | 84 +------- src/styles/tokens.css | 83 ++++++++ src/styles/ui.css | 243 ++++++++++++++++++++++++ tests/facts.test.js | 118 ++++++++++++ tests/logos.test.js | 24 +++ 83 files changed, 2448 insertions(+), 813 deletions(-) create mode 100644 src/assets/logos/README.md create mode 100644 src/assets/logos/brands/asus.svg create mode 100644 src/assets/logos/brands/fairphone.svg create mode 100644 src/assets/logos/brands/google.svg create mode 100644 src/assets/logos/brands/htc.svg create mode 100644 src/assets/logos/brands/huawei.svg create mode 100644 src/assets/logos/brands/lenovo.svg create mode 100644 src/assets/logos/brands/lg.svg create mode 100644 src/assets/logos/brands/meizu.svg create mode 100644 src/assets/logos/brands/motorola.svg create mode 100644 src/assets/logos/brands/nokia.svg create mode 100644 src/assets/logos/brands/nvidia.svg create mode 100644 src/assets/logos/brands/oneplus.svg create mode 100644 src/assets/logos/brands/oppo.svg create mode 100644 src/assets/logos/brands/razer.svg create mode 100644 src/assets/logos/brands/samsung.svg create mode 100644 src/assets/logos/brands/solana.svg create mode 100644 src/assets/logos/brands/sony.svg create mode 100644 src/assets/logos/brands/xiaomi.svg create mode 100644 src/assets/logos/roms/calyxos.svg create mode 100644 src/assets/logos/roms/crdroid.svg create mode 100644 src/assets/logos/roms/eos.svg create mode 100644 src/assets/logos/roms/evolutionx.svg create mode 100644 src/assets/logos/roms/grapheneos.svg create mode 100644 src/assets/logos/roms/iodeos.svg create mode 100644 src/assets/logos/roms/lineageos.svg create mode 100644 src/assets/logos/roms/pixelos.svg create mode 100644 src/components/cards/CardGrid.astro create mode 100644 src/components/cards/FeatureList.astro create mode 100644 src/components/cards/RomCard.astro create mode 100644 src/components/cards/RomSummary.astro create mode 100644 src/components/layout/PageHead.astro create mode 100644 src/components/table/ColumnPicker.astro delete mode 100644 src/components/table/Controls.astro create mode 100644 src/components/ui/DeviceList.astro delete mode 100644 src/components/ui/DeviceTables.astro create mode 100644 src/components/ui/FilterBar.astro create mode 100644 src/components/ui/Logo.astro delete mode 100644 src/components/ui/RomFeatures.astro create mode 100644 src/components/ui/ViewSwitch.astro create mode 100644 src/lib/cards.js create mode 100644 src/lib/facts.js create mode 100644 src/scripts/filter.js rename src/styles/{global.css => base.css} (53%) create mode 100644 src/styles/tokens.css create mode 100644 src/styles/ui.css create mode 100644 tests/facts.test.js create mode 100644 tests/logos.test.js diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 438a59f..14425ef 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -27,7 +27,7 @@ The files in `upstream/` get rewritten by a bot every Monday, so any change you ## Reporting what works -The [form](https://github.com/NotAFlightRisk/android-rom-compat/issues/new?template=report-feature.yml) is the easy way. Pick a device and ROM, set whatever you've tried, and a bot opens a pull request for you with your name on the commit. If something's missing or doesn't add up, it comments on the issue saying what - just edit the issue and it'll try again. The "Report" link on each ROM row of a device page puts the device, its codename and the ROM in the title, so you can copy them across. +The [form](https://github.com/NotAFlightRisk/android-rom-compat/issues/new?template=report-feature.yml) is the easy way. Pick a device and ROM, set whatever you've tried, and a bot opens a pull request for you with your name on the commit. If something's missing or doesn't add up, it comments on the issue saying what - just edit the issue and it'll try again. The "Report what works" button on each ROM on a device page puts the device, its codename and the ROM in the title, so you can copy them across. Rather do it by hand? Add a `features` section to `data/support//.yml`, making the file if it's not there yet. Anything you leave out shows as unknown, which is fine. @@ -40,7 +40,7 @@ features: widevine: L3 ``` -`android` and `build` are what you tested on, `checked` is the date, and `variant` is for a ROM's other builds (like LineageOS for microG). A report shows as stale once the ROM moves to a newer Android than yours, or `checked` is over a year old. +`android` and `build` are what you tested on, `checked` is the date, and `variant` is for a ROM's other builds (like LineageOS for microG). Once the ROM moves to a newer Android than yours, or `checked` is over a year old, the site says when it was last checked. The keys come from [`features.yml`](../data/features.yml). Most features use these: diff --git a/.github/README.md b/.github/README.md index ea73334..ccf0343 100644 --- a/.github/README.md +++ b/.github/README.md @@ -16,7 +16,7 @@ Covers GrapheneOS, LineageOS, CalyxOS, /e/OS, crDroid, iodéOS, Evolution X and PixelOS, official builds only. Every bit of data lives as YAML in [`data/`](../data), so fixing a mistake just means editing a file - no coding needed. -It'd rather leave a gap than guess, so anything nobody has checked shows as unknown. A report goes stale once the ROM moves to a newer Android than it was checked on, or when it's over a year old. +It'd rather leave a gap than guess, so anything nobody has checked is left out, and shows as unknown in the table view. A report goes stale once the ROM moves to a newer Android than it was checked on, or when it's over a year old. --- diff --git a/package-lock.json b/package-lock.json index d10c144..9099aeb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@astrojs/sitemap": "^3.7.4", "@fontsource-variable/roboto": "^5.3.0", "@fontsource-variable/roboto-mono": "^5.3.0", + "@lucide/astro": "^1.52.0", "@sentry/browser": "^11.4.0", "astro": "^7.3.5" }, @@ -1832,6 +1833,15 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@lucide/astro": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/@lucide/astro/-/astro-1.52.0.tgz", + "integrity": "sha512-Vyo3sHYPtLvP5fbvqrMSMutcRzu8tbZXG6xFylrDnpeGVjLisokqKrWKuEm6K4IKwxkTrKK/xyXkVBE0WjxZKg==", + "license": "ISC", + "peerDependencies": { + "astro": "^4 || ^5 || ^6 || ^7" + } + }, "node_modules/@napi-rs/wasm-runtime": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.4.tgz", diff --git a/package.json b/package.json index 30042ed..0240746 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@astrojs/sitemap": "^3.7.4", "@fontsource-variable/roboto": "^5.3.0", "@fontsource-variable/roboto-mono": "^5.3.0", + "@lucide/astro": "^1.52.0", "@sentry/browser": "^11.4.0", "astro": "^7.3.5" }, diff --git a/public/icons/broken.svg b/public/icons/broken.svg index d0860b4..b50c2d2 100644 --- a/public/icons/broken.svg +++ b/public/icons/broken.svg @@ -1 +1 @@ - + diff --git a/public/icons/ended.svg b/public/icons/ended.svg index a3a7ac1..9b99fae 100644 --- a/public/icons/ended.svg +++ b/public/icons/ended.svg @@ -1 +1 @@ - + diff --git a/public/icons/na.svg b/public/icons/na.svg index cca95cc..66042ad 100644 --- a/public/icons/na.svg +++ b/public/icons/na.svg @@ -1 +1 @@ - + diff --git a/public/icons/note.svg b/public/icons/note.svg index 457533c..a1bdf99 100644 --- a/public/icons/note.svg +++ b/public/icons/note.svg @@ -1 +1 @@ - + diff --git a/public/icons/partial.svg b/public/icons/partial.svg index 0d18c89..bf115b7 100644 --- a/public/icons/partial.svg +++ b/public/icons/partial.svg @@ -1 +1 @@ - + diff --git a/public/icons/sort-down.svg b/public/icons/sort-down.svg index 46c0ed7..2da218a 100644 --- a/public/icons/sort-down.svg +++ b/public/icons/sort-down.svg @@ -1 +1 @@ - + diff --git a/public/icons/sort-up.svg b/public/icons/sort-up.svg index 5133e98..8df68b2 100644 --- a/public/icons/sort-up.svg +++ b/public/icons/sort-up.svg @@ -1 +1 @@ - + diff --git a/public/icons/sort.svg b/public/icons/sort.svg index 6f0a0b1..3229b07 100644 --- a/public/icons/sort.svg +++ b/public/icons/sort.svg @@ -1 +1 @@ - + diff --git a/public/icons/stale.svg b/public/icons/stale.svg index 08bc4db..0090270 100644 --- a/public/icons/stale.svg +++ b/public/icons/stale.svg @@ -1 +1 @@ - + diff --git a/public/icons/unknown.svg b/public/icons/unknown.svg index 6174fa5..2ded53b 100644 --- a/public/icons/unknown.svg +++ b/public/icons/unknown.svg @@ -1 +1 @@ - + diff --git a/public/icons/working.svg b/public/icons/working.svg index 238bb33..49b86c4 100644 --- a/public/icons/working.svg +++ b/public/icons/working.svg @@ -1 +1 @@ - + diff --git a/src/assets/logos/README.md b/src/assets/logos/README.md new file mode 100644 index 0000000..7d6e9f9 --- /dev/null +++ b/src/assets/logos/README.md @@ -0,0 +1,38 @@ +# Logos + +Single-colour marks used to identify each brand and ROM. The site paints them as a CSS mask, so they always show in the current text colour. + +Brand and ROM names and logos are trademarks of their respective owners and are used here only to identify them. No endorsement is implied. + +| File | Source | Licence / terms | +| --- | --- | --- | +| `brands/asus.svg` | https://unpkg.com/simple-icons@16.34.0/icons/asus.svg | Simple Icons 16.34.0, CC0-1.0 | +| `brands/fairphone.svg` | https://unpkg.com/simple-icons@16.34.0/icons/fairphone.svg | Simple Icons 16.34.0, CC0-1.0 | +| `brands/google.svg` | https://unpkg.com/simple-icons@16.34.0/icons/google.svg | Simple Icons 16.34.0, CC0-1.0 | +| `brands/htc.svg` | https://unpkg.com/simple-icons@16.34.0/icons/htc.svg | Simple Icons 16.34.0, CC0-1.0 | +| `brands/huawei.svg` | https://unpkg.com/simple-icons@16.34.0/icons/huawei.svg | Simple Icons 16.34.0, CC0-1.0 | +| `brands/lenovo.svg` | https://unpkg.com/simple-icons@16.34.0/icons/lenovo.svg | Simple Icons 16.34.0, CC0-1.0 | +| `brands/lg.svg` | https://unpkg.com/simple-icons@16.34.0/icons/lg.svg | Simple Icons 16.34.0, CC0-1.0 (face symbol only, "LG" letters removed) | +| `brands/meizu.svg` | https://unpkg.com/simple-icons@16.34.0/icons/meizu.svg | Simple Icons 16.34.0, CC0-1.0 | +| `brands/motorola.svg` | https://unpkg.com/simple-icons@16.34.0/icons/motorola.svg | Simple Icons 16.34.0, CC0-1.0 | +| `brands/nokia.svg` | https://unpkg.com/simple-icons@16.34.0/icons/nokia.svg | Simple Icons 16.34.0, CC0-1.0 | +| `brands/nvidia.svg` | https://unpkg.com/simple-icons@16.34.0/icons/nvidia.svg | Simple Icons 16.34.0, CC0-1.0 | +| `brands/oneplus.svg` | https://unpkg.com/simple-icons@16.34.0/icons/oneplus.svg | Simple Icons 16.34.0, CC0-1.0 | +| `brands/oppo.svg` | https://unpkg.com/simple-icons@16.34.0/icons/oppo.svg | Simple Icons 16.34.0, CC0-1.0 | +| `brands/razer.svg` | https://unpkg.com/simple-icons@16.34.0/icons/razer.svg | Simple Icons 16.34.0, CC0-1.0 | +| `brands/samsung.svg` | https://unpkg.com/simple-icons@16.34.0/icons/samsung.svg | Simple Icons 16.34.0, CC0-1.0 | +| `brands/solana.svg` | https://unpkg.com/simple-icons@16.34.0/icons/solana.svg | Simple Icons 16.34.0, CC0-1.0 | +| `brands/sony.svg` | https://unpkg.com/simple-icons@16.34.0/icons/sony.svg | Simple Icons 16.34.0, CC0-1.0 | +| `brands/xiaomi.svg` | https://unpkg.com/simple-icons@16.34.0/icons/xiaomi.svg | Simple Icons 16.34.0, CC0-1.0 | +| `roms/lineageos.svg` | https://unpkg.com/simple-icons@16.34.0/icons/lineageos.svg | Simple Icons 16.34.0, CC0-1.0 | +| `roms/grapheneos.svg` | https://unpkg.com/simple-icons@16.34.0/icons/grapheneos.svg | Simple Icons 16.34.0, CC0-1.0 | +| `roms/eos.svg` | https://unpkg.com/simple-icons@16.34.0/icons/e.svg | Simple Icons 16.34.0, CC0-1.0 | +| `roms/calyxos.svg` | https://gitlab.com/CalyxOS/branding/-/raw/main/calyxos/icon/Icon-CalyxOS.light.svg | Registered trademark of the Calyx Institute (background square removed) | +| `roms/crdroid.svg` | https://raw.githubusercontent.com/crdroidandroid/android_packages_apps_crDroidSettings/17.0/res/drawable/ic_crdroid_logo.xml | Trademark of the crDroid Android Project; file header Apache-2.0 | +| `roms/iodeos.svg` | https://gitlab.com/iode/os/public_archive/blocker/iode/-/raw/main/android/app/src/main/res/drawable/ic_iode_foreground.xml | Trademark of iodé Technologies; file header AGPL-3.0-or-later | +| `roms/evolutionx.svg` | https://raw.githubusercontent.com/Evolution-X/wiki/main/public/icon.svg | Trademark of Evolution X | +| `roms/pixelos.svg` | https://pixelos.net/images/logo.svg | Trademark of PixelOS | + +Simple Icons releases its icon data under CC0-1.0, but its disclaimer notes that the logos themselves remain trademarks of their owners: https://github.com/simple-icons/simple-icons/blob/develop/DISCLAIMER.md + +To add a logo, drop a single-colour SVG named after the brand or ROM key into `brands/` or `roms/`; anything without one shows its initials. diff --git a/src/assets/logos/brands/asus.svg b/src/assets/logos/brands/asus.svg new file mode 100644 index 0000000..fece3c0 --- /dev/null +++ b/src/assets/logos/brands/asus.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/fairphone.svg b/src/assets/logos/brands/fairphone.svg new file mode 100644 index 0000000..8738949 --- /dev/null +++ b/src/assets/logos/brands/fairphone.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/google.svg b/src/assets/logos/brands/google.svg new file mode 100644 index 0000000..70d0318 --- /dev/null +++ b/src/assets/logos/brands/google.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/htc.svg b/src/assets/logos/brands/htc.svg new file mode 100644 index 0000000..70d11b3 --- /dev/null +++ b/src/assets/logos/brands/htc.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/huawei.svg b/src/assets/logos/brands/huawei.svg new file mode 100644 index 0000000..72e9610 --- /dev/null +++ b/src/assets/logos/brands/huawei.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/lenovo.svg b/src/assets/logos/brands/lenovo.svg new file mode 100644 index 0000000..53f569f --- /dev/null +++ b/src/assets/logos/brands/lenovo.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/lg.svg b/src/assets/logos/brands/lg.svg new file mode 100644 index 0000000..f032f8a --- /dev/null +++ b/src/assets/logos/brands/lg.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/meizu.svg b/src/assets/logos/brands/meizu.svg new file mode 100644 index 0000000..e9b287b --- /dev/null +++ b/src/assets/logos/brands/meizu.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/motorola.svg b/src/assets/logos/brands/motorola.svg new file mode 100644 index 0000000..fd59645 --- /dev/null +++ b/src/assets/logos/brands/motorola.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/nokia.svg b/src/assets/logos/brands/nokia.svg new file mode 100644 index 0000000..9279606 --- /dev/null +++ b/src/assets/logos/brands/nokia.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/nvidia.svg b/src/assets/logos/brands/nvidia.svg new file mode 100644 index 0000000..a9c8fc4 --- /dev/null +++ b/src/assets/logos/brands/nvidia.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/oneplus.svg b/src/assets/logos/brands/oneplus.svg new file mode 100644 index 0000000..4f75925 --- /dev/null +++ b/src/assets/logos/brands/oneplus.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/oppo.svg b/src/assets/logos/brands/oppo.svg new file mode 100644 index 0000000..7744171 --- /dev/null +++ b/src/assets/logos/brands/oppo.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/razer.svg b/src/assets/logos/brands/razer.svg new file mode 100644 index 0000000..bf97c1e --- /dev/null +++ b/src/assets/logos/brands/razer.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/samsung.svg b/src/assets/logos/brands/samsung.svg new file mode 100644 index 0000000..6f6e1ae --- /dev/null +++ b/src/assets/logos/brands/samsung.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/solana.svg b/src/assets/logos/brands/solana.svg new file mode 100644 index 0000000..9b8119f --- /dev/null +++ b/src/assets/logos/brands/solana.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/sony.svg b/src/assets/logos/brands/sony.svg new file mode 100644 index 0000000..cec8b2c --- /dev/null +++ b/src/assets/logos/brands/sony.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/brands/xiaomi.svg b/src/assets/logos/brands/xiaomi.svg new file mode 100644 index 0000000..fb4cd3d --- /dev/null +++ b/src/assets/logos/brands/xiaomi.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/roms/calyxos.svg b/src/assets/logos/roms/calyxos.svg new file mode 100644 index 0000000..b88831b --- /dev/null +++ b/src/assets/logos/roms/calyxos.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/roms/crdroid.svg b/src/assets/logos/roms/crdroid.svg new file mode 100644 index 0000000..061b7e3 --- /dev/null +++ b/src/assets/logos/roms/crdroid.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/roms/eos.svg b/src/assets/logos/roms/eos.svg new file mode 100644 index 0000000..c36a8f3 --- /dev/null +++ b/src/assets/logos/roms/eos.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/roms/evolutionx.svg b/src/assets/logos/roms/evolutionx.svg new file mode 100644 index 0000000..cef38ed --- /dev/null +++ b/src/assets/logos/roms/evolutionx.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/roms/grapheneos.svg b/src/assets/logos/roms/grapheneos.svg new file mode 100644 index 0000000..3201907 --- /dev/null +++ b/src/assets/logos/roms/grapheneos.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/roms/iodeos.svg b/src/assets/logos/roms/iodeos.svg new file mode 100644 index 0000000..012aa67 --- /dev/null +++ b/src/assets/logos/roms/iodeos.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/roms/lineageos.svg b/src/assets/logos/roms/lineageos.svg new file mode 100644 index 0000000..1984577 --- /dev/null +++ b/src/assets/logos/roms/lineageos.svg @@ -0,0 +1 @@ + diff --git a/src/assets/logos/roms/pixelos.svg b/src/assets/logos/roms/pixelos.svg new file mode 100644 index 0000000..2d49b22 --- /dev/null +++ b/src/assets/logos/roms/pixelos.svg @@ -0,0 +1 @@ + diff --git a/src/components/cards/CardGrid.astro b/src/components/cards/CardGrid.astro new file mode 100644 index 0000000..887895a --- /dev/null +++ b/src/components/cards/CardGrid.astro @@ -0,0 +1,143 @@ +--- +// Device cards in optional brand groups, from plain items built in src/lib/cards.js +import Logo from '../ui/Logo.astro'; + +const { id, groups, level = 2 } = Astro.props; +const Heading = `h${level}`; +--- + +
+ {groups.map(({ brand, items }) => ( +
+ {brand && ( + + + {brand.name} + + )} +
    + {items.map((item) => ( +
  • + + {item.title} + + {item.code} + {item.meta &&

    {item.meta}

    } + {item.status && ( + + {item.status.text} + + )} + {item.chips.length > 0 && ( +
      + {item.chips.map((chip) => ( +
    • + {chip.note ? `${chip.text}, ${chip.note}` : chip.text} +
    • + ))} +
    + )} + {item.empty && ( + + {item.empty} + + )} +
  • + ))} +
+
+ ))} +
+ + diff --git a/src/components/cards/FeatureList.astro b/src/components/cards/FeatureList.astro new file mode 100644 index 0000000..81adb3d --- /dev/null +++ b/src/components/cards/FeatureList.astro @@ -0,0 +1,70 @@ +--- +// What works, one feature per line, from knownFeatures() in src/lib/facts.js +import Icon from '../ui/Icon.astro'; + +const { items } = Astro.props; +--- + +
    + {items.map((item) => ( +
  • + {item.name} + {item.text} + {(item.note || item.stale || item.source) && ( +

    + {item.stale && {item.stale}.} {item.note} + {item.source && ( + + + + )} +

    + )} +
  • + ))} +
+ + diff --git a/src/components/cards/RomCard.astro b/src/components/cards/RomCard.astro new file mode 100644 index 0000000..8826a60 --- /dev/null +++ b/src/components/cards/RomCard.astro @@ -0,0 +1,156 @@ +--- +// One ROM on one device: its build, what it needs, what works, and where to install it from +import FeatureList from './FeatureList.astro'; +import Icon from '../ui/Icon.astro'; +import Logo from '../ui/Logo.astro'; +import { buildFact, googleApps, knownFeatures, needsOf, relockFact } from '../../lib/facts.js'; +import { formatDate } from '../../lib/dates.js'; +import { reportUrl } from '../../lib/table.js'; + +const { row, features } = Astro.props; +const { rom, device } = row; +const build = buildFact(row.latest); +const relock = relockFact(row); +const needs = needsOf(row); +const known = knownFeatures(features, row.cells); +const builds = row.variants.filter((variant) => variant.status === 'active'); +const id = `rom-${rom.key}`; +--- + +
+
+ +
+

+ {rom.name} +

+

{googleApps(rom)}

+
+ {row.android && Android {row.android}} +
+ +
    + {build && ( +
  • + Built + {build.old && · {build.old}} +
  • + )} + {build?.patch &&
  • {build.patch} security patch
  • } + {relock && ( +
  • + + {relock.text} + + {relock.note && {relock.note}} +
  • + )} + {needs.map((need) => ( +
  • {need}
  • + ))} +
+ + {known.length > 0 && } + + {builds.map((variant) => ( +

+ Also as {variant.name} + {variant.latest && <>, built {formatDate(variant.latest.date)}} +

+ ))} + + +
+ + diff --git a/src/components/cards/RomSummary.astro b/src/components/cards/RomSummary.astro new file mode 100644 index 0000000..bd52d57 --- /dev/null +++ b/src/components/cards/RomSummary.astro @@ -0,0 +1,74 @@ +--- +// A ROM in brief: what it is, its take on Google apps and security, and how many devices it runs on +import Logo from '../ui/Logo.astro'; +import { googleApps, romRelock } from '../../lib/facts.js'; +import { labelOf } from '../../lib/labels.js'; +import { plural } from '../../lib/text.js'; + +const { rom, level = 3 } = Astro.props; +const Heading = `h${level}`; +const relock = romRelock(rom); +const badges = [ + googleApps(rom), + relock !== 'No' && (relock === 'Yes' ? 'Relockable bootloader' : 'Relocks on some devices'), + ...rom.focus.map(labelOf), +].filter(Boolean); +--- + +
+
+ + + + {rom.name} + + + {plural(rom.activeCount, 'device')} +
+

{rom.description}

+
    + {badges.map((badge) => ( +
  • {badge}
  • + ))} +
+
+ + diff --git a/src/components/layout/Base.astro b/src/components/layout/Base.astro index b2a6955..545a176 100644 --- a/src/components/layout/Base.astro +++ b/src/components/layout/Base.astro @@ -1,7 +1,9 @@ --- import '@fontsource-variable/roboto'; import '@fontsource-variable/roboto-mono'; -import '../../styles/global.css'; +import '../../styles/tokens.css'; +import '../../styles/base.css'; +import '../../styles/ui.css'; import roboto from '@fontsource-variable/roboto/files/roboto-latin-wght-normal.woff2?url'; import Header from './Header.astro'; import Footer from './Footer.astro'; @@ -70,13 +72,9 @@ const sentry = import.meta.env.PUBLIC_SENTRY_DSN; - + {graph.length > 0 && ( + + diff --git a/src/components/ui/Icon.astro b/src/components/ui/Icon.astro index 7f7fcaa..30ab3c7 100644 --- a/src/components/ui/Icon.astro +++ b/src/components/ui/Icon.astro @@ -1,25 +1,40 @@ --- -const { name, label } = Astro.props; -const paths = { - search: 'M10.5 17a6.5 6.5 0 1 0 0-13 6.5 6.5 0 0 0 0 13zM15.5 15.5L20 20', - columns: 'M4 5h16v14H4zM9.5 5v14M14.5 5v14', - external: 'M14 5h5v5M19 5l-8 8M17 14v5H5V7h5', - edit: 'M4 20h4L19 9l-4-4L4 16v4zM13.5 6.5l4 4', +// The Lucide icons the site uses, by name. Each renders as inline SVG at build time, text-sized +import ArrowUpRight from '@lucide/astro/icons/arrow-up-right'; +import BookOpen from '@lucide/astro/icons/book-open'; +import CodeXml from '@lucide/astro/icons/code-xml'; +import Columns3 from '@lucide/astro/icons/columns-3'; +import Flag from '@lucide/astro/icons/flag'; +import Globe from '@lucide/astro/icons/globe'; +import LayoutGrid from '@lucide/astro/icons/layout-grid'; +import MessagesSquare from '@lucide/astro/icons/messages-square'; +import Pencil from '@lucide/astro/icons/pencil'; +import Search from '@lucide/astro/icons/search'; +import Table2 from '@lucide/astro/icons/table-2'; + +const icons = { + cards: LayoutGrid, + columns: Columns3, + community: MessagesSquare, + docs: BookOpen, + edit: Pencil, + external: ArrowUpRight, + install: BookOpen, + report: Flag, + search: Search, + source: CodeXml, + table: Table2, + website: Globe, }; + +const { name, label } = Astro.props; +const Glyph = icons[name]; +if (!Glyph) throw new Error(`There's no icon called "${name}" in Icon.astro`); --- - - - +/> diff --git a/src/components/ui/Logo.astro b/src/components/ui/Logo.astro new file mode 100644 index 0000000..ce63bd0 --- /dev/null +++ b/src/components/ui/Logo.astro @@ -0,0 +1,76 @@ +--- +// A brand or ROM mark on a plate, or its initials when src/assets/logos/ has no file for it +const marks = import.meta.glob('../../assets/logos/*/*.svg', { + query: '?raw', + import: 'default', + eager: true, +}); +const urls = import.meta.glob('../../assets/logos/*/*.svg', { + query: '?url', + import: 'default', + eager: true, +}); + +const { kind, item, size = 'md' } = Astro.props; +const file = `../../assets/logos/${kind}/${item.key}.svg`; +const [, , width, height] = + marks[file] + ?.match(/viewBox="([^"]+)"/)[1] + .split(' ') + .map(Number) ?? []; +const initials = item.name.length <= 3 ? item.name : item.name.match(/[a-z0-9]/i)[0].toUpperCase(); +--- + +