feat: replace capacitor components
This commit is contained in:
3
bun.lock
3
bun.lock
@ -26,6 +26,7 @@
|
|||||||
"pmtiles": "^4.3.0",
|
"pmtiles": "^4.3.0",
|
||||||
"sql.js": "^1.13.0",
|
"sql.js": "^1.13.0",
|
||||||
"svelte-maplibre-gl": "^0.1.8",
|
"svelte-maplibre-gl": "^0.1.8",
|
||||||
|
"tauri-plugin-duck-api": "^0.1.1",
|
||||||
"tauri-plugin-keep-screen-on-api": "^0.1.4",
|
"tauri-plugin-keep-screen-on-api": "^0.1.4",
|
||||||
"typescript-eslint": "^8.34.1",
|
"typescript-eslint": "^8.34.1",
|
||||||
},
|
},
|
||||||
@ -926,6 +927,8 @@
|
|||||||
|
|
||||||
"tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="],
|
"tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="],
|
||||||
|
|
||||||
|
"tauri-plugin-duck-api": ["tauri-plugin-duck-api@0.1.1", "", { "dependencies": { "@tauri-apps/api": ">=2.0.0-beta.6" } }, "sha512-1mhz1SI2Lu8bHmgF5dmvutHmYpY78qITR0cMQbS5Tbk3NlW+e6WGew6ujUepqQvL6/WdWcPi7XNM0Lfd4haDNQ=="],
|
||||||
|
|
||||||
"tauri-plugin-keep-screen-on-api": ["tauri-plugin-keep-screen-on-api@0.1.4", "", { "dependencies": { "@tauri-apps/api": ">=2.0.0-beta.6" } }, "sha512-uFY2EKWiKQ3xmwpMYfjaXgYr5USSNS0/Nz8h75lnG0bgttsEcUs4soP0fHPpE7tL3BKbzJdyTycusirkS9aKkA=="],
|
"tauri-plugin-keep-screen-on-api": ["tauri-plugin-keep-screen-on-api@0.1.4", "", { "dependencies": { "@tauri-apps/api": ">=2.0.0-beta.6" } }, "sha512-uFY2EKWiKQ3xmwpMYfjaXgYr5USSNS0/Nz8h75lnG0bgttsEcUs4soP0fHPpE7tL3BKbzJdyTycusirkS9aKkA=="],
|
||||||
|
|
||||||
"terra-draw": ["terra-draw@1.6.2", "", {}, "sha512-U5vHQ8CPOM52cHcHUrCewuQnmaUWRXF2g3UJV2IDLyVtzeOBbkBXl2ZNXD4AhA3roEDwYi5wZ5ZbB6pKuC62Kw=="],
|
"terra-draw": ["terra-draw@1.6.2", "", {}, "sha512-U5vHQ8CPOM52cHcHUrCewuQnmaUWRXF2g3UJV2IDLyVtzeOBbkBXl2ZNXD4AhA3roEDwYi5wZ5ZbB6pKuC62Kw=="],
|
||||||
|
|||||||
@ -59,6 +59,7 @@
|
|||||||
"pmtiles": "^4.3.0",
|
"pmtiles": "^4.3.0",
|
||||||
"sql.js": "^1.13.0",
|
"sql.js": "^1.13.0",
|
||||||
"svelte-maplibre-gl": "^0.1.8",
|
"svelte-maplibre-gl": "^0.1.8",
|
||||||
|
"tauri-plugin-duck-api": "^0.1.1",
|
||||||
"tauri-plugin-keep-screen-on-api": "^0.1.4",
|
"tauri-plugin-keep-screen-on-api": "^0.1.4",
|
||||||
"typescript-eslint": "^8.34.1"
|
"typescript-eslint": "^8.34.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +0,0 @@
|
|||||||
import { registerPlugin, WebPlugin } from "@capacitor/core";
|
|
||||||
|
|
||||||
export interface DuckPlugin {
|
|
||||||
duck: () => void;
|
|
||||||
unduck: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
class DuckWeb extends WebPlugin implements DuckPlugin {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
||||||
duck(): void {}
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
||||||
unduck(): void {}
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duck = registerPlugin<DuckPlugin>("Duck", {
|
|
||||||
web: new DuckWeb(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export default Duck;
|
|
||||||
@ -1,173 +0,0 @@
|
|||||||
import {
|
|
||||||
CapacitorSQLite,
|
|
||||||
SQLiteConnection,
|
|
||||||
SQLiteDBConnection,
|
|
||||||
} from "@capacitor-community/sqlite";
|
|
||||||
import initSqlJs from "sql.js";
|
|
||||||
import { Buffer } from "buffer";
|
|
||||||
import { Capacitor } from "@capacitor/core";
|
|
||||||
import { ungzip } from "pako";
|
|
||||||
|
|
||||||
let sqlite: SQLiteConnection;
|
|
||||||
let db: SQLiteDBConnection;
|
|
||||||
|
|
||||||
export async function downloadMBTiles(url: string): Promise<Uint8Array> {
|
|
||||||
return fetch(url)
|
|
||||||
.then((res) => res.arrayBuffer())
|
|
||||||
.then((ab) => new Uint8Array(ab));
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function copyMBTiles(data: Uint8Array) {
|
|
||||||
if (!db) {
|
|
||||||
await initDB();
|
|
||||||
}
|
|
||||||
const SQL = await initSqlJs();
|
|
||||||
const mdb = new SQL.Database(data);
|
|
||||||
const res = mdb.exec("SELECT * FROM tiles");
|
|
||||||
//// const chunkSize = 10; // Adjust chunk size as needed
|
|
||||||
//// const values = res[0].values;
|
|
||||||
//// for (let i = 0; i < values.length; i += chunkSize) {
|
|
||||||
//// const chunk = values.slice(i, i + chunkSize);
|
|
||||||
//// const statements = chunk.map(row => {
|
|
||||||
//// const [z, x, y, data] = row;
|
|
||||||
//// return {
|
|
||||||
//// statement: `INSERT OR REPLACE INTO tiles (z, x, y, data) VALUES (?, ?, ?, ?)`,
|
|
||||||
//// values: [z, x, y, Buffer.from(data as Uint8Array)]
|
|
||||||
//// };
|
|
||||||
//// });
|
|
||||||
//// await db.executeSet(statements);
|
|
||||||
//// console.log(`Inserted chunk ${i / chunkSize + 1} of ${Math.ceil(values.length / chunkSize)}: z=${chunk[0][0]}, x=${chunk[0][1]}, y=${chunk[0][2]}`);
|
|
||||||
//// }
|
|
||||||
const total = res[0].values.length;
|
|
||||||
for (const [idx, row] of res[0].values.entries()) {
|
|
||||||
const [z, x, y, data] = row;
|
|
||||||
await db.run(
|
|
||||||
`INSERT OR REPLACE INTO tiles (z, x, y, data) VALUES (?, ?, ?, ?)`,
|
|
||||||
[
|
|
||||||
z,
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
Buffer.from(data as Uint8Array), // Convert Uint8Array to Buffer
|
|
||||||
],
|
|
||||||
);
|
|
||||||
console.log(
|
|
||||||
`Inserted tile z=${z}, x=${x}, y=${y}. Item ${idx + 1} of ${total}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
console.log(`Copied ${res[0].values.length} tiles from MBTiles data`);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function test(url: string) {
|
|
||||||
const res = await downloadMBTiles(url);
|
|
||||||
console.log("Downloaded MBTiles data");
|
|
||||||
await copyMBTiles(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function initDB() {
|
|
||||||
if (!Capacitor.isNativePlatform()) {
|
|
||||||
throw new Error("initDB is only available on native platforms");
|
|
||||||
}
|
|
||||||
console.log("Initializing SQLite database for tiles");
|
|
||||||
sqlite = new SQLiteConnection(CapacitorSQLite);
|
|
||||||
db = await sqlite.createConnection("tiles", false, "no-encryption", 1, false);
|
|
||||||
await db.open();
|
|
||||||
await db.execute(`CREATE TABLE IF NOT EXISTS tiles (
|
|
||||||
z INTEGER NOT NULL,
|
|
||||||
x INTEGER NOT NULL,
|
|
||||||
y INTEGER NOT NULL,
|
|
||||||
data BLOB NOT NULL,
|
|
||||||
PRIMARY KEY (z, x, y)
|
|
||||||
)`);
|
|
||||||
await db.execute(
|
|
||||||
`CREATE INDEX IF NOT EXISTS idx_tiles_zxy ON tiles (z, x, y)`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteDB() {
|
|
||||||
if (!Capacitor.isNativePlatform()) {
|
|
||||||
throw new Error("deleteDB is only available on native platforms");
|
|
||||||
}
|
|
||||||
await db.execute(`DROP TABLE IF EXISTS tiles`);
|
|
||||||
await initDB();
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-expect-error aaaaa
|
|
||||||
window.deleteDB = deleteDB;
|
|
||||||
|
|
||||||
// @ts-expect-error aaaaa
|
|
||||||
window.initDB = initDB;
|
|
||||||
|
|
||||||
export async function getTile(
|
|
||||||
z: number,
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
signal?: AbortSignal
|
|
||||||
): Promise<Uint8Array | null> {
|
|
||||||
if (signal?.aborted) {
|
|
||||||
throw new DOMException("Aborted", "AbortError");
|
|
||||||
}
|
|
||||||
const abortPromise = new Promise<never>((_, reject) => {
|
|
||||||
if (signal) {
|
|
||||||
signal.addEventListener("abort", () => {
|
|
||||||
reject(new DOMException("Aborted", "AbortError"));
|
|
||||||
}, { once: true });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const queryPromise = db.query(
|
|
||||||
`SELECT data FROM tiles WHERE z = ? AND x = ? AND y = ?`,
|
|
||||||
[z, x, y],
|
|
||||||
);
|
|
||||||
const res = await Promise.race([queryPromise, abortPromise]);
|
|
||||||
if (!res.values || res.values.length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
console.log(res);
|
|
||||||
return await decompressGzip(res.values[0].data as Uint8Array);
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-expect-error aaaaa
|
|
||||||
window.getTile = getTile;
|
|
||||||
|
|
||||||
async function decompressGzip(blob: Uint8Array): Promise<Uint8Array> {
|
|
||||||
// const ds = new DecompressionStream("gzip");
|
|
||||||
// const decompressedStream = new Blob([blob]).stream().pipeThrough(ds);
|
|
||||||
// return new Uint8Array(await new Response(decompressedStream).arrayBuffer());
|
|
||||||
return ungzip(blob);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function protocol(params: {
|
|
||||||
url: string;
|
|
||||||
}, { signal }: AbortController): Promise<{ data: Uint8Array }> {
|
|
||||||
console.log("Protocol called with params:", params);
|
|
||||||
const url = new URL(params.url);
|
|
||||||
const pathname = url.pathname.replace(/^\//, ""); // Remove leading slash
|
|
||||||
const z = parseInt(pathname.split("/")[0]);
|
|
||||||
const x = parseInt(pathname.split("/")[1]);
|
|
||||||
const y = parseInt(pathname.split("/")[2]);
|
|
||||||
if (!Capacitor.isNativePlatform()) {
|
|
||||||
const t = await fetch(
|
|
||||||
`https://tiles.openfreemap.org/planet/20250528_001001_pt/${z}/${x}/${y}.pbf`,
|
|
||||||
{ signal }
|
|
||||||
);
|
|
||||||
if (t.status == 200) {
|
|
||||||
const buffer = await t.arrayBuffer();
|
|
||||||
return { data: new Uint8Array(buffer) };
|
|
||||||
} else {
|
|
||||||
throw new Error(`Tile fetch error: ${t.statusText}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!db) {
|
|
||||||
await initDB();
|
|
||||||
}
|
|
||||||
const tmsY = (1 << z) - 1 - y; // Invert y for TMS
|
|
||||||
console.log(`Fetching tile: z=${z}, x=${x}, y=${y}, tmsY=${tmsY}`);
|
|
||||||
const data = await getTile(z, x, tmsY, signal);
|
|
||||||
if (!data) {
|
|
||||||
console.warn(`Tile not found: z=${z}, x=${x}, y=${y}`);
|
|
||||||
return {
|
|
||||||
data: new Uint8Array(), // Return empty array if tile not found
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// return { data: await fetch("/0.pbf").then(res => res.arrayBuffer()).then(ab => new Uint8Array(ab)) };
|
|
||||||
return { data };
|
|
||||||
}
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import type { TextToSpeechPlugin } from "@capacitor-community/text-to-speech";
|
import type { TextToSpeechPlugin } from "@capacitor-community/text-to-speech";
|
||||||
import { Capacitor } from "@capacitor/core";
|
import { Capacitor } from "@capacitor/core";
|
||||||
import Duck from "../DuckPlugin";
|
import { duck, unduck } from "tauri-plugin-duck-api";
|
||||||
|
|
||||||
export let tts: TextToSpeechPlugin | "web" | null = null;
|
export let tts: TextToSpeechPlugin | "web" | null = null;
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ export default async function say(text: string) {
|
|||||||
await initTTS();
|
await initTTS();
|
||||||
// return;
|
// return;
|
||||||
}
|
}
|
||||||
Duck.duck();
|
duck();
|
||||||
if (tts !== "web") {
|
if (tts !== "web") {
|
||||||
try {
|
try {
|
||||||
await tts?.speak({
|
await tts?.speak({
|
||||||
@ -37,5 +37,5 @@ export default async function say(text: string) {
|
|||||||
utterance.lang = "de-DE";
|
utterance.lang = "de-DE";
|
||||||
window.speechSynthesis.speak(utterance);
|
window.speechSynthesis.speak(utterance);
|
||||||
}
|
}
|
||||||
Duck.unduck();
|
unduck();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,8 +5,6 @@ import type { ValhallaRequest } from "./ValhallaRequest";
|
|||||||
import type { LngLatBoundsLike } from "maplibre-gl";
|
import type { LngLatBoundsLike } from "maplibre-gl";
|
||||||
import { generateVoiceGuidance } from "./VoiceGuidance";
|
import { generateVoiceGuidance } from "./VoiceGuidance";
|
||||||
import { keepScreenOn } from "tauri-plugin-keep-screen-on-api";
|
import { keepScreenOn } from "tauri-plugin-keep-screen-on-api";
|
||||||
// import { Capacitor } from "@capacitor/core";
|
|
||||||
// import { KeepAwake } from "@capacitor-community/keep-awake";
|
|
||||||
|
|
||||||
export const routing = $state({
|
export const routing = $state({
|
||||||
geojson: {
|
geojson: {
|
||||||
@ -131,9 +129,6 @@ function drawCurrentTrip() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function startRoute(trip: Trip) {
|
export async function startRoute(trip: Trip) {
|
||||||
/* if (Capacitor.isNativePlatform()) {
|
|
||||||
await KeepAwake.keepAwake();
|
|
||||||
} */
|
|
||||||
if(window.__TAURI__) {
|
if(window.__TAURI__) {
|
||||||
await keepScreenOn(true);
|
await keepScreenOn(true);
|
||||||
}
|
}
|
||||||
@ -275,9 +270,6 @@ export function stopNavigation() {
|
|||||||
routing.currentTrip = null;
|
routing.currentTrip = null;
|
||||||
map.updateMapPadding(); // TODO: REMOVE
|
map.updateMapPadding(); // TODO: REMOVE
|
||||||
removeAllRoutes();
|
removeAllRoutes();
|
||||||
//if (Capacitor.isNativePlatform()) {
|
|
||||||
// KeepAwake.allowSleep();
|
|
||||||
//}
|
|
||||||
if(window.__TAURI__) {
|
if(window.__TAURI__) {
|
||||||
keepScreenOn(false);
|
keepScreenOn(false);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user