Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Download the files for your system from the [releases page](https://github.com/d

### Windows

Download **Diamond-File-Converter-Setup-`<version>`.exe** and run it. It installs for all users, so it will ask for administrator rights.
Download **Diamond-File-Converter-Setup-`<version>`.exe** and run it. It asks who it's for: only you (the default, with no administrator prompt) or everyone on the computer. If Diamond File Converter is already installed for everyone, as every version before 2.0.0-beta.6 was, that copy is updated instead. It then asks which file types to open with it, all ticked, and whether to add **Convert with Diamond File Converter** to the menu files and folders show when you right-click them.

> [!NOTE]
> You may get a Windows SmartScreen popup when trying to run the installer. This is normal as the installer is not signed.
Expand All @@ -45,7 +45,7 @@ Download **Diamond-File-Converter-Setup-`<version>`.exe** and run it. It install
- **Fedora, openSUSE and others using RPM:** download **Diamond-File-Converter-`<version>`.rpm** and install it with your package manager, such as `sudo dnf install ./Diamond-File-Converter-<version>.rpm`.
- **Anywhere else:** download **Diamond-File-Converter-`<version>`.AppImage**, make it executable with `chmod +x`, and run it.

Linux builds start with 2.0. For now, the app isn't offered in "Open with" for media files on Linux, and the dock may show a generic icon for its window; opening files from a terminal (`diamond-file-converter file.mp4`) works.
Linux builds start with 2.0. With the `.deb` or `.rpm`, the app is in your file manager's "Open with" for the files it converts. Opening files from a terminal (`diamond-file-converter file.mp4`) works too.

### On every system

Expand Down
47 changes: 47 additions & 0 deletions docs/MANUAL-TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2716,3 +2716,50 @@ Use a video long enough to convert for ten seconds or more (a few minutes of
format select all work again. Advanced Options opens, and Apply says
**Settings applied to 1 file.**
- [ ] Bulk Edit still works on a selection when nothing is converting.

## 2.0.0-beta.6: the kit's installer, and electron-kit 0.1.0-beta.8 (2026-10-06)

DFC moves its build config to the kit's `config()` (`electron-builder.cjs`), so
the Windows installer is the kit's asking installer and `installer.nsh` is gone.
It also passes its `appId` to the kit, says when it's busy, and takes the kit's
Update tab changes since 0.1.0-beta.3.

> **Status: not yet run.**

### Upgrading an install for everyone (every earlier version's)

- [ ] With beta.5 installed (for everyone), run the beta.6 installer. It does
not ask who it's for: it upgrades that copy, and Settings > Apps lists
Diamond File Converter once.
- [ ] Right-click a file, then a folder: **Convert with Diamond File
Converter** is there once on each (Windows 11: under "Show more
options"), with the app's icon, and opens the file or folder in the app.
- [ ] Right-click an `.mp3`, Open with: Diamond File Converter is offered.

### A fresh install, only for me

- [ ] Uninstall, then run the installer again: it asks who it's for, "Only for
me" chosen, and installs with no administrator prompt.
- [ ] The file types page shows the 22 types in three groups, all ticked, and
the right-click box ticked. Untick **WMA** and the right-click box.
- [ ] After the install, a `.wma` doesn't offer the app in Open with, an
`.mp3` does, and there's no Convert entry on right-click.
- [ ] Install the same build again over it: WMA and the right-click box start
unticked.
- [ ] Uninstall: the app is gone from Open with for every type.

### The Update tab and Restart Now

- [ ] Open the app and go straight to Settings > Update: the status line is
never empty. It says "Updates haven't been checked yet." for a moment
at most, then "Checking for updates…", then the result.
- [ ] Open Settings > Update only after ten seconds: one check has run, and
Check for Updates runs another.
- [ ] With an update downloaded, start a long conversion and press **Restart
Now**: it asks first ("A conversion is running."), and Cancel keeps the
conversion going. The same while a join runs ("A join is running.").

### Notifications and the taskbar (Windows)

- [ ] Pin the app to the taskbar and open it: its window groups under the
pinned icon, not a second one.
2 changes: 1 addition & 1 deletion docs/design-system/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,7 @@ card("shell/context-menu.html", "Context Menu",
!macro customUninstall
DeleteRegKey HKCR "*\\shell\\&lt;App&gt;"
!macroend</pre></div>
<p class="note">Lives in <code>installer.nsh</code>, referenced from <code>build.nsis.include</code>. <b>Always pair customInstall with customUninstall</b> — an uninstall that leaves the key behind puts a dead entry in every user's context menu.</p>
<p class="note">Made by electron-kit's <code>config()</code> from <code>contextMenu</code> in <code>electron-builder.cjs</code>: the installer asks before adding it, and uninstalling takes it away. An app never writes its own <code>installer.nsh</code>.</p>

<h2>The batching problem</h2>
<p class="note"><b>Windows launches one process per selected file.</b> Selecting 30 files spawns 30 processes, 29 of which hit the single-instance lock and forward their path through <code>second-instance</code>. Collect those arrivals and debounce for <code>500ms</code> before handing them to the renderer, or the queue is rebuilt 30 times. Dropgate's <code>BATCH_DEBOUNCE_MS</code> is the reference.</p>
Expand Down
2 changes: 1 addition & 1 deletion docs/design-system/shell/context-menu.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ <h2>How it is registered</h2>
!macro customUninstall
DeleteRegKey HKCR "*\shell\&lt;App&gt;"
!macroend</pre></div>
<p class="note">Lives in <code>installer.nsh</code>, referenced from <code>build.nsis.include</code>. <b>Always pair customInstall with customUninstall</b> — an uninstall that leaves the key behind puts a dead entry in every user's context menu.</p>
<p class="note">Made by electron-kit's <code>config()</code> from <code>contextMenu</code> in <code>electron-builder.cjs</code>: the installer asks before adding it, and uninstalling takes it away. An app never writes its own <code>installer.nsh</code>.</p>

<h2>The batching problem</h2>
<p class="note"><b>Windows launches one process per selected file.</b> Selecting 30 files spawns 30 processes, 29 of which hit the single-instance lock and forward their path through <code>second-instance</code>. Collect those arrivals and debounce for <code>500ms</code> before handing them to the renderer, or the queue is rebuilt 30 times. Dropgate's <code>BATCH_DEBOUNCE_MS</code> is the reference.</p>
Expand Down
61 changes: 61 additions & 0 deletions electron-builder.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"use strict";

// The desktop app's electron-builder config, made by the kit's config() on its
// base (NSIS in the Diamond Digital Development menu folder; AppImage, .deb and
// .rpm). It's .cjs, never .js: on Windows, electron-builder typed in this
// folder would run electron-builder.js with Windows Script Host instead.
//
// - The installer asks who it's for (an install for everyone, as every one
// before 2.0.0-beta.6 was, is upgraded in place), then which of the 22 types
// to open and whether to add "Convert with Diamond File Converter" to the
// menu files and folders have when they're right-clicked. It replaced
// installer.nsh, and keeps its registry key, so an upgrade never shows the
// entry twice. On Linux, the app is in Open With for each type.
// - ffmpeg and ffprobe are packed per platform, where main.js looks for them;
// the packages' own binaries stay out of app.asar.unpacked (415 MB in 2.0.0).
const { config } = require("@diamonddigitaldev/electron-kit/builder");

module.exports = config(require("./package.json"), {
build: {
appId: "com.diamonddigitaldev.diamondfileconverter",
productName: "Diamond File Converter",
artifactName: "Diamond-File-Converter-${version}.${ext}",
files: [
"**/*",
"!test-media",
"!test-media/**/*",
"!node_modules/ffmpeg-static/ffmpeg{,.exe}",
"!node_modules/ffprobe-static/bin/**",
],
publish: {
provider: "github",
owner: "diamonddigitaldev",
repo: "Diamond-File-Converter",
},
win: {
icon: "src/assets/diamondfileconverter.ico",
extraResources: [
{ from: "node_modules/ffmpeg-static/ffmpeg.exe", to: "ffmpeg/ffmpeg.exe" },
{ from: "node_modules/ffprobe-static/bin/win32/x64/ffprobe.exe", to: "ffmpeg/ffprobe.exe" },
],
},
linux: {
icon: "src/assets/diamondfileconverter.png",
category: "AudioVideo",
extraResources: [
{ from: "node_modules/ffmpeg-static/ffmpeg", to: "ffmpeg/ffmpeg" },
{ from: "node_modules/ffprobe-static/bin/linux/x64/ffprobe", to: "ffmpeg/ffprobe" },
],
},
// The installer's name is what its update files point at: unchanged from 2.0.0.
nsis: {
artifactName: "Diamond-File-Converter-Setup-${version}.${ext}",
},
},
fileTypes: [
{ name: "Audio File", ext: ["mp3", "wav", "flac", "ogg", "aac", "m4a", "opus", "wma"] },
{ name: "Video File", ext: ["mp4", "mkv", "webm", "avi", "mov", "wmv", "flv"] },
{ name: "Image File", ext: ["jpg", "jpeg", "png", "webp", "gif", "bmp", "tiff"] },
],
contextMenu: { label: "Convert with Diamond File Converter", folders: true },
});
17 changes: 0 additions & 17 deletions installer.nsh

This file was deleted.

12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

97 changes: 2 additions & 95 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "diamond-file-converter",
"version": "2.0.0-beta.5",
"version": "2.0.0-beta.6",
"description": "An Electron-based desktop app for converting audio, video, and image files.",
"main": "src/main.js",
"funding": {
Expand All @@ -16,99 +16,6 @@
"type": "git",
"url": "https://github.com/diamonddigitaldev/Diamond-File-Converter"
},
"build": {
"extends": "@diamonddigitaldev/electron-kit/builder/base.json",
"appId": "com.diamonddigitaldev.diamondfileconverter",
"files": [
"**/*",
"!test-media",
"!test-media/**/*",
"!node_modules/ffmpeg-static/ffmpeg{,.exe}",
"!node_modules/ffprobe-static/bin/**"
],
"productName": "Diamond File Converter",
"artifactName": "Diamond-File-Converter-${version}.${ext}",
"fileAssociations": [
{
"ext": [
"mp3",
"wav",
"flac",
"ogg",
"aac",
"m4a",
"opus",
"wma"
],
"name": "Audio File",
"role": "Editor"
},
{
"ext": [
"mp4",
"mkv",
"webm",
"avi",
"mov",
"wmv",
"flv"
],
"name": "Video File",
"role": "Editor"
},
{
"ext": [
"jpg",
"jpeg",
"png",
"webp",
"gif",
"bmp",
"tiff"
],
"name": "Image File",
"role": "Editor"
}
],
"publish": {
"provider": "github",
"owner": "diamonddigitaldev",
"repo": "Diamond-File-Converter"
},
"win": {
"icon": "src/assets/diamondfileconverter.ico",
"extraResources": [
{
"from": "node_modules/ffmpeg-static/ffmpeg.exe",
"to": "ffmpeg/ffmpeg.exe"
},
{
"from": "node_modules/ffprobe-static/bin/win32/x64/ffprobe.exe",
"to": "ffmpeg/ffprobe.exe"
}
]
},
"linux": {
"icon": "src/assets/diamondfileconverter.png",
"category": "AudioVideo",
"extraResources": [
{
"from": "node_modules/ffmpeg-static/ffmpeg",
"to": "ffmpeg/ffmpeg"
},
{
"from": "node_modules/ffprobe-static/bin/linux/x64/ffprobe",
"to": "ffmpeg/ffprobe"
}
]
},
"nsis": {
"artifactName": "Diamond-File-Converter-Setup-${version}.${ext}",
"perMachine": true,
"createDesktopShortcut": true,
"include": "installer.nsh"
}
},
"keywords": [],
"author": "Diamond Digital Development <https://diamonddigital.dev>",
"license": "Apache-2.0",
Expand All @@ -117,7 +24,7 @@
"electron-builder": "^26.15.3"
},
"dependencies": {
"@diamonddigitaldev/electron-kit": "0.1.0-beta.3",
"@diamonddigitaldev/electron-kit": "0.1.0-beta.8",
"bootstrap": "^5.3.3",
"electron-store": "^11.0.2",
"electron-updater": "^6.8.9",
Expand Down
3 changes: 3 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ function extensionsOfKind(kind) {
const kit = require("@diamonddigitaldev/electron-kit/main").start({
// package.json's name is the npm name, which names the userData folder too.
name: APP_NAME,
// electron-builder.cjs's appId: Windows shows the app's notifications, and
// groups its windows under its pinned icon, only when the two match.
appId: "com.diamonddigitaldev.diamondfileconverter",
settings: {
defaults: SETTINGS_DEFAULTS,
// Version 2: the settings v1 wrote that 2.0 can't show, and the store
Expand Down
2 changes: 2 additions & 0 deletions src/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2024,6 +2024,8 @@ document.addEventListener("DOMContentLoaded", async () => {
toolbar: $("toolbar"),
credits: { logo: "assets/diamondfileconverter.png" },
onViewChange,
// Restart Now asks first while a conversion or a join runs: the restart would stop it.
busy: () => (converting ? "A conversion is running." : joinRunning ? "A join is running." : null),
});

FORMATS = await api.getFormats();
Expand Down
27 changes: 19 additions & 8 deletions test/kit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,23 @@ test("the updater is the kit's: DFC passes updates, and has no updater or update
assert.equal(version.isOfferableUpdate("1.0.0", "2.0.0-alpha.1", "stable"), false);
});

test("the build extends the kit's base config, and keeps DFC's own", () => {
const pkg = require("../package.json");
assertBuildExtendsKit(pkg);
assert.deepEqual(pkg.build.publish, { provider: "github", owner: "diamonddigitaldev", repo: "Diamond-File-Converter" });
assert.equal(pkg.build.nsis.perMachine, true);
assert.equal(pkg.build.nsis.include, "installer.nsh");
test("the build is the kit's config(), with DFC's own: its 22 types and its right-click entry, on files and folders", () => {
const build = require("../electron-builder.cjs");
assertBuildExtendsKit(build);
assert.equal(require("../package.json").build, undefined, "electron-builder would read package.json's build first");
assert.ok(!fs.existsSync(path.join(__dirname, "..", "installer.nsh")), "the kit's installer adds the right-click entry");
assert.deepEqual(build.publish, { provider: "github", owner: "diamonddigitaldev", repo: "Diamond-File-Converter" });
assert.equal(build.appId, "com.diamonddigitaldev.diamondfileconverter");
// The same ID in main.js, for Windows' notifications and taskbar grouping.
assert.match(read("main.js"), /\.start\(\{[^]*?appId: "com\.diamonddigitaldev\.diamondfileconverter",/);
assert.equal(build.fileAssociations, undefined, "the kit's installer asks for each type instead");
const script = fs.readFileSync(build.nsis.include, "utf8");
for (const ext of ["mp3", "wma", "mp4", "flv", "jpg", "tiff"]) assert.ok(script.includes(`DiamondFileConverter.${ext}`), ext);
assert.equal(script.match(/WriteRegStr SHELL_CONTEXT "Software\\Classes\\\.[a-z0-9]+\\OpenWithProgids"/g)?.length, 22);
// The key installer.nsh wrote, so an install upgraded from it shows the entry once.
assert.ok(script.includes("Software\\Classes\\*\\shell\\DiamondFileConverter"));
assert.ok(script.includes("Software\\Classes\\Directory\\shell\\DiamondFileConverter"));
assert.ok(script.includes("Convert with Diamond File Converter"));
});

test("the Credits tab is given the app's name, not package.json's npm name", () => {
Expand Down Expand Up @@ -161,7 +172,7 @@ test("every icon is hidden from screen readers, and every icon-only button has a
});

test("ffmpeg and ffprobe are packed per platform, where main.js looks for them, and only once", () => {
const { build } = require("../package.json");
const build = require("../electron-builder.cjs");
const main = read("main.js");
const exe = { win: ".exe", linux: "" };
for (const platform of ["win", "linux"]) {
Expand All @@ -179,7 +190,7 @@ test("ffmpeg and ffprobe are packed per platform, where main.js looks for them,
});

test("the Windows installer is the one called Setup: Linux's files are named for the app and version only", () => {
const { build } = require("../package.json");
const build = require("../electron-builder.cjs");
assert.equal(build.artifactName, "Diamond-File-Converter-${version}.${ext}");
// The installer's name is what its update files point at: unchanged from 2.0.0.
assert.equal(build.nsis.artifactName, "Diamond-File-Converter-Setup-${version}.${ext}");
Expand Down
Loading