fixup! Implement desktop builds

This commit is contained in:
William Brawner 2023-08-22 22:14:47 -06:00
parent 7bbbb022e3
commit 6286016da2
Signed by: wbrawner
GPG key ID: 8FF12381C6C90D35
7 changed files with 227 additions and 0 deletions

2
desktop/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/build
/release

View file

@ -0,0 +1,21 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="desktop" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName"/>
<option name="externalProjectPath" value="$PROJECT_DIR$"/>
<option name="externalSystemIdString" value="GRADLE"/>
<option name="scriptParameters" value=""/>
<option name="taskDescriptions">
<list/>
</option>
<option name="taskNames">
<list>
<option value="run"/>
</list>
</option>
<option name="vmOptions" value=""/>
</ExternalSystemSettings>
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled>
<method v="2"/>
</configuration>
</component>

69
desktop/build.gradle.kts Normal file
View file

@ -0,0 +1,69 @@
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins {
kotlin("jvm")
id("org.jetbrains.compose")
java
}
group = "com.wbrawner.pihelper"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
google()
}
val osName = System.getProperty("os.name")
val targetOs = when {
osName == "Mac OS X" -> "macos"
osName.startsWith("Win") -> "windows"
osName.startsWith("Linux") -> "linux"
else -> error("Unsupported OS: $osName")
}
val targetArch = when (val osArch = System.getProperty("os.arch")) {
"x86_64", "amd64" -> "x64"
"aarch64" -> "arm64"
else -> error("Unsupported arch: $osArch")
}
val skikoVersion = "0.7.77" // or any more recent version
val target = "${targetOs}-${targetArch}"
dependencies {
// Note, if you develop a library, you should use compose.desktop.common.
// compose.desktop.currentOs should be used in launcher-sourceSet
// (in a separate module for demo project and in testMain).
// With compose.desktop.common you will also lose @Preview functionality
implementation(project(":shared"))
implementation(compose.desktop.currentOs)
// implementation("org.jetbrains.skiko:skiko-awt-runtime-$target:$skikoVersion")
implementation(libs.kotlinx.coroutines.jvm)
implementation("ch.qos.logback:logback-classic:1.4.5")
}
compose.desktop {
application {
mainClass = "MainKt"
nativeDistributions {
includeAllModules = true
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "Pi-helper"
packageVersion = "1.0.0"
macOS {
iconFile.set(project.file("src/main/resources/icon.icns"))
}
windows {
iconFile.set(project.file("icon.ico"))
}
linux {
iconFile.set(project.file("icon.png"))
}
}
}
}

View file

@ -0,0 +1,135 @@
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.window.Tray
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import androidx.compose.ui.window.rememberTrayState
import com.wbrawner.pihelper.shared.*
import com.wbrawner.pihelper.shared.State
import com.wbrawner.pihelper.shared.ui.AddScreen
import com.wbrawner.pihelper.shared.ui.AuthScreen
import com.wbrawner.pihelper.shared.ui.InfoScreen
import com.wbrawner.pihelper.shared.ui.MainScreen
import com.wbrawner.pihelper.shared.ui.theme.PihelperTheme
import java.net.InetAddress
val store = Store(PiholeAPIService.create())
@OptIn(ExperimentalAnimationApi::class)
@Composable
@Preview
fun App(state: State) {
val error by store.effects.collectAsState(Effect.Empty)
PihelperTheme {
when (state.route) {
Route.CONNECT -> AddScreen(
scanNetwork = {
store.dispatch(Action.Scan(InetAddress.getLocalHost().hostAddress))
},
connectToPihole = { store.dispatch(Action.Connect(it)) },
loading = state.loading,
error = error as? Effect.Error
)
Route.AUTH -> AuthScreen(store)
Route.HOME -> MainScreen(store)
Route.ABOUT -> InfoScreen(store)
else -> {
Text("Not yet implemented")
}
}
}
}
fun main() = application {
LaunchedEffect(Unit) {
System.loadLibrary("app/Pi-helper.app/Contents/app/libskiko-macos-arm64.dylib")
println("loaded skiko")
System.setProperty("apple.awt.enableTemplateImages", "true")
}
val state by store.state.collectAsState()
val trayState = rememberTrayState()
var isOpen by remember { mutableStateOf(state.apiKey.isNullOrBlank()) }
val statusText = when (val status = state.status) {
is Status.Enabled -> "Enabled"
is Status.Disabled -> status.timeRemaining?.let { "Disabled (${it})" } ?: "Disabled"
else -> "Not connected"
}
Tray(
state = trayState,
tooltip = statusText,
icon = painterResource("IconTemplate.png"),
menu = {
Item(
text = statusText,
enabled = false,
onClick = {}
)
if (state.status is Status.Disabled) {
Item(
"Enable",
onClick = {
store.dispatch(Action.Enable)
}
)
} else if (state.status is Status.Enabled) {
Item(
"Disable for 10 seconds",
onClick = {
store.dispatch(Action.Disable(duration = 10))
}
)
Item(
"Disable for 30 seconds",
onClick = {
store.dispatch(Action.Disable(duration = 30))
}
)
Item(
"Disable for 1 minute",
onClick = {
store.dispatch(Action.Disable(duration = 30))
}
)
Item(
"Disable for 5 minutes",
onClick = {
store.dispatch(Action.Disable(duration = 30))
}
)
Item(
"Disable permanently",
onClick = {
store.dispatch(Action.Disable())
}
)
}
Item(
text = if (isOpen) "Hide window" else "Show window",
onClick = {
isOpen = !isOpen
}
)
Item(
"Exit",
onClick = {
isOpen = false
}
)
}
)
if (isOpen) {
Window(
title = "Pi-helper",
onCloseRequest = {
isOpen = false
}) {
App(state)
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB