feat: migrate from hilt to koin for DI

This commit is contained in:
infi 2026-05-03 19:43:07 +02:00
parent 10efd73965
commit 68e0b56afa
22 changed files with 141 additions and 150 deletions

View File

@ -1,20 +1,18 @@
import com.mikepenz.aboutlibraries.plugin.StrictMode import com.mikepenz.aboutlibraries.plugin.StrictMode
import io.sentry.android.gradle.instrumentation.logcat.LogcatLevel import io.sentry.android.gradle.instrumentation.logcat.LogcatLevel
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import java.io.FileInputStream import java.io.FileInputStream
import java.util.Properties import java.util.Properties
plugins { plugins {
alias(libs.plugins.android.application) alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.serialization) alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.kotlin.compose) alias(libs.plugins.kotlin.compose)
alias(libs.plugins.aboutlibraries) alias(libs.plugins.aboutlibraries)
alias(libs.plugins.hilt)
alias(libs.plugins.ksp) alias(libs.plugins.ksp)
alias(libs.plugins.sentry.android) alias(libs.plugins.sentry.android)
alias(libs.plugins.sqldelight) alias(libs.plugins.sqldelight)
alias(libs.plugins.google.services) alias(libs.plugins.google.services)
id("kotlin-kapt")
id("kotlin-parcelize") id("kotlin-parcelize")
} }
@ -128,9 +126,6 @@ android {
sourceCompatibility = JavaVersion.VERSION_17 sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17
} }
kotlinOptions {
jvmTarget = "17"
}
buildFeatures { buildFeatures {
viewBinding = true viewBinding = true
compose = true compose = true
@ -156,6 +151,12 @@ android {
} }
} }
kotlin {
compilerOptions {
jvmTarget = JvmTarget.JVM_17
}
}
sentry { sentry {
autoUploadProguardMapping = autoUploadProguardMapping =
buildproperty("sentry.upload_mappings", "RVX_SENTRY_UPLOAD_MAPPINGS") == "true" buildproperty("sentry.upload_mappings", "RVX_SENTRY_UPLOAD_MAPPINGS") == "true"
@ -209,10 +210,6 @@ dependencies {
debugImplementation(libs.compose.ui.tooling) debugImplementation(libs.compose.ui.tooling)
debugImplementation(libs.compose.ui.test.manifest) debugImplementation(libs.compose.ui.test.manifest)
implementation(libs.hilt.android)
implementation(libs.hilt.navigation.compose)
ksp(libs.hilt.compiler)
implementation(libs.glide) implementation(libs.glide)
implementation(libs.glide.compose) implementation(libs.glide.compose)
ksp(libs.glide.ksp) ksp(libs.glide.ksp)
@ -272,6 +269,10 @@ dependencies {
implementation(libs.square.logcat) implementation(libs.square.logcat)
implementation(libs.koin)
implementation(libs.koin.compose)
implementation(libs.koin.compose.viewmodel.navigation)
androidTestImplementation(libs.android.test.core) androidTestImplementation(libs.android.test.core)
androidTestImplementation(libs.android.test.rules) androidTestImplementation(libs.android.test.rules)
androidTestImplementation(libs.compose.ui.test.junit4) androidTestImplementation(libs.compose.ui.test.junit4)
@ -283,15 +284,16 @@ aboutLibraries {
strictMode = StrictMode.FAIL strictMode = StrictMode.FAIL
allowedLicenses += listOf( allowedLicenses += listOf(
"Apache-2.0", "Apache-2.0",
"OFL",
"MIT",
"ASDKL", "ASDKL",
"BSD-2-Clause", "BSD-2-Clause",
"BSD-3-Clause", "The 3-Clause BSD License",
"BSD License",
"cmark", "cmark",
"EPL-1.0", "EPL-1.0",
"BSD-3-Clause", "MIT",
"BSD License", "ML Kit Terms of Service",
"ML Kit Terms of Service" "OFL",
"Public Domain"
) )
configPath = "compliance" configPath = "compliance"
} }

View File

@ -3,12 +3,15 @@ package chat.stoat
import android.app.Application import android.app.Application
import android.os.Build import android.os.Build
import android.os.StrictMode import android.os.StrictMode
import chat.stoat.di.appModule
import chat.stoat.di.viewModelModule
import com.google.android.material.color.DynamicColors import com.google.android.material.color.DynamicColors
import dagger.hilt.android.HiltAndroidApp
import logcat.AndroidLogcatLogger import logcat.AndroidLogcatLogger
import logcat.LogPriority import logcat.LogPriority
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.startKoin
@HiltAndroidApp
class StoatApplication : Application() { class StoatApplication : Application() {
companion object { companion object {
lateinit var instance: StoatApplication lateinit var instance: StoatApplication
@ -18,6 +21,12 @@ class StoatApplication : Application() {
super.onCreate() super.onCreate()
AndroidLogcatLogger.installOnDebuggableApp(this, minPriority = LogPriority.VERBOSE) AndroidLogcatLogger.installOnDebuggableApp(this, minPriority = LogPriority.VERBOSE)
startKoin {
androidContext(this@StoatApplication)
androidLogger()
modules(appModule, viewModelModule)
}
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
// Enable strict mode primarily to catch non-API usage, although we detect all // Enable strict mode primarily to catch non-API usage, although we detect all
// violations for our reference. // violations for our reference.

View File

@ -1,6 +1,5 @@
package chat.stoat.activities package chat.stoat.activities
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.NetworkCapabilities import android.net.NetworkCapabilities
@ -15,7 +14,6 @@ import android.view.ViewTreeObserver
import android.widget.Toast import android.widget.Toast
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.compose.animation.AnimatedContentTransitionScope import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
@ -126,20 +124,15 @@ import chat.stoat.screens.settings.channel.ChannelSettingsOverview
import chat.stoat.screens.settings.channel.ChannelSettingsPermissions import chat.stoat.screens.settings.channel.ChannelSettingsPermissions
import chat.stoat.ui.theme.StoatTheme import chat.stoat.ui.theme.StoatTheme
import com.google.android.material.color.DynamicColors import com.google.android.material.color.DynamicColors
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import io.ktor.client.request.get import io.ktor.client.request.get
import io.sentry.android.core.SentryAndroid import io.sentry.android.core.SentryAndroid
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import org.koin.androidx.viewmodel.ext.android.viewModel
@HiltViewModel class MainActivityViewModel(
@SuppressLint("StaticFieldLeak")
class MainActivityViewModel @Inject constructor(
private val kvStorage: KVStorage, private val kvStorage: KVStorage,
@ApplicationContext private val context: Context private val context: Context
) : ViewModel() { ) : ViewModel() {
val nextDestination = MutableStateFlow<String?>(null) val nextDestination = MutableStateFlow<String?>(null)
var isConnected = MutableStateFlow(false) var isConnected = MutableStateFlow(false)
@ -324,9 +317,8 @@ class MainActivityViewModel @Inject constructor(
} }
} }
@AndroidEntryPoint
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
private val viewModel by viewModels<MainActivityViewModel>() private val viewModel: MainActivityViewModel by viewModel()
// Fix for SDK >=31, where core-splashscreen accidentally removes dynamic colours // Fix for SDK >=31, where core-splashscreen accidentally removes dynamic colours
// See the other one in DefaultDestinationScreen.kt // See the other one in DefaultDestinationScreen.kt

View File

@ -43,11 +43,11 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalResources
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import chat.stoat.R import chat.stoat.R
@ -57,7 +57,6 @@ import chat.stoat.api.routes.channel.sendMessage
import chat.stoat.api.routes.microservices.autumn.FileArgs import chat.stoat.api.routes.microservices.autumn.FileArgs
import chat.stoat.api.routes.microservices.autumn.MAX_ATTACHMENTS_PER_MESSAGE import chat.stoat.api.routes.microservices.autumn.MAX_ATTACHMENTS_PER_MESSAGE
import chat.stoat.api.routes.microservices.autumn.uploadToAutumn import chat.stoat.api.routes.microservices.autumn.uploadToAutumn
import chat.stoat.core.model.schemas.ChannelType
import chat.stoat.api.settings.LoadedSettings import chat.stoat.api.settings.LoadedSettings
import chat.stoat.api.settings.SyncedSettings import chat.stoat.api.settings.SyncedSettings
import chat.stoat.composables.chat.MessageField import chat.stoat.composables.chat.MessageField
@ -66,17 +65,15 @@ import chat.stoat.composables.screens.chat.AttachmentManager
import chat.stoat.composables.screens.chat.drawer.ChannelItem import chat.stoat.composables.screens.chat.drawer.ChannelItem
import chat.stoat.composables.screens.chat.drawer.ChannelItemIconType import chat.stoat.composables.screens.chat.drawer.ChannelItemIconType
import chat.stoat.composables.screens.chat.drawer.DMOrGroupItem import chat.stoat.composables.screens.chat.drawer.DMOrGroupItem
import chat.stoat.core.model.schemas.ChannelType
import chat.stoat.persistence.KVStorage import chat.stoat.persistence.KVStorage
import chat.stoat.screens.chat.views.channel.ChannelScreenActivePane import chat.stoat.screens.chat.views.channel.ChannelScreenActivePane
import chat.stoat.ui.theme.StoatTheme import chat.stoat.ui.theme.StoatTheme
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.lifecycle.HiltViewModel
import io.ktor.http.ContentType import io.ktor.http.ContentType
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.androidx.compose.koinViewModel
import java.io.File import java.io.File
import javax.inject.Inject
@AndroidEntryPoint
class ShareTargetActivity : ComponentActivity() { class ShareTargetActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -163,8 +160,7 @@ class ShareTargetActivity : ComponentActivity() {
} }
} }
@HiltViewModel class ShareTargetScreenViewModel(
class ShareTargetScreenViewModel @Inject constructor(
private val kvStorage: KVStorage, private val kvStorage: KVStorage,
) : ViewModel() { ) : ViewModel() {
var apiIsReady by mutableStateOf(false) var apiIsReady by mutableStateOf(false)
@ -229,15 +225,16 @@ fun ShareTargetScreen(
text: String?, text: String?,
media: List<Uri>?, media: List<Uri>?,
onFinished: () -> Unit = {}, onFinished: () -> Unit = {},
viewModel: ShareTargetScreenViewModel = hiltViewModel() viewModel: ShareTargetScreenViewModel = koinViewModel()
) { ) {
val context = LocalContext.current val context = LocalContext.current
val resources = LocalResources.current
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
if (!viewModel.isLoggedIn()) { if (!viewModel.isLoggedIn()) {
Toast.makeText( Toast.makeText(
context, context,
context.getString(R.string.share_target_login_first), resources.getString(R.string.share_target_login_first),
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
@ -412,7 +409,7 @@ fun ShareTargetScreen(
if (selectedChannel == null) { if (selectedChannel == null) {
Toast.makeText( Toast.makeText(
context, context,
context.getString(R.string.share_target_select_channel), resources.getString(R.string.share_target_select_channel),
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
return@MessageField return@MessageField

View File

@ -0,0 +1,10 @@
package chat.stoat.di
import chat.stoat.persistence.KVStorage
import org.koin.android.ext.koin.androidContext
import org.koin.dsl.module
//
val appModule = module {
single { KVStorage(androidContext()) }
}

View File

@ -0,0 +1,35 @@
package chat.stoat.di
import chat.stoat.activities.MainActivityViewModel
import chat.stoat.activities.ShareTargetScreenViewModel
import chat.stoat.screens.chat.ChatRouterViewModel
import chat.stoat.screens.chat.views.channel.ChannelScreenViewModel
import chat.stoat.screens.login.LoginViewModel
import chat.stoat.screens.login.MfaScreenViewModel
import chat.stoat.screens.settings.AppearanceSettingsScreenViewModel
import chat.stoat.screens.settings.ChangelogsSettingsScreenViewModel
import chat.stoat.screens.settings.DebugSettingsScreenViewModel
import chat.stoat.screens.settings.ProfileSettingsScreenViewModel
import chat.stoat.screens.settings.SettingsScreenViewModel
import chat.stoat.screens.settings.channel.ChannelSettingsOverviewViewModel
import chat.stoat.sheets.MemberListSheetViewModel
import org.koin.android.ext.koin.androidApplication
import org.koin.android.ext.koin.androidContext
import org.koin.core.module.dsl.viewModel
import org.koin.dsl.module
val viewModelModule = module {
viewModel { MainActivityViewModel(get(), androidContext()) }
viewModel { ChatRouterViewModel(get(), androidContext()) }
viewModel { MemberListSheetViewModel(androidApplication()) }
viewModel { ShareTargetScreenViewModel(get()) }
viewModel { ChannelScreenViewModel(get()) }
viewModel { MfaScreenViewModel(get()) }
viewModel { SettingsScreenViewModel(get()) }
viewModel { DebugSettingsScreenViewModel(get()) }
viewModel { LoginViewModel(get()) }
viewModel { ProfileSettingsScreenViewModel(androidApplication()) }
viewModel { ChangelogsSettingsScreenViewModel(get(), androidApplication()) }
viewModel { AppearanceSettingsScreenViewModel(androidApplication()) }
viewModel { ChannelSettingsOverviewViewModel(androidApplication()) }
}

View File

@ -6,16 +6,12 @@ import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore import androidx.datastore.preferences.preferencesDataStore
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.firstOrNull
import javax.inject.Inject
import javax.inject.Singleton
val Context.stoatKVStorage: DataStore<Preferences> by preferencesDataStore(name = "revolt_kv") val Context.stoatKVStorage: DataStore<Preferences> by preferencesDataStore(name = "revolt_kv")
@Singleton class KVStorage(
class KVStorage @Inject constructor( private val mContext: Context
@ApplicationContext private val mContext: Context
) { ) {
private val dataStore = mContext.stoatKVStorage private val dataStore = mContext.stoatKVStorage

View File

@ -1,6 +1,5 @@
package chat.stoat.screens.chat package chat.stoat.screens.chat
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
import android.util.Log import android.util.Log
@ -60,7 +59,6 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.compose.LifecycleEventEffect import androidx.lifecycle.compose.LifecycleEventEffect
@ -101,12 +99,10 @@ import chat.stoat.sheets.WebHookUserSheet
import chat.stoat.sheets.spark.SwipeToReplySparkSheet import chat.stoat.sheets.spark.SwipeToReplySparkSheet
import com.google.android.gms.tasks.OnCompleteListener import com.google.android.gms.tasks.OnCompleteListener
import com.google.firebase.messaging.FirebaseMessaging import com.google.firebase.messaging.FirebaseMessaging
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import io.sentry.Sentry import io.sentry.Sentry
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import org.koin.androidx.compose.koinViewModel
sealed class ChatRouterDestination { sealed class ChatRouterDestination {
data object Overview : ChatRouterDestination() data object Overview : ChatRouterDestination()
@ -145,11 +141,9 @@ sealed class ChatRouterDestination {
} }
} }
@HiltViewModel class ChatRouterViewModel(
@SuppressLint("StaticFieldLeak")
class ChatRouterViewModel @Inject constructor(
private val kvStorage: KVStorage, private val kvStorage: KVStorage,
@ApplicationContext val context: Context val context: Context
) : ViewModel() { ) : ViewModel() {
var currentDestination by mutableStateOf<ChatRouterDestination>(ChatRouterDestination.default) var currentDestination by mutableStateOf<ChatRouterDestination>(ChatRouterDestination.default)
var latestChangelogRead by mutableStateOf(true) var latestChangelogRead by mutableStateOf(true)
@ -281,7 +275,7 @@ fun ChatRouterScreen(
disableBackHandler: Boolean, disableBackHandler: Boolean,
onNullifiedUser: () -> Unit, onNullifiedUser: () -> Unit,
onEnterVoiceUI: (String) -> Unit, onEnterVoiceUI: (String) -> Unit,
viewModel: ChatRouterViewModel = hiltViewModel() viewModel: ChatRouterViewModel = koinViewModel()
) { ) {
val drawerState = rememberDrawerState(DrawerValue.Closed) val drawerState = rememberDrawerState(DrawerValue.Closed)
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()

View File

@ -104,7 +104,6 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import androidx.hilt.navigation.compose.hiltViewModel
import chat.stoat.R import chat.stoat.R
import chat.stoat.StoatApplication import chat.stoat.StoatApplication
import chat.stoat.activities.StoatTweenDp import chat.stoat.activities.StoatTweenDp
@ -153,6 +152,7 @@ import com.valentinilk.shimmer.shimmer
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.datetime.Instant import kotlinx.datetime.Instant
import org.koin.androidx.compose.koinViewModel
import java.io.File import java.io.File
import kotlin.math.max import kotlin.math.max
@ -198,7 +198,7 @@ fun ChannelScreen(
drawerIsOpen: Boolean = false, drawerIsOpen: Boolean = false,
backButtonAction: (() -> Unit)? = null, backButtonAction: (() -> Unit)? = null,
useChatUI: Boolean = false, useChatUI: Boolean = false,
viewModel: ChannelScreenViewModel = hiltViewModel() viewModel: ChannelScreenViewModel = koinViewModel()
) { ) {
// <editor-fold desc="State and effects"> // <editor-fold desc="State and effects">
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()

View File

@ -52,7 +52,6 @@ import chat.stoat.internals.text.MessageProcessor
import chat.stoat.persistence.KVStorage import chat.stoat.persistence.KVStorage
import chat.stoat.screens.chat.ChatRouterDestination import chat.stoat.screens.chat.ChatRouterDestination
import chat.stoat.settings.providers.AgeGateUnlockedStorageProvider import chat.stoat.settings.providers.AgeGateUnlockedStorageProvider
import dagger.hilt.android.lifecycle.HiltViewModel
import io.ktor.http.ContentType import io.ktor.http.ContentType
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
@ -66,10 +65,8 @@ import kotlinx.datetime.Clock
import kotlinx.datetime.Instant import kotlinx.datetime.Instant
import kotlinx.datetime.toJavaInstant import kotlinx.datetime.toJavaInstant
import java.time.ZoneId import java.time.ZoneId
import javax.inject.Inject
@HiltViewModel class ChannelScreenViewModel(
class ChannelScreenViewModel @Inject constructor(
private val kvStorage: KVStorage, private val kvStorage: KVStorage,
) : ViewModel() { ) : ViewModel() {
var items = mutableStateListOf<ChannelScreenItem>() var items = mutableStateListOf<ChannelScreenItem>()

View File

@ -43,7 +43,6 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.navigation.NavController import androidx.navigation.NavController
@ -58,12 +57,10 @@ import chat.stoat.composables.generic.FormTextField
import chat.stoat.composables.generic.Weblink import chat.stoat.composables.generic.Weblink
import chat.stoat.persistence.KVStorage import chat.stoat.persistence.KVStorage
import chat.stoat.ui.theme.FragmentMono import chat.stoat.ui.theme.FragmentMono
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import org.koin.androidx.compose.koinViewModel
@HiltViewModel class LoginViewModel(
class LoginViewModel @Inject constructor(
private val kvStorage: KVStorage private val kvStorage: KVStorage
) : ViewModel() { ) : ViewModel() {
private var _email by mutableStateOf("") private var _email by mutableStateOf("")
@ -151,7 +148,7 @@ class LoginViewModel @Inject constructor(
} }
@Composable @Composable
fun LoginScreen(navController: NavController, viewModel: LoginViewModel = hiltViewModel()) { fun LoginScreen(navController: NavController, viewModel: LoginViewModel = koinViewModel()) {
val passwordTextFieldState = rememberTextFieldState() val passwordTextFieldState = rememberTextFieldState()
LaunchedEffect(passwordTextFieldState.text) { LaunchedEffect(passwordTextFieldState.text) {
viewModel.setPassword(passwordTextFieldState.text.toString()) viewModel.setPassword(passwordTextFieldState.text.toString())

View File

@ -32,7 +32,6 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.navigation.NavController import androidx.navigation.NavController
@ -45,12 +44,10 @@ import chat.stoat.api.routes.account.authenticateWithMfaTotpCode
import chat.stoat.composables.generic.CollapsibleCard import chat.stoat.composables.generic.CollapsibleCard
import chat.stoat.composables.generic.FormTextField import chat.stoat.composables.generic.FormTextField
import chat.stoat.persistence.KVStorage import chat.stoat.persistence.KVStorage
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import org.koin.androidx.compose.koinViewModel
@HiltViewModel class MfaScreenViewModel(
class MfaScreenViewModel @Inject constructor(
private val kvStorage: KVStorage private val kvStorage: KVStorage
) : ViewModel() { ) : ViewModel() {
private var _totpCode by mutableStateOf("") private var _totpCode by mutableStateOf("")
@ -142,7 +139,7 @@ fun MfaScreen(
navController: NavController, navController: NavController,
allowedAuthTypesCommaSep: String, allowedAuthTypesCommaSep: String,
mfaTicket: String, mfaTicket: String,
viewModel: MfaScreenViewModel = hiltViewModel() viewModel: MfaScreenViewModel = koinViewModel()
) { ) {
val allowedAuthTypes = allowedAuthTypesCommaSep.split(",") val allowedAuthTypes = allowedAuthTypesCommaSep.split(",")

View File

@ -1,6 +1,6 @@
package chat.stoat.screens.settings package chat.stoat.screens.settings
import android.content.Context import android.app.Application
import android.net.Uri import android.net.Uri
import android.widget.Toast import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
@ -50,6 +50,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalResources
import androidx.compose.ui.platform.testTag import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@ -59,7 +60,6 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.navigation.NavController import androidx.navigation.NavController
@ -82,20 +82,14 @@ import chat.stoat.ui.theme.getFieldByName
import chat.stoat.ui.theme.overridableColourSchemeFieldNameToResource import chat.stoat.ui.theme.overridableColourSchemeFieldNameToResource
import chat.stoat.ui.theme.overridableColourSchemeFieldNames import chat.stoat.ui.theme.overridableColourSchemeFieldNames
import chat.stoat.ui.theme.systemSupportsDynamicColors import chat.stoat.ui.theme.systemSupportsDynamicColors
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.builtins.MapSerializer import kotlinx.serialization.builtins.MapSerializer
import kotlinx.serialization.builtins.serializer import kotlinx.serialization.builtins.serializer
import org.koin.androidx.compose.koinViewModel
import java.io.File import java.io.File
import javax.inject.Inject
@HiltViewModel class AppearanceSettingsScreenViewModel(val context: Application) : ViewModel() {
@Suppress("StaticFieldLeak")
class AppearanceSettingsScreenViewModel @Inject constructor(
@ApplicationContext val context: Context
) : ViewModel() {
var showColourOverrides by mutableStateOf(false) var showColourOverrides by mutableStateOf(false)
var selectedOverrideName by mutableStateOf<String?>(null) var selectedOverrideName by mutableStateOf<String?>(null)
var selectedOverrideInitialValue by mutableStateOf<Int?>(null) var selectedOverrideInitialValue by mutableStateOf<Int?>(null)
@ -224,7 +218,7 @@ class AppearanceSettingsScreenViewModel @Inject constructor(
@Composable @Composable
fun AppearanceSettingsScreen( fun AppearanceSettingsScreen(
navController: NavController, navController: NavController,
viewModel: AppearanceSettingsScreenViewModel = hiltViewModel() viewModel: AppearanceSettingsScreenViewModel = koinViewModel()
) { ) {
val colourOverridesOpenerArrowRotation by animateFloatAsState( val colourOverridesOpenerArrowRotation by animateFloatAsState(
if (viewModel.showColourOverrides) { if (viewModel.showColourOverrides) {
@ -249,6 +243,7 @@ fun AppearanceSettingsScreen(
} }
val context = LocalContext.current val context = LocalContext.current
val resources = LocalResources.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
if (viewModel.overridePickerSheetVisible) { if (viewModel.overridePickerSheetVisible) {
@ -404,9 +399,7 @@ fun AppearanceSettingsScreen(
) { ) {
Toast.makeText( Toast.makeText(
context, context,
context.getString( resources.getString(R.string.settings_appearance_theme_m3dynamic_unsupported_toast),
R.string.settings_appearance_theme_m3dynamic_unsupported_toast
),
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
} }
@ -555,7 +548,7 @@ fun AppearanceSettingsScreen(
ColourChip( ColourChip(
color = Color(value ?: 0), color = Color(value ?: 0),
text = overridableColourSchemeFieldNameToResource[fieldName] text = overridableColourSchemeFieldNameToResource[fieldName]
?.let { context.getString(it) } ?.let { stringResource(it) }
?: fieldName, ?: fieldName,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()

View File

@ -1,6 +1,6 @@
package chat.stoat.screens.settings package chat.stoat.screens.settings
import android.content.Context import android.app.Application
import android.text.format.DateUtils import android.text.format.DateUtils
import androidx.compose.animation.Crossfade import androidx.compose.animation.Crossfade
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@ -36,7 +36,6 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.navigation.NavController import androidx.navigation.NavController
@ -45,16 +44,13 @@ import chat.stoat.internals.ChangelogIndex
import chat.stoat.internals.Changelogs import chat.stoat.internals.Changelogs
import chat.stoat.persistence.KVStorage import chat.stoat.persistence.KVStorage
import chat.stoat.sheets.ChangelogSheet import chat.stoat.sheets.ChangelogSheet
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.datetime.Instant import kotlinx.datetime.Instant
import javax.inject.Inject import org.koin.androidx.compose.koinViewModel
@HiltViewModel class ChangelogsSettingsScreenViewModel(
class ChangelogsSettingsScreenViewModel @Inject constructor(
val kvStorage: KVStorage, val kvStorage: KVStorage,
@ApplicationContext val context: Context val context: Application
) : ViewModel() { ) : ViewModel() {
var index by mutableStateOf<ChangelogIndex?>(null) var index by mutableStateOf<ChangelogIndex?>(null)
var renderedChangelog by mutableStateOf("") var renderedChangelog by mutableStateOf("")
@ -87,7 +83,7 @@ class ChangelogsSettingsScreenViewModel @Inject constructor(
@Composable @Composable
fun ChangelogsSettingsScreen( fun ChangelogsSettingsScreen(
navController: NavController, navController: NavController,
viewModel: ChangelogsSettingsScreenViewModel = hiltViewModel() viewModel: ChangelogsSettingsScreenViewModel = koinViewModel()
) { ) {
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
viewModel.populate() viewModel.populate()

View File

@ -42,7 +42,6 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.navigation.NavController import androidx.navigation.NavController
@ -57,12 +56,10 @@ import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailabilityLight import com.google.android.gms.common.GoogleApiAvailabilityLight
import com.google.android.gms.tasks.OnCompleteListener import com.google.android.gms.tasks.OnCompleteListener
import com.google.firebase.messaging.FirebaseMessaging import com.google.firebase.messaging.FirebaseMessaging
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import org.koin.androidx.compose.koinViewModel
@HiltViewModel class DebugSettingsScreenViewModel(
class DebugSettingsScreenViewModel @Inject constructor(
private val kvStorage: KVStorage private val kvStorage: KVStorage
) : ViewModel() { ) : ViewModel() {
fun forgetAllSparks() { fun forgetAllSparks() {
@ -103,7 +100,7 @@ class DebugSettingsScreenViewModel @Inject constructor(
@Composable @Composable
fun DebugSettingsScreen( fun DebugSettingsScreen(
navController: NavController, navController: NavController,
viewModel: DebugSettingsScreenViewModel = hiltViewModel() viewModel: DebugSettingsScreenViewModel = koinViewModel()
) { ) {
val context = LocalContext.current val context = LocalContext.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()

View File

@ -1,6 +1,6 @@
package chat.stoat.screens.settings package chat.stoat.screens.settings
import android.content.Context import android.app.Application
import android.net.Uri import android.net.Uri
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@ -42,7 +42,6 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.navigation.NavController import androidx.navigation.NavController
@ -52,19 +51,15 @@ import chat.stoat.api.StoatAPI
import chat.stoat.api.routes.microservices.autumn.uploadToAutumn import chat.stoat.api.routes.microservices.autumn.uploadToAutumn
import chat.stoat.api.routes.user.fetchUserProfile import chat.stoat.api.routes.user.fetchUserProfile
import chat.stoat.api.routes.user.patchSelf import chat.stoat.api.routes.user.patchSelf
import chat.stoat.core.model.schemas.Profile
import chat.stoat.composables.generic.InlineMediaPicker import chat.stoat.composables.generic.InlineMediaPicker
import chat.stoat.composables.screens.settings.RawUserOverview import chat.stoat.composables.screens.settings.RawUserOverview
import dagger.hilt.android.lifecycle.HiltViewModel import chat.stoat.core.model.schemas.Profile
import dagger.hilt.android.qualifiers.ApplicationContext
import io.ktor.http.ContentType import io.ktor.http.ContentType
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.androidx.compose.koinViewModel
import java.io.File import java.io.File
import javax.inject.Inject
@HiltViewModel class ProfileSettingsScreenViewModel(val context: Application) :
@Suppress("StaticFieldLeak")
class ProfileSettingsScreenViewModel @Inject constructor(@ApplicationContext val context: Context) :
ViewModel() { ViewModel() {
var isLoading by mutableStateOf(true) var isLoading by mutableStateOf(true)
var pfpModel by mutableStateOf<Any?>(null) var pfpModel by mutableStateOf<Any?>(null)
@ -237,7 +232,7 @@ class ProfileSettingsScreenViewModel @Inject constructor(@ApplicationContext val
@Composable @Composable
fun ProfileSettingsScreen( fun ProfileSettingsScreen(
navController: NavController, navController: NavController,
viewModel: ProfileSettingsScreenViewModel = hiltViewModel() viewModel: ProfileSettingsScreenViewModel = koinViewModel()
) { ) {
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior() val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()

View File

@ -29,7 +29,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import chat.stoat.BuildConfig import chat.stoat.BuildConfig
@ -40,12 +39,10 @@ import chat.stoat.api.settings.FeatureFlags
import chat.stoat.api.settings.LoadedSettings import chat.stoat.api.settings.LoadedSettings
import chat.stoat.composables.generic.ListHeader import chat.stoat.composables.generic.ListHeader
import chat.stoat.persistence.KVStorage import chat.stoat.persistence.KVStorage
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import javax.inject.Inject import org.koin.androidx.compose.koinViewModel
@HiltViewModel class SettingsScreenViewModel(
class SettingsScreenViewModel @Inject constructor(
private val kvStorage: KVStorage private val kvStorage: KVStorage
) : ViewModel() { ) : ViewModel() {
fun logout() { fun logout() {
@ -61,7 +58,7 @@ class SettingsScreenViewModel @Inject constructor(
@Composable @Composable
fun SettingsScreen( fun SettingsScreen(
navController: NavController, navController: NavController,
viewModel: SettingsScreenViewModel = hiltViewModel() viewModel: SettingsScreenViewModel = koinViewModel()
) { ) {
val context = LocalContext.current val context = LocalContext.current
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior() val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()

View File

@ -1,6 +1,6 @@
package chat.stoat.screens.settings.channel package chat.stoat.screens.settings.channel
import android.content.Context import android.app.Application
import android.net.Uri import android.net.Uri
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
@ -47,7 +47,6 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.navigation.NavController import androidx.navigation.NavController
@ -57,18 +56,15 @@ import chat.stoat.api.STOAT_FILES
import chat.stoat.api.StoatAPI import chat.stoat.api.StoatAPI
import chat.stoat.api.routes.channel.patchChannel import chat.stoat.api.routes.channel.patchChannel
import chat.stoat.api.routes.microservices.autumn.uploadToAutumn import chat.stoat.api.routes.microservices.autumn.uploadToAutumn
import chat.stoat.core.model.schemas.Channel
import chat.stoat.composables.generic.InlineMediaPicker import chat.stoat.composables.generic.InlineMediaPicker
import chat.stoat.composables.generic.ListHeader import chat.stoat.composables.generic.ListHeader
import dagger.hilt.android.lifecycle.HiltViewModel import chat.stoat.core.model.schemas.Channel
import dagger.hilt.android.qualifiers.ApplicationContext
import io.ktor.http.ContentType import io.ktor.http.ContentType
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.androidx.compose.koinViewModel
import java.io.File import java.io.File
import javax.inject.Inject
@HiltViewModel class ChannelSettingsOverviewViewModel(val context: Application) :
class ChannelSettingsOverviewViewModel @Inject constructor(@ApplicationContext val context: Context) :
ViewModel() { ViewModel() {
var initialChannel by mutableStateOf<Channel?>(null) var initialChannel by mutableStateOf<Channel?>(null)
@ -211,7 +207,7 @@ class ChannelSettingsOverviewViewModel @Inject constructor(@ApplicationContext v
fun ChannelSettingsOverview( fun ChannelSettingsOverview(
navController: NavController, navController: NavController,
channelId: String, channelId: String,
viewModel: ChannelSettingsOverviewViewModel = hiltViewModel() viewModel: ChannelSettingsOverviewViewModel = koinViewModel()
) { ) {
val currentChannel = StoatAPI.channelCache[channelId] val currentChannel = StoatAPI.channelCache[channelId]
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior() val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()

View File

@ -1,7 +1,6 @@
package chat.stoat.sheets package chat.stoat.sheets
import android.annotation.SuppressLint import android.app.Application
import android.content.Context
import android.util.Log import android.util.Log
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
@ -29,7 +28,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import chat.stoat.R import chat.stoat.R
@ -46,11 +44,9 @@ import chat.stoat.composables.generic.SheetHeaderPadding
import chat.stoat.composables.generic.presenceFromStatus import chat.stoat.composables.generic.presenceFromStatus
import chat.stoat.core.model.schemas.Member import chat.stoat.core.model.schemas.Member
import chat.stoat.core.model.schemas.User import chat.stoat.core.model.schemas.User
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import org.koin.androidx.compose.koinViewModel
val DO_NOT_FETCH_OFFLINE_MEMBERS_SERVERS = listOf( val DO_NOT_FETCH_OFFLINE_MEMBERS_SERVERS = listOf(
"01F7ZSBSFHQ8TA81725KQCSDDP" // Lounge "01F7ZSBSFHQ8TA81725KQCSDDP" // Lounge
@ -62,10 +58,8 @@ sealed class MemberListSheetItem {
data class CategoryItem(val category: String, val count: Int) : MemberListSheetItem() data class CategoryItem(val category: String, val count: Int) : MemberListSheetItem()
} }
@HiltViewModel class MemberListSheetViewModel(
@SuppressLint("StaticFieldLeak") private val context: Application
class MemberListSheetViewModel @Inject constructor(
@ApplicationContext private val context: Context
) : ViewModel() { ) : ViewModel() {
val fullItemList = mutableStateListOf<MemberListSheetItem>() val fullItemList = mutableStateListOf<MemberListSheetItem>()
@ -207,7 +201,7 @@ class MemberListSheetViewModel @Inject constructor(
fun MemberListSheet( fun MemberListSheet(
channelId: String, channelId: String,
serverId: String? = null, serverId: String? = null,
viewModel: MemberListSheetViewModel = hiltViewModel() viewModel: MemberListSheetViewModel = koinViewModel()
) { ) {
var showUserInfoSheet by remember { mutableStateOf(false) } var showUserInfoSheet by remember { mutableStateOf(false) }
var userInfoSheetTarget by remember { mutableStateOf("") } var userInfoSheetTarget by remember { mutableStateOf("") }

View File

@ -5,7 +5,6 @@ plugins {
alias(libs.plugins.kotlin.serialization) apply false alias(libs.plugins.kotlin.serialization) apply false
alias(libs.plugins.kotlin.compose) apply false alias(libs.plugins.kotlin.compose) apply false
alias(libs.plugins.kotlin.jvm) apply false alias(libs.plugins.kotlin.jvm) apply false
alias(libs.plugins.hilt) apply false
alias(libs.plugins.aboutlibraries) apply false alias(libs.plugins.aboutlibraries) apply false
alias(libs.plugins.ksp) apply false alias(libs.plugins.ksp) apply false
alias(libs.plugins.google.services) apply false alias(libs.plugins.google.services) apply false

View File

@ -1,7 +1,6 @@
plugins { plugins {
alias(libs.plugins.android.library) alias(libs.plugins.android.library)
id("kotlin-parcelize") id("kotlin-parcelize")
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.serialization) alias(libs.plugins.kotlin.serialization)
} }
java { java {

View File

@ -7,10 +7,9 @@ kotlin = "2.3.10"
kotlin-serialization = "1.10.0" kotlin-serialization = "1.10.0"
ksp = "2.3.5" ksp = "2.3.5"
agp = "9.1.0" agp = "9.1.0"
hilt = "2.59.2"
google-services = "4.4.4" google-services = "4.4.4"
sentry = "8.13.2" # This is separate from the gradle plugin version which is defined ad hoc below sentry = "8.13.2" # This is separate from the gradle plugin version which is defined ad hoc below
sqldelight = "2.0.1" sqldelight = "2.3.2"
compose-bom = "2026.03.00" compose-bom = "2026.03.00"
material3 = "1.5.0-alpha15" material3 = "1.5.0-alpha15"
lifecycle = "2.10.0" lifecycle = "2.10.0"
@ -25,6 +24,7 @@ chucker = "4.3.1"
androidx-test = "1.6.1" androidx-test = "1.6.1"
livekit = "2.24.1" livekit = "2.24.1"
livekit-compose = "2.3.0" livekit-compose = "2.3.0"
koin = "4.2.1"
[libraries] [libraries]
android-core-ktx = { module = "androidx.core:core-ktx", version = "1.16.0" } android-core-ktx = { module = "androidx.core:core-ktx", version = "1.16.0" }
@ -67,10 +67,7 @@ ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "k
ktor-client-contentnegotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } ktor-client-contentnegotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }
ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", 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" }
navigation-compose = { module = "androidx.navigation:navigation-compose", version = "2.9.0" } navigation-compose = { module = "androidx.navigation:navigation-compose", version = "2.9.8" }
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version = "1.2.0" }
hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }
glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" } glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }
glide-compose = { module = "com.github.bumptech.glide:compose", version = "1.0.0-beta01" } glide-compose = { module = "com.github.bumptech.glide:compose", version = "1.0.0-beta01" }
glide-ksp = { module = "com.github.bumptech.glide:ksp", version.ref = "glide" } glide-ksp = { module = "com.github.bumptech.glide:ksp", version.ref = "glide" }
@ -101,6 +98,9 @@ square-logcat = { module = "com.squareup.logcat:logcat", version = "0.1" }
livekit-android = { module = "io.livekit:livekit-android", version.ref = "livekit" } livekit-android = { module = "io.livekit:livekit-android", version.ref = "livekit" }
livekit-android-camerax = { module = "io.livekit:livekit-android-camerax", version.ref = "livekit" } livekit-android-camerax = { module = "io.livekit:livekit-android-camerax", version.ref = "livekit" }
livekit-android-compose = { module = "io.livekit:livekit-android-compose-components", version.ref = "livekit-compose" } livekit-android-compose = { module = "io.livekit:livekit-android-compose-components", version.ref = "livekit-compose" }
koin = { module = "io.insert-koin:koin-android", version.ref = "koin" }
koin-compose = { module = "io.insert-koin:koin-androidx-compose", version.ref = "koin" }
koin-compose-viewmodel-navigation = { module = "io.insert-koin:koin-compose-viewmodel-navigation", version.ref = "koin" }
[plugins] [plugins]
android-application = { id = "com.android.application", version.ref = "agp" } android-application = { id = "com.android.application", version.ref = "agp" }
@ -109,9 +109,8 @@ kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
aboutlibraries = { id = "com.mikepenz.aboutlibraries.plugin", version.ref = "aboutlibraries" } aboutlibraries = { id = "com.mikepenz.aboutlibraries.plugin", version.ref = "aboutlibraries" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
google-services = { id = "com.google.gms.google-services", version.ref = "google-services" } google-services = { id = "com.google.gms.google-services", version.ref = "google-services" }
sentry-android = { id = "io.sentry.android.gradle", version = "4.12.0" } sentry-android = { id = "io.sentry.android.gradle", version = "6.5.0" }
sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" } sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" }