Skip to content

Commit

Permalink
Window management improvements and added error dialog when discord is…
Browse files Browse the repository at this point in the history
… not opened
  • Loading branch information
lilstiffy committed Apr 8, 2023
1 parent 0f84a5b commit 466708a
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 104 deletions.
1 change: 1 addition & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ compose.desktop {
mainClass = "MainKt"
nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "Count-Bot"
packageVersion = "1.0.0"
packageName = "Discord counter"
packageVersion = "1.0.2"
}
}
}
105 changes: 3 additions & 102 deletions src/jvmMain/kotlin/Main.kt
Original file line number Diff line number Diff line change
@@ -1,111 +1,12 @@
import androidx.compose.foundation.Image
import androidx.compose.material.MaterialTheme
import androidx.compose.foundation.layout.*
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowPosition
import androidx.compose.ui.window.WindowState
import androidx.compose.ui.window.application
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers
import org.sikuli.script.App
import org.sikuli.script.Key
import org.sikuli.script.Screen
import java.util.concurrent.TimeUnit


@Composable
fun CounterView(viewModel: CounterViewModel) {
var isError by remember { mutableStateOf(false) }

MaterialTheme {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painter = painterResource("lilstiffy.png"),
contentDescription = "stiffy",
modifier = Modifier
.width(100.dp)
.height(100.dp)
)

Spacer(modifier = Modifier.height(16.dp))

TextField(
value = viewModel.number.value.toString(),
label = { Text("Start from") },
enabled = !viewModel.running.value,
onValueChange = {
try {
if (it.isBlank()) viewModel.number.value = 0 else viewModel.number.value = it.toInt()
isError = false
} catch (e: Exception) {
isError = true
}
},
isError = isError,
modifier = Modifier.padding(horizontal = 16.dp)
)

if (isError) {
Text("Please enter only digits")
}

Spacer(Modifier.height(16.dp))

Button(
onClick = {
viewModel.countButtonClicked()
}
) {
Text(if (!viewModel.running.value) "Start counting" else "Stop counting")
}
}
}
}

class CounterViewModel {
val running = mutableStateOf(false)
val number = mutableStateOf(0)

private val screenObservable = Single.fromCallable { Screen() }.subscribeOn(Schedulers.io())
private var countingDisposable: Disposable? = null
private var screen: Screen? = null

init {
screenObservable.subscribe { s -> screen = s }
}

fun countButtonClicked() {
val currentlyRunning = running.value
running.value = !running.value

if (currentlyRunning) {
countingDisposable?.dispose()
} else {
App.focus("Discord")
countingDisposable = Observable.interval(1500L, TimeUnit.MILLISECONDS)
.observeOn(Schedulers.io())
.subscribe { count() }
}
}

private fun count() {
screen?.paste("${number.value}")
screen?.type(Key.ENTER)
number.value += 1
}
}
import view.CounterView
import view.CounterViewModel

fun main() = application {
Window(
Expand All @@ -121,4 +22,4 @@ fun main() = application {
) {
CounterView(CounterViewModel())
}
}
}
51 changes: 51 additions & 0 deletions src/jvmMain/kotlin/custom/ErrorDialog.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package custom

import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.ExperimentalUnitApi
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.TextUnitType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogState

@OptIn(ExperimentalUnitApi::class)
@Composable
fun ErrorDialog(errorMessage: String, onClose: () -> Unit) {
Dialog(
onCloseRequest = onClose,
state = DialogState(width = 200.dp, height = 200.dp),
resizable = false,
title = "Error"
) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Column(Modifier.padding(16.dp), verticalArrangement = Arrangement.Center) {
Text(
text = "Error",
fontSize = TextUnit(22f, TextUnitType.Sp),
textDecoration = TextDecoration.Underline,
modifier = Modifier.align(Alignment.CenterHorizontally)
)
Spacer(Modifier.height(16.dp))
Text(
text = errorMessage,
modifier = Modifier.align(Alignment.CenterHorizontally)
)
Spacer(Modifier.height(16.dp))
Button(
onClick = onClose,
modifier = Modifier.align(Alignment.CenterHorizontally))
{
Text(text = "OK")
}
}
}
}
}
117 changes: 117 additions & 0 deletions src/jvmMain/kotlin/view/CounterView.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package view

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import custom.ErrorDialog
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers
import org.sikuli.script.App
import org.sikuli.script.Key
import java.lang.NullPointerException
import java.util.concurrent.TimeUnit

@Composable
fun CounterView(viewModel: CounterViewModel) {
var inputError by remember { mutableStateOf(false) }

MaterialTheme {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painter = painterResource("lilstiffy.png"),
contentDescription = "stiffy",
modifier = Modifier
.width(100.dp)
.height(100.dp)
)

Spacer(modifier = Modifier.height(16.dp))

TextField(
value = viewModel.number.value.toString(),
label = { Text("Start from") },
enabled = !viewModel.running.value,
onValueChange = {
try {
if (it.isBlank()) viewModel.number.value = 0 else viewModel.number.value = it.toInt()
inputError = false
} catch (e: Exception) {
inputError = true
}
},
isError = inputError,
modifier = Modifier.padding(horizontal = 16.dp)
)

if (inputError) {
Text("Please enter only digits")
}

if (viewModel.showError.value != null) {
ErrorDialog(viewModel.showError.value!!) {
viewModel.showError.value = null
}
}

Spacer(Modifier.height(16.dp))

Button(
onClick = {
viewModel.countButtonClicked()
}
) {
Text(if (!viewModel.running.value) "Start counting" else "Stop counting")
}
}
}
}

class CounterViewModel {
val running = mutableStateOf(false)
val number = mutableStateOf(0)
val showError = mutableStateOf<String?>(null)

//Discord
private val discord = App("Discord")
private var countingDisposable: Disposable? = null

fun countButtonClicked() {
val currentlyRunning = running.value
running.value = !running.value

if (currentlyRunning) {
countingDisposable?.dispose()
} else {
countingDisposable = Observable.interval(1500L, TimeUnit.MILLISECONDS)
.observeOn(Schedulers.io())
.doOnSubscribe { discord.focus() }
.doOnDispose { running.value = false }
.subscribe { count() }
}
}

private fun count() {
try {
discord.window().paste("${number.value}")
discord.window().type(Key.ENTER)
number.value += 1
} catch (e: Exception) {
when (e) {
is NullPointerException -> showError.value = "Discord not open"
else -> showError.value = "Unknown error you're on your own dude"
}
countingDisposable?.dispose()
}
}
}

0 comments on commit 466708a

Please sign in to comment.