mirror of
https://codeberg.org/PLG-Development/PLG-MuDiCS
synced 2026-07-06 17:07:08 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fab846d843 |
-11
@@ -1,13 +1,2 @@
|
|||||||
.aider*
|
.aider*
|
||||||
.env
|
.env
|
||||||
|
|
||||||
/display/internal/pdfjs/node_modules/*
|
|
||||||
|
|
||||||
!/display/internal/pdfjs/node_modules/pdfjs-dist/
|
|
||||||
/display/internal/pdfjs/node_modules/pdfjs-dist/*
|
|
||||||
|
|
||||||
!/display/internal/pdfjs/node_modules/pdfjs-dist/build/
|
|
||||||
/display/internal/pdfjs/node_modules/pdfjs-dist/build/*
|
|
||||||
|
|
||||||
!/display/internal/pdfjs/node_modules/pdfjs-dist/build/pdf.min.mjs
|
|
||||||
!/display/internal/pdfjs/node_modules/pdfjs-dist/build/pdf.worker.min.mjs
|
|
||||||
@@ -266,10 +266,12 @@
|
|||||||
? 'text-stone-500 cursor-not-allowed'
|
? 'text-stone-500 cursor-not-allowed'
|
||||||
: 'hover:bg-stone-600 active:bg-stone-500 cursor-pointer'} py-2 rounded-xl flex justify-center items-center transition-colors duration-200"
|
: 'hover:bg-stone-600 active:bg-stone-500 cursor-pointer'} py-2 rounded-xl flex justify-center items-center transition-colors duration-200"
|
||||||
disabled={$selected_online_display_ids.length === 0 || key_pressed.ArrowLeft}
|
disabled={$selected_online_display_ids.length === 0 || key_pressed.ArrowLeft}
|
||||||
onmousedown={() => {
|
onmousedown={(e: MouseEvent) => {
|
||||||
|
if (e.button !== 0) return;
|
||||||
add_to_keyboard_queue(async () => await send_single_key_press('ArrowLeft', 'press'));
|
add_to_keyboard_queue(async () => await send_single_key_press('ArrowLeft', 'press'));
|
||||||
}}
|
}}
|
||||||
onmouseup={() => {
|
onmouseup={(e: MouseEvent) => {
|
||||||
|
if (e.button !== 0) return;
|
||||||
add_to_keyboard_queue(
|
add_to_keyboard_queue(
|
||||||
async () => await send_single_key_press('ArrowLeft', 'release')
|
async () => await send_single_key_press('ArrowLeft', 'release')
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -141,11 +141,13 @@
|
|||||||
<button
|
<button
|
||||||
title="Windows-/Meta-Taste [gedrückt halten möglich]"
|
title="Windows-/Meta-Taste [gedrückt halten möglich]"
|
||||||
class="px-3 bg-stone-700 py-2 gap-2 rounded-xl flex items-center transition-colors duration-200 hover:bg-stone-600 active:bg-stone-500 cursor-pointer"
|
class="px-3 bg-stone-700 py-2 gap-2 rounded-xl flex items-center transition-colors duration-200 hover:bg-stone-600 active:bg-stone-500 cursor-pointer"
|
||||||
onmousedown={async (e) => {
|
onmousedown={async (e: MouseEvent) => {
|
||||||
|
if (e.button !== 0) return;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
await on_key('MetaLeft', true);
|
await on_key('MetaLeft', true);
|
||||||
}}
|
}}
|
||||||
onmouseup={async () => {
|
onmouseup={async (e: MouseEvent) => {
|
||||||
|
if (e.button !== 0) return;
|
||||||
await on_key('MetaLeft', false);
|
await on_key('MetaLeft', false);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
package pdfjs
|
|
||||||
|
|
||||||
import "embed"
|
|
||||||
|
|
||||||
//go:embed node_modules/pdfjs-dist/build/pdf.min.mjs
|
|
||||||
//go:embed node_modules/pdfjs-dist/build/pdf.worker.min.mjs
|
|
||||||
var Files embed.FS
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"nodeModulesDir": "manual",
|
|
||||||
"nodeModulesLinker": "hoisted",
|
|
||||||
"imports": {
|
|
||||||
"pdfjs-dist": "npm:pdfjs-dist@6.0.227"
|
|
||||||
},
|
|
||||||
"tasks": {
|
|
||||||
"install": "deno install --frozen"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Generated
-90
@@ -1,90 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "5",
|
|
||||||
"specifiers": {
|
|
||||||
"npm:pdfjs-dist@6.0.227": "6.0.227"
|
|
||||||
},
|
|
||||||
"npm": {
|
|
||||||
"@napi-rs/canvas-android-arm64@1.0.0": {
|
|
||||||
"integrity": "sha512-3hNKJObUK7JsCF9aJlVCs1J0/KE/gGfZNeK8MO1ge6bB3aicr5walGme9t9No1f/oyk9GgvdAT/rjSdsx3gbIw==",
|
|
||||||
"os": ["android"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
|
||||||
"@napi-rs/canvas-darwin-arm64@1.0.0": {
|
|
||||||
"integrity": "sha512-ZIja19/BiGz2puhki+WUYSRriwFeFJ8Mi9eK3hZdSS85w4Y60cuEAJVhMCfKwswQkKkUtrnzdKMBuO7TupvexA==",
|
|
||||||
"os": ["darwin"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
|
||||||
"@napi-rs/canvas-darwin-x64@1.0.0": {
|
|
||||||
"integrity": "sha512-hImggWc82jqZVpEsFR9S7PE9OQYjq/H/D7vwCGB6X1jRH+UVBP1+1niJTPBOat1B154T6GKK7/kcFtoWgjgFzQ==",
|
|
||||||
"os": ["darwin"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
|
||||||
"@napi-rs/canvas-linux-arm-gnueabihf@1.0.0": {
|
|
||||||
"integrity": "sha512-hlJRy6d+kWLKVOG/+1rEvNQVURZ0DxxRPJsLmEWwhwiXZUJc0BF5o9esALHSEP4CoJK4wChRtj3hnyBgVx2oWA==",
|
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["arm"]
|
|
||||||
},
|
|
||||||
"@napi-rs/canvas-linux-arm64-gnu@1.0.0": {
|
|
||||||
"integrity": "sha512-5Hru4T3RXkosRQafcjelv7AUzw9mXqmGYsxnzeDDOWveFCJyEPMSJltvGCM+jfH98seOCbfwm9KyFg6Jm5FhAA==",
|
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
|
||||||
"@napi-rs/canvas-linux-arm64-musl@1.0.0": {
|
|
||||||
"integrity": "sha512-LTUl9jS8WsLSUGaxQZKQkxfluOJRpgvBuxxdM4pYcjib+di8AU4OzQc6+L6SzGMLcKc9H0RAjojRatBhTMqYdg==",
|
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
|
||||||
"@napi-rs/canvas-linux-riscv64-gnu@1.0.0": {
|
|
||||||
"integrity": "sha512-Iz931SAZf+WVDzpjk52Q3ffW3zw0YflFwEZMgs036Wfu1kX/LrwT9wGjsuSqyduqefUkl91/vTdAjn8hQu5ezA==",
|
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["riscv64"]
|
|
||||||
},
|
|
||||||
"@napi-rs/canvas-linux-x64-gnu@1.0.0": {
|
|
||||||
"integrity": "sha512-pFEQ5eFK4JusgN1K6KkO9DKP/Hi1WMJOkF8Ch03/khTc4bFbCKkCCsJG4YcOMOW9bI4XbT2/eMAWxhO0xaWgPA==",
|
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
|
||||||
"@napi-rs/canvas-linux-x64-musl@1.0.0": {
|
|
||||||
"integrity": "sha512-jnvr8NrLHiZ3NCiOKWqDbkI4Ah+QDrqtZ+sddPZBltEb1mQ2coSvCSJYfict+oAwcm0c970oTmVySpjKP/lnaA==",
|
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
|
||||||
"@napi-rs/canvas-win32-arm64-msvc@1.0.0": {
|
|
||||||
"integrity": "sha512-y2j9/Gfd5joqiqxdP/L1smqjQ+uAx3C4N0EC7bDHrnZEEH8ToM/OC5p3uHvtj4Lq591aHj+ArL01UDLNwT5HgQ==",
|
|
||||||
"os": ["win32"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
|
||||||
"@napi-rs/canvas-win32-x64-msvc@1.0.0": {
|
|
||||||
"integrity": "sha512-qwdhh9N6Gge/hC4pL9S1tQp0iKwhSl/dYjg7+RGp9k26iRGRi5MqqUyKGOXIWli0zOcuy5Y2wIH/jk2ry6i/jA==",
|
|
||||||
"os": ["win32"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
|
||||||
"@napi-rs/canvas@1.0.0": {
|
|
||||||
"integrity": "sha512-Jqxcy1XOIqj+lH9sl1GT+il6GR3uQv13vI2mrwubP3uT8Olak2ClDrK2RnxlQKjwv8BRr4b3ug0YR7c6hBX8wg==",
|
|
||||||
"optionalDependencies": [
|
|
||||||
"@napi-rs/canvas-android-arm64",
|
|
||||||
"@napi-rs/canvas-darwin-arm64",
|
|
||||||
"@napi-rs/canvas-darwin-x64",
|
|
||||||
"@napi-rs/canvas-linux-arm-gnueabihf",
|
|
||||||
"@napi-rs/canvas-linux-arm64-gnu",
|
|
||||||
"@napi-rs/canvas-linux-arm64-musl",
|
|
||||||
"@napi-rs/canvas-linux-riscv64-gnu",
|
|
||||||
"@napi-rs/canvas-linux-x64-gnu",
|
|
||||||
"@napi-rs/canvas-linux-x64-musl",
|
|
||||||
"@napi-rs/canvas-win32-arm64-msvc",
|
|
||||||
"@napi-rs/canvas-win32-x64-msvc"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"pdfjs-dist@6.0.227": {
|
|
||||||
"integrity": "sha512-/P6M4SXw+70waMVLUM7rdRtvo+dEzqE1t6W/zQNvBETo2MaRa5rrvCcAYdfWGiUzadTgM0lJmRApUrW0d9zgKg==",
|
|
||||||
"optionalDependencies": [
|
|
||||||
"@napi-rs/canvas"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"workspace": {
|
|
||||||
"dependencies": [
|
|
||||||
"npm:pdfjs-dist@6.0.227"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-29
File diff suppressed because one or more lines are too long
-29
File diff suppressed because one or more lines are too long
@@ -1,7 +1,5 @@
|
|||||||
package pkg
|
package pkg
|
||||||
|
|
||||||
import "strings"
|
|
||||||
|
|
||||||
templ basicTemplate() {
|
templ basicTemplate() {
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
@@ -117,166 +115,6 @@ templ deviceInfoTemplate(ip string, mac string, showQR bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
templ pdfTemplate(path string, serverOrigin string) {
|
|
||||||
@basicTemplate() {
|
|
||||||
<base href={ serverOrigin + "/" }/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
id="pdf"
|
|
||||||
data-src={ "api/file/" + strings.Split(path, "/.local/share/plg-mudics/display")[1] }
|
|
||||||
data-lib="static/pdfjs/pdf.min.mjs"
|
|
||||||
data-worker="static/pdfjs/pdf.worker.min.mjs"
|
|
||||||
></div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
html,body,#pdf {
|
|
||||||
margin:0;
|
|
||||||
width:100%;
|
|
||||||
height:100%;
|
|
||||||
overflow:hidden;
|
|
||||||
background:#000;
|
|
||||||
}
|
|
||||||
#pdf {
|
|
||||||
display:grid;
|
|
||||||
place-items:center;
|
|
||||||
}
|
|
||||||
#pdf canvas {
|
|
||||||
grid-area:1/1;
|
|
||||||
display:block;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script type="module">
|
|
||||||
const host=document.querySelector("#pdf");
|
|
||||||
const resolve=x=>new URL(x,document.baseURI).href;
|
|
||||||
|
|
||||||
const P=await import(resolve(host.dataset.lib));
|
|
||||||
P.GlobalWorkerOptions.workerSrc=resolve(host.dataset.worker);
|
|
||||||
|
|
||||||
const pdf=await P.getDocument({
|
|
||||||
url:resolve(host.dataset.src),
|
|
||||||
useWasm:false
|
|
||||||
}).promise;
|
|
||||||
|
|
||||||
const cache=new Map();
|
|
||||||
let currentPage=1;
|
|
||||||
let wantedPage=1;
|
|
||||||
let requestNumber=0;
|
|
||||||
|
|
||||||
function renderPage(number) {
|
|
||||||
if(cache.has(number)) return cache.get(number);
|
|
||||||
|
|
||||||
const promise=(async()=>{
|
|
||||||
const page=await pdf.getPage(number);
|
|
||||||
const original=page.getViewport({scale:1});
|
|
||||||
const scale=Math.min(
|
|
||||||
innerWidth/original.width,
|
|
||||||
innerHeight/original.height
|
|
||||||
);
|
|
||||||
|
|
||||||
// Use 1 on old hardware. Raise to 1.5 for sharper output.
|
|
||||||
const pixelRatio=1;
|
|
||||||
const viewport=page.getViewport({
|
|
||||||
scale:scale*pixelRatio
|
|
||||||
});
|
|
||||||
|
|
||||||
const canvas=document.createElement("canvas");
|
|
||||||
canvas.width=Math.ceil(viewport.width);
|
|
||||||
canvas.height=Math.ceil(viewport.height);
|
|
||||||
canvas.style.width=`${viewport.width/pixelRatio}px`;
|
|
||||||
canvas.style.height=`${viewport.height/pixelRatio}px`;
|
|
||||||
|
|
||||||
const task=page.render({
|
|
||||||
canvasContext:canvas.getContext("2d"),
|
|
||||||
viewport
|
|
||||||
});
|
|
||||||
|
|
||||||
await task.promise;
|
|
||||||
return canvas;
|
|
||||||
})().catch(error=>{
|
|
||||||
cache.delete(number);
|
|
||||||
throw error;
|
|
||||||
});
|
|
||||||
|
|
||||||
cache.set(number,promise);
|
|
||||||
return promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function show(number) {
|
|
||||||
wantedPage=Math.max(1,Math.min(pdf.numPages,number));
|
|
||||||
const request=++requestNumber;
|
|
||||||
const canvas=await renderPage(wantedPage);
|
|
||||||
|
|
||||||
// Ignore an obsolete result after multiple fast key presses.
|
|
||||||
if(request!==requestNumber) return;
|
|
||||||
|
|
||||||
// The new canvas is already completely rendered.
|
|
||||||
host.replaceChildren(canvas);
|
|
||||||
currentPage=wantedPage;
|
|
||||||
|
|
||||||
pruneCache();
|
|
||||||
preloadNeighbours();
|
|
||||||
}
|
|
||||||
|
|
||||||
function preloadNeighbours() {
|
|
||||||
const page=currentPage;
|
|
||||||
|
|
||||||
requestIdleCallback(async()=>{
|
|
||||||
if(page+1<=pdf.numPages) {
|
|
||||||
await renderPage(page+1);
|
|
||||||
}
|
|
||||||
if(page-1>=1) {
|
|
||||||
await renderPage(page-1);
|
|
||||||
}
|
|
||||||
},{timeout:250});
|
|
||||||
}
|
|
||||||
|
|
||||||
function pruneCache() {
|
|
||||||
const keep=new Set([
|
|
||||||
currentPage-1,
|
|
||||||
currentPage,
|
|
||||||
currentPage+1
|
|
||||||
]);
|
|
||||||
|
|
||||||
for(const [number,promise] of cache) {
|
|
||||||
if(keep.has(number)) continue;
|
|
||||||
|
|
||||||
cache.delete(number);
|
|
||||||
promise.then(canvas=>{
|
|
||||||
if(!canvas.isConnected) {
|
|
||||||
canvas.width=0;
|
|
||||||
canvas.height=0;
|
|
||||||
}
|
|
||||||
}).catch(()=>{});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addEventListener("keydown",event=>{
|
|
||||||
if(event.key==="ArrowRight") {
|
|
||||||
event.preventDefault();
|
|
||||||
show(wantedPage+1);
|
|
||||||
} else if(event.key==="ArrowLeft") {
|
|
||||||
event.preventDefault();
|
|
||||||
show(wantedPage-1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
addEventListener("resize",()=>{
|
|
||||||
cache.clear();
|
|
||||||
show(currentPage);
|
|
||||||
});
|
|
||||||
|
|
||||||
window.pdfViewer={
|
|
||||||
page:()=>currentPage,
|
|
||||||
count:()=>pdf.numPages,
|
|
||||||
show
|
|
||||||
};
|
|
||||||
|
|
||||||
await show(1);
|
|
||||||
</script>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
templ startScreenTemplate(splashScreenHtml string, ip string, mac string, qrPath string) {
|
templ startScreenTemplate(splashScreenHtml string, ip string, mac string, qrPath string) {
|
||||||
@basicTemplate() {
|
@basicTemplate() {
|
||||||
<div style="width: 100vw; height: 100vh; display: flex; flex-direction: row; justify-content: space-between;">
|
<div style="width: 100vw; height: 100vh; display: flex; flex-direction: row; justify-content: space-between;">
|
||||||
|
|||||||
@@ -40,12 +40,7 @@ func OpenFile(path string) error {
|
|||||||
_ = imageTemplate(path).Render(context.Background(), &templateBuffer)
|
_ = imageTemplate(path).Render(context.Background(), &templateBuffer)
|
||||||
err = browser.Browser.OpenHTML(templateBuffer.String())
|
err = browser.Browser.OpenHTML(templateBuffer.String())
|
||||||
case "application/pdf":
|
case "application/pdf":
|
||||||
var templateBuffer bytes.Buffer
|
err = browser.Browser.OpenPDF(path)
|
||||||
err = pdfTemplate(path, "http://127.0.0.1:1323").Render(context.Background(), &templateBuffer)
|
|
||||||
if err == nil {
|
|
||||||
err = browser.Browser.OpenHTML(templateBuffer.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
case "application/vnd.openxmlformats-officedocument.presentationml.presentation", "application/vnd.oasis.opendocument.presentation":
|
case "application/vnd.openxmlformats-officedocument.presentationml.presentation", "application/vnd.oasis.opendocument.presentation":
|
||||||
err = fileHandler.openFileWithApp(path)
|
err = fileHandler.openFileWithApp(path)
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -16,20 +16,12 @@ import (
|
|||||||
"github.com/labstack/echo/v4/middleware"
|
"github.com/labstack/echo/v4/middleware"
|
||||||
|
|
||||||
"plg-mudics/display/browser"
|
"plg-mudics/display/browser"
|
||||||
"plg-mudics/display/internal/pdfjs"
|
|
||||||
"plg-mudics/display/pkg"
|
"plg-mudics/display/pkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
func StartWebServer(port string) {
|
func StartWebServer(port string) {
|
||||||
e := echo.New()
|
e := echo.New()
|
||||||
|
|
||||||
pdfJSGroup := e.Group("/static/pdfjs")
|
|
||||||
pdfJSGroup.Use(middleware.CORS())
|
|
||||||
pdfJSGroup.StaticFS(
|
|
||||||
"/",
|
|
||||||
echo.MustSubFS(pdfjs.Files, "node_modules/pdfjs-dist/build"),
|
|
||||||
)
|
|
||||||
|
|
||||||
apiGroup := e.Group("/api")
|
apiGroup := e.Group("/api")
|
||||||
apiGroup.Use(middleware.CORS())
|
apiGroup.Use(middleware.CORS())
|
||||||
apiGroup.GET("/ping", pingRoute)
|
apiGroup.GET("/ping", pingRoute)
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
v0.1.7
|
v0.1.5
|
||||||
Reference in New Issue
Block a user