feat: add desktop app (#3)
@@ -8,19 +8,87 @@ env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
check:
|
||||
rust-lint:
|
||||
name: Rust Lint
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
- uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
|
||||
with:
|
||||
components: rustfmt, clippy
|
||||
- uses: cashapp/activate-hermit@e49f5cb4dd64ff0b0b659d1d8df499595451155a # v1
|
||||
- uses: Swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db # v2
|
||||
- run: cargo fmt --all -- --check
|
||||
- run: cargo clippy --workspace --all-targets -- -D warnings
|
||||
- run: cargo test --workspace
|
||||
- run: cargo install cargo-audit --locked
|
||||
- run: cargo audit --ignore RUSTSEC-2023-0071 --ignore RUSTSEC-2024-0384
|
||||
- run: cargo install cargo-deny --locked
|
||||
- run: cargo deny check
|
||||
- name: Format check
|
||||
run: just fmt-check
|
||||
- name: Clippy
|
||||
run: just clippy
|
||||
|
||||
unit-tests:
|
||||
name: Unit Tests
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
- uses: cashapp/activate-hermit@e49f5cb4dd64ff0b0b659d1d8df499595451155a # v1
|
||||
- uses: Swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db # v2
|
||||
- name: Unit tests
|
||||
run: just test-unit
|
||||
|
||||
desktop:
|
||||
name: Desktop
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
- uses: cashapp/activate-hermit@e49f5cb4dd64ff0b0b659d1d8df499595451155a # v1
|
||||
- uses: Swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db # v2
|
||||
with:
|
||||
workspaces: desktop/src-tauri
|
||||
- name: Install Tauri dependencies (Linux)
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
run: |
|
||||
sudo apt-get update \
|
||||
-o Acquire::Retries=3 \
|
||||
-o Acquire::http::Timeout=30 \
|
||||
-o Acquire::https::Timeout=30
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
-o Acquire::Retries=3 \
|
||||
-o Acquire::http::Timeout=30 \
|
||||
-o Acquire::https::Timeout=30 \
|
||||
-o DPkg::Lock::Timeout=120 \
|
||||
build-essential \
|
||||
curl \
|
||||
file \
|
||||
libayatana-appindicator3-dev \
|
||||
libgtk-3-dev \
|
||||
librsvg2-dev \
|
||||
libssl-dev \
|
||||
libwebkit2gtk-4.1-dev \
|
||||
libxdo-dev \
|
||||
patchelf \
|
||||
wget
|
||||
- name: Install desktop dependencies
|
||||
run: just desktop-install-ci
|
||||
- name: Desktop lint and format
|
||||
run: just desktop-check
|
||||
- name: Desktop build
|
||||
run: just desktop-build
|
||||
- name: Desktop Tauri check
|
||||
run: just desktop-tauri-check
|
||||
|
||||
security:
|
||||
name: Security
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
- uses: cashapp/activate-hermit@e49f5cb4dd64ff0b0b659d1d8df499595451155a # v1
|
||||
- name: Dependency policy
|
||||
run: cargo-deny check
|
||||
|
||||
@@ -39,8 +39,11 @@ unacceptable behavior to **conduct@sprout-relay.org**.
|
||||
| Tool | Version | Notes |
|
||||
|------|---------|-------|
|
||||
| Rust | 1.88+ | Install via [rustup](https://rustup.rs/) |
|
||||
| Node.js | 24+ | Required for desktop app commands and `just ci` |
|
||||
| pnpm | 10+ | Required for desktop app commands and `just ci` |
|
||||
| Docker | 24+ | For MySQL, Redis, Typesense |
|
||||
| `just` | latest | Task runner — `cargo install just` |
|
||||
| `lefthook` | latest | Optional; run `lefthook install` for local Git hooks |
|
||||
| `sqlx-cli` | latest | Optional; `just migrate` falls back to `docker exec` |
|
||||
|
||||
This repo uses [Hermit](https://cashapp.github.io/hermit/) for toolchain
|
||||
@@ -68,6 +71,9 @@ cp .env.example .env
|
||||
|
||||
# 4. Start infrastructure + run migrations
|
||||
just setup
|
||||
|
||||
# 5. Install Git hooks (optional, recommended)
|
||||
lefthook install
|
||||
```
|
||||
|
||||
`just setup` starts Docker services (MySQL on `:3306`, Redis on `:6379`,
|
||||
@@ -134,7 +140,7 @@ Before opening a PR, run the full CI gate locally:
|
||||
|
||||
```bash
|
||||
just ci
|
||||
# Runs: fmt-check + clippy + unit tests
|
||||
# Runs: check + unit tests + desktop build + Tauri check
|
||||
```
|
||||
|
||||
This is the same check that runs in CI. PRs that fail `just ci` will not be
|
||||
|
||||
@@ -14,6 +14,7 @@ members = [
|
||||
"crates/sprout-admin",
|
||||
"crates/sprout-workflow",
|
||||
]
|
||||
exclude = ["desktop/src-tauri"]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
|
||||
@@ -193,7 +193,7 @@ Set `SPROUT_PRIVATE_KEY` (nsec format) to use a persistent identity.
|
||||
|
||||
## Development
|
||||
|
||||
**Prerequisites:** Rust 1.88+, Docker, [`just`](https://github.com/casey/just)
|
||||
**Prerequisites:** Rust 1.88+, Docker, Node.js 24+, pnpm 10+, [`just`](https://github.com/casey/just)
|
||||
|
||||
This repo uses [Hermit](https://cashapp.github.io/hermit/) for toolchain pinning. Activate with:
|
||||
|
||||
@@ -206,11 +206,15 @@ This repo uses [Hermit](https://cashapp.github.io/hermit/) for toolchain pinning
|
||||
```bash
|
||||
just setup # Start Docker services + run migrations
|
||||
just relay # Run the relay (dev mode)
|
||||
just build # Build entire workspace
|
||||
just check # fmt-check + clippy
|
||||
just build # Build the Rust workspace
|
||||
just desktop-install # Install desktop dependencies
|
||||
just desktop-dev # Run the desktop web UI only
|
||||
just desktop-app # Run the Tauri desktop app
|
||||
just desktop-ci # Desktop check + build + Tauri Rust check
|
||||
just check # Rust fmt/clippy + desktop check
|
||||
just test-unit # Unit tests (no infra required)
|
||||
just test # All tests (starts services if needed)
|
||||
just ci # fmt-check + clippy + unit tests (CI gate)
|
||||
just ci # check + unit tests + desktop build + Tauri check
|
||||
just migrate # Run pending migrations
|
||||
just down # Stop Docker services (keep data)
|
||||
just reset # ⚠️ Wipe all data and recreate environment
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
hermit
|
||||
@@ -0,0 +1 @@
|
||||
hermit
|
||||
@@ -0,0 +1 @@
|
||||
hermit
|
||||
@@ -0,0 +1 @@
|
||||
hermit
|
||||
@@ -1 +1 @@
|
||||
.rust@1.88.pkg
|
||||
.rustup-1.28.2.pkg
|
||||
@@ -0,0 +1 @@
|
||||
.cargo-deny-0.19.0.pkg
|
||||
@@ -1 +1 @@
|
||||
.rust@1.88.pkg
|
||||
.rustup-1.28.2.pkg
|
||||
@@ -0,0 +1 @@
|
||||
.rustup-1.28.2.pkg
|
||||
@@ -1 +1 @@
|
||||
.rust@1.88.pkg
|
||||
.rustup-1.28.2.pkg
|
||||
@@ -0,0 +1 @@
|
||||
.node-24.14.0.pkg
|
||||
@@ -17,7 +17,7 @@ if [ -z "${HERMIT_STATE_DIR}" ]; then
|
||||
esac
|
||||
fi
|
||||
|
||||
export HERMIT_DIST_URL="${HERMIT_DIST_URL:-https://d1abdrezunyhdp.cloudfront.net/square}"
|
||||
export HERMIT_DIST_URL="${HERMIT_DIST_URL:-https://github.com/cashapp/hermit/releases/download/stable}"
|
||||
HERMIT_CHANNEL="$(basename "${HERMIT_DIST_URL}")"
|
||||
export HERMIT_CHANNEL
|
||||
export HERMIT_EXE=${HERMIT_EXE:-${HERMIT_STATE_DIR}/pkg/hermit@${HERMIT_CHANNEL}/hermit}
|
||||
@@ -26,7 +26,7 @@ if [ ! -x "${HERMIT_EXE}" ]; then
|
||||
echo "Bootstrapping ${HERMIT_EXE} from ${HERMIT_DIST_URL}" 1>&2
|
||||
INSTALL_SCRIPT="$(mktemp)"
|
||||
# This value must match that of the install script
|
||||
INSTALL_SCRIPT_SHA256="4b006236f2e5e81939229b377bb355e3608f94d73ff8feccbd5792d1ed5699cd"
|
||||
INSTALL_SCRIPT_SHA256="09ed936378857886fd4a7a4878c0f0c7e3d839883f39ca8b4f2f242e3126e1c6"
|
||||
if [ "${INSTALL_SCRIPT_SHA256}" = "BYPASS" ]; then
|
||||
curl -fsSL "${HERMIT_DIST_URL}/install.sh" -o "${INSTALL_SCRIPT}"
|
||||
else
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
.lefthook-2.1.3.pkg
|
||||
@@ -1 +1 @@
|
||||
.rust@1.88.pkg
|
||||
.rustup-1.28.2.pkg
|
||||
@@ -1 +1 @@
|
||||
.rust@1.88.pkg
|
||||
.rustup-1.28.2.pkg
|
||||
@@ -1 +1 @@
|
||||
.rust@1.88.pkg
|
||||
.rustup-1.28.2.pkg
|
||||
@@ -1 +1 @@
|
||||
.rust@1.88.pkg
|
||||
.rustup-1.28.2.pkg
|
||||
@@ -1 +1 @@
|
||||
.rust@1.88.pkg
|
||||
.rustup-1.28.2.pkg
|
||||
@@ -1 +1 @@
|
||||
.rust@1.88.pkg
|
||||
.rustup-1.28.2.pkg
|
||||
@@ -0,0 +1 @@
|
||||
.rustup-1.28.2.pkg
|
||||
@@ -0,0 +1,25 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.pnpm-store
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
@@ -0,0 +1,25 @@
|
||||
# Sprout
|
||||
|
||||
Desktop chat shell with:
|
||||
|
||||
- Tauri + React + TypeScript + Vite
|
||||
- Tailwind CSS
|
||||
- shadcn/ui-ready shared components
|
||||
- Biome (lint/format/check)
|
||||
- Feature-driven frontend structure
|
||||
|
||||
## Scripts
|
||||
|
||||
- `pnpm dev` - run the web frontend
|
||||
- `pnpm tauri dev` - run the desktop app
|
||||
- `pnpm build` - typecheck and build frontend
|
||||
- `pnpm typecheck` - TypeScript checks
|
||||
- `pnpm lint` - Biome lint
|
||||
- `pnpm format` - Biome format (write)
|
||||
- `pnpm check` - Biome check
|
||||
|
||||
## Structure
|
||||
|
||||
- `src/shared` - reusable app-wide code (`ui`, `lib`, `styles`)
|
||||
- `src/features` - feature modules (vertical slices)
|
||||
- `src/app` - top-level app composition
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/2.4.6/schema.json",
|
||||
"vcs": {
|
||||
"enabled": true,
|
||||
"clientKind": "git",
|
||||
"useIgnoreFile": true
|
||||
},
|
||||
"files": {
|
||||
"ignoreUnknown": false
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentStyle": "space"
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": true,
|
||||
"suspicious": {
|
||||
"noUnknownAtRules": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
"assist": {
|
||||
"enabled": false
|
||||
},
|
||||
"javascript": {
|
||||
"formatter": {
|
||||
"quoteStyle": "double"
|
||||
}
|
||||
},
|
||||
"css": {
|
||||
"parser": {
|
||||
"tailwindDirectives": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "new-york",
|
||||
"rsc": false,
|
||||
"tsx": true,
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.js",
|
||||
"css": "src/shared/styles/globals.css",
|
||||
"baseColor": "zinc",
|
||||
"cssVariables": true,
|
||||
"prefix": ""
|
||||
},
|
||||
"aliases": {
|
||||
"components": "@/shared/ui",
|
||||
"utils": "@/shared/lib/cn",
|
||||
"ui": "@/shared/ui",
|
||||
"lib": "@/shared/lib"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/png" href="/sprout.png?v=20260309" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "sprout",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"packageManager": "pnpm@10.12.1",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"lint": "biome lint .",
|
||||
"check": "biome check .",
|
||||
"format": "biome format --write .",
|
||||
"preview": "vite preview",
|
||||
"tauri": "tauri"
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@radix-ui/react-separator": "^1.1.8",
|
||||
"@radix-ui/react-slot": "^1.2.4",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@tauri-apps/api": "^2",
|
||||
"@tauri-apps/plugin-opener": "^2",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"lucide-react": "^0.577.0",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"tailwind-merge": "^3.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^2.4.6",
|
||||
"@tauri-apps/cli": "^2",
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"@vitejs/plugin-react": "^4.6.0",
|
||||
"autoprefixer": "^10.4.27",
|
||||
"postcss": "^8.5.8",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"typescript": "~5.8.3",
|
||||
"vite": "^7.0.4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
|
After Width: | Height: | Size: 240 KiB |
@@ -0,0 +1,69 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="none">
|
||||
<defs>
|
||||
<linearGradient id="sprout-bg" x1="92" y1="72" x2="432" y2="448" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#225E39" />
|
||||
<stop offset="1" stop-color="#112C1C" />
|
||||
</linearGradient>
|
||||
<radialGradient id="sprout-glow" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(380 126) rotate(119.845) scale(152.955)">
|
||||
<stop stop-color="#B6F06B" stop-opacity=".4" />
|
||||
<stop offset="1" stop-color="#B6F06B" stop-opacity="0" />
|
||||
</radialGradient>
|
||||
<linearGradient id="sprout-leaf-left" x1="123" y1="188" x2="252" y2="282" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#B9F173" />
|
||||
<stop offset="1" stop-color="#63BD43" />
|
||||
</linearGradient>
|
||||
<linearGradient id="sprout-leaf-right" x1="270" y1="169" x2="421" y2="274" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#97E45F" />
|
||||
<stop offset="1" stop-color="#4FA53A" />
|
||||
</linearGradient>
|
||||
<linearGradient id="sprout-soil" x1="171" y1="309" x2="341" y2="403" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D89747" />
|
||||
<stop offset="1" stop-color="#8D5228" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="32" y="32" width="448" height="448" rx="112" fill="url(#sprout-bg)" />
|
||||
<circle cx="380" cy="126" r="124" fill="url(#sprout-glow)" />
|
||||
<path
|
||||
d="M149 346c0-31 25-56 56-56h102c31 0 56 25 56 56 0 49-43 70-107 70s-107-21-107-70Z"
|
||||
fill="#714121"
|
||||
/>
|
||||
<ellipse cx="256" cy="347" rx="80" ry="32" fill="url(#sprout-soil)" />
|
||||
<path
|
||||
d="M256 339c-8-39-7-83 12-125"
|
||||
stroke="#DAF9B8"
|
||||
stroke-linecap="round"
|
||||
stroke-width="22"
|
||||
/>
|
||||
<path
|
||||
d="M259 239c-33-43-80-60-136-54 2 52 33 90 87 100 24 4 44-9 49-46Z"
|
||||
fill="url(#sprout-leaf-left)"
|
||||
/>
|
||||
<path
|
||||
d="M270 220c39-46 91-66 153-56-4 57-38 92-98 99-24 3-43-11-55-43Z"
|
||||
fill="url(#sprout-leaf-right)"
|
||||
/>
|
||||
<path
|
||||
d="M210 252c-14-18-30-33-50-45"
|
||||
stroke="#E7FBD0"
|
||||
stroke-linecap="round"
|
||||
stroke-width="10"
|
||||
opacity=".75"
|
||||
/>
|
||||
<path
|
||||
d="M315 242c22-26 46-43 73-55"
|
||||
stroke="#D8F5B8"
|
||||
stroke-linecap="round"
|
||||
stroke-width="10"
|
||||
opacity=".65"
|
||||
/>
|
||||
<path
|
||||
d="M231 316c2 17 15 31 32 31 18 0 33-15 35-34 2-17-8-31-24-35-18-5-39 8-43 27Z"
|
||||
fill="#E09A49"
|
||||
/>
|
||||
<path
|
||||
d="M244 308c6-7 15-11 24-10"
|
||||
stroke="#F7C97C"
|
||||
stroke-linecap="round"
|
||||
stroke-width="8"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,7 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
|
||||
# Generated by Tauri
|
||||
# will have schema files for capabilities auto-completion
|
||||
/gen/schemas
|
||||
@@ -0,0 +1,24 @@
|
||||
[package]
|
||||
name = "sprout"
|
||||
version = "0.1.0"
|
||||
description = "Sprout desktop app"
|
||||
authors = ["you"]
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[lib]
|
||||
# The `_lib` suffix may seem redundant but it is necessary
|
||||
# to make the lib name unique and wouldn't conflict with the bin name.
|
||||
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
|
||||
name = "sprout_lib"
|
||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2", features = [] }
|
||||
|
||||
[dependencies]
|
||||
tauri = { version = "2", features = [] }
|
||||
tauri-plugin-opener = "2"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "default",
|
||||
"description": "Capability for the main window",
|
||||
"windows": ["main"],
|
||||
"permissions": ["core:default", "opener:default"]
|
||||
}
|
||||
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 9.6 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 175 KiB |
|
After Width: | Height: | Size: 36 KiB |
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#fff</color>
|
||||
</resources>
|
||||
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 240 KiB |
|
After Width: | Height: | Size: 802 B |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 843 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 2.7 MiB |
@@ -0,0 +1,18 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" fill="none">
|
||||
<defs>
|
||||
<clipPath id="icon-clip">
|
||||
<rect x="132" y="132" width="760" height="760" rx="171" ry="171" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g clip-path="url(#icon-clip)">
|
||||
<rect x="132" y="132" width="760" height="760" rx="171" ry="171" fill="#F4F0E6" />
|
||||
<image
|
||||
href="./sprout-art.png"
|
||||
x="156"
|
||||
y="156"
|
||||
width="712"
|
||||
height="712"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 506 B |