From b9ac324d21829a95dae5957285e375d89223610b Mon Sep 17 00:00:00 2001 From: Richard Toth Date: Sun, 6 Sep 2026 11:08:16 +0200 Subject: [PATCH] release 1.1.3 --- .github/workflows/release.yml | 121 +++++++++++++++++++++++----- package-lock.json | 14 +++- package.json | 3 +- snap/snapcraft.yaml | 34 ++++++++ src-tauri/Cargo.lock | 94 +++++++++++++++++---- src-tauri/Cargo.toml | 11 +-- src-tauri/capabilities/default.json | 3 +- src-tauri/capabilities/desktop.json | 3 +- src-tauri/src/lib.rs | 1 + src-tauri/tauri.conf.json | 2 +- src/app/app.component.ts | 78 +++++++++++++----- src/app/i18n/translations.ts | 14 ++-- src/app/tab3/tab3.page.html | 2 +- 13 files changed, 309 insertions(+), 71 deletions(-) create mode 100644 snap/snapcraft.yaml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c7a158b..42f21df 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,9 +12,12 @@ concurrency: cancel-in-progress: true env: - CN_APPLICATION: "trweb/court-pilot" + CN_APPLICATION: 'trweb/court-pilot' jobs: + # --------------------------------------------------------- + # Create CrabNebula draft release + # --------------------------------------------------------- draft: runs-on: ubuntu-22.04 @@ -27,18 +30,13 @@ jobs: command: release draft ${{ env.CN_APPLICATION }} --framework tauri api-key: ${{ secrets.CN_API_KEY }} - build: + # --------------------------------------------------------- + # Windows Tauri build + # --------------------------------------------------------- + windows: needs: draft - strategy: - fail-fast: false - - matrix: - os: - - ubuntu-22.04 - - windows-latest - - runs-on: ${{ matrix.os }} + runs-on: windows-latest steps: - name: Checkout @@ -56,16 +54,6 @@ jobs: toolchain: stable cache: true - - name: Install Linux dependencies - if: matrix.os == 'ubuntu-22.04' - run: | - sudo apt-get update - sudo apt-get install -y \ - webkit2gtk-4.1 \ - libappindicator3-dev \ - librsvg2-dev \ - patchelf - - name: Install dependencies run: npm ci @@ -85,8 +73,97 @@ jobs: api-key: ${{ secrets.CN_API_KEY }} path: ./src-tauri + # --------------------------------------------------------- + # Linux Tauri build + Snap + # --------------------------------------------------------- + snap: + needs: draft + + runs-on: ubuntu-22.04 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + + - name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + cache: true + + - name: Install Linux dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + libssl-dev \ + libxdo-dev \ + libayatana-appindicator3-dev \ + librsvg2-dev \ + libwebkit2gtk-4.1-dev \ + dpkg + + - name: Install dependencies + run: npm ci + + - name: Install Ionic CLI + run: npm install -g @ionic/cli + + - name: Build Tauri Debian package + env: + TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + run: npm run tauri build -- --bundles deb + + - name: Extract Debian package + run: | + rm -rf snap-root + mkdir -p snap-root + + dpkg -x src-tauri/target/release/bundle/deb/*.deb snap-root/ + + - name: Show extracted Snap filesystem + run: | + echo "Snap root:" + find snap-root -maxdepth 5 -type f | sort + + - name: Build Snap + uses: snapcore/action-build@v1 + id: snapcraft + with: + snapcraft-channel: stable + + - name: Show generated Snap + run: | + echo "Snap created:" + echo "${{ steps.snapcraft.outputs.snap }}" + + - name: Upload Snap as GitHub artifact + uses: actions/upload-artifact@v4 + with: + name: court-pilot-snap + path: ${{ steps.snapcraft.outputs.snap }} + + - name: Publish Snap to Snap Store + uses: snapcore/action-publish@v1 + env: + SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }} + with: + snap: ${{ steps.snapcraft.outputs.snap }} + release: edge + + # --------------------------------------------------------- + # Publish CrabNebula release + # --------------------------------------------------------- publish: - needs: build + needs: + - windows + - snap runs-on: ubuntu-22.04 diff --git a/package-lock.json b/package-lock.json index 9291f1c..7cb51b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "court-pilot", - "version": "0.0.1", + "version": "1.1.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "court-pilot", - "version": "0.0.1", + "version": "1.1.2", "dependencies": { "@angular/animations": "^20.3.28", "@angular/cdk": "^20.2.14", @@ -23,6 +23,7 @@ "@capacitor/keyboard": "8.0.3", "@capacitor/status-bar": "8.0.2", "@ionic/angular": "^8.0.0", + "@tauri-apps/plugin-os": "^2.3.2", "@tauri-apps/plugin-process": "^2.3.1", "@tauri-apps/plugin-updater": "^2.10.1", "dexie": "^4.4.2", @@ -6833,6 +6834,15 @@ "node": ">= 10" } }, + "node_modules/@tauri-apps/plugin-os": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.3.2.tgz", + "integrity": "sha512-n+nXWeuSeF9wcEsSPmRnBEGrRgOy6jjkSU+UVCOV8YUGKb2erhDOxis7IqRXiRVHhY8XMKks00BJ0OAdkpf6+A==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, "node_modules/@tauri-apps/plugin-process": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-process/-/plugin-process-2.3.1.tgz", diff --git a/package.json b/package.json index 6cb2ca9..ccf01fa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "court-pilot", - "version": "1.1.2", + "version": "1.1.3", "author": "Ionic Framework", "homepage": "https://ionicframework.com/", "scripts": { @@ -29,6 +29,7 @@ "@capacitor/keyboard": "8.0.3", "@capacitor/status-bar": "8.0.2", "@ionic/angular": "^8.0.0", + "@tauri-apps/plugin-os": "^2.3.2", "@tauri-apps/plugin-process": "^2.3.1", "@tauri-apps/plugin-updater": "^2.10.1", "dexie": "^4.4.2", diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml new file mode 100644 index 0000000..29be844 --- /dev/null +++ b/snap/snapcraft.yaml @@ -0,0 +1,34 @@ +name: court-pilot +base: core22 + +version: '1.1.2' + +summary: Badminton umpire rotation application + +description: | + Court Pilot is a desktop application for managing badminton + umpire rotations and court assignments. + +grade: stable +confinement: strict + +apps: + court-pilot: + command: usr/bin/court-pilot + desktop: usr/share/applications/court-pilot.desktop + + extensions: + - gnome + + plugs: + - network + - home + +parts: + court-pilot: + plugin: dump + source: snap-root + + stage-packages: + - libwebkit2gtk-4.1-0 + - libayatana-appindicator3-1 diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 05e5ab3..8bee091 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -75,20 +75,6 @@ version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" -[[package]] -name = "app" -version = "0.1.0" -dependencies = [ - "log", - "serde", - "serde_json", - "tauri", - "tauri-build", - "tauri-plugin-log", - "tauri-plugin-process", - "tauri-plugin-updater", -] - [[package]] name = "arbitrary" version = "1.4.2" @@ -514,6 +500,21 @@ dependencies = [ "libc", ] +[[package]] +name = "court-pilot" +version = "0.1.0" +dependencies = [ + "log", + "serde", + "serde_json", + "tauri", + "tauri-build", + "tauri-plugin-log", + "tauri-plugin-os", + "tauri-plugin-process", + "tauri-plugin-updater", +] + [[package]] name = "cpufeatures" version = "0.2.17" @@ -1183,6 +1184,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "gethostname" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" +dependencies = [ + "rustix", + "windows-link 0.2.1", +] + [[package]] name = "getrandom" version = "0.2.17" @@ -2055,6 +2066,18 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" +dependencies = [ + "bitflags 2.11.1", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "num-conv" version = "0.2.1" @@ -2327,6 +2350,22 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "os_info" +version = "3.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf20a545b305cf1da722b236b5155c9bb35f1d5ceb28c048bd96ca842f41b5b" +dependencies = [ + "android_system_properties", + "log", + "nix", + "objc2", + "objc2-foundation", + "objc2-ui-kit", + "serde", + "windows-sys 0.61.2", +] + [[package]] name = "osakit" version = "0.3.1" @@ -3478,6 +3517,15 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "sys-locale" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4" +dependencies = [ + "libc", +] + [[package]] name = "system-deps" version = "6.2.2" @@ -3716,6 +3764,24 @@ dependencies = [ "time", ] +[[package]] +name = "tauri-plugin-os" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8f08346c8deb39e96f86973da0e2d76cbb933d7ac9b750f6dc4daf955a6f997" +dependencies = [ + "gethostname", + "log", + "os_info", + "serde", + "serde_json", + "serialize-to-javascript", + "sys-locale", + "tauri", + "tauri-plugin", + "thiserror 2.0.18", +] + [[package]] name = "tauri-plugin-process" version = "2.3.1" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 00bba35..0f28775 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,10 +1,10 @@ [package] -name = "app" +name = "court-pilot" version = "0.1.0" -description = "A Tauri App" -authors = ["you"] -license = "" -repository = "" +description = "Court Pilot" +authors = ["Richard Toth"] +license = "MIT" +repository = "https://github.com/tricsusz/court-pilot" edition = "2021" rust-version = "1.77.2" @@ -24,6 +24,7 @@ log = "0.4" tauri = { version = "2.11.2", features = [] } tauri-plugin-log = "2" tauri-plugin-process = "2" +tauri-plugin-os = "2" [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] tauri-plugin-updater = "2" diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index 40da078..1aadf7f 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -7,6 +7,7 @@ ], "permissions": [ "core:default", - "process:default" + "process:default", + "os:default" ] } \ No newline at end of file diff --git a/src-tauri/capabilities/desktop.json b/src-tauri/capabilities/desktop.json index ba6d080..e5baac3 100644 --- a/src-tauri/capabilities/desktop.json +++ b/src-tauri/capabilities/desktop.json @@ -9,6 +9,7 @@ "main" ], "permissions": [ - "updater:default" + "updater:default", + "os:default" ] } \ No newline at end of file diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index f2d3d5a..60b6230 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1,6 +1,7 @@ #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() + .plugin(tauri_plugin_os::init()) .plugin(tauri_plugin_process::init()) .plugin(tauri_plugin_updater::Builder::new().build()) .setup(|app| { diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 68356e6..b6c9ed3 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "../node_modules/@tauri-apps/cli/config.schema.json", "productName": "court-pilot", - "version": "1.1.2", + "version": "1.1.3", "identifier": "com.courtpilot.dev", "build": { "frontendDist": "../www", diff --git a/src/app/app.component.ts b/src/app/app.component.ts index f2b23f6..7991818 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -2,13 +2,17 @@ import { Component, inject } from '@angular/core'; import { AlertController, IonApp, - IonRouterOutlet + IonRouterOutlet, + LoadingController } from '@ionic/angular/standalone'; -import { check } from '@tauri-apps/plugin-updater'; +import { check, DownloadEvent } from '@tauri-apps/plugin-updater'; import { isTauri } from '@tauri-apps/api/core'; +import { platform } from '@tauri-apps/plugin-os'; import { relaunch } from '@tauri-apps/plugin-process'; import { TranslationService } from './i18n/translation.service'; + + @Component({ selector: 'app-root', templateUrl: 'app.component.html', @@ -16,6 +20,7 @@ import { TranslationService } from './i18n/translation.service'; }) export class AppComponent { readonly alertController: AlertController = inject(AlertController); + readonly loadingController: LoadingController = inject(LoadingController); readonly translationService: TranslationService = inject(TranslationService); constructor() { @@ -27,6 +32,11 @@ export class AppComponent { return; } + // Snap handles updates on Linux. + if (platform() === 'linux') { + return; + } + try { const update = await check(); @@ -40,29 +50,61 @@ export class AppComponent { { text: 'OK', handler: async () => { + const loading = await this.loadingController.create({ + message: + this.translationService.translate('updateDownloading'), + spinner: 'crescent', + backdropDismiss: false + }); + + await loading.present(); + + let downloaded = 0; + let total = 0; + try { - // Show loading message - alert.message = - this.translationService.translate('updateDownloading'); + await update.downloadAndInstall((event: DownloadEvent) => { + switch (event.event) { + case 'Started': + total = event.data.contentLength ?? 0; + downloaded = 0; + break; - // Disable the button while updating - const okButton = alert.buttons[0]; - if (typeof okButton !== 'string') { - okButton.htmlAttributes = { disabled: true }; - } + case 'Progress': + downloaded += event.data.chunkLength; - await update.downloadAndInstall(); + if (total > 0) { + const percent = Math.min( + 100, + Math.round((downloaded / total) * 100) + ); + + loading.message = `${this.translationService.translate('updateDownloading')} ${percent}%`; + } + + break; + + case 'Finished': + loading.message = + this.translationService.translate('updateInstalling'); + break; + } + }); + + await loading.dismiss(); await relaunch(); } catch (error) { console.error('Failed to install update:', error); - alert.message = - this.translationService.translate('updateFailed'); - const okButton = alert.buttons[0]; - // Re-enable the button if the update failed - if (typeof okButton !== 'string') { - okButton.htmlAttributes = { disabled: false }; - } + await loading.dismiss(); + + const errorAlert = await this.alertController.create({ + header: this.translationService.translate('updateFailed'), + message: String(error), + buttons: ['OK'] + }); + + await errorAlert.present(); } } } diff --git a/src/app/i18n/translations.ts b/src/app/i18n/translations.ts index ce35e06..ab4b6bd 100644 --- a/src/app/i18n/translations.ts +++ b/src/app/i18n/translations.ts @@ -42,11 +42,13 @@ export const translations = { sendUmpiresMessage: '{umpire} - {serviceJudge}', version: 'Version', updateAvailable: 'Update available', - newVersion: 'A new version {version} is available. The application will restart to install the update.', + newVersion: + 'A new version {version} is available. The application will restart to install the update.', english: 'English', hungarian: 'Hungarian', - updateDownloading: 'Downloading and installing update...', - updateFailed: 'Failed to install the update. Please try again.', + updateDownloading: 'Downloading update...', + updateInstalling: 'Installing update...', + updateFailed: 'Failed to install the update. Please try again.' }, hu: { @@ -87,11 +89,13 @@ export const translations = { sendUmpiresMessage: '{umpire} - {serviceJudge}', version: 'Verzió', updateAvailable: 'Új verzió elérhető', - newVersion: 'Új elérhető verzió: {version}. A frissítések telepítése után az alkalmazás újraindul.', + newVersion: + 'Új elérhető verzió: {version}. A frissítések telepítése után az alkalmazás újraindul.', english: 'Angol', hungarian: 'Magyar', - updateDownloading: 'Frissítés letöltése és telepítése...', + updateDownloading: 'Frissítés letöltése...', updateFailed: 'Frissítés sikertelen. Kérlek próbáld újra.', + updateInstalling: 'Frissítés telepítése...' } } as const; diff --git a/src/app/tab3/tab3.page.html b/src/app/tab3/tab3.page.html index 4946ba8..ac7af49 100644 --- a/src/app/tab3/tab3.page.html +++ b/src/app/tab3/tab3.page.html @@ -62,7 +62,7 @@ {{ 'version' | translate }}: 1.1.2{{ 'version' | translate }}: 1.1.3