Compare commits

...

5 Commits

Author SHA1 Message Date
Kingkor Roy Tirtho
27e591d8a3 cd: remove AppImage upload steps from Linux build process 2026-07-22 01:11:53 +06:00
Kingkor Roy Tirtho
2af3a41bba cd: remove AppImage packaging and upload steps from Linux build process 2026-07-22 01:06:50 +06:00
Kingkor Roy Tirtho
720ac1136a cd: move ssh to end 2026-07-21 23:53:49 +06:00
Kingkor Roy Tirtho
8fcd35eb9b feat: add SSH debug session setup on failure for improved troubleshooting 2026-07-21 22:38:51 +06:00
Kingkor Roy Tirtho
019bbfae14 feat: add hover effect to menu items in System Tray for improved user experience 2026-07-21 22:22:12 +06:00
2 changed files with 77 additions and 7 deletions

View File

@ -16,6 +16,11 @@ on:
required: false
type: boolean
default: false
debug_ssh:
description: 'Enable SSH debug session on failure (tmate)'
required: false
type: boolean
default: false
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@ -149,6 +154,12 @@ jobs:
name: android-apk
path: Spotube-android-all-arch.apk
- name: Setup tmate session on failure
if: ${{ inputs.debug_ssh && failure() }}
uses: mxschmitt/action-tmate@v3
with:
limit-access-to-actor: true
build-linux:
name: Linux Desktop
needs: prepare-deps
@ -183,16 +194,14 @@ jobs:
run: chmod +x gradlew
- name: Package Linux
run: ./gradlew :composeApp:packageReleaseDeb :composeApp:packageReleaseRpm :composeApp:packageReleaseAppImage
run: ./gradlew :composeApp:packageReleaseDeb :composeApp:packageReleaseRpm
- name: Rename Linux artifacts
run: |
DEB_FILE=$(find composeApp/build -name "*.deb" -type f | head -1)
RPM_FILE=$(find composeApp/build -name "*.rpm" -type f | head -1)
APPIMAGE_FILE=$(find composeApp/build -name "*.AppImage" -type f | head -1)
cp "$DEB_FILE" Spotube-linux-x86_64.deb
cp "$RPM_FILE" Spotube-linux-x86_64.rpm
cp "$APPIMAGE_FILE" Spotube-linux-x86_64.AppImage
- name: Upload DEB
uses: actions/upload-artifact@v4
@ -206,11 +215,11 @@ jobs:
name: linux-rpm
path: Spotube-linux-x86_64.rpm
- name: Upload AppImage
uses: actions/upload-artifact@v4
- name: Setup tmate session on failure
if: ${{ inputs.debug_ssh && failure() }}
uses: mxschmitt/action-tmate@v3
with:
name: linux-appimage
path: Spotube-linux-x86_64.AppImage
limit-access-to-actor: true
build-windows:
name: Windows Desktop
@ -252,6 +261,12 @@ jobs:
name: windows-exe
path: Spotube-windows-x86_64-setup.exe
- name: Setup tmate session on failure
if: ${{ inputs.debug_ssh && failure() }}
uses: mxschmitt/action-tmate@v3
with:
limit-access-to-actor: true
build-macos:
name: macOS Desktop
needs: prepare-deps
@ -294,6 +309,12 @@ jobs:
name: macos-dmg
path: Spotube-macos-universal.dmg
- name: Setup tmate session on failure
if: ${{ inputs.debug_ssh && failure() }}
uses: mxschmitt/action-tmate@v3
with:
limit-access-to-actor: true
create-release:
name: Create GitHub Release
if: ${{ !inputs.dry_run }}

View File

@ -217,6 +217,23 @@ class SystemTrayService(
val loopNone = javax.swing.JRadioButtonMenuItem("Loop: OFF", state.loopState == LoopState.NONE)
val loopOne = javax.swing.JRadioButtonMenuItem("Loop: ONE", state.loopState == LoopState.ONE)
val loopAll = javax.swing.JRadioButtonMenuItem("Loop: ALL", state.loopState == LoopState.ALL)
val hoverBackground = UIManager.getColor("MenuItem.selectionBackground") ?: Color(75, 110, 175)
listOf(loopNone, loopOne, loopAll).forEach { item ->
item.isOpaque = true
val normalBackground = item.background
item.addMouseListener(object : MouseAdapter() {
override fun mouseEntered(e: MouseEvent) {
item.background = hoverBackground
}
override fun mouseExited(e: MouseEvent) {
item.background = normalBackground
}
})
}
loopGroup.add(loopNone)
loopGroup.add(loopOne)
loopGroup.add(loopAll)
@ -318,15 +335,47 @@ class SystemTrayService(
private fun createMenuItem(label: String, enabled: Boolean = true, action: () -> Unit): JMenuItem {
return JMenuItem(label).apply {
isEnabled = enabled
isOpaque = true
maximumSize = Dimension(Int.MAX_VALUE, preferredSize.height)
addActionListener { action() }
val normalBackground = background
val hoverBackground = UIManager.getColor("MenuItem.selectionBackground") ?: Color(75, 110, 175)
addMouseListener(object : MouseAdapter() {
override fun mouseEntered(e: MouseEvent) {
if (isEnabled) {
background = hoverBackground
}
}
override fun mouseExited(e: MouseEvent) {
background = normalBackground
}
})
}
}
private fun createCheckBoxMenuItem(label: String, selected: Boolean, action: () -> Unit): JCheckBoxMenuItem {
return JCheckBoxMenuItem(label, selected).apply {
isOpaque = true
maximumSize = Dimension(Int.MAX_VALUE, preferredSize.height)
addActionListener { action() }
val normalBackground = background
val hoverBackground = UIManager.getColor("MenuItem.selectionBackground") ?: Color(75, 110, 175)
addMouseListener(object : MouseAdapter() {
override fun mouseEntered(e: MouseEvent) {
if (isEnabled) {
background = hoverBackground
}
}
override fun mouseExited(e: MouseEvent) {
background = normalBackground
}
})
}
}