diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ad42479..3c4b4db 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,28 +1,12 @@ name: Build Electron App on: - push: - tags: - - 'v*' pull_request: - issue_comment: - types: [created] - -env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + types: [synchronize] # This will trigger the workflow on new commits to the PR jobs: - build: - if: | - github.event_name == 'push' || - github.event_name == 'pull_request' || - (github.event_name == 'issue_comment' && - github.event.issue.pull_request != null && - contains(github.event.comment.body, '/build')) + build-linux: runs-on: ubuntu-latest - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] steps: - name: Checkout repository @@ -34,66 +18,88 @@ jobs: node-version: '18' - name: Clear NPM Cache - run: npm cache clean --force + run: | + npm cache clean --force - name: Install dependencies - run: npm install + run: | + npm install - - name: Build Electron App + - name: Build Linux AppImage run: | - if [[ "${{ matrix.os }}" == "ubuntu-latest" ]]; then - npm run build:linux - elif [[ "${{ matrix.os }}" == "windows-latest" ]]; then - npm run build:win - elif [[ "${{ matrix.os }}" == "macos-latest" ]]; then - npm run build:mac - fi - - - name: Upload Artifact + npm run build:linux + + - name: Upload Linux AppImage uses: actions/upload-artifact@v4 with: - name: jg-desktop-${{ matrix.os }} - path: | - dist/*.AppImage - dist/*.exe - dist/*.dmg - - create-release: - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') - needs: build - runs-on: ubuntu-latest + name: jg-desktop-linux + path: dist/*.AppImage + + - name: List Linux dist directory + run: ls -la dist # List contents after building + + build-windows: + runs-on: windows-latest steps: - name: Checkout repository uses: actions/checkout@v2 - - name: Download Linux AppImage - uses: actions/download-artifact@v4 + - name: Set up Node.js + uses: actions/setup-node@v3 with: - name: jg-desktop-ubuntu-latest - path: ./dist + node-version: '18' - - name: Download Windows Installer - uses: actions/download-artifact@v4 + - name: Clear NPM Cache + run: | + npm cache clean --force + + - name: Install dependencies + run: | + npm install + + - name: Build Windows Packages + run: | + npm run build:win + + - name: Upload Windows Installer + uses: actions/upload-artifact@v4 with: - name: jg-desktop-windows-latest - path: ./dist + name: jg-desktop-windows + path: dist/*.exe - - name: Download macOS Package - uses: actions/download-artifact@v4 + - name: List Windows dist directory + run: dir dist # List contents after building + + build-macos: + runs-on: macos-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v3 with: - name: jg-desktop-macos-latest - path: ./dist + node-version: '18' - - name: List files in dist directory for debugging - run: ls -la ./dist + - name: Clear NPM Cache + run: | + npm cache clean --force + + - name: Install dependencies + run: | + npm install - - name: Create GitHub Release - env: - GH_TOKEN: ${{ secrets.GH_TOKEN }} + - name: Build macOS Packages run: | - TAG_NAME="${{ github.ref_name }}" - gh release create "$TAG_NAME" \ - --title "$TAG_NAME" \ - --notes "Release for $TAG_NAME" \ - ./dist/* + npm run build:mac + + - name: Upload macOS Package + uses: actions/upload-artifact@v4 + with: + name: jg-desktop-macos + path: dist/*.dmg + + - name: List macOS dist directory + run: ls -la dist # List contents after building diff --git a/config.json b/config.json index dc580e9..495953f 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,9 @@ { "url": "https://jublaglattbrugg.ch", - "allowedDomains": ["jublaglattbrugg.ch", "www.jublaglattbrugg.ch", "www.jubla.ch"], + "allowedDomains": ["jublaglattbrugg.ch", "www.jublaglattbrugg.ch", "www.jubla.ch", "toolbox.jublaglattbrugg.ch"], "url_help": "https://jublaglattbrugg.ch/jg-desktop-help", - "url_Agenda": "jgdesktop://jublaglattbrugg.ch/agenda" + "url_Agenda": "jgdesktop://jublaglattbrugg.ch/agenda", + "keywords": { + "neos": "jgdesktop://jublaglattbrugg.ch/neos" + } } diff --git a/main.js b/main.js index 5be55a3..98c5182 100644 --- a/main.js +++ b/main.js @@ -1,4 +1,4 @@ -const { app, BrowserWindow, Menu, shell, dialog } = require('electron'); +const { app, BrowserWindow, Menu, shell, dialog, globalShortcut, ipcMain } = require('electron'); const path = require('path'); const fs = require('fs'); @@ -35,6 +35,9 @@ function createWindow(url = config.url) { // Create the application menu createMenu(); + + // Register shortcut to open popup + globalShortcut.register('Control+O', openPopup); } // Function to create the application menu @@ -46,9 +49,9 @@ function createMenu() { { label: 'Agenda', click: () => { - shell.openExternal(config.url_Agenda); + loadUrlInWindow(mainWindow, config.link_Agenda); } - } + }, ] }, { @@ -60,33 +63,25 @@ function createMenu() { shell.openExternal(config.url); } }, - { type: 'separator' }, + { + type: 'separator' + }, { label: 'Beenden', - accelerator: 'Command+Q', // For macOS + accelerator: 'Command+Q', click: () => { app.quit(); } } ] }, - { - label: 'Bearbeiten', - submenu: [ - { label: 'Rückgängig', accelerator: 'Command+Z', role: 'undo' }, - { label: 'Wiederholen', accelerator: 'Shift+Command+Z', role: 'redo' }, - { type: 'separator' }, - { label: 'Kopieren', accelerator: 'Command+C', role: 'copy' }, - { label: 'Einfügen', accelerator: 'Command+V', role: 'paste' } - ] - }, { label: 'Hilfe', submenu: [ { label: 'Fehler melden', click: () => { - shell.openExternal('config.url_help'); + shell.openExternal(config.url_help); } }, { @@ -95,7 +90,7 @@ function createMenu() { dialog.showMessageBox(mainWindow, { type: 'info', title: 'Über Jubla Glattbrugg', - message: 'Die offizielle Desktop-App für Jubla Glattbrugg\nVersion 0.0.7', + message: 'Die offizielle Desktop-App für Jubla Glattbrugg\nVersion 0.0.8', buttons: ['OK'] }); } @@ -108,8 +103,84 @@ function createMenu() { Menu.setApplicationMenu(menu); } +// Function to open the popup for URL entry +function openPopup() { + const popupWindow = new BrowserWindow({ + width: 400, + height: 200, + parent: mainWindow, + modal: true, + webPreferences: { + nodeIntegration: true, + contextIsolation: false, + } + }); + + const htmlContent = ` + + +

Open URL

+ + + + + + `; + + popupWindow.loadURL(`data:text/html;charset=UTF-8,${encodeURIComponent(htmlContent)}`); + + // Handle keyword submission + ipcMain.on('keyword-submitted', (event, keyword) => { + if (!popupWindow.isDestroyed()) { // Check if the window is still open + popupWindow.close(); // Close the window after processing + const url = config.keywords[keyword]; // Retrieve the URL based on the keyword + if (url) { + openProtocolLink(url); + } else { + dialog.showMessageBox(mainWindow, { + type: 'error', + title: 'Ungültiges Schlüsselwort', + message: 'Das eingegebene Schlüsselwort ist ungültig oder nicht konfiguriert.' + }); + } + } + }); + + // Handle window closed event + popupWindow.on('closed', () => { + // Remove the IPC listener when the popup is closed + ipcMain.removeAllListeners('keyword-submitted'); + }); +} + +// Function to handle protocol link and validate domain +function openProtocolLink(url) { + const formattedUrl = formatUrl(url); + if (isAllowedUrl(formattedUrl)) { + loadUrlInWindow(mainWindow, formattedUrl); + } else { + dialog.showMessageBox(mainWindow, { + type: 'warning', + title: 'URL nicht erlaubt', + message: `Die Seite "${formattedUrl}" kann nicht in der Desktop App geöffnet werden.`, + buttons: ['In Browser öffnen', 'Zurück zur Startseite'] + }).then(result => { + if (result.response === 0) { + shell.openExternal(formattedUrl); + } else { + loadUrlInWindow(mainWindow, config.url); + } + }); + } +} -// Function to load a URL into the window with a loader +// Function to load a URL into the window function loadUrlInWindow(window, url) { const loaderHtml = `