mirror of
https://github.com/arabianq/pipewire-soundpad.git
synced 2026-04-28 06:21:23 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 86b38a250e | |||
| 54fa278cea | |||
| db040aa820 | |||
| 04449e7525 | |||
| 9f50809a99 | |||
| 7dda4bc2b1 | |||
| 1569955e12 | |||
| 9adc6cfbda | |||
| 76b1d4f345 | |||
| 10f9937dc3 | |||
| 498c09eb50 |
@@ -0,0 +1,88 @@
|
|||||||
|
name: Flatter
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main, master ]
|
||||||
|
release:
|
||||||
|
types: [ published ]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
tag_name:
|
||||||
|
description: "TAG (empty to build from current branch)"
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
build_branch:
|
||||||
|
description: "Flatpak branch to build (stable/nightly)"
|
||||||
|
required: true
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- stable
|
||||||
|
- nightly
|
||||||
|
default: "stable"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
flatter:
|
||||||
|
name: Flatter
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
container:
|
||||||
|
image: ghcr.io/andyholmes/flatter/freedesktop:25.08
|
||||||
|
options: --privileged
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ inputs.tag_name || github.ref }}
|
||||||
|
|
||||||
|
- name: Setup GPG
|
||||||
|
id: gpg
|
||||||
|
uses: crazy-max/ghaction-import-gpg@v6
|
||||||
|
with:
|
||||||
|
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||||
|
passphrase: ${{ secrets.GPG_PASSPHRASE }}
|
||||||
|
|
||||||
|
- name: Set Default Branch
|
||||||
|
id: set_branch
|
||||||
|
run: |
|
||||||
|
if [ "${{ github.event_name }}" == "release" ]; then
|
||||||
|
echo "branch=stable" >> $GITHUB_OUTPUT
|
||||||
|
elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
|
||||||
|
echo "branch=${{ inputs.build_branch }}" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "branch=nightly" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Modify Manifest
|
||||||
|
run: |
|
||||||
|
echo "branch: ${{ steps.set_branch.outputs.branch }}" >> packages/flatpak/ru.arabianq.pwsp.yaml
|
||||||
|
echo "default-branch: ${{ steps.set_branch.outputs.branch }}" >> packages/flatpak/ru.arabianq.pwsp.yaml
|
||||||
|
|
||||||
|
- name: Install SDK Extensions
|
||||||
|
run: flatpak install -y flathub org.freedesktop.Sdk.Extension.rust-stable//25.08
|
||||||
|
org.freedesktop.Sdk.Extension.llvm20//25.08
|
||||||
|
|
||||||
|
- name: Build Flatpak
|
||||||
|
uses: andyholmes/flatter@main
|
||||||
|
with:
|
||||||
|
files: packages/flatpak/ru.arabianq.pwsp.yaml
|
||||||
|
gpg-sign: ${{ steps.gpg.outputs.fingerprint }}
|
||||||
|
upload-bundles: false
|
||||||
|
upload-pages-artifact: true
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
name: Deploy to GitHub Pages
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: flatter
|
||||||
|
permissions:
|
||||||
|
pages: write
|
||||||
|
id-token: write
|
||||||
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: GitHub Pages
|
||||||
|
id: deployment
|
||||||
|
uses: actions/deploy-pages@v4
|
||||||
@@ -174,10 +174,3 @@ jobs:
|
|||||||
cache: true
|
cache: true
|
||||||
branch: master
|
branch: master
|
||||||
build-bundle: true
|
build-bundle: true
|
||||||
|
|
||||||
- name: Upload Flatpak to release
|
|
||||||
uses: softprops/action-gh-release@v2
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
tag_name: ${{ needs.prepare.outputs.tag }}
|
|
||||||
files: ru.arabianq.pwsp.flatpak
|
|
||||||
|
|||||||
Generated
+171
-22
@@ -486,9 +486,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.60"
|
version = "1.2.61"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20"
|
checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"find-msvc-tools",
|
"find-msvc-tools",
|
||||||
"jobserver",
|
"jobserver",
|
||||||
@@ -601,6 +601,15 @@ dependencies = [
|
|||||||
"error-code",
|
"error-code",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cmake"
|
||||||
|
version = "0.1.58"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "codespan-reporting"
|
name = "codespan-reporting"
|
||||||
version = "0.13.1"
|
version = "0.13.1"
|
||||||
@@ -729,11 +738,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpal"
|
name = "cpal"
|
||||||
version = "0.17.3"
|
version = "0.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/RustAudio/cpal#e5d618c625e978a105c57edf12f4738c65056cef"
|
||||||
checksum = "d8942da362c0f0d895d7cac616263f2f9424edc5687364dfd1d25ef7eba506d7"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alsa",
|
"alsa",
|
||||||
|
"block2 0.6.2",
|
||||||
"coreaudio-rs",
|
"coreaudio-rs",
|
||||||
"dasp_sample",
|
"dasp_sample",
|
||||||
"jni 0.21.1",
|
"jni 0.21.1",
|
||||||
@@ -751,8 +760,6 @@ dependencies = [
|
|||||||
"objc2-core-audio-types",
|
"objc2-core-audio-types",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-foundation 0.3.2",
|
"objc2-foundation 0.3.2",
|
||||||
"wasm-bindgen",
|
|
||||||
"wasm-bindgen-futures",
|
|
||||||
"web-sys",
|
"web-sys",
|
||||||
"windows",
|
"windows",
|
||||||
]
|
]
|
||||||
@@ -1022,6 +1029,20 @@ dependencies = [
|
|||||||
"web-time",
|
"web-time",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "egui_extras"
|
||||||
|
version = "0.34.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62bfc6870c68d3f254e33aca8200095d422e09edacb0f365f79fe23a5ba10963"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
"egui",
|
||||||
|
"enum-map",
|
||||||
|
"log",
|
||||||
|
"mime_guess2",
|
||||||
|
"profiling",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "egui_glow"
|
name = "egui_glow"
|
||||||
version = "0.34.1"
|
version = "0.34.1"
|
||||||
@@ -1079,6 +1100,26 @@ version = "1.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099"
|
checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enum-map"
|
||||||
|
version = "2.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9"
|
||||||
|
dependencies = [
|
||||||
|
"enum-map-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enum-map-derive"
|
||||||
|
version = "0.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "enumflags2"
|
name = "enumflags2"
|
||||||
version = "0.7.12"
|
version = "0.7.12"
|
||||||
@@ -1898,9 +1939,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.185"
|
version = "0.2.186"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
|
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libflate"
|
name = "libflate"
|
||||||
@@ -2029,12 +2070,9 @@ checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mach2"
|
name = "mach2"
|
||||||
version = "0.5.0"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a1b95cd5421ec55b445b5ae102f5ea0e768de1f82bd3001e11f426c269c3aea"
|
checksum = "dae608c151f68243f2b000364e1f7b186d9c29845f7d2d85bd31b9ad77ad552b"
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
@@ -2060,6 +2098,24 @@ dependencies = [
|
|||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mime"
|
||||||
|
version = "0.3.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mime_guess2"
|
||||||
|
version = "2.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1706dc14a2e140dec0a7a07109d9a3d5890b81e85bd6c60b906b249a77adf0ca"
|
||||||
|
dependencies = [
|
||||||
|
"mime",
|
||||||
|
"phf",
|
||||||
|
"phf_shared",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minimal-lexical"
|
name = "minimal-lexical"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@@ -2368,6 +2424,7 @@ version = "0.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13a380031deed8e99db00065c45937da434ca987c034e13b87e4441f9e4090be"
|
checksum = "13a380031deed8e99db00065c45937da434ca987c034e13b87e4441f9e4090be"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bitflags 2.11.1",
|
||||||
"objc2 0.6.4",
|
"objc2 0.6.4",
|
||||||
"objc2-foundation 0.3.2",
|
"objc2-foundation 0.3.2",
|
||||||
]
|
]
|
||||||
@@ -2653,6 +2710,15 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opusic-sys"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc3280fe5b6f97ac1a35a0ac003e2fb0b92f8e4bdf2b2057e1bf9b87acca5696"
|
||||||
|
dependencies = [
|
||||||
|
"cmake",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "orbclient"
|
name = "orbclient"
|
||||||
version = "0.3.53"
|
version = "0.3.53"
|
||||||
@@ -2721,6 +2787,50 @@ version = "2.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
|
||||||
|
dependencies = [
|
||||||
|
"phf_macros",
|
||||||
|
"phf_shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_generator"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
|
||||||
|
dependencies = [
|
||||||
|
"phf_shared",
|
||||||
|
"rand",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_macros"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
|
||||||
|
dependencies = [
|
||||||
|
"phf_generator",
|
||||||
|
"phf_shared",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_shared"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
|
||||||
|
dependencies = [
|
||||||
|
"siphasher",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.1.11"
|
version = "1.1.11"
|
||||||
@@ -2913,7 +3023,7 @@ checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pwsp"
|
name = "pwsp"
|
||||||
version = "1.7.3"
|
version = "1.7.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"clap",
|
"clap",
|
||||||
@@ -2921,6 +3031,7 @@ dependencies = [
|
|||||||
"eframe",
|
"eframe",
|
||||||
"egui",
|
"egui",
|
||||||
"egui_dnd",
|
"egui_dnd",
|
||||||
|
"egui_extras",
|
||||||
"egui_material_icons",
|
"egui_material_icons",
|
||||||
"evdev",
|
"evdev",
|
||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
@@ -2981,6 +3092,21 @@ version = "0.7.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "raw-window-handle"
|
name = "raw-window-handle"
|
||||||
version = "0.6.2"
|
version = "0.6.2"
|
||||||
@@ -3123,13 +3249,13 @@ checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "rodio"
|
name = "rodio"
|
||||||
version = "0.22.2"
|
version = "0.22.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/RustAudio/rodio.git?rev=57ad9d8a9f30398f634fbf8e4e1d53dde7243c21#57ad9d8a9f30398f634fbf8e4e1d53dde7243c21"
|
||||||
checksum = "d0a536bb79db59098ef71a4dd4246c02eb87b316deceb1b68e0cde7167ec01eb"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cpal",
|
"cpal",
|
||||||
"dasp_sample",
|
"dasp_sample",
|
||||||
"num-rational",
|
"num-rational",
|
||||||
"symphonia",
|
"symphonia",
|
||||||
|
"symphonia-adapter-libopus",
|
||||||
"thiserror 2.0.18",
|
"thiserror 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -3326,6 +3452,12 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c82d449ab1bccfeec125893c6875008206f038d4eb8a09e1e10caf86f44d574e"
|
checksum = "c82d449ab1bccfeec125893c6875008206f038d4eb8a09e1e10caf86f44d574e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "siphasher"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "skrifa"
|
name = "skrifa"
|
||||||
version = "0.40.0"
|
version = "0.40.0"
|
||||||
@@ -3480,6 +3612,17 @@ dependencies = [
|
|||||||
"symphonia-metadata",
|
"symphonia-metadata",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "symphonia-adapter-libopus"
|
||||||
|
version = "0.2.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9d17450685dda0e87467eddf3e0f9c0b2a1707fc5c3234c111f70d46c6e4494"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"opusic-sys",
|
||||||
|
"symphonia-core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "symphonia-bundle-flac"
|
name = "symphonia-bundle-flac"
|
||||||
version = "0.5.5"
|
version = "0.5.5"
|
||||||
@@ -3816,7 +3959,7 @@ dependencies = [
|
|||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"toml_parser",
|
"toml_parser",
|
||||||
"toml_writer",
|
"toml_writer",
|
||||||
"winnow 1.0.1",
|
"winnow 1.0.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3837,7 +3980,7 @@ dependencies = [
|
|||||||
"indexmap",
|
"indexmap",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"toml_parser",
|
"toml_parser",
|
||||||
"winnow 1.0.1",
|
"winnow 1.0.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3846,7 +3989,7 @@ version = "1.1.2+spec-1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
|
checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winnow 1.0.1",
|
"winnow 1.0.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3907,6 +4050,12 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicase"
|
||||||
|
version = "2.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.24"
|
version = "1.0.24"
|
||||||
@@ -4824,9 +4973,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "1.0.1"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5"
|
checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|||||||
+4
-2
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "pwsp"
|
name = "pwsp"
|
||||||
version = "1.7.3"
|
version = "1.7.5"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
authors = ["arabian"]
|
authors = ["arabian"]
|
||||||
description = "PWSP lets you play audio files through your microphone. Has both CLI and GUI clients."
|
description = "PWSP lets you play audio files through your microphone. Has both CLI and GUI clients."
|
||||||
@@ -29,8 +29,9 @@ clap = { version = "4.6.1", default-features = false, features = [
|
|||||||
dirs = "6.0.0"
|
dirs = "6.0.0"
|
||||||
itertools = "0.14.0"
|
itertools = "0.14.0"
|
||||||
|
|
||||||
rodio = { version = "0.22.2", default-features = false, features = [
|
rodio = { git = "https://github.com/RustAudio/rodio.git", rev = "57ad9d8a9f30398f634fbf8e4e1d53dde7243c21", default-features = false, features = [
|
||||||
"symphonia-all",
|
"symphonia-all",
|
||||||
|
"symphonia-libopus",
|
||||||
"playback",
|
"playback",
|
||||||
] }
|
] }
|
||||||
pipewire = "0.9.2"
|
pipewire = "0.9.2"
|
||||||
@@ -50,6 +51,7 @@ eframe = { version = "0.34.1", default-features = false, features = [
|
|||||||
"x11",
|
"x11",
|
||||||
"wayland",
|
"wayland",
|
||||||
] }
|
] }
|
||||||
|
egui_extras = "0.34.1"
|
||||||
egui_material_icons = "0.6.0"
|
egui_material_icons = "0.6.0"
|
||||||
egui_dnd = "0.15.0"
|
egui_dnd = "0.15.0"
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,28 @@ three main components:
|
|||||||
You can download pre-built binaries and .deb packages from
|
You can download pre-built binaries and .deb packages from
|
||||||
the [releases page](https://github.com/arabianq/pipewire-soundpad/releases).
|
the [releases page](https://github.com/arabianq/pipewire-soundpad/releases).
|
||||||
|
|
||||||
|
## **Flatpak**
|
||||||
|
|
||||||
|
You can install PWSP via Flatpak from our custom repository hosted on GitHub Pages.
|
||||||
|
|
||||||
|
Add the repository:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
flatpak remote-add --user --if-not-exists arabianq-repo https://arabianq.github.io/pipewire-soundpad/index.flatpakrepo
|
||||||
|
```
|
||||||
|
|
||||||
|
Install the stable version:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
flatpak install --user arabianq-repo ru.arabianq.pwsp//stable
|
||||||
|
```
|
||||||
|
|
||||||
|
Or install the nightly version (latest commit to `main`):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
flatpak install --user arabianq-repo ru.arabianq.pwsp//nightly
|
||||||
|
```
|
||||||
|
|
||||||
## **Fedora Linux (and derivatives)**
|
## **Fedora Linux (and derivatives)**
|
||||||
|
|
||||||
If you're using Fedora, you can install PWSP from a dedicated repository using DNF.
|
If you're using Fedora, you can install PWSP from a dedicated repository using DNF.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
pkgbase = pwsp-bin
|
pkgbase = pwsp-bin
|
||||||
pkgdesc = Lets you play audio files through your microphone (Pre-built binaries)
|
pkgdesc = Lets you play audio files through your microphone (Pre-built binaries)
|
||||||
pkgver = 1.7.3
|
pkgver = 1.7.5
|
||||||
pkgrel = 2
|
pkgrel = 2
|
||||||
url = https://github.com/arabianq/pipewire-soundpad
|
url = https://github.com/arabianq/pipewire-soundpad
|
||||||
arch = x86_64
|
arch = x86_64
|
||||||
@@ -9,8 +9,8 @@ depends = pipewire
|
|||||||
depends = alsa-lib
|
depends = alsa-lib
|
||||||
provides = pwsp
|
provides = pwsp
|
||||||
conflicts = pwsp
|
conflicts = pwsp
|
||||||
source = pwsp-bin-1.7.3.zip :: https://github.com/arabianq/pipewire-soundpad/releases/download/v1.7.3/pwsp-v1.7.3-linux-x64.zip
|
source = pwsp-bin-1.7.5.zip :: https://github.com/arabianq/pipewire-soundpad/releases/download/v1.7.5/pwsp-v1.7.5-linux-x64.zip
|
||||||
source = pipewire-soundpad-1.7.3.tar.gz :: https://github.com/arabianq/pipewire-soundpad/archive/refs/tags/v1.7.3.tar.gz
|
source = pipewire-soundpad-1.7.5.tar.gz :: https://github.com/arabianq/pipewire-soundpad/archive/refs/tags/v1.7.5.tar.gz
|
||||||
sha256sums = SKIP
|
sha256sums = SKIP
|
||||||
sha256sums = SKIP
|
sha256sums = SKIP
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Maintainer: Alexander Tarasov <a.tevg@ya.ru>
|
# Maintainer: Alexander Tarasov <a.tevg@ya.ru>
|
||||||
pkgname=pwsp-bin
|
pkgname=pwsp-bin
|
||||||
_pkgname=pipewire-soundpad
|
_pkgname=pipewire-soundpad
|
||||||
pkgver=1.7.3
|
pkgver=1.7.5
|
||||||
pkgrel=2
|
pkgrel=2
|
||||||
pkgdesc="Lets you play audio files through your microphone (Pre-built binaries)"
|
pkgdesc="Lets you play audio files through your microphone (Pre-built binaries)"
|
||||||
arch=('x86_64')
|
arch=('x86_64')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
pkgbase = pwsp
|
pkgbase = pwsp
|
||||||
pkgdesc = Lets you play audio files through your microphone
|
pkgdesc = Lets you play audio files through your microphone
|
||||||
pkgver = 1.7.3
|
pkgver = 1.7.5
|
||||||
pkgrel = 1
|
pkgrel = 1
|
||||||
url = https://github.com/arabianq/pipewire-soundpad
|
url = https://github.com/arabianq/pipewire-soundpad
|
||||||
arch = any
|
arch = any
|
||||||
@@ -10,7 +10,7 @@ pkgbase = pwsp
|
|||||||
makedepends = cargo
|
makedepends = cargo
|
||||||
makedepends = pipewire
|
makedepends = pipewire
|
||||||
makedepends = alsa-lib
|
makedepends = alsa-lib
|
||||||
source = https://github.com/arabianq/pipewire-soundpad/archive/refs/tags/v1.7.3.tar.gz
|
source = https://github.com/arabianq/pipewire-soundpad/archive/refs/tags/v1.7.5.tar.gz
|
||||||
sha256sums = SKIP
|
sha256sums = SKIP
|
||||||
|
|
||||||
pkgname = pwsp
|
pkgname = pwsp
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Maintainer: Alexander Tarasov <a.tevg@ya.ru>
|
# Maintainer: Alexander Tarasov <a.tevg@ya.ru>
|
||||||
pkgsubn=pwsp
|
pkgsubn=pwsp
|
||||||
pkgname=pwsp
|
pkgname=pwsp
|
||||||
pkgver=1.7.3
|
pkgver=1.7.5
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Lets you play audio files through your microphone"
|
pkgdesc="Lets you play audio files through your microphone"
|
||||||
arch=('any')
|
arch=('any')
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -25,7 +25,7 @@
|
|||||||
<name>arabian</name>
|
<name>arabian</name>
|
||||||
</developer>
|
</developer>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="1.7.3" date="2026-04-20" />
|
<release version="1.7.5" date="2026-04-26" />
|
||||||
</releases>
|
</releases>
|
||||||
<content_rating type="oars-1.1" />
|
<content_rating type="oars-1.1" />
|
||||||
</component>
|
</component>
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
%global cargo_install_lib 0
|
%global cargo_install_lib 0
|
||||||
|
|
||||||
Name: pwsp
|
Name: pwsp
|
||||||
Version: 1.7.3
|
Version: 1.7.5
|
||||||
Release: %autorelease
|
Release: %autorelease
|
||||||
Summary: Lets you play audio files through your microphone
|
Summary: Lets you play audio files through your microphone
|
||||||
|
|
||||||
|
|||||||
+100
-80
@@ -1,9 +1,10 @@
|
|||||||
use crate::gui::SoundpadGui;
|
use crate::gui::SoundpadGui;
|
||||||
use egui::{
|
use egui::{
|
||||||
Align, AtomExt, Button, CollapsingHeader, Color32, ComboBox, CursorIcon, FontFamily, Grid,
|
Align, AtomExt, Button, CollapsingHeader, Color32, ComboBox, CursorIcon, FontFamily, Label,
|
||||||
Label, Layout, RichText, ScrollArea, Sense, Slider, TextEdit, Ui, Vec2,
|
Layout, RichText, ScrollArea, Sense, Slider, TextEdit, Ui, Vec2,
|
||||||
};
|
};
|
||||||
use egui_dnd::dnd;
|
use egui_dnd::dnd;
|
||||||
|
use egui_extras::{Column, TableBuilder};
|
||||||
use egui_material_icons::icons::*;
|
use egui_material_icons::icons::*;
|
||||||
use pwsp::types::socket::Request;
|
use pwsp::types::socket::Request;
|
||||||
use pwsp::types::{audio_player::TrackInfo, gui::AppState};
|
use pwsp::types::{audio_player::TrackInfo, gui::AppState};
|
||||||
@@ -133,26 +134,24 @@ impl SoundpadGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_hotkeys(&mut self, ui: &mut Ui) {
|
pub fn draw_hotkeys(&mut self, ui: &mut Ui) {
|
||||||
let area_size = ui.available_size();
|
|
||||||
ui.vertical(|ui| {
|
ui.vertical(|ui| {
|
||||||
ui.set_min_width(area_size.x);
|
|
||||||
ui.set_min_height(area_size.y);
|
|
||||||
ui.spacing_mut().item_spacing.y = 5.0;
|
ui.spacing_mut().item_spacing.y = 5.0;
|
||||||
|
|
||||||
// Header
|
// --- Header ---
|
||||||
ui.horizontal_top(|ui| {
|
ui.horizontal(|ui| {
|
||||||
let back_button = Button::new(ICON_ARROW_BACK).frame(false);
|
let back_button = Button::new(ICON_ARROW_BACK).frame(false);
|
||||||
if ui.add(back_button).clicked() {
|
if ui.add(back_button).clicked() {
|
||||||
self.app_state.show_hotkeys = false;
|
self.app_state.show_hotkeys = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.add_space(ui.available_width() / 2.0 - 40.0);
|
ui.vertical_centered(|ui| {
|
||||||
ui.label(RichText::new("Hotkeys").color(Color32::WHITE).monospace());
|
ui.label(RichText::new("Hotkeys").color(Color32::WHITE).monospace());
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
// Search and Add Command
|
// --- Search and Add Command ---
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.menu_button(format!("{} Add Command", ICON_ADD.codepoint), |ui| {
|
ui.menu_button(format!("{} Add Command", ICON_ADD.codepoint), |ui| {
|
||||||
let mut selected_cmd = None;
|
let mut selected_cmd = None;
|
||||||
@@ -185,10 +184,10 @@ impl SoundpadGui {
|
|||||||
|
|
||||||
ui.add_space(10.0);
|
ui.add_space(10.0);
|
||||||
|
|
||||||
ui.add_sized(
|
ui.add(
|
||||||
[ui.available_width(), 22.0],
|
|
||||||
TextEdit::singleline(&mut self.app_state.hotkey_search_query)
|
TextEdit::singleline(&mut self.app_state.hotkey_search_query)
|
||||||
.hint_text("Search hotkeys..."),
|
.hint_text("Search hotkeys...")
|
||||||
|
.desired_width(f32::INFINITY),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -200,46 +199,7 @@ impl SoundpadGui {
|
|||||||
conflicts.into_iter().flat_map(|(a, b)| [a, b]).collect();
|
conflicts.into_iter().flat_map(|(a, b)| [a, b]).collect();
|
||||||
|
|
||||||
let search = self.app_state.hotkey_search_query.to_lowercase();
|
let search = self.app_state.hotkey_search_query.to_lowercase();
|
||||||
|
|
||||||
// Slots table
|
|
||||||
let mut action: Option<HotkeyAction> = None;
|
let mut action: Option<HotkeyAction> = None;
|
||||||
let area_size = ui.available_size();
|
|
||||||
|
|
||||||
ScrollArea::vertical().show(ui, |ui| {
|
|
||||||
ui.set_min_width(area_size.x);
|
|
||||||
Grid::new("hotkeys_grid")
|
|
||||||
.striped(true)
|
|
||||||
.num_columns(4)
|
|
||||||
.max_col_width(area_size.x)
|
|
||||||
.min_col_width(area_size.x / 4.0)
|
|
||||||
.spacing([40.0, 10.0])
|
|
||||||
.show(ui, |ui| {
|
|
||||||
// Table header
|
|
||||||
ui.label(
|
|
||||||
RichText::new("Slot")
|
|
||||||
.strong()
|
|
||||||
.monospace()
|
|
||||||
.color(Color32::LIGHT_GRAY),
|
|
||||||
);
|
|
||||||
ui.label(
|
|
||||||
RichText::new("Sound")
|
|
||||||
.strong()
|
|
||||||
.monospace()
|
|
||||||
.color(Color32::LIGHT_GRAY),
|
|
||||||
);
|
|
||||||
ui.label(
|
|
||||||
RichText::new("Key Chord")
|
|
||||||
.strong()
|
|
||||||
.monospace()
|
|
||||||
.color(Color32::LIGHT_GRAY),
|
|
||||||
);
|
|
||||||
ui.label(
|
|
||||||
RichText::new("Actions")
|
|
||||||
.strong()
|
|
||||||
.monospace()
|
|
||||||
.color(Color32::LIGHT_GRAY),
|
|
||||||
);
|
|
||||||
ui.end_row();
|
|
||||||
|
|
||||||
let slots: Vec<_> = self
|
let slots: Vec<_> = self
|
||||||
.app_state
|
.app_state
|
||||||
@@ -261,9 +221,70 @@ impl SoundpadGui {
|
|||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let available_width = ui.available_width();
|
||||||
|
let col_width = (available_width / 4.0).max(80.0);
|
||||||
|
|
||||||
|
TableBuilder::new(ui)
|
||||||
|
.striped(true)
|
||||||
|
.column(Column::exact(col_width).clip(true)) // Slot
|
||||||
|
.column(Column::exact(col_width).clip(true)) // Sound / Action name
|
||||||
|
.column(Column::exact(col_width).clip(true)) // Key Chord
|
||||||
|
.column(Column::exact(col_width).clip(true)) // Actions
|
||||||
|
.header(30.0, |mut header| {
|
||||||
|
header.col(|ui| {
|
||||||
|
ui.label(
|
||||||
|
RichText::new("Slot")
|
||||||
|
.strong()
|
||||||
|
.monospace()
|
||||||
|
.color(Color32::LIGHT_GRAY),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
header.col(|ui| {
|
||||||
|
ui.label(
|
||||||
|
RichText::new("Sound")
|
||||||
|
.strong()
|
||||||
|
.monospace()
|
||||||
|
.color(Color32::LIGHT_GRAY),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
header.col(|ui| {
|
||||||
|
ui.label(
|
||||||
|
RichText::new("Key Chord")
|
||||||
|
.strong()
|
||||||
|
.monospace()
|
||||||
|
.color(Color32::LIGHT_GRAY),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
header.col(|ui| {
|
||||||
|
ui.label(
|
||||||
|
RichText::new("Actions")
|
||||||
|
.strong()
|
||||||
|
.monospace()
|
||||||
|
.color(Color32::LIGHT_GRAY),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.body(|mut body| {
|
||||||
|
if slots.is_empty() {
|
||||||
|
body.row(30.0, |mut row| {
|
||||||
|
row.col(|_| {});
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.label(
|
||||||
|
RichText::new("No hotkey slots configured.")
|
||||||
|
.color(Color32::GRAY),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
row.col(|_| {});
|
||||||
|
row.col(|_| {});
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for slot in &slots {
|
for slot in &slots {
|
||||||
|
body.row(30.0, |mut row| {
|
||||||
|
// Column 1: Slot
|
||||||
|
row.col(|ui| {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
// Conflict badge
|
|
||||||
if conflict_slots.contains(slot.slot.as_str()) {
|
if conflict_slots.contains(slot.slot.as_str()) {
|
||||||
ui.label(
|
ui.label(
|
||||||
RichText::new(ICON_WARNING.codepoint)
|
RichText::new(ICON_WARNING.codepoint)
|
||||||
@@ -271,16 +292,20 @@ impl SoundpadGui {
|
|||||||
)
|
)
|
||||||
.on_hover_text("Key chord conflict");
|
.on_hover_text("Key chord conflict");
|
||||||
}
|
}
|
||||||
|
ui.add(
|
||||||
// Slot name
|
Label::new(RichText::new(&slot.slot).monospace())
|
||||||
let slot_text = RichText::new(&slot.slot).monospace();
|
.truncate(),
|
||||||
ui.label(slot_text);
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Action description
|
// Column 2: Sound / Action name
|
||||||
|
row.col(|ui| {
|
||||||
let action_name = match slot.action.name.as_str() {
|
let action_name = match slot.action.name.as_str() {
|
||||||
"play" => {
|
"play" => {
|
||||||
if let Some(file_path_str) = slot.action.args.get("file_path") {
|
if let Some(file_path_str) =
|
||||||
|
slot.action.args.get("file_path")
|
||||||
|
{
|
||||||
Path::new(file_path_str)
|
Path::new(file_path_str)
|
||||||
.file_name()
|
.file_name()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
@@ -297,20 +322,29 @@ impl SoundpadGui {
|
|||||||
"toggle_loop" => "Toggle Loop".to_string(),
|
"toggle_loop" => "Toggle Loop".to_string(),
|
||||||
other => other.to_string(),
|
other => other.to_string(),
|
||||||
};
|
};
|
||||||
ui.add(Label::new(RichText::new(action_name).monospace()).truncate());
|
ui.add(
|
||||||
|
Label::new(RichText::new(action_name).monospace()).truncate(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// Key chord
|
// Column 3: Key Chord
|
||||||
|
row.col(|ui| {
|
||||||
let chord_text = slot.key_chord.as_deref().unwrap_or("(none)");
|
let chord_text = slot.key_chord.as_deref().unwrap_or("(none)");
|
||||||
ui.label(RichText::new(chord_text).monospace().color(
|
ui.add(
|
||||||
|
Label::new(RichText::new(chord_text).monospace().color(
|
||||||
if slot.key_chord.is_some() {
|
if slot.key_chord.is_some() {
|
||||||
Color32::from_rgb(100, 200, 100)
|
Color32::from_rgb(100, 200, 100)
|
||||||
} else {
|
} else {
|
||||||
Color32::GRAY
|
Color32::GRAY
|
||||||
},
|
},
|
||||||
));
|
))
|
||||||
|
.truncate(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Column 4: Actions
|
||||||
|
row.col(|ui| {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
// Delete button
|
|
||||||
if ui
|
if ui
|
||||||
.add(Button::new(ICON_DELETE).frame(false))
|
.add(Button::new(ICON_DELETE).frame(false))
|
||||||
.on_hover_text("Remove slot")
|
.on_hover_text("Remove slot")
|
||||||
@@ -318,8 +352,6 @@ impl SoundpadGui {
|
|||||||
{
|
{
|
||||||
action = Some(HotkeyAction::Remove(slot.slot.clone()));
|
action = Some(HotkeyAction::Remove(slot.slot.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set key chord button
|
|
||||||
if ui
|
if ui
|
||||||
.add(Button::new(ICON_KEYBOARD).frame(false))
|
.add(Button::new(ICON_KEYBOARD).frame(false))
|
||||||
.on_hover_text("Set key chord")
|
.on_hover_text("Set key chord")
|
||||||
@@ -327,8 +359,6 @@ impl SoundpadGui {
|
|||||||
{
|
{
|
||||||
action = Some(HotkeyAction::Capture(slot.slot.clone()));
|
action = Some(HotkeyAction::Capture(slot.slot.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear key chord
|
|
||||||
if slot.key_chord.is_some()
|
if slot.key_chord.is_some()
|
||||||
&& ui
|
&& ui
|
||||||
.add(Button::new(ICON_BACKSPACE).frame(false))
|
.add(Button::new(ICON_BACKSPACE).frame(false))
|
||||||
@@ -337,8 +367,6 @@ impl SoundpadGui {
|
|||||||
{
|
{
|
||||||
action = Some(HotkeyAction::ClearChord(slot.slot.clone()));
|
action = Some(HotkeyAction::ClearChord(slot.slot.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Play button
|
|
||||||
if ui
|
if ui
|
||||||
.add(Button::new(ICON_PLAY_ARROW).frame(false))
|
.add(Button::new(ICON_PLAY_ARROW).frame(false))
|
||||||
.on_hover_text("Play")
|
.on_hover_text("Play")
|
||||||
@@ -347,18 +375,10 @@ impl SoundpadGui {
|
|||||||
action = Some(HotkeyAction::Play(slot.slot.clone()));
|
action = Some(HotkeyAction::Play(slot.slot.clone()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ui.end_row();
|
|
||||||
}
|
|
||||||
|
|
||||||
if slots.is_empty() {
|
|
||||||
ui.label("No hotkey slots configured.");
|
|
||||||
ui.label("");
|
|
||||||
ui.label("");
|
|
||||||
ui.label("");
|
|
||||||
ui.end_row();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if let Some(action) = action {
|
if let Some(action) = action {
|
||||||
match action {
|
match action {
|
||||||
@@ -731,7 +751,7 @@ impl SoundpadGui {
|
|||||||
file_button_text = file_button_text.color(Color32::WHITE);
|
file_button_text = file_button_text.color(Color32::WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
let file_button = Button::new(file_button_text).frame(false);
|
let file_button = Button::new(file_button_text).frame(false).truncate();
|
||||||
let file_button_response = ui.add(file_button);
|
let file_button_response = ui.add(file_button);
|
||||||
if file_button_response.clicked() {
|
if file_button_response.clicked() {
|
||||||
ui.input(|i| {
|
ui.input(|i| {
|
||||||
|
|||||||
+2
-2
@@ -9,7 +9,7 @@ use std::path::PathBuf;
|
|||||||
fn chord_from_event(modifiers: &Modifiers, key: &Key) -> Option<String> {
|
fn chord_from_event(modifiers: &Modifiers, key: &Key) -> Option<String> {
|
||||||
let key_name = key.name();
|
let key_name = key.name();
|
||||||
let is_valid = (key_name.len() == 1
|
let is_valid = (key_name.len() == 1
|
||||||
&& key_name.chars().next().unwrap().is_ascii_alphanumeric())
|
&& key_name.chars().next().is_some_and(|c| c.is_ascii_alphanumeric()))
|
||||||
|| (key_name.starts_with('F')
|
|| (key_name.starts_with('F')
|
||||||
&& key_name.len() > 1
|
&& key_name.len() > 1
|
||||||
&& key_name[1..].chars().all(|c| c.is_ascii_digit()));
|
&& key_name[1..].chars().all(|c| c.is_ascii_digit()));
|
||||||
@@ -60,7 +60,7 @@ pub fn parse_chord(chord: &str) -> Option<(Modifiers, Key)> {
|
|||||||
|
|
||||||
let key_name = parts[parts.len() - 1];
|
let key_name = parts[parts.len() - 1];
|
||||||
let is_valid = (key_name.len() == 1
|
let is_valid = (key_name.len() == 1
|
||||||
&& key_name.chars().next().unwrap().is_ascii_alphanumeric())
|
&& key_name.chars().next().is_some_and(|c| c.is_ascii_alphanumeric()))
|
||||||
|| (key_name.starts_with('F')
|
|| (key_name.starts_with('F')
|
||||||
&& key_name.len() > 1
|
&& key_name.len() > 1
|
||||||
&& key_name[1..].chars().all(|c| c.is_ascii_digit()));
|
&& key_name[1..].chars().all(|c| c.is_ascii_digit()));
|
||||||
|
|||||||
+2
-2
@@ -25,8 +25,8 @@ use std::{
|
|||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
const SUPPORTED_EXTENSIONS: [&str; 12] = [
|
const SUPPORTED_EXTENSIONS: [&str; 13] = [
|
||||||
"mp3", "wav", "ogg", "flac", "mp4", "m4a", "aac", "mov", "mkv", "mka", "webm", "avi",
|
"mp3", "wav", "ogg", "flac", "mp4", "m4a", "aac", "mov", "mkv", "mka", "webm", "avi", "opus",
|
||||||
];
|
];
|
||||||
|
|
||||||
struct SoundpadGui {
|
struct SoundpadGui {
|
||||||
|
|||||||
@@ -122,3 +122,88 @@ pub fn parse_command(request: &Request) -> Option<Box<dyn Executable + Send>> {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::types::socket::Request;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_set_volume_valid() {
|
||||||
|
let mut args = HashMap::new();
|
||||||
|
args.insert("volume".to_string(), "0.5".to_string());
|
||||||
|
args.insert("id".to_string(), "1".to_string());
|
||||||
|
let request = Request {
|
||||||
|
name: "set_volume".to_string(),
|
||||||
|
args,
|
||||||
|
};
|
||||||
|
|
||||||
|
let cmd = parse_command(&request);
|
||||||
|
assert!(cmd.is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_set_volume_missing_volume() {
|
||||||
|
let mut args = HashMap::new();
|
||||||
|
args.insert("id".to_string(), "1".to_string());
|
||||||
|
let request = Request {
|
||||||
|
name: "set_volume".to_string(),
|
||||||
|
args,
|
||||||
|
};
|
||||||
|
|
||||||
|
let cmd = parse_command(&request);
|
||||||
|
assert!(cmd.is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_set_volume_invalid_volume() {
|
||||||
|
let mut args = HashMap::new();
|
||||||
|
args.insert("volume".to_string(), "not-a-float".to_string());
|
||||||
|
let request = Request {
|
||||||
|
name: "set_volume".to_string(),
|
||||||
|
args,
|
||||||
|
};
|
||||||
|
|
||||||
|
let cmd = parse_command(&request);
|
||||||
|
assert!(cmd.is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_set_volume_missing_id() {
|
||||||
|
let mut args = HashMap::new();
|
||||||
|
args.insert("volume".to_string(), "0.5".to_string());
|
||||||
|
let request = Request {
|
||||||
|
name: "set_volume".to_string(),
|
||||||
|
args,
|
||||||
|
};
|
||||||
|
|
||||||
|
let cmd = parse_command(&request);
|
||||||
|
assert!(cmd.is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_set_volume_invalid_id() {
|
||||||
|
let mut args = HashMap::new();
|
||||||
|
args.insert("id".to_string(), "not-an-int".to_string());
|
||||||
|
args.insert("volume".to_string(), "0.5".to_string());
|
||||||
|
let request = Request {
|
||||||
|
name: "set_volume".to_string(),
|
||||||
|
args,
|
||||||
|
};
|
||||||
|
|
||||||
|
let cmd = parse_command(&request);
|
||||||
|
assert!(cmd.is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_set_volume_empty_args() {
|
||||||
|
let request = Request {
|
||||||
|
name: "set_volume".to_string(),
|
||||||
|
args: HashMap::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let cmd = parse_command(&request);
|
||||||
|
assert!(cmd.is_some());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user