This commit is contained in:
Rizky 2024-02-04 14:52:58 +07:00
parent d335510e69
commit 42c4d97b1c
10 changed files with 111 additions and 9 deletions

View File

@ -8,8 +8,17 @@ import { g } from "utils/global";
export const _ = {
url: "/npm/:mode/:id/*",
async api(mode: "site" | "page", id: string) {
async api(mode: "site" | "page" | "apk-qr", id: string) {
const { req, res, mode: _mode } = apiContext(this);
if (mode === "apk-qr") {
const file_apk = Bun.file(dir.path(`${g.datadir}/prasi-wrap.apk`));
if (!await file_apk.exists()) {
return new Response('not found');
}
return new Response(file_apk);
}
let path = dir.path(`${g.datadir}/npm/${mode}/${id}/${req.params._}`);
const contentType = mime.lookup(path);

View File

@ -10,6 +10,7 @@
"@floating-ui/react": "^0.26.4",
"@leeoniya/ufuzzy": "^1.0.14",
"@minoru/react-dnd-treeview": "^3.4.4",
"@wojtekmaj/react-qr-svg": "^1.0.0",
"constrained-editor-plugin": "^1.3.0",
"@monaco-editor/react": "^4.6.0",
"@paralleldrive/cuid2": "2.2.2",

View File

@ -6,12 +6,12 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Prasi: App Builder</title>
<link rel="stylesheet" href="/index.css">
<script>window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = { isDisabled: true };</script>
</head>
<body className="flex-col flex-1 w-full min-h-screen flex opacity-0">
<div id="root"></div>
<script src="/index.js"></script>
<script>window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = { isDisabled: true };</script>
</body>
</html>

View File

@ -30,7 +30,12 @@ export const loadApiProxyDef = async (_url: string, with_types: boolean) => {
} else {
script.src = `${base}/_prasi/load.js?url=${url}&v3&ts=${ts}`;
}
if (!document.querySelector(`script[src="${script.src}"]`)) {
d.body.appendChild(script);
} else {
done();
}
});
} else {
const apiEntry = await fetch(base + "/_prasi/api-entry");

View File

@ -9,9 +9,10 @@ import { TopBtn } from "./panel/header/top-btn";
import { useGlobal } from "web-utils";
import { ResponsiveToggle } from "./panel/header/right/responsive-toggle";
import { EdCompEditable } from "./panel/header/mid/comp-editable";
import { MobileQRButton } from "./panel/side/style/tools/mobile-qr";
export const EdMid: FC<{}> = () => {
const ed = useGlobal(EDGlobal, "EDITORF");
const p = useGlobal(EDGlobal, "EDITORF");
return (
<div className="flex flex-col">
<div
@ -36,14 +37,15 @@ export const EdMid: FC<{}> = () => {
</div>
</div>
<div className="flex items-stretch flex-1 justify-end">
{p.site.responsive !== "desktop-only" && <MobileQRButton />}
<label className=" text-slate-400 flex items-center pr-1">
<div className=" px-1"> Zoom</div>
<select
value={ed.ui.zoom}
value={p.ui.zoom}
onChange={(e) => {
ed.ui.zoom = e.currentTarget.value;
localStorage.zoom = ed.ui.zoom;
ed.render();
p.ui.zoom = e.currentTarget.value;
localStorage.zoom = p.ui.zoom;
p.render();
}}
>
{["50%", "60%", "70%", "80%", "90%", "100%", "120%", "150%"].map(

View File

@ -20,7 +20,7 @@ export const EdPopScript = () => {
if (script.prop_name && script.type === "prop-master") {
propPopover.name = script.prop_name;
const render = propPopover.render[propPopover.name];
const render = propPopover.render;
if (render) render();
}

View File

@ -0,0 +1,78 @@
import QrSvg from "@wojtekmaj/react-qr-svg";
import { useGlobal, useLocal } from "web-utils";
import { ToolbarBox } from "../../../../../../utils/ui/box";
import { Modal } from "../../../../../../utils/ui/modal";
import { EDGlobal } from "../../../../logic/ed-global";
export const MobileQRButton = () => {
const p = useGlobal(EDGlobal, "EDITOR");
const local = useLocal({ open: false });
return (
<>
<ToolbarBox
className="flex"
items={[
{
onClick() {
local.open = true;
local.render();
},
content: (
<svg
xmlns="http://www.w3.org/2000/svg"
width="15"
height="15"
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
className="lucide lucide-qr-code"
viewBox="0 0 24 24"
>
<rect width="5" height="5" x="3" y="3" rx="1"></rect>
<rect width="5" height="5" x="16" y="3" rx="1"></rect>
<rect width="5" height="5" x="3" y="16" rx="1"></rect>
<path d="M21 16h-3a2 2 0 00-2 2v3M21 21v.01M12 7v3a2 2 0 01-2 2H7M3 12h.01M12 3h.01M12 16v.01M16 12h1M21 12v.01M12 21v-1"></path>
</svg>
),
},
]}
/>
<Modal
open={local.open}
onOpenChange={(open) => {
local.open = open;
local.render();
}}
>
<div
className={cx(
"flex flex-col w-[400px] items-stretch bg-white -mx-[8px] -my-[3px] text-[14px]"
)}
>
<div className="min-h-[80vh] flex flex-col items-center p-3">
<QrSvg
value={JSON.stringify({
site: { name: p.site.name, id: p.site.id },
page: {
name: p.page.cur.name,
id: p.page.cur.id,
url: p.page.cur.url,
},
})}
/>
<br />
<a
href="/npm/apk-qr/_/_"
target="_blank"
className="border p-2 rounded-sm"
>
Download APK
</a>
</div>
</div>
</Modal>
</>
);
};

BIN
bun.lockb

Binary file not shown.

View File

@ -1,5 +1,8 @@
import { gzipAsync } from "../../../app/srv/ws/sync/entity/zlib";
import { CORS_HEADERS } from "../server/serve-api";
import brotliPromise from "brotli-wasm";
const brotli = await brotliPromise;
export const _ = {
url: "/_proxy/*",
@ -34,6 +37,9 @@ export const _ = {
if (headers["content-encoding"] === "gzip") {
body = await gzipAsync(new Uint8Array(body));
} else if (headers["content-encoding"] === "br") {
body = brotli.decompress(new Uint8Array(body));
delete headers["content-encoding"];
} else {
delete headers["content-encoding"];
}

View File

@ -7,6 +7,7 @@
"@types/mime": "^3.0.3",
"@types/unzipper": "^0.10.8",
"esbuild": "^0.19.5",
"brotli-wasm": "^2.0.1",
"execa": "^8.0.1",
"fs-jetpack": "^5.1.0",
"lmdb": "^2.8.5",