Random small improvements

This commit is contained in:
Rukira 2026-03-04 15:33:29 +00:00
parent d738b133d0
commit 17ba07deef
5 changed files with 164 additions and 19 deletions

View file

@ -0,0 +1,94 @@
name: Bug Report
about: Something not working right? Let us know so we can fix it!
title: "[Bug] "
labels:
- bug
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to report this! The more detail you can give, the faster we can track it down.
Don't worry about being too technical — just describe what happened in your own words.
- type: textarea
id: what-happened
attributes:
label: What happened?
description: Tell us what went wrong. What did you see or experience?
placeholder: "e.g. The app froze after I clicked Save, and my backup never ran."
validations:
required: true
- type: textarea
id: expected
attributes:
label: What did you expect to happen?
placeholder: "e.g. I expected my settings to save and the backup to start at the scheduled time."
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to reproduce
description: |
Walk us through exactly what you did before the problem showed up.
Try to be specific — even small details can help! Number each step.
placeholder: |
1. Opened WoW Backup
2. Went to Settings
3. Changed the backup time to 5:00 PM
4. Clicked Save
5. The app froze and stopped responding
validations:
required: true
- type: dropdown
id: frequency
attributes:
label: How often does this happen?
options:
- Every time
- Sometimes
- It only happened once
validations:
required: true
- type: dropdown
id: os
attributes:
label: Operating system
options:
- macOS
- Windows
validations:
required: true
- type: input
id: app-version
attributes:
label: App version
description: You can find this in the app's title bar or About screen.
placeholder: "e.g. 1.0.0"
- type: textarea
id: logs
attributes:
label: Log file
description: |
Logs help us understand what went wrong behind the scenes. Here's how to find them:
**macOS:** Open Finder, press **Cmd+Shift+G**, and paste: `~/Library/Application Support/WoWBackup/logs`
**Windows:** Press **Win+R**, and paste: `%APPDATA%\WoWBackup\logs`
You can also open this folder from the app: go to **Settings** and click the **Open Logs** button at the bottom.
Attach the most recent `wowbackup.log` file by dragging it into this text box.
placeholder: Drag your log file here, or paste any relevant log lines.
- type: textarea
id: extra
attributes:
label: Anything else?
description: Screenshots, screen recordings, or any other context that might help.

View file

@ -34,6 +34,33 @@ kotlin {
} }
} }
val appVersion = "0.1.0"
val generatedSrcDir = layout.buildDirectory.dir("generated/src/jvmMain/kotlin")
val generateBuildConfig by tasks.registering {
val outputDir = generatedSrcDir
val version = appVersion
outputs.dir(outputDir)
doLast {
val dir = outputDir.get().asFile.resolve("com/rukira/wowbackup")
dir.mkdirs()
dir.resolve("BuildConfig.kt").writeText(
"""
|package com.rukira.wowbackup
|
|object BuildConfig {
| const val VERSION = "$version"
|}
""".trimMargin()
)
}
}
kotlin.sourceSets.named("jvmMain") {
kotlin.srcDir(generateBuildConfig)
}
compose.desktop { compose.desktop {
application { application {
mainClass = "com.rukira.wowbackup.MainKt" mainClass = "com.rukira.wowbackup.MainKt"
@ -43,7 +70,7 @@ compose.desktop {
nativeDistributions { nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "com.rukira.wowbackup" packageName = "com.rukira.wowbackup"
packageVersion = "1.0.0" packageVersion = appVersion
} }
} }
} }

View file

@ -11,7 +11,6 @@ import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowPosition import androidx.compose.ui.window.WindowPosition
import androidx.compose.ui.window.WindowState import androidx.compose.ui.window.WindowState
import androidx.compose.ui.window.application import androidx.compose.ui.window.application
import androidx.compose.ui.window.TrayState
import androidx.compose.ui.window.rememberTrayState import androidx.compose.ui.window.rememberTrayState
import com.rukira.wowbackup.backup.BackupNotifier import com.rukira.wowbackup.backup.BackupNotifier
import com.rukira.wowbackup.backup.BackupScheduler import com.rukira.wowbackup.backup.BackupScheduler
@ -43,14 +42,13 @@ fun main() {
logger.info { "Auto-detected WoW at: $detectedWoW" } logger.info { "Auto-detected WoW at: $detectedWoW" }
} }
val startScreen = if (ConfigManager.isConfigured) Screen.STATUS else Screen.CONFIG val isConfigured = ConfigManager.isConfigured
// Start backup scheduler // Start backup scheduler
BackupScheduler.start() BackupScheduler.start()
application { application {
var isWindowVisible by remember { mutableStateOf(true) } var currentScreen by remember { mutableStateOf(if (isConfigured) null else Screen.CONFIG) }
var currentScreen by remember { mutableStateOf(startScreen) }
val trayState = rememberTrayState() val trayState = rememberTrayState()
// Wire up notifications // Wire up notifications
@ -60,16 +58,10 @@ fun main() {
state = trayState, state = trayState,
icon = trayIconPainter(), icon = trayIconPainter(),
tooltip = "WoW Backup", tooltip = "WoW Backup",
onAction = { isWindowVisible = true }, onAction = { currentScreen = Screen.STATUS },
menu = { menu = {
Item("Status", onClick = { Item("Status", onClick = { currentScreen = Screen.STATUS })
currentScreen = Screen.STATUS Item("Settings", onClick = { currentScreen = Screen.CONFIG })
isWindowVisible = true
})
Item("Settings", onClick = {
currentScreen = Screen.CONFIG
isWindowVisible = true
})
Separator() Separator()
Item("Quit", onClick = { Item("Quit", onClick = {
BackupScheduler.stop() BackupScheduler.stop()
@ -78,8 +70,9 @@ fun main() {
}, },
) )
if (isWindowVisible) { val activeScreen = currentScreen
val windowState = remember(isWindowVisible) { if (activeScreen != null) {
val windowState = remember(activeScreen) {
WindowState( WindowState(
size = DpSize(480.dp, 620.dp), size = DpSize(480.dp, 620.dp),
position = trayAlignedPosition(), position = trayAlignedPosition(),
@ -87,13 +80,13 @@ fun main() {
} }
Window( Window(
onCloseRequest = { isWindowVisible = false }, onCloseRequest = { currentScreen = null },
title = "WoW Backup", title = "WoW Backup",
state = windowState, state = windowState,
resizable = true, resizable = true,
) { ) {
App( App(
currentScreen = currentScreen, currentScreen = activeScreen,
onNavigate = { currentScreen = it }, onNavigate = { currentScreen = it },
) )
} }

View file

@ -8,14 +8,19 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.ScrollbarStyle
import androidx.compose.foundation.VerticalScrollbar
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.rememberScrollbarAdapter
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.Checkbox import androidx.compose.material3.Checkbox
@ -56,11 +61,13 @@ fun ConfigScreen(
val config = uiState.config val config = uiState.config
val errors = uiState.errors val errors = uiState.errors
var showForceBackupDialog by remember { mutableStateOf(false) } var showForceBackupDialog by remember { mutableStateOf(false) }
val scrollState = rememberScrollState()
Box(modifier = Modifier.fillMaxSize()) {
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.verticalScroll(rememberScrollState()) .verticalScroll(scrollState)
.padding(24.dp), .padding(24.dp),
verticalArrangement = Arrangement.spacedBy(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp),
) { ) {
@ -296,6 +303,20 @@ fun ConfigScreen(
} }
} }
VerticalScrollbar(
modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight(),
adapter = rememberScrollbarAdapter(scrollState),
style = ScrollbarStyle(
minimalHeight = 48.dp,
thickness = 8.dp,
shape = RoundedCornerShape(4.dp),
hoverDurationMillis = 300,
unhoverColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.3f),
hoverColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f),
),
)
}
// Force backup confirmation dialog // Force backup confirmation dialog
if (showForceBackupDialog) { if (showForceBackupDialog) {
ConfirmationDialog( ConfirmationDialog(

View file

@ -24,6 +24,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.rukira.wowbackup.BuildConfig
import com.rukira.wowbackup.backup.BackupScheduler import com.rukira.wowbackup.backup.BackupScheduler
import com.rukira.wowbackup.platform.DesktopActions import com.rukira.wowbackup.platform.DesktopActions
import java.io.File import java.io.File
@ -211,5 +212,14 @@ fun StatusScreen(
Text("Restore (Coming Soon)") Text("Restore (Coming Soon)")
} }
} }
Spacer(Modifier.weight(1f))
Text(
"WoW Backup v${BuildConfig.VERSION}",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.fillMaxWidth(),
textAlign = androidx.compose.ui.text.style.TextAlign.Center,
)
} }
} }