Skip to content

Commit

Permalink
🔨 Refactor code to prepare for subsequent feature development (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
guiyanakuang authored Nov 20, 2023
1 parent f53981b commit 18dd599
Show file tree
Hide file tree
Showing 13 changed files with 136 additions and 131 deletions.
3 changes: 3 additions & 0 deletions composeApp/src/commonMain/kotlin/com/clipevery/AppConfig.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.clipevery

data class AppConfig(val bindingState: Boolean = false)
75 changes: 38 additions & 37 deletions composeApp/src/commonMain/kotlin/com/clipevery/ClipeveryApp.kt
Original file line number Diff line number Diff line change
@@ -1,55 +1,56 @@
package com.clipevery

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toComposeImageBitmap
import com.clipevery.clip.AbstractClipboard
import org.jetbrains.compose.resources.ExperimentalResourceApi
import java.awt.image.BufferedImage

@OptIn(ExperimentalResourceApi::class)
@Composable
fun ClipeveryApp(clipboard: AbstractClipboard, copyText: MutableState<String>, generateQRCode: BufferedImage) {
fun ClipeveryApp(dependencies: Dependencies) {
MaterialTheme {
val pid: Long = ProcessHandle.current().pid()
var showImage by remember { mutableStateOf(false) }
var start by remember { mutableStateOf(true) }
Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
Button(onClick = {
showImage = !showImage
}) {
Text(copyText.value)
}
Button(onClick = {
if (start) {
clipboard.stop()
} else {
clipboard.start()
}
start = !start
}) {
Text(start.toString() + " " + pid)
}
AnimatedVisibility(showImage) {
Image(
generateQRCode.toComposeImageBitmap(),
// painterResource("compose-multiplatform.xml"),
null
)
}
ClipeveryCommon(dependencies)
}
}
}


@Composable
fun ClipeveryCommon(dependencies: Dependencies) {
CompositionLocalProvider(
LocalClipeveryServer provides dependencies.clipServer,
LocalConfigManager provides dependencies.configManager
) {
ClipeveryWithProvidedDependencies()
}
}

@Composable
fun ClipeveryWithProvidedDependencies() {
val configManager = LocalConfigManager.current

val config = remember { mutableStateOf(configManager.config) }

if (!config.value.bindingState) {
bindingQRCode()
} else {
mainUI()
}
}


@Composable
fun bindingQRCode() {
Text("bindingQRCode")
}

@Composable
fun mainUI() {
Text("mainUI")
}
22 changes: 22 additions & 0 deletions composeApp/src/commonMain/kotlin/com/clipevery/Dependencies.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.clipevery

import androidx.compose.runtime.staticCompositionLocalOf
import com.clipevery.net.ClipServer
import com.clipevery.net.ConfigManager

abstract class Dependencies {
abstract val clipServer: ClipServer
abstract val configManager: ConfigManager
}

internal val LocalClipeveryServer = staticCompositionLocalOf<ClipServer> {
noLocalProvidedFor("ClipeveryServer")
}

internal val LocalConfigManager = staticCompositionLocalOf<ConfigManager> {
noLocalProvidedFor("ConfigManager")
}

private fun noLocalProvidedFor(name: String): Nothing {
error("CompositionLocal $name not present")
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.clipevery.clip
import java.awt.datatransfer.Transferable
import java.util.function.Consumer

interface AbstractClipboard: Runnable, ClipboardMonitor {
interface ClipboardService: Runnable, ClipboardMonitor {

val clipConsumer: Consumer<Transferable>

Expand Down
10 changes: 10 additions & 0 deletions composeApp/src/commonMain/kotlin/com/clipevery/net/ClipServer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.clipevery.net

import com.clipevery.AppConfig

interface ClipServer {
}

interface ConfigManager {
val config: AppConfig
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.clipevery.utils

import kotlinx.coroutines.CoroutineDispatcher

expect val ioDispatcher: CoroutineDispatcher
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
package com.clipevery

import com.clipevery.clip.AbstractClipboard
import com.clipevery.macos.MacosClipboard
import com.clipevery.clip.ClipboardService
import com.clipevery.macos.MacosClipboardService
import com.clipevery.platform.currentPlatform
import com.clipevery.windows.WindowsClipboard
import com.clipevery.windows.WindowsClipboardService
import java.awt.datatransfer.Transferable
import java.util.function.Consumer

fun getClipboard(clipConsumer: Consumer<Transferable>): AbstractClipboard {
fun getClipboard(clipConsumer: Consumer<Transferable>): ClipboardService {
val platform = currentPlatform()
return if (platform.name == "Macos") {
MacosClipboard(clipConsumer)
} else if (platform.name == "Windows") {
WindowsClipboard(clipConsumer)
} else {
throw Exception("Unknown platform: ${platform.name}")
return when (platform.name) {
"Macos" -> {
MacosClipboardService(clipConsumer)
}
"Windows" -> {
WindowsClipboardService(clipConsumer)
}
else -> {
throw Exception("Unknown platform: ${platform.name}")
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.clipevery.macos

import com.clipevery.clip.AbstractClipboard
import com.clipevery.clip.ClipboardService
import com.clipevery.macos.api.MacClipboard
import java.awt.Toolkit
import java.awt.datatransfer.Clipboard
Expand All @@ -11,8 +11,8 @@ import java.util.concurrent.TimeUnit
import java.util.function.Consumer


class MacosClipboard
(override val clipConsumer: Consumer<Transferable>) : AbstractClipboard {
class MacosClipboardService
(override val clipConsumer: Consumer<Transferable>) : ClipboardService {

private var executor: ScheduledExecutorService? = null

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.clipevery.utils

import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers

actual val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.clipevery.windows

import com.clipevery.clip.AbstractClipboard
import com.clipevery.clip.ClipboardService
import com.clipevery.windows.api.User32
import com.sun.jna.Pointer
import com.sun.jna.platform.win32.Kernel32
Expand All @@ -17,8 +17,8 @@ import java.util.concurrent.TimeUnit
import java.util.function.Consumer


class WindowsClipboard
(override val clipConsumer: Consumer<Transferable>) : AbstractClipboard, User32.WNDPROC {
class WindowsClipboardService
(override val clipConsumer: Consumer<Transferable>) : ClipboardService, User32.WNDPROC {

private var systemClipboard: Clipboard = Toolkit.getDefaultToolkit().systemClipboard

Expand Down
88 changes: 31 additions & 57 deletions composeApp/src/desktopMain/kotlin/main.kt
Original file line number Diff line number Diff line change
@@ -1,43 +1,30 @@
import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.toComposeImageBitmap
import androidx.compose.runtime.rememberCoroutineScope
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 com.clipevery.AppConfig
import com.clipevery.ClipeveryApp
import com.clipevery.getClipboard
import com.clipevery.utils.generateQRCode
import org.jetbrains.skia.Image
import java.awt.datatransfer.DataFlavor
import java.awt.datatransfer.Transferable
import java.awt.image.BufferedImage
import java.io.InputStream
import java.util.function.Consumer
import com.clipevery.Dependencies
import com.clipevery.net.ClipServer
import com.clipevery.net.ConfigManager
import com.clipevery.utils.ioDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlin.system.exitProcess


fun main() = application {
val copyText = remember { mutableStateOf("Hello World!") }
val consumer = Consumer<Transferable> {
if (it.isDataFlavorSupported(DataFlavor.stringFlavor)) {
try {
copyText.value = it.getTransferData(DataFlavor.stringFlavor).toString()
println(it.getTransferData(DataFlavor.stringFlavor))
} catch (e: Exception) {
e.printStackTrace()
}
}
}
val clipboard = getClipboard(consumer)
clipboard.start()

val imageBitmap = loadIconFromResources("clipevery_icon.png")
val ioScope = rememberCoroutineScope { ioDispatcher }
val bingingState = remember { mutableStateOf(false) }

val dependencies = remember {
getDependencies(ioScope, bingingState)
}

Tray(icon = imageBitmap,
Tray(icon = painterResource("clipevery_icon.png"),
menu = {
Item(
"Exit",
Expand All @@ -46,42 +33,29 @@ fun main() = application {
}
)

val generateQRCode: BufferedImage = generateQRCode("Hello World!", 200, 200)

Window(onCloseRequest = ::exitApplication,
title = "Clipevery",
icon = imageBitmap,
icon = painterResource("clipevery_icon.png"),
undecorated = true,
resizable = false) {
ClipeveryApp(clipboard, copyText, generateQRCode)
resizable = true) {
ClipeveryApp(dependencies)
}
}

fun loadIconFromResources(resourceName: String): BitmapPainter {
val resourceStream: InputStream? = Thread.currentThread().contextClassLoader.getResourceAsStream(resourceName)
resourceStream?.let {
val image = Image.makeFromEncoded(it.readAllBytes())
return BitmapPainter(image.toComposeImageBitmap())
private fun getDependencies(
ioScope: CoroutineScope,
bingingState: MutableState<Boolean>
) = object : Dependencies() {
override val clipServer: ClipServer = object : ClipServer {
}
throw IllegalArgumentException("Resource not found: $resourceName")
}

@Preview
@Composable
fun AppDesktopPreview() {
val copyText = remember { mutableStateOf("Hello World!") }
val consumer = Consumer<Transferable> {
if (it.isDataFlavorSupported(DataFlavor.stringFlavor)) {
try {
copyText.value = it.getTransferData(DataFlavor.stringFlavor).toString()
println(it.getTransferData(DataFlavor.stringFlavor))
} catch (e: Exception) {
e.printStackTrace()
}
}
override val configManager: ConfigManager = object : ConfigManager {
override val config: AppConfig = AppConfig(false) // todo: read from disk config file
}
val clipboard = getClipboard(consumer)
val generateQRCode: BufferedImage = generateQRCode("Hello World!", 200, 200)
}

ClipeveryApp(clipboard, copyText, generateQRCode)
}
//@Preview
//@Composable
//fun AppDesktopPreview() {
// ClipeveryApp(clipeveryAppState)
//}

0 comments on commit 18dd599

Please sign in to comment.