diff --git a/build/installer.nsh b/build/installer.nsh new file mode 100644 index 0000000..32d47b6 --- /dev/null +++ b/build/installer.nsh @@ -0,0 +1,110 @@ +!include LogicLib.nsh +!include nsDialogs.nsh + +Var StepForgeDesktopShortcutCheckbox +Var StepForgeDesktopShortcutState + +!ifndef BUILD_UNINSTALLER + ; Assisted installer page for the desktop shortcut choice. + !macro customInit + StrCpy $StepForgeDesktopShortcutState "true" + ${If} ${isNoDesktopShortcut} + StrCpy $StepForgeDesktopShortcutState "false" + ${EndIf} + !macroend + + !macro customHeader + Function StepForgeDesktopShortcutPagePre + !insertmacro MUI_PAGE_FUNCTION_CUSTOM PRE + !insertmacro MUI_HEADER_TEXT "Desktop Icon" "Choose whether StepForge creates a desktop icon." + + nsDialogs::Create 1018 + Pop $0 + ${If} $0 == error + Abort + ${EndIf} + + ${NSD_CreateLabel} 0u 0u 280u 24u "StepForge can create a desktop icon for quick access from the desktop." + Pop $0 + + ${NSD_CreateCheckbox} 0u 34u 280u 12u "Create a desktop icon" + Pop $StepForgeDesktopShortcutCheckbox + + StrCpy $StepForgeDesktopShortcutState "true" + ${If} ${isNoDesktopShortcut} + StrCpy $StepForgeDesktopShortcutState "false" + EnableWindow $StepForgeDesktopShortcutCheckbox 0 + ${Else} + ReadRegStr $0 SHELL_CONTEXT "${INSTALL_REGISTRY_KEY}" CreateDesktopShortcut + ${If} $0 == "false" + StrCpy $StepForgeDesktopShortcutState "false" + ${Else} + ReadRegStr $1 SHELL_CONTEXT "${INSTALL_REGISTRY_KEY}" ShortcutName + ${If} $1 == "" + StrCpy $1 "${SHORTCUT_NAME}" + ${EndIf} + + ${If} ${FileExists} "$DESKTOP\$1.lnk" + StrCpy $StepForgeDesktopShortcutState "true" + ${ElseIf} ${FileExists} "$INSTDIR\${APP_EXECUTABLE_FILENAME}" + StrCpy $StepForgeDesktopShortcutState "false" + ${EndIf} + ${EndIf} + ${EndIf} + + ${If} $StepForgeDesktopShortcutState == "false" + SendMessage $StepForgeDesktopShortcutCheckbox ${BM_SETCHECK} ${BST_UNCHECKED} 0 + ${Else} + SendMessage $StepForgeDesktopShortcutCheckbox ${BM_SETCHECK} ${BST_CHECKED} 0 + ${EndIf} + + !insertmacro MUI_PAGE_FUNCTION_CUSTOM SHOW + nsDialogs::Show + FunctionEnd + + Function StepForgeDesktopShortcutPageLeave + !insertmacro MUI_PAGE_FUNCTION_CUSTOM LEAVE + + SendMessage $StepForgeDesktopShortcutCheckbox ${BM_GETCHECK} 0 0 $StepForgeDesktopShortcutState + ${If} $StepForgeDesktopShortcutState == ${BST_UNCHECKED} + StrCpy $StepForgeDesktopShortcutState "false" + ${Else} + StrCpy $StepForgeDesktopShortcutState "true" + ${EndIf} + FunctionEnd + !macroend + + !macro customPageAfterChangeDir + !insertmacro MUI_PAGE_INIT + PageEx custom + PageCallbacks StepForgeDesktopShortcutPagePre StepForgeDesktopShortcutPageLeave + Caption " " + PageExEnd + !macroend + + !macro customInstall + ; Reconcile the desktop shortcut after the default installer logic runs. + ${If} ${isNoDesktopShortcut} + StrCpy $StepForgeDesktopShortcutState "false" + ${EndIf} + + WriteRegStr SHELL_CONTEXT "${INSTALL_REGISTRY_KEY}" CreateDesktopShortcut "$StepForgeDesktopShortcutState" + + ${If} $StepForgeDesktopShortcutState == "false" + Delete "$newDesktopLink" + Delete "$oldDesktopLink" + ${Else} + ${IfNot} ${FileExists} "$newDesktopLink" + ${If} ${FileExists} "$oldDesktopLink" + Rename "$oldDesktopLink" "$newDesktopLink" + ${Else} + CreateShortCut "$newDesktopLink" "$appExe" "" "$appExe" 0 "" "" "${APP_DESCRIPTION}" + ${EndIf} + ClearErrors + WinShell::SetLnkAUMI "$newDesktopLink" "${APP_ID}" + ${EndIf} + ${EndIf} + + System::Call 'shell32::SHChangeNotify(i 0x08000000, i 0, i 0, i 0)' + !macroend +!endif diff --git a/package-lock.json b/package-lock.json index 9cc3468..b21f5fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "stepforge", - "version": "0.1.0", + "version": "0.3.2.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "stepforge", - "version": "0.1.0", + "version": "0.3.2.1", "license": "MPL-2.0", "dependencies": { "@tesseract.js-data/eng": "^1.0.0", diff --git a/package.json b/package.json index 585df32..7ed31dd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "stepforge", - "version": "0.1.0", + "version": "0.3.2.1", "description": "Fully offline desktop tool for capturing, annotating, and exporting step-by-step guides.", "main": "app/main.js", "author": "StepForge tyler@twestbrook.com", diff --git a/scripts/package-windows.js b/scripts/package-windows.js index 4d8883f..f37cec0 100644 --- a/scripts/package-windows.js +++ b/scripts/package-windows.js @@ -52,6 +52,7 @@ function createWindowsInstallerConfig(outputDir) { createDesktopShortcut: true, createStartMenuShortcut: true, shortcutName: 'StepForge', + include: 'build/installer.nsh', }, }; } diff --git a/tests/unit/capture-worker.test.js b/tests/unit/capture-worker.test.js index ebae4e7..ab1bf04 100644 --- a/tests/unit/capture-worker.test.js +++ b/tests/unit/capture-worker.test.js @@ -128,7 +128,8 @@ test('capture worker requests the selected desktop source, not a plain camera st await streamReady; assert.equal(mediaCalls.length, 1); - assert.deepEqual(mediaCalls[0], { + const constraints = JSON.parse(JSON.stringify(mediaCalls[0])); + assert.deepEqual(constraints, { audio: false, video: { mandatory: { diff --git a/tests/unit/package-windows.test.js b/tests/unit/package-windows.test.js index 4699b40..123e557 100644 --- a/tests/unit/package-windows.test.js +++ b/tests/unit/package-windows.test.js @@ -21,6 +21,7 @@ test('Windows packaging uses an assisted NSIS installer', (t) => { assert.equal(config.nsis.createDesktopShortcut, true); assert.equal(config.nsis.createStartMenuShortcut, true); assert.equal(config.nsis.shortcutName, 'StepForge'); + assert.equal(config.nsis.include, 'build/installer.nsh'); assert.equal(config.asar, true); assert.ok(config.files.includes('app/**/*')); assert.ok(config.files.includes('core/**/*'));