diff --git a/.github/workflows/build_macos_binary.yml b/.github/workflows/build_macos_binary.yml new file mode 100644 index 0000000..6765854 --- /dev/null +++ b/.github/workflows/build_macos_binary.yml @@ -0,0 +1,27 @@ +name: Build & Ship + +on: + workflow_dispatch: + +jobs: + desktop-build: + runs-on: macos-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-java@v4 + with: + distribution: 'corretto' + java-version: '17' + + - name: Build exe app + run: | + .\gradlew packageReleaseExe + + - name: Archive Artifacts Release + uses: actions/upload-artifact@v4 + with: + name: Windows Release + if-no-files-found: ignore + path: build/compose/binaries/main-release/dmg \ No newline at end of file diff --git a/.github/workflows/build_windows_binary.yml b/.github/workflows/build_windows_binary.yml new file mode 100644 index 0000000..4966bd0 --- /dev/null +++ b/.github/workflows/build_windows_binary.yml @@ -0,0 +1,27 @@ +name: Build & Ship + +on: + workflow_dispatch: + +jobs: + desktop-build: + runs-on: windows-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-java@v4 + with: + distribution: 'corretto' + java-version: '17' + + - name: Build exe app + run: | + .\gradlew packageReleaseExe + + - name: Archive Artifacts Release + uses: actions/upload-artifact@v4 + with: + name: Windows Release + if-no-files-found: ignore + path: build/compose/binaries/main-release/exe \ No newline at end of file diff --git a/.github/workflows/pull_request_check.yaml b/.github/workflows/pull_request_check.yaml index 37d4dfe..c8f08b6 100644 --- a/.github/workflows/pull_request_check.yaml +++ b/.github/workflows/pull_request_check.yaml @@ -15,7 +15,7 @@ jobs: java-version: '17' - uses: ruby/setup-ruby@v1 with: - ruby-version: '3.0' + ruby-version: '3' - name: Install danger run: | gem install danger danger-junit danger-checkstyle_format diff --git a/.idea/AdbPad-develop.iml b/.idea/AdbPad-develop.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/AdbPad-develop.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/appInsightsSettings.xml b/.idea/appInsightsSettings.xml new file mode 100644 index 0000000..f06b65e --- /dev/null +++ b/.idea/appInsightsSettings.xml @@ -0,0 +1,23 @@ + + + + + + \ No newline at end of file diff --git a/.idea/artifacts/adbpad_jvm_1_3_0.xml b/.idea/artifacts/adbpad_jvm_1_3_0.xml new file mode 100644 index 0000000..e7e1f78 --- /dev/null +++ b/.idea/artifacts/adbpad_jvm_1_3_0.xml @@ -0,0 +1,8 @@ + + + $PROJECT_DIR$/build/libs + + + + + \ No newline at end of file diff --git a/.idea/caches/deviceStreaming.xml b/.idea/caches/deviceStreaming.xml new file mode 100644 index 0000000..b81700b --- /dev/null +++ b/.idea/caches/deviceStreaming.xml @@ -0,0 +1,329 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index fa29266..77ef4f3 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -4,15 +4,16 @@ diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index b0137f1..ac801d8 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ - diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..16660f1 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/Dangerfile b/Dangerfile index 7ee1a69..0266d6d 100644 --- a/Dangerfile +++ b/Dangerfile @@ -9,4 +9,4 @@ end # Notify ktlint warning checkstyle_format.base_path = Dir.pwd -checkstyle_format.report 'build/reports/ktlint/ktlintJvmMainSourceSetCheck/ktlintJvmMainSourceSetCheck.xml' \ No newline at end of file +checkstyle_format.report 'build/reports/ktlint/ktlintJvmMainSourceSetCheck/ktlintJvmMainSourceSetCheck.xml' diff --git a/build.gradle.kts b/build.gradle.kts index cea47d0..ca04fa8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,5 @@ +import org.gradle.internal.impldep.org.junit.experimental.categories.Categories.CategoryFilter.exclude + plugins { alias(libs.plugins.multiplatform) alias(libs.plugins.compose) @@ -7,7 +9,7 @@ plugins { } group = "jp.kaleidot725" -version = "1.2.0" +version = "1.3.0" repositories { mavenCentral() @@ -18,11 +20,6 @@ repositories { } kotlin { - jvmToolchain { - vendor = JvmVendorSpec.JETBRAINS - languageVersion = JavaLanguageVersion.of(17) - } - jvm { } sourceSets { @@ -36,12 +33,10 @@ kotlin { implementation(libs.kotlinx.coroutines.swing) implementation(libs.kotlin.serialization) implementation(libs.koin) - implementation(libs.jSystemThemeDetectorVer) - implementation("org.jetbrains.jewel:jewel-int-ui-standalone-241:0.26.2") - implementation("org.jetbrains.jewel:jewel-int-ui-decorated-window-241:0.26.2") implementation(compose.desktop.currentOs) { exclude(group = "org.jetbrains.compose.material") } implementation(libs.ktor.core) implementation(libs.ktor.client.okhttp) + implementation(libs.jSystemThemeDetectorVer) } } val jvmTest by getting { @@ -55,6 +50,10 @@ kotlin { compose.desktop { application { mainClass = "MainKt" + buildTypes.release { + proguard.isEnabled = false + } + nativeDistributions { packageName = "AdbPad" modules("jdk.management") @@ -64,6 +63,11 @@ compose.desktop { org.jetbrains.compose.desktop.application.dsl.TargetFormat.Dmg, org.jetbrains.compose.desktop.application.dsl.TargetFormat.Msi, org.jetbrains.compose.desktop.application.dsl.TargetFormat.Deb, + org.jetbrains.compose.desktop.application.dsl.TargetFormat.Exe, + ) + + jvmArgs( + "-Dapple.awt.application.appearance=NSAppearanceNameDarkAqua", ) macOS { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 07239ec..3f1c688 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,7 @@ kotlin="2.0.21" kotlin_coroutines="1.9.0" kotlin_serialization="1.7.3" -compose="1.7.0" +compose="1.7.3" ktlint_plugin="12.1.1" adam="0.5.8" junit="5.11.3" diff --git a/src/jvmMain/compose-desktop.pro b/src/jvmMain/compose-desktop.pro new file mode 100644 index 0000000..84f47f0 --- /dev/null +++ b/src/jvmMain/compose-desktop.pro @@ -0,0 +1,119 @@ +# 保留 Jetpack Compose 的编译器生成代码和注解 +-keep class androidx.compose.** { *; } +-keep class androidx.lifecycle.** { *; } +-keepattributes *Annotation* + +# 禁止混淆 Compose 的内联函数 +-keepclassmembers class ** { + @androidx.compose.runtime.Composable ; +} + +# 保留 UI Preview 用于开发 +-keep class androidx.compose.ui.tooling.** { *; } + +# 保留 Kotlin 协程的内联函数和调试信息 +-keep class kotlinx.coroutines.** { *; } +-keepattributes *Annotation* +-keepclassmembers class **$* { *; } + +# 保留 Koin 的 DI 容器 +-keep class org.koin.** { *; } +-keepclassmembers class org.koin.** { *; } + +# Room 的实体类和 DAO +-keep @androidx.room.* class * { *; } +-keep class androidx.room.** { *; } +-keep interface androidx.room.** { *; } +-keep class android.arch.** { *; } +-keep @androidx.room.Entity class * +-keep class androidx.sqlite.** { *; } + + + +# DataStore 相关规则 +-keep class androidx.datastore.** { *; } +-keepattributes *Annotation* + +# 保留 Compose Multiplatform 的底层实现 +-keep class org.jetbrains.compose.** { *; } + + + +# ----------------------------------------- Basic ------------------------------------------------ # +-keepattributes *Annotation* + +# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native +-keepclasseswithmembernames class * { + native ; +} + +# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + + +# ----------------------------------------- Okio ------------------------------------------------- # +# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java. +-dontwarn org.codehaus.mojo.animal_sniffer.* + + +# ----------------------------------------- OkHttp ----------------------------------------------- # +# JSR 305 annotations are for embedding nullability information. +-dontwarn javax.annotation.** + +# A resource is loaded with a relative path so the package of this class must be preserved. +-adaptresourcefilenames okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz + +# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java. +-dontwarn org.codehaus.mojo.animal_sniffer.* + +# OkHttp platform used only on JVM and when Conscrypt and other security providers are available. +-dontwarn okhttp3.internal.platform.** +-dontwarn org.conscrypt.** +-dontwarn org.bouncycastle.** +-dontwarn org.openjsse.** + + +# ----------------------------------------- kotlinx serialization -------------------------------- # +-keepattributes *Annotation*, InnerClasses +-dontnote kotlinx.serialization.AnnotationsKt # core serialization annotations + +# kotlinx-serialization-json specific. Add this if you have java.lang.NoClassDefFoundError kotlinx.serialization.json.JsonObjectSerializer +-keepclassmembers class kotlinx.serialization.json.** { + *** Companion; +} +-keepclasseswithmembers class kotlinx.serialization.json.** { + kotlinx.serialization.KSerializer serializer(...); +} + + +# ----------------------------------------- ktor ------------------------------------------------- # +-keep class io.ktor.** { *; } +-keepclassmembers class io.ktor.** { volatile ; } +-keep class io.ktor.client.engine.cio.** { *; } +-keep class kotlinx.coroutines.** { *; } +-dontwarn kotlinx.atomicfu.** +-dontwarn io.netty.** +-dontwarn com.typesafe.** +-dontwarn org.slf4j.** + +# Obfuscation breaks coroutines/ktor for some reason +-dontobfuscate + + +# ----------------------------------------- App Ruls --------------------------------------------- # +# Change here com.github.panpf.sketch.sample +-keepclassmembers @kotlinx.serialization.Serializable class com.github.panpf.sketch.sample.** { + # lookup for plugin generated serializable classes + *** Companion; + # lookup for serializable objects + *** INSTANCE; + kotlinx.serialization.KSerializer serializer(...); +} +# lookup for plugin generated serializable classes +-if @kotlinx.serialization.Serializable class com.github.panpf.sketch.sample.** +-keepclassmembers class com.github.panpf.sketch.sample.<1>$Companion { + kotlinx.serialization.KSerializer serializer(...); +} \ No newline at end of file diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/Main.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/Main.kt index 9c39527..a8ee73e 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/Main.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/Main.kt @@ -4,16 +4,17 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Colors import androidx.compose.material.Icon import androidx.compose.material.MaterialTheme import androidx.compose.material.Surface -import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.RestartAlt import androidx.compose.runtime.Composable @@ -28,12 +29,12 @@ import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.rotate -import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.pointer.PointerEventType import androidx.compose.ui.input.pointer.onPointerEvent import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Window +import androidx.compose.ui.window.WindowScope import androidx.compose.ui.window.WindowState import androidx.compose.ui.window.application import jp.kaleidot725.adbpad.MainCategory @@ -44,7 +45,6 @@ import jp.kaleidot725.adbpad.domain.model.Dialog import jp.kaleidot725.adbpad.domain.model.UserColor import jp.kaleidot725.adbpad.domain.model.device.Device import jp.kaleidot725.adbpad.domain.model.language.Language -import jp.kaleidot725.adbpad.domain.model.log.Event import jp.kaleidot725.adbpad.domain.model.setting.WindowSize import jp.kaleidot725.adbpad.domain.model.setting.getWindowSize import jp.kaleidot725.adbpad.repository.di.repositoryModule @@ -59,19 +59,6 @@ import jp.kaleidot725.adbpad.ui.screen.screenshot.ScreenshotScreen import jp.kaleidot725.adbpad.ui.screen.setting.SettingScreen import jp.kaleidot725.adbpad.ui.screen.setting.SettingStateHolder import jp.kaleidot725.adbpad.ui.screen.text.TextCommandScreen -import org.jetbrains.jewel.foundation.theme.JewelTheme -import org.jetbrains.jewel.intui.standalone.theme.IntUiTheme -import org.jetbrains.jewel.intui.standalone.theme.darkThemeDefinition -import org.jetbrains.jewel.intui.standalone.theme.lightThemeDefinition -import org.jetbrains.jewel.intui.window.decoratedWindow -import org.jetbrains.jewel.intui.window.styling.dark -import org.jetbrains.jewel.intui.window.styling.light -import org.jetbrains.jewel.ui.ComponentStyling -import org.jetbrains.jewel.window.DecoratedWindow -import org.jetbrains.jewel.window.DecoratedWindowScope -import org.jetbrains.jewel.window.TitleBar -import org.jetbrains.jewel.window.newFullscreenControls -import org.jetbrains.jewel.window.styling.TitleBarStyle import org.koin.core.context.GlobalContext import org.koin.core.context.startKoin @@ -92,32 +79,15 @@ fun main() { mutableStateOf(WindowState(width = state.size.width.dp, height = state.size.height.dp)) } - MaterialTheme(colors = if (state.isDark) DarkColors else LightColors) { - IntUiTheme( - theme = - if (state.isDark) { - JewelTheme.darkThemeDefinition() - } else { - JewelTheme.lightThemeDefinition() - }, - styling = - if (state.isDark) { - ComponentStyling.decoratedWindow(titleBarStyle = TitleBarStyle.dark()) - } else { - ComponentStyling.decoratedWindow(titleBarStyle = TitleBarStyle.light()) - }, - ) { - DecoratedWindow( + val isDark = state.isDark + if (isDark != null) { + MaterialTheme(colors = if (isDark) DarkColors else LightColors) { + Window( title = Language.windowTitle, icon = painterResource("icon.png"), onCloseRequest = ::exitApplication, state = windowState, ) { - TitleBarView( - state = state, - onSelectDevice = mainStateHolder::selectDevice, - onRefresh = mainStateHolder::refresh, - ) App(mainStateHolder) } } @@ -125,59 +95,8 @@ fun main() { } } -@OptIn(ExperimentalComposeUiApi::class) @Composable -fun DecoratedWindowScope.TitleBarView( - state: MainState, - onSelectDevice: (Device) -> Unit, - onRefresh: () -> Unit, -) { - TitleBar( - style = TitleBarStyle.dark(), - modifier = Modifier.newFullscreenControls(), - ) { - Row(Modifier.align(Alignment.Start).wrapContentSize()) { - DropDownDeviceMenu( - devices = state.devices, - selectedDevice = state.selectedDevice, - onSelectDevice = onSelectDevice, - modifier = Modifier.width(200.dp), - ) - } - - Text( - text = title, - color = Color.White, - textAlign = TextAlign.Center, - ) - - Row(Modifier.align(Alignment.End).wrapContentSize().padding(4.dp)) { - var isPress: Boolean by remember { mutableStateOf(false) } - val degrees: Float by animateFloatAsState(if (isPress) -90f else 0f) - Box( - modifier = - Modifier - .size(28.dp) - .clip(RoundedCornerShape(4.dp)) - .clickableBackground(isDarker = true) - .onPointerEvent(PointerEventType.Press) { isPress = true } - .onPointerEvent(PointerEventType.Release) { isPress = false } - .clickable { onRefresh() }, - ) { - Icon( - imageVector = Icons.Default.RestartAlt, - tint = Color.White, - contentDescription = null, - modifier = Modifier.rotate(degrees).align(Alignment.Center), - ) - } - } - } -} - -@Composable -fun DecoratedWindowScope.App(mainStateHolder: MainStateHolder) { - val event by mainStateHolder.event.collectAsState(Event.NULL) +fun WindowScope.App(mainStateHolder: MainStateHolder) { val state by mainStateHolder.state.collectAsState() val decoratedWindowScope = this @@ -192,6 +111,13 @@ fun DecoratedWindowScope.App(mainStateHolder: MainStateHolder) { Crossfade(state.language) { Surface { ScreenLayout( + top = { + TitleBarView( + state = state, + onSelectDevice = mainStateHolder::selectDevice, + onRefresh = mainStateHolder::refresh, + ) + }, navigationRail = { NavigationRail( category = state.category, @@ -321,6 +247,52 @@ fun DecoratedWindowScope.App(mainStateHolder: MainStateHolder) { } } +@OptIn(ExperimentalComposeUiApi::class) +@Composable +private fun TitleBarView( + state: MainState, + onSelectDevice: (Device) -> Unit, + onRefresh: () -> Unit, +) { + Surface( + color = MaterialTheme.colors.background, + modifier = Modifier.fillMaxWidth(), + ) { + Box { + Row(Modifier.align(Alignment.CenterStart).wrapContentSize()) { + DropDownDeviceMenu( + devices = state.devices, + selectedDevice = state.selectedDevice, + onSelectDevice = onSelectDevice, + modifier = Modifier.wrapContentWidth(), + ) + } + + Row(Modifier.align(Alignment.CenterEnd).wrapContentSize().padding(4.dp)) { + var isPress: Boolean by remember { mutableStateOf(false) } + val degrees: Float by animateFloatAsState(if (isPress) -90f else 0f) + Box( + modifier = + Modifier + .size(28.dp) + .clip(RoundedCornerShape(4.dp)) + .clickableBackground(isDarker = true) + .onPointerEvent(PointerEventType.Press) { isPress = true } + .onPointerEvent(PointerEventType.Release) { isPress = false } + .clickable { onRefresh() }, + ) { + Icon( + imageVector = Icons.Default.RestartAlt, + tint = MaterialTheme.colors.onBackground, + contentDescription = null, + modifier = Modifier.rotate(degrees).align(Alignment.Center), + ) + } + } + } + } +} + private val LightColors = Colors( primary = UserColor.Light.PRIMARY, diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/MainState.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/MainState.kt index 794bb92..912b629 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/MainState.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/MainState.kt @@ -7,7 +7,7 @@ import jp.kaleidot725.adbpad.domain.model.setting.WindowSize data class MainState( val language: Language.Type = Language.Type.ENGLISH, - val isDark: Boolean = false, + val isDark: Boolean? = null, val size: WindowSize = WindowSize.UNKNOWN, val dialog: Dialog? = null, val category: MainCategory = MainCategory.Command, diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/MainStateHolder.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/MainStateHolder.kt index 1d280e3..b651b67 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/MainStateHolder.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/MainStateHolder.kt @@ -3,13 +3,11 @@ package jp.kaleidot725.adbpad import jp.kaleidot725.adbpad.domain.model.Dialog import jp.kaleidot725.adbpad.domain.model.device.Device import jp.kaleidot725.adbpad.domain.model.language.Language -import jp.kaleidot725.adbpad.domain.model.log.Event import jp.kaleidot725.adbpad.domain.model.setting.WindowSize import jp.kaleidot725.adbpad.domain.usecase.adb.StartAdbUseCase import jp.kaleidot725.adbpad.domain.usecase.device.GetSelectedDeviceFlowUseCase import jp.kaleidot725.adbpad.domain.usecase.device.SelectDeviceUseCase import jp.kaleidot725.adbpad.domain.usecase.device.UpdateDevicesUseCase -import jp.kaleidot725.adbpad.domain.usecase.event.GetEventFlowUseCase import jp.kaleidot725.adbpad.domain.usecase.language.GetLanguageUseCase import jp.kaleidot725.adbpad.domain.usecase.refresh.RefreshUseCase import jp.kaleidot725.adbpad.domain.usecase.theme.GetDarkModeFlowUseCase @@ -26,7 +24,6 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -40,7 +37,6 @@ class MainStateHolder( val commandStateHolder: CommandStateHolder, val textCommandStateHolder: TextCommandStateHolder, val screenshotStateHolder: ScreenshotStateHolder, - private val getEventFlowUseCase: GetEventFlowUseCase, private val getWindowSizeUseCase: GetWindowSizeUseCase, private val saveWindowSizeUseCase: SaveWindowSizeUseCase, private val startAdbUseCase: StartAdbUseCase, @@ -54,7 +50,7 @@ class MainStateHolder( private val coroutineScope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main + Dispatchers.IO) private val language: MutableStateFlow = MutableStateFlow(Language.Type.ENGLISH) private val windowSize: MutableStateFlow = MutableStateFlow(WindowSize.UNKNOWN) - private val isDark: MutableStateFlow = MutableStateFlow(true) + private val isDark: MutableStateFlow = MutableStateFlow(null) private val dialog: MutableStateFlow = MutableStateFlow(null) private val category: MutableStateFlow = MutableStateFlow(MainCategory.Command) @@ -66,12 +62,11 @@ class MainStateHolder( private val _selectedDevice: MutableStateFlow = MutableStateFlow(null) private val selectedDevice: StateFlow = _selectedDevice.asStateFlow() - val event: SharedFlow = getEventFlowUseCase() val state: StateFlow = combine(language, isDark, windowSize, dialog, category, devices, selectedDevice) { data -> MainState( data[0] as Language.Type, - data[1] as Boolean, + data[1] as Boolean?, data[2] as WindowSize, data[3] as Dialog?, data[4] as MainCategory, diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/di/DomainModule.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/di/DomainModule.kt index f251f62..957a404 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/di/DomainModule.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/di/DomainModule.kt @@ -9,7 +9,6 @@ import jp.kaleidot725.adbpad.domain.usecase.command.GetNormalCommandGroup import jp.kaleidot725.adbpad.domain.usecase.device.GetSelectedDeviceFlowUseCase import jp.kaleidot725.adbpad.domain.usecase.device.SelectDeviceUseCase import jp.kaleidot725.adbpad.domain.usecase.device.UpdateDevicesUseCase -import jp.kaleidot725.adbpad.domain.usecase.event.GetEventFlowUseCase import jp.kaleidot725.adbpad.domain.usecase.language.GetLanguageUseCase import jp.kaleidot725.adbpad.domain.usecase.language.SaveLanguageUseCase import jp.kaleidot725.adbpad.domain.usecase.refresh.RefreshUseCase @@ -39,7 +38,7 @@ val domainModule = RestartAdbUseCase(get()) } factory { - ExecuteCommandUseCase(get(), get()) + ExecuteCommandUseCase(get()) } factory { GetNormalCommandGroup(get()) @@ -57,25 +56,22 @@ val domainModule = DeleteTextCommandUseCase(get()) } factory { - ExecuteTextCommandUseCase(get(), get()) + ExecuteTextCommandUseCase(get()) } factory { GetTextCommandUseCase(get()) } factory { - TakeScreenshotUseCase(get(), get()) + TakeScreenshotUseCase(get()) } factory { GetScreenshotCommandUseCase(get()) } factory { - GetEventFlowUseCase(get()) + SendUserInputTextCommandUseCase(get()) } factory { - SendUserInputTextCommandUseCase(get(), get()) - } - factory { - DeleteScreenshotPreviewUseCase(get(), get()) + DeleteScreenshotPreviewUseCase(get()) } factory { GetWindowSizeUseCase(get()) @@ -105,10 +101,10 @@ val domainModule = GetLanguageUseCase(get()) } factory { - CopyScreenshotToClipboardUseCase(get(), get()) + CopyScreenshotToClipboardUseCase(get()) } factory { - SendTabCommandUseCase(get(), get()) + SendTabCommandUseCase(get()) } factory { RefreshUseCase(get(), get(), get()) diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/command/NormalCommand.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/command/NormalCommand.kt index 0b1ad70..3f3d365 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/command/NormalCommand.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/command/NormalCommand.kt @@ -10,6 +10,26 @@ interface NormalCommand { val requests: List val category: NormalCommandCategory + data class PointerLocationOn(override val isRunning: Boolean = false) : NormalCommand { + override val title: String get() = Language.commandPointerLocationOnTitle + override val details: String get() = Language.commandPointerLocationOnDetails + override val requests: List = + listOf( + ShellCommandRequest("settings put system pointer_location 1"), + ) + override val category: NormalCommandCategory = NormalCommandCategory.UI + } + + data class PointerLocationOff(override val isRunning: Boolean = false) : NormalCommand { + override val title: String get() = Language.commandPointerLocationOffTitle + override val details: String get() = Language.commandPointerLocationOffDetails + override val requests: List = + listOf( + ShellCommandRequest("settings put system pointer_location 0"), + ) + override val category: NormalCommandCategory = NormalCommandCategory.UI + } + data class LayoutBorderOn(override val isRunning: Boolean = false) : NormalCommand { override val title: String get() = Language.commandLayoutBorderOnTitle override val details: String get() = Language.commandLayoutBorderOnDetails diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/Language.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/Language.kt index ad88c87..d0ab7e0 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/Language.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/Language.kt @@ -1,5 +1,6 @@ package jp.kaleidot725.adbpad.domain.model.language +import jp.kaleidot725.adbpad.domain.model.language.resources.ChineseResources import jp.kaleidot725.adbpad.domain.model.language.resources.EnglishResources import jp.kaleidot725.adbpad.domain.model.language.resources.JapaneseResources import jp.kaleidot725.adbpad.domain.model.language.resources.StringResources @@ -55,6 +56,16 @@ object Language : StringResources { get() = getCurrentResources().commandEndEventFormat override val commandErrorEventFormat: String get() = getCurrentResources().commandErrorEventFormat + + override val commandPointerLocationOnTitle: String + get() = getCurrentResources().commandPointerLocationOnTitle + override val commandPointerLocationOnDetails: String + get() = getCurrentResources().commandPointerLocationOnDetails + override val commandPointerLocationOffTitle: String + get() = getCurrentResources().commandPointerLocationOffTitle + override val commandPointerLocationOffDetails: String + get() = getCurrentResources().commandPointerLocationOffDetails + override val commandLayoutBorderOnTitle: String get() = getCurrentResources().commandLayoutBorderOnTitle override val commandLayoutBorderOnDetails: String @@ -155,6 +166,8 @@ object Language : StringResources { get() = getCurrentResources().settingLanguageEnglish override val settingLanguageJapanese: String get() = getCurrentResources().settingLanguageJapanese + override val settingLanguageChinese: String + get() = getCurrentResources().settingLanguageChinese override val settingAppearanceHeader: String get() = getCurrentResources().settingAppearanceHeader override val settingAdbHeader: String @@ -186,11 +199,13 @@ object Language : StringResources { return when (currentType) { Type.ENGLISH -> EnglishResources Type.JAPANESE -> JapaneseResources + Type.CHINESE -> ChineseResources } } enum class Type { ENGLISH, JAPANESE, + CHINESE, } } diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/ChineseResources.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/ChineseResources.kt new file mode 100644 index 0000000..c6dffe6 --- /dev/null +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/ChineseResources.kt @@ -0,0 +1,104 @@ +package jp.kaleidot725.adbpad.domain.model.language.resources + +object ChineseResources : StringResources { + override val version = "v1.3.0" + override val windowTitle = "AdbPad($version)" + + override val notFoundDevice = "未找到设备" + override val notFoundCommand = "未找到命令" + override val notFoundInputText = "未找到输入文本" + override val notFoundScreenshot = "未找到截图" + + override val execute = "运行" + override val save = "保存" + override val delete = "删除" + override val tab = "标签" + override val send = "发送" + override val cancel = "取消" + override val targetDevice = "设备" + override val tool = "工具" + override val setting = "设置" + override val dark = "深色" + override val light = "浅色" + override val system = "系统" + + override val screenshotTakeByCurrentTheme = "按当前主题截图" + override val screenshotTakeByDarkTheme = "按深色主题截图" + override val screenshotTakeByLightTheme = "按浅色主题截图" + override val screenshotTakeByBothTheme = "按两种主题截图" + + override val commandStartEventFormat = "开始发送命令 「%s」" + override val commandEndEventFormat = "结束发送命令 「%s」" + override val commandErrorEventFormat = "发送命令失败 「%s」" + + override val commandPointerLocationOnTitle = "指针位置:开启" + override val commandPointerLocationOnDetails = "启用屏幕叠加层显示当前触摸点坐标" + override val commandPointerLocationOffTitle = "指针位置:关闭" + override val commandPointerLocationOffDetails = "禁用屏幕叠加层显示当前触摸点坐标" + override val commandLayoutBorderOnTitle = "显示布局边界: 开启" + override val commandLayoutBorderOnDetails = "启用显示裁剪边界、边距等。" + override val commandLayoutBorderOffTitle = "显示布局边界: 关闭" + override val commandLayoutBorderOffDetails = "禁用显示裁剪边界、边距等。" + override val commandTapEffectOnTitle = "显示触摸点: 开启" + override val commandTapEffectOnDetails = "启用显示触摸点的视觉反馈。" + override val commandTapEffectOffTitle = "显示触摸点: 关闭" + override val commandTapEffectOffDetails = "禁用显示触摸点的视觉反馈。" + override val commandSleepModeOnTitle = "休眠模式: 开启" + override val commandSleepModeOnDetails = "启用休眠模式,设备进入休眠状态。" + override val commandSleepModeOffTitle = "休眠模式: 关闭" + override val commandSleepModeOffDetails = "禁用休眠模式,设备不会进入休眠。" + override val commandDarkThemeOnTitle = "深色主题: 开启" + override val commandDarkThemeOnDetails = "启用深色主题。" + override val commandDarkThemeOffTitle = "深色主题: 关闭" + override val commandDarkThemeOffDetails = "禁用深色主题。" + override val commandWifiOnTitle = "Wi-Fi: 开启" + override val commandWifiOnDetails = "启用 Wi-Fi 通信。" + override val commandWifiOffTitle = "Wi-Fi: 关闭" + override val commandWifiOffDetails = "禁用 Wi-Fi 通信。" + override val commandDataOnTitle = "蜂窝网络: 开启" + override val commandDataOnDetails = "启用蜂窝网络通信。" + override val commandDataOffTitle = "蜂窝网络: 关闭" + override val commandDataOffDetails = "禁用蜂窝网络通信。" + override val commandWifiAndDataOnTitle = "Wi-Fi 和蜂窝网络: 开启" + override val commandWifiAndDataOnDetails = "启用 Wi-Fi 和蜂窝网络通信。" + override val commandWifiAndDataOffTitle = "Wi-Fi 和蜂窝网络: 关闭" + override val commandWifiAndDataOffDetails = "禁用 Wi-Fi 和蜂窝网络通信。" + override val commandScreenPinningOffTitle = "屏幕固定: 关闭" + override val commandScreenPinningOffDetails = "禁用屏幕固定功能。" + + override val textCommandStartEventFormat = "开始发送文本 「%s」" + override val textCommandEndEventFormat = "结束发送文本 「%s」" + override val textCommandErrorEventFormat = "发送文本失败 「%s」" + + override val keyCommandStartEventFormat = "开始发送按键 「%s」" + override val keyCommandEndEventFormat = "结束发送按键 「%s」" + override val keyCommandErrorEventFormat = "发送按键失败 「%s」" + + override val screenshotCommandStartEventFormat = "开始截屏" + override val screenshotCommandEndEventFormat = "结束截屏" + override val screenshotCommandErrorEventFormat = "截屏失败" + override val screenshotCopyToClipbaordEventFormat = "已复制截图到剪贴板" + override val cantScreenshotCopyToClipbaordEventFormat = "无法复制截图到剪贴板" + override val screenshotClearCache = "删除截图" + + override val menuCommandTitle = "命令" + override val menuInputTextTitle = "发送文本" + override val menuScreenshot = "截图" + + override val settingLanguageHeader = "语言" + override val settingLanguageEnglish = "英语" + override val settingLanguageJapanese = "日语 (日本語)" + override val settingLanguageChinese = "简体中文" + + override val settingAppearanceHeader = "外观" + override val settingAdbHeader = "ADB" + override val settingAdbDirectoryPathTitle = "二进制路径" + override val settingAdbPortNumberTitle = "服务端口" + override val settingAndroidSdkHeader = "Android SDK" + override val settingAndroidSdkDirectoryPathTitle = "目录路径" + override val settingAdbRestartTitle = "重启 ADB" + + override val adbErrorTitle = "ADB 错误" + override val adbErrorMessage = "无法启动 ADB 服务,请更改 ADB 设置。" + override val adbErrorOpenSetting = "打开设置" +} diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/EnglishResources.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/EnglishResources.kt index d7a96b5..b4ae549 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/EnglishResources.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/EnglishResources.kt @@ -1,7 +1,7 @@ package jp.kaleidot725.adbpad.domain.model.language.resources object EnglishResources : StringResources { - override val version = "v1.2.0" + override val version = "v1.3.0" override val windowTitle = "AdbPad($version)" override val notFoundDevice = "Not found device" @@ -31,6 +31,10 @@ object EnglishResources : StringResources { override val commandEndEventFormat = "End sending command 「%s」" override val commandErrorEventFormat = "Error sending command 「%s」" + override val commandPointerLocationOnTitle = "Pointer position: On" + override val commandPointerLocationOnDetails = "Enable screen overlay to display current touch point coordinates" + override val commandPointerLocationOffTitle = "Pointer position: off" + override val commandPointerLocationOffDetails = "Disable screen overlay showing current touch point coordinates" override val commandLayoutBorderOnTitle = "Show layout bounds: ON" override val commandLayoutBorderOnDetails = "Enable showing clip bounds, margins, etc." override val commandLayoutBorderOffTitle = "Show layout bonds: OFF" @@ -84,6 +88,7 @@ object EnglishResources : StringResources { override val settingLanguageHeader = "Language" override val settingLanguageEnglish = "English" override val settingLanguageJapanese = "Japanese(日本語)" + override val settingLanguageChinese = "Chinese(简体中文)" override val settingAppearanceHeader = "Appearance" override val settingAdbHeader = "ADB" diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/JapaneseResources.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/JapaneseResources.kt index f7588cb..70834de 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/JapaneseResources.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/JapaneseResources.kt @@ -1,7 +1,7 @@ package jp.kaleidot725.adbpad.domain.model.language.resources object JapaneseResources : StringResources { - override val version = "v1.2.0" + override val version = "v1.3.0" override val windowTitle = "AdbPad($version)" override val notFoundDevice = "デバイスがありません" @@ -31,6 +31,10 @@ object JapaneseResources : StringResources { override val commandEndEventFormat = "「%s」のコマンド送信が完了しました" override val commandErrorEventFormat = "「%s」のコマンド送信に失敗しました" + override val commandPointerLocationOnTitle = "ポインターの位置: オン" + override val commandPointerLocationOnDetails = "画面オーバーレイを有効にして現在のタッチポイント座標を表示します" + override val commandPointerLocationOffTitle = "ポインターの位置: オフ" + override val commandPointerLocationOffDetails = "現在のタッチポイント座標を表示する画面オーバーレイを無効にする" override val commandLayoutBorderOnTitle = "レイアウト境界表示: ON" override val commandLayoutBorderOnDetails = "レイアウトの境界やマージンなどの表示を有効化します" override val commandLayoutBorderOffTitle = "レイアウト境界表示: OFF" @@ -84,6 +88,7 @@ object JapaneseResources : StringResources { override val settingLanguageHeader = "表示言語" override val settingLanguageEnglish = "英語(English)" override val settingLanguageJapanese = "日本語" + override val settingLanguageChinese = "簡体字中国語" override val settingAppearanceHeader = "テーマ" override val settingAdbHeader = "ADB" diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/StringResources.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/StringResources.kt index 9c81241..4d587e8 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/StringResources.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/StringResources.kt @@ -30,6 +30,10 @@ interface StringResources { val commandEndEventFormat: String val commandErrorEventFormat: String + val commandPointerLocationOnTitle: String + val commandPointerLocationOnDetails: String + val commandPointerLocationOffTitle: String + val commandPointerLocationOffDetails: String val commandLayoutBorderOnTitle: String val commandLayoutBorderOnDetails: String val commandLayoutBorderOffTitle: String @@ -85,6 +89,7 @@ interface StringResources { val settingLanguageHeader: String val settingLanguageEnglish: String val settingLanguageJapanese: String + val settingLanguageChinese: String val settingAdbHeader: String val settingAdbDirectoryPathTitle: String diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/log/Event.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/log/Event.kt deleted file mode 100644 index 5d6b6d0..0000000 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/log/Event.kt +++ /dev/null @@ -1,142 +0,0 @@ -package jp.kaleidot725.adbpad.domain.model.log - -import jp.kaleidot725.adbpad.domain.model.language.Language - -interface Event { - val message: String - val level: Level - - data class StartCommand(val commandName: String) : Event { - override val message: String - get() = String.format(Language.commandStartEventFormat, commandName) - - override val level: Level - get() = Level.INFO - } - - data class EndCommand(val commandName: String) : Event { - override val message: String - get() = String.format(Language.commandEndEventFormat, commandName) - - override val level: Level - get() = Level.INFO - } - - data class ErrorCommand(val commandName: String) : Event { - override val message: String - get() = String.format(Language.commandErrorEventFormat, commandName) - - override val level: Level - get() = Level.ERROR - } - - data class StartSendTextCommand(val text: String) : Event { - override val message: String - get() = String.format(Language.textCommandStartEventFormat, text) - - override val level: Level - get() = Level.INFO - } - - data class EndSendTextCommand(val text: String) : Event { - override val message: String - get() = String.format(Language.textCommandEndEventFormat, text) - - override val level: Level - get() = Level.INFO - } - - data class ErrorSendTextCommand(val text: String) : Event { - override val message: String - get() = String.format(Language.textCommandErrorEventFormat) - - override val level: Level - get() = Level.ERROR - } - - data class StartSendKeyCommand(val code: Int) : Event { - override val message: String - get() = String.format(Language.keyCommandStartEventFormat, code.toString()) - - override val level: Level - get() = Level.INFO - } - - data class EndSendKeyCommand(val code: Int) : Event { - override val message: String - get() = String.format(Language.keyCommandEndEventFormat, code.toString()) - - override val level: Level - get() = Level.INFO - } - - data class ErrorSendKeyCommand(val code: Int) : Event { - override val message: String - get() = String.format(Language.keyCommandErrorEventFormat, code.toString()) - - override val level: Level - get() = Level.ERROR - } - - object StartSendScreenshotCommand : Event { - override val message: String - get() = Language.screenshotCommandStartEventFormat - - override val level: Level - get() = Level.INFO - } - - object EndSendScreenshotCommand : Event { - override val message: String - get() = Language.screenshotCommandEndEventFormat - - override val level: Level - get() = Level.INFO - } - - object ErrorSendScreenshotCommand : Event { - override val message: String - get() = Language.screenshotCommandErrorEventFormat - - override val level: Level - get() = Level.ERROR - } - - object CopyScreenshotToClipBoard : Event { - override val message: String - get() = Language.screenshotCopyToClipbaordEventFormat - - override val level: Level - get() = Level.INFO - } - - object CantCopyScreenshotToClipBoard : Event { - override val message: String - get() = Language.screenshotCopyToClipbaordEventFormat - - override val level: Level - get() = Level.ERROR - } - - object ClearScreenshotCache : Event { - override val message: String - get() = Language.screenshotClearCache - - override val level: Level - get() = Level.INFO - } - - object NULL : Event { - override val message: String - get() = "" - - override val level: Level - get() = Level.INFO - } - - enum class Level { - INFO, - WARN, - ERROR, - } -} diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/setting/WindowSize.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/setting/WindowSize.kt index 17838ab..cad44a5 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/setting/WindowSize.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/setting/WindowSize.kt @@ -1,6 +1,6 @@ package jp.kaleidot725.adbpad.domain.model.setting -import androidx.compose.ui.window.FrameWindowScope +import androidx.compose.ui.window.WindowScope import kotlinx.serialization.Serializable @Serializable @@ -14,7 +14,7 @@ data class WindowSize( } } -fun FrameWindowScope.getWindowSize(): WindowSize { +fun WindowScope.getWindowSize(): WindowSize { return WindowSize( this.window.width, this.window.height, diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/repository/EventRepository.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/repository/EventRepository.kt deleted file mode 100644 index 9bf68ed..0000000 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/repository/EventRepository.kt +++ /dev/null @@ -1,10 +0,0 @@ -package jp.kaleidot725.adbpad.domain.repository - -import jp.kaleidot725.adbpad.domain.model.log.Event -import kotlinx.coroutines.flow.SharedFlow - -interface EventRepository { - val event: SharedFlow - - suspend fun sendEvent(event: Event) -} diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/service/SettingFileCreator.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/service/SettingFileCreator.kt index 6d6b905..98e2b57 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/service/SettingFileCreator.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/service/SettingFileCreator.kt @@ -51,7 +51,7 @@ object SettingFileCreator { @Serializable data class Setting( val language: Language.Type = Language.Type.ENGLISH, - val appearance: Appearance = Appearance.SYSTEM, + val appearance: Appearance = Appearance.LIGHT, val sdkPath: SdkPath = SdkPath(), val inputTexts: List = emptyList(), val windowSize: WindowSize = WindowSize.DEFAULT, diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/command/ExecuteCommandUseCase.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/command/ExecuteCommandUseCase.kt index ccb4949..98708ee 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/command/ExecuteCommandUseCase.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/command/ExecuteCommandUseCase.kt @@ -2,12 +2,9 @@ package jp.kaleidot725.adbpad.domain.usecase.command import jp.kaleidot725.adbpad.domain.model.command.NormalCommand import jp.kaleidot725.adbpad.domain.model.device.Device -import jp.kaleidot725.adbpad.domain.model.log.Event -import jp.kaleidot725.adbpad.domain.repository.EventRepository import jp.kaleidot725.adbpad.domain.repository.NormalCommandRepository class ExecuteCommandUseCase( - private val eventRepository: EventRepository, private val normalCommandRepository: NormalCommandRepository, ) { suspend operator fun invoke( @@ -21,15 +18,12 @@ class ExecuteCommandUseCase( device = device, command = command, onStart = { - eventRepository.sendEvent(Event.StartCommand(command.title)) onStart() }, onFailed = { - eventRepository.sendEvent(Event.ErrorCommand(command.title)) onFailed() }, onComplete = { - eventRepository.sendEvent(Event.EndCommand(command.title)) onComplete() }, ) diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/event/GetEventFlowUseCase.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/event/GetEventFlowUseCase.kt deleted file mode 100644 index 6b595e5..0000000 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/event/GetEventFlowUseCase.kt +++ /dev/null @@ -1,13 +0,0 @@ -package jp.kaleidot725.adbpad.domain.usecase.event - -import jp.kaleidot725.adbpad.domain.model.log.Event -import jp.kaleidot725.adbpad.domain.repository.EventRepository -import kotlinx.coroutines.flow.SharedFlow - -class GetEventFlowUseCase( - private val eventRepository: EventRepository, -) { - operator fun invoke(): SharedFlow { - return eventRepository.event - } -} diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/screenshot/CopyScreenshotToClipboardUseCase.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/screenshot/CopyScreenshotToClipboardUseCase.kt index 3f170ae..ec45e3b 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/screenshot/CopyScreenshotToClipboardUseCase.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/screenshot/CopyScreenshotToClipboardUseCase.kt @@ -1,15 +1,12 @@ package jp.kaleidot725.adbpad.domain.usecase.screenshot -import jp.kaleidot725.adbpad.domain.model.log.Event import jp.kaleidot725.adbpad.domain.model.screenshot.Screenshot -import jp.kaleidot725.adbpad.domain.repository.EventRepository import jp.kaleidot725.adbpad.domain.repository.ScreenshotCommandRepository import jp.kaleidot725.adbpad.domain.utils.ClipBoardUtils import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext class CopyScreenshotToClipboardUseCase( - private val eventRepository: EventRepository, private val screenshotCommandRepository: ScreenshotCommandRepository, ) { suspend operator fun invoke() { @@ -17,9 +14,6 @@ class CopyScreenshotToClipboardUseCase( val cache = screenshotCommandRepository.getScreenshotCache() if (cache != Screenshot.EMPTY) { ClipBoardUtils.copyFile(cache.file!!) - eventRepository.sendEvent(Event.CopyScreenshotToClipBoard) - } else { - eventRepository.sendEvent(Event.CantCopyScreenshotToClipBoard) } } } diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/screenshot/DeleteScreenshotPreviewUseCase.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/screenshot/DeleteScreenshotPreviewUseCase.kt index cbcc834..09d8c63 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/screenshot/DeleteScreenshotPreviewUseCase.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/screenshot/DeleteScreenshotPreviewUseCase.kt @@ -1,15 +1,11 @@ package jp.kaleidot725.adbpad.domain.usecase.screenshot -import jp.kaleidot725.adbpad.domain.model.log.Event -import jp.kaleidot725.adbpad.domain.repository.EventRepository import jp.kaleidot725.adbpad.domain.repository.ScreenshotCommandRepository class DeleteScreenshotPreviewUseCase( - private val eventRepository: EventRepository, private val screenshotCommandRepository: ScreenshotCommandRepository, ) { suspend operator fun invoke() { - eventRepository.sendEvent(Event.ClearScreenshotCache) return screenshotCommandRepository.deleteScreenshotCache() } } diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/screenshot/TakeScreenshotUseCase.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/screenshot/TakeScreenshotUseCase.kt index a523908..7ef18da 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/screenshot/TakeScreenshotUseCase.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/screenshot/TakeScreenshotUseCase.kt @@ -2,13 +2,10 @@ package jp.kaleidot725.adbpad.domain.usecase.screenshot import jp.kaleidot725.adbpad.domain.model.command.ScreenshotCommand import jp.kaleidot725.adbpad.domain.model.device.Device -import jp.kaleidot725.adbpad.domain.model.log.Event import jp.kaleidot725.adbpad.domain.model.screenshot.Screenshot -import jp.kaleidot725.adbpad.domain.repository.EventRepository import jp.kaleidot725.adbpad.domain.repository.ScreenshotCommandRepository class TakeScreenshotUseCase( - private val eventRepository: EventRepository, private val screenshotCommandRepository: ScreenshotCommandRepository, ) { suspend operator fun invoke( @@ -22,15 +19,12 @@ class TakeScreenshotUseCase( device = device, command = command, onStart = { - eventRepository.sendEvent(Event.StartSendScreenshotCommand) onStart() }, onFailed = { - eventRepository.sendEvent(Event.ErrorSendScreenshotCommand) onFailed() }, onComplete = { - eventRepository.sendEvent(Event.EndSendScreenshotCommand) onComplete(it) }, ) diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/text/ExecuteTextCommandUseCase.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/text/ExecuteTextCommandUseCase.kt index 4dfea73..272fbf0 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/text/ExecuteTextCommandUseCase.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/text/ExecuteTextCommandUseCase.kt @@ -2,12 +2,9 @@ package jp.kaleidot725.adbpad.domain.usecase.text import jp.kaleidot725.adbpad.domain.model.command.TextCommand import jp.kaleidot725.adbpad.domain.model.device.Device -import jp.kaleidot725.adbpad.domain.model.log.Event -import jp.kaleidot725.adbpad.domain.repository.EventRepository import jp.kaleidot725.adbpad.domain.repository.TextCommandRepository class ExecuteTextCommandUseCase( - private val eventRepository: EventRepository, private val textCommandRepository: TextCommandRepository, ) { suspend operator fun invoke( @@ -21,15 +18,12 @@ class ExecuteTextCommandUseCase( device = device, command = command, onStart = { - eventRepository.sendEvent(Event.StartSendTextCommand(command.text)) onStart() }, onFailed = { - eventRepository.sendEvent(Event.ErrorSendTextCommand(command.text)) onFailed() }, onComplete = { - eventRepository.sendEvent(Event.EndSendTextCommand(command.text)) onComplete() }, ) diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/text/SendTabCommandUseCase.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/text/SendTabCommandUseCase.kt index 49ccffc..560026f 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/text/SendTabCommandUseCase.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/text/SendTabCommandUseCase.kt @@ -1,12 +1,9 @@ package jp.kaleidot725.adbpad.domain.usecase.text import jp.kaleidot725.adbpad.domain.model.device.Device -import jp.kaleidot725.adbpad.domain.model.log.Event -import jp.kaleidot725.adbpad.domain.repository.EventRepository import jp.kaleidot725.adbpad.domain.repository.KeyCommandRepository class SendTabCommandUseCase( - private val eventRepository: EventRepository, private val keyCommandRepository: KeyCommandRepository, ) { suspend operator fun invoke( @@ -20,15 +17,12 @@ class SendTabCommandUseCase( device = device, keycode = tabKeyCode, onStart = { - eventRepository.sendEvent(Event.StartSendKeyCommand(tabKeyCode)) onStart() }, onFailed = { - eventRepository.sendEvent(Event.ErrorSendKeyCommand(tabKeyCode)) onFailed() }, onComplete = { - eventRepository.sendEvent(Event.EndSendKeyCommand(tabKeyCode)) onComplete() }, ) diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/text/SendUserInputTextCommandUseCase.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/text/SendUserInputTextCommandUseCase.kt index e3ec4d4..a87b3d1 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/text/SendUserInputTextCommandUseCase.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/text/SendUserInputTextCommandUseCase.kt @@ -1,12 +1,9 @@ package jp.kaleidot725.adbpad.domain.usecase.text import jp.kaleidot725.adbpad.domain.model.device.Device -import jp.kaleidot725.adbpad.domain.model.log.Event -import jp.kaleidot725.adbpad.domain.repository.EventRepository import jp.kaleidot725.adbpad.domain.repository.TextCommandRepository class SendUserInputTextCommandUseCase( - private val eventRepository: EventRepository, private val textCommandRepository: TextCommandRepository, ) { suspend operator fun invoke( @@ -20,15 +17,12 @@ class SendUserInputTextCommandUseCase( device = device, text = text, onStart = { - eventRepository.sendEvent(Event.StartSendTextCommand(text)) onStart() }, onFailed = { - eventRepository.sendEvent(Event.ErrorSendTextCommand(text)) onFailed() }, onComplete = { - eventRepository.sendEvent(Event.EndSendTextCommand(text)) onComplete() }, ) diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/di/RepositoryModule.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/di/RepositoryModule.kt index 529b1d4..346379e 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/di/RepositoryModule.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/di/RepositoryModule.kt @@ -1,14 +1,12 @@ package jp.kaleidot725.adbpad.repository.di import jp.kaleidot725.adbpad.domain.repository.DeviceRepository -import jp.kaleidot725.adbpad.domain.repository.EventRepository import jp.kaleidot725.adbpad.domain.repository.KeyCommandRepository import jp.kaleidot725.adbpad.domain.repository.NormalCommandRepository import jp.kaleidot725.adbpad.domain.repository.ScreenshotCommandRepository import jp.kaleidot725.adbpad.domain.repository.SettingRepository import jp.kaleidot725.adbpad.domain.repository.TextCommandRepository import jp.kaleidot725.adbpad.repository.impl.DeviceRepositoryImpl -import jp.kaleidot725.adbpad.repository.impl.EventRepositoryImpl import jp.kaleidot725.adbpad.repository.impl.KeyCommandRepositoryImpl import jp.kaleidot725.adbpad.repository.impl.NormalCommandRepositoryImpl import jp.kaleidot725.adbpad.repository.impl.ScreenshotCommandRepositoryImpl @@ -19,9 +17,6 @@ import ui.repository.VersionRepository val repositoryModule = module { - single { - EventRepositoryImpl() - } single { DeviceRepositoryImpl() } diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/impl/EventRepositoryImpl.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/impl/EventRepositoryImpl.kt deleted file mode 100644 index bea08e6..0000000 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/impl/EventRepositoryImpl.kt +++ /dev/null @@ -1,15 +0,0 @@ -package jp.kaleidot725.adbpad.repository.impl - -import jp.kaleidot725.adbpad.domain.model.log.Event -import jp.kaleidot725.adbpad.domain.repository.EventRepository -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.SharedFlow - -class EventRepositoryImpl : EventRepository { - private val _event: MutableSharedFlow = MutableSharedFlow() - override val event: SharedFlow = _event - - override suspend fun sendEvent(event: Event) { - _event.emit(event) - } -} diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/impl/NormalCommandRepositoryImpl.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/impl/NormalCommandRepositoryImpl.kt index dc4fc29..1e81b92 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/impl/NormalCommandRepositoryImpl.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/impl/NormalCommandRepositoryImpl.kt @@ -14,6 +14,8 @@ class NormalCommandRepositoryImpl : NormalCommandRepository { override fun getCommands(): List { return listOf( + NormalCommand.PointerLocationOn(runningCommands.any { it is NormalCommand.PointerLocationOn }), + NormalCommand.PointerLocationOff(runningCommands.any { it is NormalCommand.PointerLocationOff }), NormalCommand.LayoutBorderOn(runningCommands.any { it is NormalCommand.LayoutBorderOn }), NormalCommand.LayoutBorderOff(runningCommands.any { it is NormalCommand.LayoutBorderOff }), NormalCommand.TapEffectOn(runningCommands.any { it is NormalCommand.TapEffectOn }), diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/component/layout/ScreenLayout.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/component/layout/ScreenLayout.kt index 25b3ac5..c11710c 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/component/layout/ScreenLayout.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/component/layout/ScreenLayout.kt @@ -21,6 +21,7 @@ import jp.kaleidot725.adbpad.domain.model.UserColor @Composable fun ScreenLayout( + top: @Composable () -> Unit, navigationRail: @Composable () -> Unit, content: @Composable () -> Unit, dialog: @Composable () -> Unit, @@ -28,6 +29,8 @@ fun ScreenLayout( ) { Box(modifier) { Column { + top() + Spacer(Modifier.height(1.dp).fillMaxWidth().border(BorderStroke(1.dp, UserColor.getSplitterColor()))) Row(modifier = Modifier.weight(0.9f, true)) { Box(Modifier.background(MaterialTheme.colors.background)) { navigationRail() } Spacer(Modifier.width(1.dp).fillMaxHeight().border(BorderStroke(1.dp, UserColor.getSplitterColor()))) @@ -43,6 +46,9 @@ fun ScreenLayout( @Composable private fun ScreenLayout_Preview() { ScreenLayout( + top = { + Box(Modifier.height(50.dp).fillMaxWidth().background(androidx.compose.ui.graphics.Color.Red)) + }, navigationRail = { Box(Modifier.width(50.dp).fillMaxHeight().background(androidx.compose.ui.graphics.Color.Yellow)) }, diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/di/StateHolderModule.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/di/StateHolderModule.kt index fb41ad0..f30f43f 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/di/StateHolderModule.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/di/StateHolderModule.kt @@ -56,7 +56,6 @@ val stateHolderModule = commandStateHolder = get(), textCommandStateHolder = get(), screenshotStateHolder = get(), - getEventFlowUseCase = get(), getWindowSizeUseCase = get(), saveWindowSizeUseCase = get(), startAdbUseCase = get(), diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/command/component/CommandItem.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/command/component/CommandItem.kt index 173959e..6bda436 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/command/component/CommandItem.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/command/component/CommandItem.kt @@ -3,6 +3,7 @@ package jp.kaleidot725.adbpad.ui.screen.command.component import androidx.compose.desktop.ui.tooling.preview.Preview import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding @@ -14,6 +15,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import jp.kaleidot725.adbpad.domain.model.language.Language import jp.kaleidot725.adbpad.ui.component.RunningIndicator @@ -30,7 +32,8 @@ fun CommandItem( Card(modifier, elevation = 1.dp) { Column(verticalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxHeight().padding(8.dp)) { Text(text = title, fontWeight = FontWeight.Bold) - Text(text = detail) + Text(text = detail, maxLines = 3, overflow = TextOverflow.Clip) + Spacer(modifier = Modifier.weight(1.0f)) Button(onClick = { onExecute() }, enabled = canExecute, modifier = Modifier.align(Alignment.End)) { when { isRunning -> RunningIndicator() diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/command/component/CommandList.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/command/component/CommandList.kt index 6453f3e..1465ef6 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/command/component/CommandList.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/command/component/CommandList.kt @@ -41,7 +41,7 @@ fun CommandList( isRunning = command.isRunning, canExecute = canExecute, onExecute = { onExecute(command) }, - modifier = Modifier.height(150.dp).fillMaxWidth().padding(2.dp), + modifier = Modifier.height(175.dp).fillMaxWidth().padding(2.dp), ) } } diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/menu/component/DeviceSelector.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/menu/component/DeviceSelector.kt index fca82bf..691b793 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/menu/component/DeviceSelector.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/menu/component/DeviceSelector.kt @@ -13,7 +13,6 @@ import androidx.compose.material.icons.filled.ArrowDropDown import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import jp.kaleidot725.adbpad.domain.model.device.Device import jp.kaleidot725.adbpad.domain.model.device.DeviceState @@ -32,14 +31,14 @@ fun DeviceSelector( Text( text = selectedDevice?.serial ?: Language.notFoundDevice, style = MaterialTheme.typography.subtitle2, - color = Color.White, + color = MaterialTheme.colors.onBackground, modifier = Modifier.align(Alignment.CenterVertically), ) Icon( imageVector = Icons.Filled.ArrowDropDown, contentDescription = "Device DropDown Icon", - tint = Color.White, + tint = MaterialTheme.colors.onBackground, modifier = Modifier.align(Alignment.CenterVertically).padding(top = 6.dp), ) } diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/menu/component/DropDownDeviceMenu.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/menu/component/DropDownDeviceMenu.kt index 981147c..4c0e050 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/menu/component/DropDownDeviceMenu.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/menu/component/DropDownDeviceMenu.kt @@ -60,6 +60,7 @@ fun DropDownDeviceMenu( ) { Text( text = device.serial, + color = MaterialTheme.colors.onBackground, style = MaterialTheme.typography.subtitle2, ) } diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/setting/component/LanguageDropButton.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/setting/component/LanguageDropButton.kt index 48d54ac..1392d62 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/setting/component/LanguageDropButton.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/ui/screen/setting/component/LanguageDropButton.kt @@ -85,6 +85,7 @@ private fun Language.Type.title(): String { return when (this) { Language.Type.ENGLISH -> Language.settingLanguageEnglish Language.Type.JAPANESE -> Language.settingLanguageJapanese + Language.Type.CHINESE -> Language.settingLanguageChinese } }