From 1cfa44cb59a3cd909756a21fe90b883c6cec7e26 Mon Sep 17 00:00:00 2001 From: Mark Samuel Date: Thu, 14 Aug 2025 17:20:15 +0300 Subject: [PATCH 1/2] ## [3.0.1] - 2025-08-14 ### Fixed - **Font Handling**: - Replaced child process font detection with direct `font-list` package integration - Improved font listing reliability ### Technical Details - Removed child process fork for font detection - Simplified package.json by removing redundant extraResources declaration - Updated resource path resolution logic --- CHANGELOG | 14 ++++++++++++++ package.json | 5 +---- src/index.js | 22 ++++------------------ 3 files changed, 19 insertions(+), 22 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index eb33db0..91af4a0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,19 @@ # Changelog +# Changelog + +## [3.0.1] - 2025-08-14 + +### Fixed +- **Font Handling**: + - Replaced child process font detection with direct `font-list` package integration + - Improved font listing reliability + +### Technical Details +- Removed child process fork for font detection +- Simplified package.json by removing redundant extraResources declaration +- Updated resource path resolution logic + ## [3.0.0] - 2025-08-13 ### Major Changes diff --git a/package.json b/package.json index 74f537a..fd4123e 100644 --- a/package.json +++ b/package.json @@ -76,8 +76,5 @@ "ts-loader": "^9.5.2", "ts-node": "^10.9.2", "typescript": "^5.9.2" - }, - "extraResources": [ - "./extraResources/**" - ] + } } diff --git a/src/index.js b/src/index.js index 8f52379..9815fdc 100644 --- a/src/index.js +++ b/src/index.js @@ -10,12 +10,14 @@ import { import MediaResponder from "./utils/MediaResponderClass"; import WorkingFile from "./workingFile"; +const fontList = require("font-list"); + import log from "electron-log/main"; import cp from "child_process"; const EXTRARESOURCES_PATH = app.isPackaged - ? path.join(process.resourcesPath, "extraResources") + ? path.join(process.resourcesPath, "app.asar.unpacked", "src") : path.join(__dirname, "../../extraResources"); const getExtraResourcesPath = (...paths) => { @@ -152,24 +154,8 @@ ipcMain.handle("getSystemFonts", async () => { "fontlist/getSystemFonts.js" ); console.log(systemFontsScriptPath); - return new Promise((resolve, reject) => { - const forked = cp.fork(systemFontsScriptPath); - - forked.on("message", (message) => { - resolve(message); - forked.kill(); - }); - forked.on("error", (err) => { - reject(err); - }); - - forked.on("exit", (code) => { - if (code !== 0) { - reject(new Error(`getSystemFonts.js exited with code ${code}`)); - } - }); - }); + return fontList.getFonts({ disableQuoting: true }); }); ipcMain.on( From d2e6a321c007012199c196cfc15e111d8365dcc0 Mon Sep 17 00:00:00 2001 From: Mark Samuel Date: Thu, 14 Aug 2025 17:21:59 +0300 Subject: [PATCH 2/2] removed extra changelog line --- .vscode/ltex.dictionary.en-US.txt | 1 + CHANGELOG | 2 - package.json | 2 +- src/cdv | 50 ++ src/renderer/ShowCreateView/index copy.html | 687 ++++++++++++++++++++ src/utils/createTempDirectory.js | 18 + src/utils/protocolHandling.js | 97 +++ 7 files changed, 854 insertions(+), 3 deletions(-) create mode 100644 .vscode/ltex.dictionary.en-US.txt create mode 100644 src/cdv create mode 100644 src/renderer/ShowCreateView/index copy.html create mode 100644 src/utils/createTempDirectory.js create mode 100644 src/utils/protocolHandling.js diff --git a/.vscode/ltex.dictionary.en-US.txt b/.vscode/ltex.dictionary.en-US.txt new file mode 100644 index 0000000..93310fe --- /dev/null +++ b/.vscode/ltex.dictionary.en-US.txt @@ -0,0 +1 @@ +Toggleable diff --git a/CHANGELOG b/CHANGELOG index 91af4a0..b5a9e8a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,5 @@ # Changelog -# Changelog - ## [3.0.1] - 2025-08-14 ### Fixed diff --git a/package.json b/package.json index fd4123e..0fb7b10 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "choirslides", "productName": "ChoirSlides", - "version": "3.0.0", + "version": "3.0.1", "description": "A software designed to create lyric slideshows. This software allows users to combine lyrics with background videos, resulting in a visually engaging slideshow that synchronizes the lyrics with the video footage.", "main": "./.webpack/main", "scripts": { diff --git a/src/cdv b/src/cdv new file mode 100644 index 0000000..a6164aa --- /dev/null +++ b/src/cdv @@ -0,0 +1,50 @@ + protocol.handle("media", async (request) => { + const requestedFileParsed = path.parse( + decodeURIComponent(request.url.slice("media://".length)) + ); + // https://github.com/electron/electron/issues/38749#issuecomment-1681531939 + const fp = `videos\\${requestedFileParsed.name}${requestedFileParsed.ext}`; + const headers = new Headers(); + headers.set("Accept-Ranges", "bytes"); + headers.set("Content-Type", mime.getType(fp)); + let status = 200; + + const rangeText = request.headers.get("range"); + let stats = fs.statSync(videoFilePath); + const ranges = parseRangeRequests(rangeText, stats.size); + const [start, end] = ranges[0]; + headers.set("Content-Length", `${end - start}`); + headers.set("Content-Range", `bytes ${start}-${end}/${stats.size}`); + status = 206; + console.log(currentProject.notInArchive); + if ( + currentProject.notInArchive[ + `${requestedFileParsed.name}${requestedFileParsed.ext}` + ] + ) { + if (rangeText) { + VidFilestream = fs.createReadStream(videoPath, { start, end }); + } else { + headers.set("Content-Length", `${stats.size}`); + VidFilestream = fs.createReadStream(videoPath); + } + return new Response(VidFilestream, { + headers, + status, + }); + } + return currentProject.fileStream.entryData(fp).then((buf) => { + if (rangeText) { + VidFilestream = buf.subarray(start, end); + } else { + headers.set("Content-Length", `${stats.size}`); + VidFilestream = buf; + } + + return new Response(VidFilestream, { + headers, + status, + }); + }); + }); + \ No newline at end of file diff --git a/src/renderer/ShowCreateView/index copy.html b/src/renderer/ShowCreateView/index copy.html new file mode 100644 index 0000000..a991f61 --- /dev/null +++ b/src/renderer/ShowCreateView/index copy.html @@ -0,0 +1,687 @@ + + + + + ChoirSlides + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+
+
+
+ videocam + Video Preview +
+
+ + + +
+
+
+
+
+ movie +

No video loaded

+ +
+
+
+
+
+
+ + +
+
+
+
+
+
+ text_fields + Slide Text Editor +
+
+
+ + + + +
+
+ + + +
+
+ + +
+
+
+
+
+ +
+
+
+
+
+ + + +
+
+ + + + + + + + diff --git a/src/utils/createTempDirectory.js b/src/utils/createTempDirectory.js new file mode 100644 index 0000000..7481ec9 --- /dev/null +++ b/src/utils/createTempDirectory.js @@ -0,0 +1,18 @@ +const fs = require("fs"); +const path = require("path"); + +export default createDirectoryifNotExists = (appName) => { + const directoryPath = path.join(__dirname, appName); + + try { + if (!fs.existsSync(directoryPath)) { + fs.mkdirSync(directoryPath, { recursive: true }); + console.log(`Directory created: ${directoryPath}`); + return directoryPath; + } else { + console.log(`Directory already exists: ${directoryPath}`); + } + } catch (err) { + console.error(`Error creating directory: ${err}`); + } +}; diff --git a/src/utils/protocolHandling.js b/src/utils/protocolHandling.js new file mode 100644 index 0000000..a06ff59 --- /dev/null +++ b/src/utils/protocolHandling.js @@ -0,0 +1,97 @@ +const fs = require("fs"); + +function parseRangeRequests(text, size) { + const token = text.split("="); + if (token.length !== 2 || token[0] !== "bytes") { + return []; + } + + return token[1] + .split(",") + .map((v) => parseRange(v, size)) + .filter(([start, end]) => !isNaN(start) && !isNaN(end) && start <= end); +} + +const NAN_ARRAY = [NaN, NaN]; + +function parseRange(text, size) { + const token = text.split("-"); + if (token.length !== 2) { + return NAN_ARRAY; + } + + const startText = token[0].trim(); + const endText = token[1].trim(); + + if (startText === "") { + if (endText === "") { + return NAN_ARRAY; + } else { + let start = size - Number(endText); + if (start < 0) { + start = 0; + } + + return [start, size - 1]; + } + } else { + if (endText === "") { + return [Number(startText), size - 1]; + } else { + let end = Number(endText); + if (end >= size) { + end = size - 1; + } + + return [Number(startText), end]; + } + } +} + +function buildRangeHeaders(rangeText, totalSize) { + if (!rangeText) return null; + const ranges = parseRangeRequests(rangeText, totalSize); + const [start, end] = ranges[0]; + return { + start, + end, + contentLength: end - start, + contentRange: `bytes ${start}-${end}/${totalSize}`, + }; +} + +function createVideoResponse( + source, + totalSize, + rangeText, + isStream = true, + headers +) { + + headers.set("Accept-Ranges", "bytes"); + const range = buildRangeHeaders(rangeText, totalSize); + let status = 200; + let body; + + if (range) { + headers.set("Content-Length", `${range.contentLength}`); + headers.set("Content-Range", range.contentRange); + status = 206; + + if (isStream) { + body = fs.createReadStream(source, { + start: range.start, + end: range.end, + }); + } else { + body = source.subarray(range.start, range.end); + } + } else { + headers.set("Content-Length", `${totalSize}`); + body = isStream ? fs.createReadStream(source) : source; + } + + return new Response(body, { headers, status }); +} + +module.exports = { createVideoResponse, buildRangeHeaders };