Skip to content

Commit 313af44

Browse files
authored
feat: add support for adding a custom iso (#43)
* feat: add support for adding a custom iso * fix: type * Fix: types, constants and add button to remove selected iso * feat: tooltip * fix: imports * Fix: show "Custom Windows" instead of "Custom" * fix: constant and make selected semibold * fix constant and label * fix: label
1 parent a9ef6f3 commit 313af44

4 files changed

Lines changed: 73 additions & 9 deletions

File tree

src/renderer/lib/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export const WINDOWS_VERSIONS = {
1414
"10": "Windows 10 Pro",
1515
"10l": "WIndows 10 LTSC 2021",
1616
"10e": "Windows 10 Enterprise",
17+
'custom': 'Custom Windows',
1718
}
1819

1920
export type WindowsVersionKey = keyof typeof WINDOWS_VERSIONS;

src/renderer/lib/install.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,11 @@ export class InstallManager {
124124
composeContent.services.windows.environment.LANGUAGE = this.conf.windowsLanguage;
125125
composeContent.services.windows.environment.USERNAME = this.conf.username;
126126
composeContent.services.windows.environment.PASSWORD = this.conf.password;
127-
128-
127+
128+
if (this.conf.customIsoPath) {
129+
composeContent.services.windows.volumes.push(`${this.conf.customIsoPath}:/boot.iso`);
130+
}
131+
129132
// Write the compose file
130133
const composeYAML = YAML.stringify(composeContent).replaceAll("null", "");
131134
fs.writeFileSync(composeFilePath, composeYAML, { encoding: 'utf8' });

src/renderer/views/SetupUI.vue

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,31 +133,38 @@
133133
<p class="text-lg text-gray-400">
134134
Pick the version of Windows you want to install, and the language you'd like to use.
135135
</p>
136-
137136
<p class="text-lg text-gray-400">
138137
You can only change these settings now. Once the installation is complete, you will not be able to change them unless you reinstall.
139138
</p>
140-
141-
142139
<div>
143140
<label for="select-edition" class="text-sm mb-4 text-neutral-400">Select Edition</label>
144-
<x-select id="select-edition" @change="(e: any) => windowsVersion = e.detail.newValue" class="w-64">
141+
<x-select
142+
id="select-edition"
143+
@change="(e: any) => windowsVersion = e.detail.newValue"
144+
class="w-64"
145+
:disabled="!!customIsoPath"
146+
>
145147
<x-menu>
146148
<x-menuitem
147149
v-for="(version, key) in WINDOWS_VERSIONS"
148150
:key="key"
149151
:value="key"
150152
:toggled="windowsVersion === key"
153+
v-show="key !== 'custom'"
151154
>
152155
<x-label>{{ version }}</x-label>
153156
</x-menuitem>
154157
</x-menu>
155158
</x-select>
156159
</div>
157-
158160
<div>
159161
<label for="select-language" class="text-sm mb-4 text-neutral-400">Select Language</label>
160-
<x-select id="select-language" @change="(e: any) => windowsLanguage = e.detail.newValue" class="w-64">
162+
<x-select
163+
id="select-language"
164+
@change="(e: any) => windowsLanguage = e.detail.newValue"
165+
class="w-64"
166+
:disabled="!!customIsoPath"
167+
>
161168
<x-menu @change="(e: any) => windowsLanguage = e.detail.newValue">
162169
<x-menuitem
163170
v-for="(language, languageWithBanner) in WINDOWS_LANGUAGES"
@@ -176,7 +183,24 @@
176183
</x-menu>
177184
</x-select>
178185
</div>
179-
186+
<div class="mt-4">
187+
<div class="flex flex-col gap-2">
188+
<label for="select-iso" class="text-xs text-neutral-400">Custom ISO (Optional)</label>
189+
<div class="flex items-center gap-2">
190+
<x-button id="select-iso" class="w-64 text-sm" @click="selectIsoFile">Select ISO File</x-button>
191+
<span class="relative group">
192+
<Icon icon="line-md:question-circle" class="text-neutral-400 cursor-pointer" />
193+
<span class="absolute left-6 top-1 z-50 w-[320px] bg-neutral-900 text-xs text-gray-300 rounded shadow-lg px-3 py-2 opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none">
194+
We offer you the possibility of using a custom Windows ISO for your convenience, however we can't provide any support if your custom ISO breaks or certain features within WinBoat stop working.
195+
</span>
196+
</span>
197+
</div>
198+
<span v-if="customIsoPath" class="text-xs text-gray-400 font-semibold flex items-center gap-2">
199+
Selected: {{ customIsoFileName }}
200+
<x-button size="small" class="ml-2 px-2 py-0" @click="deselectIsoFile">Remove</x-button>
201+
</span>
202+
</div>
203+
</div>
180204
<div class="flex flex-row gap-4 mt-6">
181205
<x-button class="px-6" @click="currentStepIdx--">Back</x-button>
182206
<x-button toggled class="px-6" @click="currentStepIdx++">Next</x-button>
@@ -410,6 +434,9 @@ import { WINDOWS_VERSIONS, WINDOWS_LANGUAGES, type WindowsVersionKey } from "../
410434
import { InstallManager, type InstallState, InstallStates } from '../lib/install';
411435
import { openAnchorLink } from '../utils/openLink';
412436
import license from '../assets/LICENSE.txt?raw'
437+
438+
const path: typeof import('path') = require('path')
439+
const electron: typeof import('electron') = require('electron').remote || require('@electron/remote');
413440
const os: typeof import('os') = require('os');
414441
415442
type Step = {
@@ -487,6 +514,8 @@ const currentStepIdx = ref(0);
487514
const currentStep = computed(() => steps[currentStepIdx.value]);
488515
const windowsVersion = ref<WindowsVersionKey>("11");
489516
const windowsLanguage = ref("English");
517+
const customIsoPath = ref("");
518+
const customIsoFileName = ref("");
490519
const cpuThreads = ref(2);
491520
const ramGB = ref(4);
492521
const diskSpaceGB = ref(32);
@@ -502,6 +531,35 @@ onMounted(async () => {
502531
console.log("Username", username.value);
503532
})
504533
534+
function selectIsoFile() {
535+
electron.dialog.showOpenDialog({
536+
title: 'Select ISO File',
537+
filters: [
538+
{
539+
name: 'ISO Files',
540+
extensions: ['iso']
541+
}
542+
],
543+
properties: ['openFile']
544+
})
545+
.then(result => {
546+
if (!result.canceled && result.filePaths.length > 0) {
547+
customIsoPath.value = result.filePaths[0];
548+
customIsoFileName.value = path.basename(result.filePaths[0]);
549+
windowsLanguage.value = 'English'; // Language can't be custom
550+
windowsVersion.value = 'custom';
551+
console.log('ISO path updated:', customIsoPath.value);
552+
}
553+
});
554+
}
555+
556+
function deselectIsoFile() {
557+
customIsoPath.value = "";
558+
customIsoFileName.value = "";
559+
windowsLanguage.value = 'English';
560+
windowsVersion.value = '11';
561+
}
562+
505563
function install() {
506564
const installConfig: InstallConfiguration = {
507565
windowsVersion: windowsVersion.value,
@@ -511,6 +569,7 @@ function install() {
511569
diskSpaceGB: diskSpaceGB.value,
512570
username: username.value,
513571
password: password.value,
572+
...(customIsoPath.value ? { customIsoPath: customIsoPath.value } : {}),
514573
}
515574
516575
// Begin installation and attach event listeners

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export type InstallConfiguration = {
2121
diskSpaceGB: number;
2222
username: string;
2323
password: string;
24+
customIsoPath?: string;
2425
}
2526

2627
export type WinApp = {

0 commit comments

Comments
 (0)