web


git clone https://radroots.dev/git/web.git
Log | Files | Refs | Submodules | README | LICENSE

commit f1bb171ba02682e0b1557a8b2c39ae3ea6950ed4
parent 04e926ee756067272a5c481263e791e6591a65fb
Author: triesap <137732411+triesap@users.noreply.github.com>
Date:   Sun, 25 Aug 2024 09:34:24 +0000

Add sqlite database and app layout configuration

Diffstat:
M.gitignore | 4++--
Mandroid/app/capacitor.build.gradle | 1+
Mandroid/capacitor.settings.gradle | 3+++
Mcapacitor.config.ts | 10++++++++++
Mios/App/App.xcodeproj/project.pbxproj | 12++++++++----
Mios/App/Podfile | 1+
Mios/App/Podfile.lock | 23++++++++++++++++++++++-
Mpackage.json | 18++++++++++++------
Msrc/app.html | 2+-
Dsrc/lib/components/index.ts | 2--
Asrc/lib/components/layout-window.svelte | 13+++++++++++++
Dsrc/lib/components/layout_window.svelte | 13-------------
Dsrc/lib/types.ts | 5-----
Asrc/routes/(app)/+page.svelte | 24++++++++++++++++++++++++
Msrc/routes/+layout.svelte | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Dsrc/routes/+page.svelte | 25-------------------------
16 files changed, 207 insertions(+), 64 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -46,4 +46,5 @@ _tmp .vscode notes*.txt justfile -dist -\ No newline at end of file +dist +static/assets/sql-wasm.wasm diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle @@ -10,6 +10,7 @@ android { apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" dependencies { implementation project(':capacitor-dialog') + implementation project(':radroots-capacitor-sqlite') } diff --git a/android/capacitor.settings.gradle b/android/capacitor.settings.gradle @@ -4,3 +4,6 @@ project(':capacitor-android').projectDir = new File('../../../node_modules/.pnpm include ':capacitor-dialog' project(':capacitor-dialog').projectDir = new File('../../../node_modules/.pnpm/@capacitor+dialog@6.0.1_@capacitor+core@6.1.2/node_modules/@capacitor/dialog/android') + +include ':radroots-capacitor-sqlite' +project(':radroots-capacitor-sqlite').projectDir = new File('../../../packages/capacitor-sqlite/android') diff --git a/capacitor.config.ts b/capacitor.config.ts @@ -2,6 +2,8 @@ import type { CapacitorConfig } from '@capacitor/cli'; const dev = process.env.NODE_ENV === `dev`; const port = process.env.RADROOTS_APP_PORT ? Number(process.env.RADROOTS_APP_PORT) : 3000; +const iosKeychainPrefix = process.env.RADROOTS_APP_SQLITE_KEYCHAIN_PREFIX; +if (!iosKeychainPrefix) throw new Error('Error: iosKeychainPrefix is required'); const config: CapacitorConfig = { appId: process.env.RADROOTS_APP_ID, @@ -13,6 +15,14 @@ const config: CapacitorConfig = { iosScheme: `radroots`, androidScheme: `radroots`, }, + plugins: { + CapacitorSQLite: { + iosDatabaseLocation: 'Library/radroots', + iosIsEncryption: true, + iosKeychainPrefix, + androidIsEncryption: true, + } + } }; export default config; diff --git a/ios/App/App.xcodeproj/project.pbxproj b/ios/App/App.xcodeproj/project.pbxproj @@ -348,11 +348,13 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; + DEVELOPMENT_TEAM = AR84X5Z9HU; INFOPLIST_FILE = App/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Radroots; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 0.1.5; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; PRODUCT_BUNDLE_IDENTIFIER = chroma.radroots.orgs; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -368,11 +370,13 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; + DEVELOPMENT_TEAM = AR84X5Z9HU; INFOPLIST_FILE = App/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Radroots; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 0.1.5; PRODUCT_BUNDLE_IDENTIFIER = chroma.radroots.orgs; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; diff --git a/ios/App/Podfile b/ios/App/Podfile @@ -12,6 +12,7 @@ def capacitor_pods pod 'Capacitor', :path => '../../../../node_modules/.pnpm/@capacitor+ios@6.1.2_@capacitor+core@6.1.2/node_modules/@capacitor/ios' pod 'CapacitorCordova', :path => '../../../../node_modules/.pnpm/@capacitor+ios@6.1.2_@capacitor+core@6.1.2/node_modules/@capacitor/ios' pod 'CapacitorDialog', :path => '../../../../node_modules/.pnpm/@capacitor+dialog@6.0.1_@capacitor+core@6.1.2/node_modules/@capacitor/dialog' + pod 'RadrootsCapacitorSqlite', :path => '../../../../packages/capacitor-sqlite' end target 'App' do diff --git a/ios/App/Podfile.lock b/ios/App/Podfile.lock @@ -4,11 +4,27 @@ PODS: - CapacitorCordova (6.1.2) - CapacitorDialog (6.0.1): - Capacitor + - RadrootsCapacitorSqlite (6.0.1): + - Capacitor + - SQLCipher + - ZIPFoundation + - SQLCipher (4.6.1): + - SQLCipher/standard (= 4.6.1) + - SQLCipher/common (4.6.1) + - SQLCipher/standard (4.6.1): + - SQLCipher/common + - ZIPFoundation (0.9.19) DEPENDENCIES: - "Capacitor (from `../../../../node_modules/.pnpm/@capacitor+ios@6.1.2_@capacitor+core@6.1.2/node_modules/@capacitor/ios`)" - "CapacitorCordova (from `../../../../node_modules/.pnpm/@capacitor+ios@6.1.2_@capacitor+core@6.1.2/node_modules/@capacitor/ios`)" - "CapacitorDialog (from `../../../../node_modules/.pnpm/@capacitor+dialog@6.0.1_@capacitor+core@6.1.2/node_modules/@capacitor/dialog`)" + - RadrootsCapacitorSqlite (from `../../../../packages/capacitor-sqlite`) + +SPEC REPOS: + trunk: + - SQLCipher + - ZIPFoundation EXTERNAL SOURCES: Capacitor: @@ -17,12 +33,17 @@ EXTERNAL SOURCES: :path: "../../../../node_modules/.pnpm/@capacitor+ios@6.1.2_@capacitor+core@6.1.2/node_modules/@capacitor/ios" CapacitorDialog: :path: "../../../../node_modules/.pnpm/@capacitor+dialog@6.0.1_@capacitor+core@6.1.2/node_modules/@capacitor/dialog" + RadrootsCapacitorSqlite: + :path: "../../../../packages/capacitor-sqlite" SPEC CHECKSUMS: Capacitor: 679f9673fdf30597493a6362a5d5bf233d46abc2 CapacitorCordova: f48c89f96c319101cd2f0ce8a2b7449b5fb8b3dd CapacitorDialog: ad752191fdb22a8d0ac199b0754b8a021d86dbf9 + RadrootsCapacitorSqlite: 11b1be8786af151612ee8e058d16f4979c2e3b1c + SQLCipher: 77fbe633cd84db04b07876dd50766b4924b57d61 + ZIPFoundation: b8c29ea7ae353b309bc810586181fd073cb3312c -PODFILE CHECKSUM: 3dfc16dbcb91ff826c375572d57a276890f42bf1 +PODFILE CHECKSUM: dd63ec13f036d53db3e3d0a7f2163fe002556b23 COCOAPODS: 1.15.2 diff --git a/package.json b/package.json @@ -5,14 +5,16 @@ "license": "GPLv3", "scripts": { "build": "just build && vite build", - "build:native": "npm run build", - "build:web": "npm run build", + "build:native": "npm run sql:wasm:rm && npm run build", + "build:web": "npm run sql:wasm:cp && npm run build", "dev": "", - "dev:web": "vite dev --debug hmr", - "dev:native": "vite dev --debug hmr", + "dev:web": "npm run sql:wasm:cp && vite dev --debug hmr", + "dev:native": "npm run sql:wasm:rm && vite dev --debug hmr", "preview": "vite preview", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", - "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", + "sql:wasm:cp": "rsync -u node_modules/sql.js/dist/sql-wasm.wasm static/assets", + "sql:wasm:rm": "rm -rf static/assets/sql-wasm.wasm" }, "devDependencies": { "@capacitor/cli": "^6.0.0", @@ -36,8 +38,12 @@ "@capacitor/core": "^6.1.2", "@capacitor/dialog": "^6.0.0", "@capacitor/ios": "^6.0.0", + "@ionic/pwa-elements": "^3.3.0", + "@radroots/capacitor-sqlite": "workspace:*", "@radroots/client": "workspace:*", + "@radroots/jeep-sqlite": "workspace:*", "@radroots/svelte-lib": "workspace:*", - "@radroots/theme": "workspace:*" + "@radroots/theme": "workspace:*", + "sql.js": "^1.11.0" } } \ No newline at end of file diff --git a/src/app.html b/src/app.html @@ -1,5 +1,5 @@ <!doctype html> -<html lang="en" data-theme="os_dark"> +<html lang="en" data-theme="os_light"> <head> <meta charset="utf-8" /> diff --git a/src/lib/components/index.ts b/src/lib/components/index.ts @@ -1,2 +0,0 @@ - -export { default as layout_window } from "./layout_window.svelte" diff --git a/src/lib/components/layout-window.svelte b/src/lib/components/layout-window.svelte @@ -0,0 +1,13 @@ +<script lang="ts"> + import type { PropChildren } from "@radroots/svelte-lib"; + + let { children }: PropChildren = $props(); +</script> + +<div + class={`relative flex flex-col h-[100vh] w-full overflow-x-hidden overflow-y-hidden bg-layer-0-surface`} +> + <div class={`flex flex-col h-full w-full`}> + {@render children()} + </div> +</div> diff --git a/src/lib/components/layout_window.svelte b/src/lib/components/layout_window.svelte @@ -1,13 +0,0 @@ -<script lang="ts"> - import type { PropChildren } from "$lib/types"; - - let { children }: PropChildren = $props(); -</script> - -<div - class={`relative flex flex-col h-[100vh] w-full overflow-x-hidden overflow-y-hidden bg-layer-0-surface`} -> - <div class={`flex flex-col h-full w-full`}> - {@render children()} - </div> -</div> diff --git a/src/lib/types.ts b/src/lib/types.ts @@ -1,5 +0,0 @@ -import type { Snippet } from "svelte"; - -export type PropChildren = { - children: Snippet; -}; diff --git a/src/routes/(app)/+page.svelte b/src/routes/(app)/+page.svelte @@ -0,0 +1,24 @@ +<script lang="ts"> + import { cl } from "$lib/client"; + import { t } from "@radroots/svelte-lib"; +</script> + +<div class={`flex flex-col w-full pt-16 justify-center items-center`}> + <button + class={`flex flex-row justify-center items-center text-white`} + onclick={async () => { + const res = await cl.dialog.alert( + `Hi! You're platform is ${cl.platform}`, + ); + console.log(`res `, res); + }} + > + <div + class={`flex flex-col h-line w-line justify-center items-center bg-layer-1-surface`} + > + <p class={`font-mono text-sm lowercase text-layer-2-glyph`}> + {$t(`app.name`)} + </p> + </div> + </button> +</div> diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte @@ -1,11 +1,116 @@ <script lang="ts"> - import { layout_window } from "$lib/components"; - import type { PropChildren } from "$lib/types"; + import { browser } from "$app/environment"; + import { goto } from "$app/navigation"; + import { PUBLIC_DATABASE_NAME } from "$env/static/public"; + import { cl } from "$lib/client"; + import LayoutWindow from "$lib/components/layout-window.svelte"; + import { + app_config, + app_lo, + app_pwa_polyfills, + app_render, + app_sqlite, + app_thc, + app_thm, + app_win, + css_static as CssStatic, + theme_set, + type PropChildren, + } from "@radroots/svelte-lib"; import "../app.css"; let { children }: PropChildren = $props(); + + let app_visible = $state(false); + + let render_pwa = browser && cl.platform === `web`; + if (render_pwa) { + const el = document.createElement(`jeep-sqlite`); + document.body.appendChild(el); + customElements + .whenDefined(`jeep-sqlite`) + .then(() => { + app_pwa_polyfills.set(true); + }) + .catch((e) => { + console.log(`(pwa polyfills) error `, e); + app_pwa_polyfills.set(false); + }); + } + + $effect(() => { + app_win.set([window.innerHeight, window.innerWidth]); + + const prefers_dark = window.matchMedia( + `(prefers-color-scheme: dark)`, + ).matches; + + if (prefers_dark) app_thc.set(`dark`); + app_config.set(true); + }); + + app_win.subscribe(([win_h, win_w]) => { + if (win_h > 800) app_lo.set("lg"); + }); + + app_thc.subscribe((color_mode) => { + theme_set($app_thm, color_mode); + }); + + app_thm.subscribe((theme_key) => { + theme_set(theme_key, $app_thc); + }); + + app_config.subscribe(async (app_config) => { + try { + if (!app_config) return; + $app_sqlite = !!(await cl.db.connect(PUBLIC_DATABASE_NAME)); + } catch (e) { + console.log(`(app_config) error `, e); + } finally { + app_render.set(true); + } + }); + + app_render.subscribe(async (app_render) => { + try { + if (!app_render) { + app_visible = false; + return; + } + + let dev_routes = false; + let route = "/"; + if (dev_routes) route = `/`; + await goto(route); + } catch (e) { + console.log(`(app_render) error `, e); + } finally { + app_visible = true; + } + }); </script> -<svelte:component this={layout_window}> - {@render children()} -</svelte:component> +{#if app_visible} + <LayoutWindow> + {@render children()} + </LayoutWindow> +{:else} + <div class={`flex flex-col w-full justify-center items-center`}> + <button + class={`flex flex-row justify-center items-center`} + onclick={async () => { + location.reload(); + }} + > + <div + class={`flex flex-col h-line w-line justify-center items-center bg-layer-1-surface`} + > + <p class={`font-mono text-sm lowercase text-layer-2-glyph`}> + {`There was an error loading the app. Click to reload.`} + </p> + </div> + </button> + </div> +{/if} +<CssStatic /> diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte @@ -1,25 +0,0 @@ -<script lang="ts"> - import { cl } from "$lib/client"; - import { t } from "@radroots/svelte-lib"; -</script> - -<div class={`flex flex-col w-full pt-16 justify-center items-center`}> - <div - class={`flex flex-col h-line w-line justify-center items-center bg-layer-1-surface`} - > - <p class={`font-mono text-sm lowercase text-layer-2-glyph`}> - {$t(`app.name`)} - </p> - </div> - <button - class={`flex flex-row justify-center items-center text-white`} - onclick={async () => { - const res = await cl.dialog.alert( - `Hi! You're platform is ${cl.platform}`, - ); - console.log(`res `, res); - }} - > - {`platform`} - </button> -</div>