Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1818aa6602 | |||
| ad2a102f1f |
+6
-6
@@ -1,8 +1,8 @@
|
|||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.multiplatform).apply(false)
|
alias(libs.plugins.multiplatform) apply false
|
||||||
alias(libs.plugins.compose.compiler).apply(false)
|
alias(libs.plugins.compose.compiler) apply false
|
||||||
alias(libs.plugins.compose).apply(false)
|
alias(libs.plugins.compose) apply false
|
||||||
alias(libs.plugins.compose.hot.reload).apply(false)
|
alias(libs.plugins.compose.hot.reload) apply false
|
||||||
alias(libs.plugins.android.application).apply(false)
|
alias(libs.plugins.android.application) apply false
|
||||||
alias(libs.plugins.kotlinx.serialization).apply(false)
|
alias(libs.plugins.kotlinx.serialization) apply false
|
||||||
}
|
}
|
||||||
|
|||||||
+46
-67
@@ -2,8 +2,6 @@ import org.jetbrains.compose.ExperimentalComposeLibrary
|
|||||||
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
|
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
|
||||||
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
||||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
@@ -15,21 +13,6 @@ plugins {
|
|||||||
alias(libs.plugins.kotlinx.serialization)
|
alias(libs.plugins.kotlinx.serialization)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<KotlinCompile>().configureEach {
|
|
||||||
compilerOptions {
|
|
||||||
freeCompilerArgs.addAll(
|
|
||||||
"-opt-in=kotlin.RequiresOptIn",
|
|
||||||
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
|
|
||||||
"-opt-in=kotlinx.coroutines.FlowPreview",
|
|
||||||
"-Xexpect-actual-classes"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compose.resources {
|
|
||||||
nameOfResClass = "R"
|
|
||||||
}
|
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
androidTarget {
|
androidTarget {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
@@ -39,53 +22,48 @@ kotlin {
|
|||||||
|
|
||||||
jvm()
|
jvm()
|
||||||
|
|
||||||
if (providers.gradleProperty("include_ios").get().toBoolean()) {
|
listOf(
|
||||||
listOf(
|
iosArm64(),
|
||||||
iosX64(),
|
iosSimulatorArm64()
|
||||||
iosArm64(),
|
).forEach { iosTarget ->
|
||||||
iosSimulatorArm64()
|
iosTarget.binaries.framework {
|
||||||
).forEach { iosTarget ->
|
baseName = "ComposeApp"
|
||||||
iosTarget.binaries.framework {
|
isStatic = true
|
||||||
baseName = "ComposeApp"
|
|
||||||
isStatic = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (providers.gradleProperty("include_wasm").get().toBoolean()) {
|
js {
|
||||||
@OptIn(ExperimentalWasmDsl::class)
|
browser()
|
||||||
wasmJs {
|
binaries.executable()
|
||||||
outputModuleName = "composeApp"
|
}
|
||||||
browser {
|
|
||||||
val rootDirPath = project.rootDir.path
|
@OptIn(ExperimentalWasmDsl::class)
|
||||||
val projectDirPath = project.projectDir.path
|
wasmJs {
|
||||||
commonWebpackConfig {
|
browser()
|
||||||
outputFileName = "composeApp.js"
|
binaries.executable()
|
||||||
devServer = (devServer ?: KotlinWebpackConfig.DevServer()).apply {
|
|
||||||
static = (static ?: mutableListOf()).apply {
|
|
||||||
// Serve sources to debug inside browser
|
|
||||||
add(rootDirPath)
|
|
||||||
add(projectDirPath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
binaries.executable()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
androidMain.dependencies {
|
||||||
|
implementation(compose.preview)
|
||||||
|
implementation(libs.androidx.activityCompose)
|
||||||
|
implementation(libs.kotlinx.coroutines.android)
|
||||||
|
implementation(libs.ktor.client.okhttp)
|
||||||
|
implementation(libs.kstore.file)
|
||||||
|
}
|
||||||
|
|
||||||
commonMain.dependencies {
|
commonMain.dependencies {
|
||||||
implementation(compose.runtime)
|
implementation(compose.runtime)
|
||||||
implementation(compose.foundation)
|
implementation(compose.foundation)
|
||||||
implementation(compose.material3)
|
implementation(compose.material3)
|
||||||
implementation(compose.materialIconsExtended)
|
implementation(compose.materialIconsExtended)
|
||||||
implementation(compose.components.resources)
|
implementation(compose.components.resources)
|
||||||
|
implementation(compose.components.uiToolingPreview)
|
||||||
implementation(libs.androidx.navigation.compose)
|
implementation(libs.androidx.navigation.compose)
|
||||||
implementation(libs.coil)
|
implementation(libs.coil)
|
||||||
implementation(libs.coil.network.ktor)
|
implementation(libs.coil.network.ktor)
|
||||||
implementation(libs.kotlinx.coroutines.core)
|
implementation(libs.kotlinx.coroutines.core)
|
||||||
implementation(libs.ktor.core)
|
implementation(libs.ktor.client.core)
|
||||||
implementation(libs.ktor.client.content.negotiation)
|
implementation(libs.ktor.client.content.negotiation)
|
||||||
implementation(libs.ktor.kotlinx.serialization.json)
|
implementation(libs.ktor.kotlinx.serialization.json)
|
||||||
implementation(libs.kotlinx.serialization.json)
|
implementation(libs.kotlinx.serialization.json)
|
||||||
@@ -102,20 +80,12 @@ kotlin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
commonTest.dependencies {
|
commonTest.dependencies {
|
||||||
implementation(kotlin("test"))
|
implementation(libs.kotlin.test)
|
||||||
@OptIn(ExperimentalComposeLibrary::class)
|
@OptIn(ExperimentalComposeLibrary::class)
|
||||||
implementation(compose.uiTest)
|
implementation(compose.uiTest)
|
||||||
implementation(libs.kotlinx.coroutines.test)
|
implementation(libs.kotlinx.coroutines.test)
|
||||||
}
|
}
|
||||||
|
|
||||||
androidMain.dependencies {
|
|
||||||
implementation(compose.uiTooling)
|
|
||||||
implementation(libs.androidx.activityCompose)
|
|
||||||
implementation(libs.kotlinx.coroutines.android)
|
|
||||||
implementation(libs.ktor.client.okhttp)
|
|
||||||
implementation(libs.kstore.file)
|
|
||||||
}
|
|
||||||
|
|
||||||
jvmMain.dependencies {
|
jvmMain.dependencies {
|
||||||
implementation(compose.desktop.currentOs)
|
implementation(compose.desktop.currentOs)
|
||||||
implementation(libs.kotlinx.coroutines.swing)
|
implementation(libs.kotlinx.coroutines.swing)
|
||||||
@@ -124,18 +94,14 @@ kotlin {
|
|||||||
implementation(libs.kstore.file)
|
implementation(libs.kstore.file)
|
||||||
}
|
}
|
||||||
|
|
||||||
findByName("iosMain")?.run {
|
iosMain.dependencies {
|
||||||
dependencies {
|
implementation(libs.ktor.client.darwin)
|
||||||
implementation(libs.ktor.client.darwin)
|
implementation(libs.kstore.file)
|
||||||
implementation(libs.kstore.file)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
findByName("wasmJsMain")?.run {
|
webMain.dependencies {
|
||||||
dependencies {
|
implementation(libs.kstore.storage)
|
||||||
implementation(libs.kstore.storage)
|
implementation(libs.ktor.client.js)
|
||||||
implementation(libs.ktor.client.js)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -211,6 +177,10 @@ dependencies {
|
|||||||
debugImplementation(compose.uiTooling)
|
debugImplementation(compose.uiTooling)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compose.resources {
|
||||||
|
nameOfResClass = "R"
|
||||||
|
}
|
||||||
|
|
||||||
compose.desktop {
|
compose.desktop {
|
||||||
application {
|
application {
|
||||||
mainClass = "MainKt"
|
mainClass = "MainKt"
|
||||||
@@ -222,3 +192,12 @@ compose.desktop {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
compilerOptions.freeCompilerArgs.addAll(
|
||||||
|
"-opt-in=kotlin.RequiresOptIn",
|
||||||
|
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
|
||||||
|
"-opt-in=kotlinx.coroutines.FlowPreview",
|
||||||
|
"-Xexpect-actual-classes"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package dev.meloda.overseerr
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
|
||||||
|
class AndroidPlatform : Platform {
|
||||||
|
override val name: String = "Android ${Build.VERSION.SDK_INT}"
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun getPlatform(): Platform = AndroidPlatform()
|
||||||
@@ -1,16 +1,5 @@
|
|||||||
package dev.meloda.overseerr.common
|
package dev.meloda.overseerr.common
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import dev.meloda.overseerr.di.appModule
|
|
||||||
import org.koin.core.context.startKoin
|
|
||||||
|
|
||||||
class AppGlobal : Application() {
|
class AppGlobal : Application()
|
||||||
|
|
||||||
override fun onCreate() {
|
|
||||||
super.onCreate()
|
|
||||||
|
|
||||||
startKoin {
|
|
||||||
modules(appModule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -8,30 +8,34 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import dev.meloda.overseerr.datastore.SettingsController
|
import dev.meloda.overseerr.datastore.SettingsController
|
||||||
|
import dev.meloda.overseerr.di.appModule
|
||||||
import dev.meloda.overseerr.screens.main.MainScreen
|
import dev.meloda.overseerr.screens.main.MainScreen
|
||||||
import dev.meloda.overseerr.theme.AppTheme
|
import dev.meloda.overseerr.theme.AppTheme
|
||||||
import io.github.aakira.napier.DebugAntilog
|
import io.github.aakira.napier.DebugAntilog
|
||||||
import io.github.aakira.napier.Napier
|
import io.github.aakira.napier.Napier
|
||||||
|
import org.koin.compose.KoinApplication
|
||||||
import org.koin.compose.koinInject
|
import org.koin.compose.koinInject
|
||||||
|
|
||||||
var appDir: String = ""
|
var appDir: String = ""
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun App() {
|
internal fun App() {
|
||||||
LaunchedEffect(true) {
|
KoinApplication(application = { modules(appModule) }) {
|
||||||
Napier.base(DebugAntilog())
|
LaunchedEffect(true) {
|
||||||
}
|
Napier.base(DebugAntilog())
|
||||||
|
}
|
||||||
|
|
||||||
val settingsController: SettingsController = koinInject()
|
val settingsController: SettingsController = koinInject()
|
||||||
val settings by settingsController.settings.collectAsStateWithLifecycle()
|
val settings by settingsController.settings.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LaunchedEffect(true) {
|
LaunchedEffect(true) {
|
||||||
settingsController.loadAppSettings()
|
settingsController.loadAppSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
AppTheme(themeMode = settings.themeMode) {
|
AppTheme(themeMode = settings.themeMode) {
|
||||||
Surface(modifier = Modifier.fillMaxSize()) {
|
Surface(modifier = Modifier.fillMaxSize()) {
|
||||||
MainScreen()
|
MainScreen()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package dev.meloda.overseerr
|
||||||
|
|
||||||
|
interface Platform {
|
||||||
|
val name: String
|
||||||
|
}
|
||||||
|
|
||||||
|
expect fun getPlatform(): Platform
|
||||||
+13
-21
@@ -1,43 +1,35 @@
|
|||||||
package dev.meloda.overseerr.datastore
|
package dev.meloda.overseerr.datastore
|
||||||
|
|
||||||
import dev.meloda.overseerr.ext.setValue
|
|
||||||
import dev.meloda.overseerr.datastore.model.AppSettings
|
import dev.meloda.overseerr.datastore.model.AppSettings
|
||||||
import dev.meloda.overseerr.datastore.model.ThemeMode
|
import dev.meloda.overseerr.datastore.model.ThemeMode
|
||||||
|
import dev.meloda.overseerr.ext.setValue
|
||||||
import io.github.xxfast.kstore.KStore
|
import io.github.xxfast.kstore.KStore
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
|
||||||
interface SettingsController {
|
|
||||||
val settings: StateFlow<AppSettings>
|
|
||||||
|
|
||||||
suspend fun saveAppSettings()
|
class SettingsController(
|
||||||
suspend fun updateAppSettings(update: (AppSettings) -> AppSettings)
|
private val store: KStore<AppSettings>,
|
||||||
suspend fun loadAppSettings(): AppSettings
|
) {
|
||||||
|
private val _settings = MutableStateFlow(AppSettings.EMPTY)
|
||||||
|
val settings: StateFlow<AppSettings> = _settings.asStateFlow()
|
||||||
|
|
||||||
fun updateThemeMode(newThemeMode: ThemeMode)
|
suspend fun saveAppSettings() {
|
||||||
}
|
|
||||||
|
|
||||||
class SettingsControllerImpl(
|
|
||||||
private val store: KStore<AppSettings>
|
|
||||||
) : SettingsController {
|
|
||||||
|
|
||||||
override val settings = MutableStateFlow(AppSettings.EMPTY)
|
|
||||||
|
|
||||||
override suspend fun saveAppSettings() {
|
|
||||||
store.set(settings.value)
|
store.set(settings.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateAppSettings(update: (AppSettings) -> AppSettings) {
|
suspend fun updateAppSettings(update: (AppSettings) -> AppSettings) {
|
||||||
store.set(update(settings.value))
|
store.set(update(settings.value))
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun loadAppSettings(): AppSettings {
|
suspend fun loadAppSettings(): AppSettings {
|
||||||
val loadedSettings = store.get() ?: AppSettings.EMPTY
|
val loadedSettings = store.get() ?: AppSettings.EMPTY
|
||||||
settings.setValue { loadedSettings }
|
_settings.setValue { loadedSettings }
|
||||||
return loadedSettings
|
return loadedSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateThemeMode(newThemeMode: ThemeMode) {
|
fun updateThemeMode(newThemeMode: ThemeMode) {
|
||||||
settings.setValue { old -> old.copy(themeMode = newThemeMode) }
|
_settings.setValue { old -> old.copy(themeMode = newThemeMode) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-3
@@ -1,13 +1,11 @@
|
|||||||
package dev.meloda.overseerr.datastore.di
|
package dev.meloda.overseerr.datastore.di
|
||||||
|
|
||||||
import dev.meloda.overseerr.datastore.SettingsController
|
import dev.meloda.overseerr.datastore.SettingsController
|
||||||
import dev.meloda.overseerr.datastore.SettingsControllerImpl
|
|
||||||
import dev.meloda.overseerr.datastore.SettingsStoreProvider
|
import dev.meloda.overseerr.datastore.SettingsStoreProvider
|
||||||
import org.koin.core.module.dsl.singleOf
|
import org.koin.core.module.dsl.singleOf
|
||||||
import org.koin.dsl.bind
|
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
|
|
||||||
val dataStoreModule = module {
|
val dataStoreModule = module {
|
||||||
single { SettingsStoreProvider().provideStore() }
|
single { SettingsStoreProvider().provideStore() }
|
||||||
singleOf(::SettingsControllerImpl) bind SettingsController::class
|
singleOf(::SettingsController)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import kotlinx.serialization.Serializable
|
|||||||
data class AppSettings(
|
data class AppSettings(
|
||||||
val url: String? = null,
|
val url: String? = null,
|
||||||
val plexToken: String? = null,
|
val plexToken: String? = null,
|
||||||
val themeMode: ThemeMode = ThemeMode.System,
|
val themeMode: ThemeMode = ThemeMode.System
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
val EMPTY: AppSettings = AppSettings()
|
val EMPTY: AppSettings = AppSettings()
|
||||||
|
|||||||
-1
@@ -21,7 +21,6 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import dev.chrisbanes.haze.hazeSource
|
import dev.chrisbanes.haze.hazeSource
|
||||||
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
|
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
|
||||||
import dev.chrisbanes.haze.materials.HazeMaterials
|
|
||||||
import dev.meloda.overseerr.screens.requests.RequestsViewModel
|
import dev.meloda.overseerr.screens.requests.RequestsViewModel
|
||||||
import dev.meloda.overseerr.screens.requests.RequestsViewModelImpl
|
import dev.meloda.overseerr.screens.requests.RequestsViewModelImpl
|
||||||
import dev.meloda.overseerr.screens.requests.model.RequestsScreenState
|
import dev.meloda.overseerr.screens.requests.model.RequestsScreenState
|
||||||
|
|||||||
-1
@@ -6,7 +6,6 @@ import androidx.compose.foundation.text.KeyboardOptions
|
|||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
|
|||||||
+1
-8
@@ -1,12 +1,5 @@
|
|||||||
import androidx.compose.ui.window.ComposeUIViewController
|
import androidx.compose.ui.window.ComposeUIViewController
|
||||||
import dev.meloda.overseerr.App
|
import dev.meloda.overseerr.App
|
||||||
import dev.meloda.overseerr.di.appModule
|
|
||||||
import org.koin.core.context.startKoin
|
|
||||||
import platform.UIKit.UIViewController
|
import platform.UIKit.UIViewController
|
||||||
|
|
||||||
fun MainViewController(): UIViewController = ComposeUIViewController {
|
fun MainViewController(): UIViewController = ComposeUIViewController { App() }
|
||||||
startKoin {
|
|
||||||
modules(appModule)
|
|
||||||
}
|
|
||||||
App()
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package dev.meloda.overseerr
|
||||||
|
|
||||||
|
import platform.UIKit.UIDevice
|
||||||
|
|
||||||
|
class IOSPlatform : Platform {
|
||||||
|
override val name: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun getPlatform(): Platform = IOSPlatform()
|
||||||
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
package dev.meloda.overseerr.settings.model
|
package dev.meloda.overseerr.datastore
|
||||||
|
|
||||||
import dev.meloda.overseerr.appDir
|
import dev.meloda.overseerr.appDir
|
||||||
|
import dev.meloda.overseerr.datastore.model.AppSettings
|
||||||
import io.github.xxfast.kstore.KStore
|
import io.github.xxfast.kstore.KStore
|
||||||
import io.github.xxfast.kstore.file.storeOf
|
import io.github.xxfast.kstore.file.storeOf
|
||||||
import kotlinx.io.files.Path
|
import kotlinx.io.files.Path
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package dev.meloda.overseerr.model
|
|
||||||
|
|
||||||
internal actual class Platform actual constructor() {
|
|
||||||
actual val name: String
|
|
||||||
get() = "iOS"
|
|
||||||
}
|
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
package dev.meloda.overseerr.network
|
||||||
|
|
||||||
|
import io.ktor.client.engine.HttpClientEngineFactory
|
||||||
|
import io.ktor.client.engine.darwin.Darwin
|
||||||
|
|
||||||
|
actual class HttpClientEngineFactoryProvider actual constructor() {
|
||||||
|
actual fun get(): HttpClientEngineFactory<*> = Darwin
|
||||||
|
}
|
||||||
-8
@@ -1,8 +0,0 @@
|
|||||||
package dev.meloda.overseerr.network.model
|
|
||||||
|
|
||||||
import io.ktor.client.engine.*
|
|
||||||
import io.ktor.client.engine.darwin.*
|
|
||||||
|
|
||||||
actual class HttpClientEngineFactoryProvider actual constructor() {
|
|
||||||
actual fun get(): HttpClientEngineFactory<*> = Darwin
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package dev.meloda.overseerr
|
||||||
|
|
||||||
|
class JsPlatform : Platform {
|
||||||
|
override val name: String = "Web with Kotlin/JS"
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun getPlatform(): Platform = JsPlatform()
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
package dev.meloda.overseerr.network
|
||||||
|
|
||||||
|
import io.ktor.client.engine.HttpClientEngineFactory
|
||||||
|
import io.ktor.client.engine.js.Js
|
||||||
|
|
||||||
|
actual class HttpClientEngineFactoryProvider actual constructor() {
|
||||||
|
actual fun get(): HttpClientEngineFactory<*> = Js
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import kotlinx.browser.window
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
actual fun ResizableWindow(content: @Composable () -> Unit) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.width(window.innerWidth.coerceIn(360..600).dp)
|
||||||
|
.height(window.innerHeight.coerceIn(minimumValue = 360, maximumValue = null).dp)
|
||||||
|
) {
|
||||||
|
content()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package dev.meloda.overseerr
|
||||||
|
|
||||||
|
class JVMPlatform : Platform {
|
||||||
|
override val name: String = "Java ${System.getProperty("java.version")}"
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun getPlatform(): Platform = JVMPlatform()
|
||||||
@@ -5,10 +5,8 @@ import androidx.compose.ui.window.application
|
|||||||
import androidx.compose.ui.window.rememberWindowState
|
import androidx.compose.ui.window.rememberWindowState
|
||||||
import dev.meloda.overseerr.App
|
import dev.meloda.overseerr.App
|
||||||
import dev.meloda.overseerr.appDir
|
import dev.meloda.overseerr.appDir
|
||||||
import dev.meloda.overseerr.di.appModule
|
|
||||||
import io.github.aakira.napier.Napier
|
import io.github.aakira.napier.Napier
|
||||||
import net.harawata.appdirs.AppDirsFactory
|
import net.harawata.appdirs.AppDirsFactory
|
||||||
import org.koin.compose.KoinApplication
|
|
||||||
import java.awt.Dimension
|
import java.awt.Dimension
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -28,10 +26,10 @@ fun main() = application {
|
|||||||
state = state,
|
state = state,
|
||||||
onCloseRequest = ::exitApplication
|
onCloseRequest = ::exitApplication
|
||||||
) {
|
) {
|
||||||
window.minimumSize = Dimension(320, 480)
|
LaunchedEffect(Unit) {
|
||||||
|
window.minimumSize = Dimension(320, 480)
|
||||||
KoinApplication(application = { modules(appModule) }) {
|
|
||||||
App()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
App()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package dev.meloda.overseerr
|
||||||
|
|
||||||
|
class WasmPlatform : Platform {
|
||||||
|
override val name: String = "Web with Kotlin/Wasm"
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun getPlatform(): Platform = WasmPlatform()
|
||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
package dev.meloda.overseerr.network
|
package dev.meloda.overseerr.network
|
||||||
|
|
||||||
import io.ktor.client.engine.*
|
import io.ktor.client.engine.HttpClientEngineFactory
|
||||||
import io.ktor.client.engine.js.*
|
import io.ktor.client.engine.js.Js
|
||||||
|
|
||||||
actual class HttpClientEngineFactoryProvider actual constructor() {
|
actual class HttpClientEngineFactoryProvider actual constructor() {
|
||||||
actual fun get(): HttpClientEngineFactory<*> = Js
|
actual fun get(): HttpClientEngineFactory<*> = Js
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.window.ComposeViewport
|
|
||||||
import dev.meloda.overseerr.App
|
|
||||||
import dev.meloda.overseerr.di.appModule
|
|
||||||
import kotlinx.browser.document
|
|
||||||
import kotlinx.browser.window
|
|
||||||
import org.koin.compose.KoinApplication
|
|
||||||
|
|
||||||
@OptIn(ExperimentalComposeUiApi::class)
|
|
||||||
fun main() {
|
|
||||||
ComposeViewport(document.body!!) {
|
|
||||||
KoinApplication(application = { modules(appModule) }) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
contentAlignment = Alignment.Center
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.width(window.innerWidth.coerceIn(360..600).dp)
|
|
||||||
.height(window.innerHeight.coerceIn(minimumValue = 360, maximumValue = null).dp)
|
|
||||||
) {
|
|
||||||
App()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import kotlinx.browser.window
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
actual fun ResizableWindow(content: @Composable () -> Unit) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.width(window.innerWidth.coerceIn(360..600).dp)
|
||||||
|
.height(window.innerHeight.coerceIn(minimumValue = 360, maximumValue = null).dp)
|
||||||
|
) {
|
||||||
|
content()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
-2
@@ -1,14 +1,12 @@
|
|||||||
package dev.meloda.overseerr.theme
|
package dev.meloda.overseerr.theme
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.navigation.ExperimentalBrowserHistoryApi
|
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal actual fun SystemAppearance(isDark: Boolean) {
|
internal actual fun SystemAppearance(isDark: Boolean) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalBrowserHistoryApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
internal actual fun NavigationSettings(navController: NavController) {
|
internal actual fun NavigationSettings(navController: NavController) {
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||||
|
import androidx.compose.ui.window.ComposeViewport
|
||||||
|
import dev.meloda.overseerr.App
|
||||||
|
|
||||||
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
|
fun main() {
|
||||||
|
ComposeViewport {
|
||||||
|
ResizableWindow {
|
||||||
|
App()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
expect fun ResizableWindow(content: @Composable () -> Unit)
|
||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Wasm App</title>
|
<title>Web App</title>
|
||||||
<link type="text/css" rel="stylesheet" href="styles.css">
|
<link type="text/css" rel="stylesheet" href="styles.css">
|
||||||
<script type="application/javascript" src="composeApp.js"></script>
|
<script type="application/javascript" src="composeApp.js"></script>
|
||||||
</head>
|
</head>
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Temporary workaround for [KT-80582](https://youtrack.jetbrains.com/issue/KT-80582)
|
||||||
|
*
|
||||||
|
* This file should be safe to be removed once the ticket is closed and the project is updated to Kotlin version which solves that issue.
|
||||||
|
*/
|
||||||
|
config.watchOptions = config.watchOptions || {
|
||||||
|
ignored: ["**/*.kt", "**/node_modules"]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.devServer) {
|
||||||
|
config.devServer.static = config.devServer.static.map(file => {
|
||||||
|
if (typeof file === "string") {
|
||||||
|
return {
|
||||||
|
directory: file,
|
||||||
|
watch: false,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
+4
-10
@@ -1,22 +1,16 @@
|
|||||||
|
#Kotlin
|
||||||
|
kotlin.code.style=official
|
||||||
|
kotlin.daemon.jvmargs=-Xmx4G
|
||||||
#Gradle
|
#Gradle
|
||||||
org.gradle.jvmargs=-Xmx4G
|
org.gradle.jvmargs=-Xmx4096M -Dfile.encoding=UTF-8
|
||||||
org.gradle.caching=true
|
org.gradle.caching=true
|
||||||
org.gradle.configuration-cache=true
|
org.gradle.configuration-cache=true
|
||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
|
|
||||||
#Kotlin
|
|
||||||
kotlin.code.style=official
|
|
||||||
kotlin.daemon.jvmargs=-Xmx4G
|
|
||||||
kotlin.native.ignoreDisabledTargets=true
|
|
||||||
kotlin.native.enableKlibsCrossCompilation=true
|
|
||||||
|
|
||||||
#Android
|
#Android
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.nonTransitiveRClass=true
|
android.nonTransitiveRClass=true
|
||||||
|
|
||||||
include_wasm=true
|
|
||||||
include_ios=false
|
include_ios=false
|
||||||
|
|
||||||
#Flip this to false when including the ios targets
|
#Flip this to false when including the ios targets
|
||||||
org.gradle.unsafe.configuration-cache=true
|
org.gradle.unsafe.configuration-cache=true
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-c
|
|||||||
kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" }
|
kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" }
|
||||||
kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" }
|
kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" }
|
||||||
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" }
|
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" }
|
||||||
ktor-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
|
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
|
||||||
ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" }
|
ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" }
|
||||||
ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" }
|
ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" }
|
||||||
ktor-client-js = { module = "io.ktor:ktor-client-js", version.ref = "ktor" }
|
ktor-client-js = { module = "io.ktor:ktor-client-js", version.ref = "ktor" }
|
||||||
@@ -52,6 +52,8 @@ kstore-storage = { module = "io.github.xxfast:kstore-storage", version.ref = "ks
|
|||||||
appdirs = { module = "net.harawata:appdirs", version.ref = "appdirs" }
|
appdirs = { module = "net.harawata:appdirs", version.ref = "appdirs" }
|
||||||
napier = { module = "io.github.aakira:napier", version.ref = "napier" }
|
napier = { module = "io.github.aakira:napier", version.ref = "napier" }
|
||||||
|
|
||||||
|
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
|
multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
|
||||||
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
) -> Bool {
|
) -> Bool {
|
||||||
window = UIWindow(frame: UIScreen.main.bounds)
|
window = UIWindow(frame: UIScreen.main.bounds)
|
||||||
if let window = window {
|
if let window = window {
|
||||||
window.rootViewController = MainKt.MainViewController()
|
window.rootViewController = MainViewControllerKt.MainViewController()
|
||||||
window.makeKeyAndVisible()
|
window.makeKeyAndVisible()
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|||||||
+13
-13
@@ -4,32 +4,32 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
|||||||
pluginManagement {
|
pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
google {
|
google {
|
||||||
content {
|
mavenContent {
|
||||||
includeGroupByRegex("com\\.android.*")
|
includeGroupAndSubgroups("androidx")
|
||||||
includeGroupByRegex("com\\.google.*")
|
includeGroupAndSubgroups("com.android")
|
||||||
includeGroupByRegex("androidx.*")
|
includeGroupAndSubgroups("com.google")
|
||||||
includeGroupByRegex("android.*")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
plugins {
|
|
||||||
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencyResolutionManagement {
|
dependencyResolutionManagement {
|
||||||
repositories {
|
repositories {
|
||||||
google {
|
google {
|
||||||
content {
|
mavenContent {
|
||||||
includeGroupByRegex("com\\.android.*")
|
includeGroupAndSubgroups("androidx")
|
||||||
includeGroupByRegex("com\\.google.*")
|
includeGroupAndSubgroups("com.android")
|
||||||
includeGroupByRegex("androidx.*")
|
includeGroupAndSubgroups("com.google")
|
||||||
includeGroupByRegex("android.*")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
|
||||||
|
}
|
||||||
|
|
||||||
include(":composeApp")
|
include(":composeApp")
|
||||||
|
|||||||
Reference in New Issue
Block a user