diff --git a/KNOWN_ISSUES.md b/KNOWN_ISSUES.md
index 17bbd57..066666e 100644
--- a/KNOWN_ISSUES.md
+++ b/KNOWN_ISSUES.md
@@ -16,7 +16,7 @@
**Key files**:
- `feature/chat/.../components/MessageList.kt` — scroll logic, `pendingFineTuneScroll` flag
- `feature/chat/.../components/MarkdownContent.kt` — `HighlightedTextSegment` with `onGloballyPositioned`
-- `feature/chat/.../components/ContentPartRenderer.kt` — forwards `onFocusedOccurrencePositioned` callback
+- `feature/chat/.../components/ContentPartRenderer.kt` — forwards `onFocusedOccurrencePosition` callback
- `feature/chat/.../components/MessageBubble.kt` — forwards callback when `isCurrentSearchMatch`
**What's needed**: On-device debugging session with Logcat/Timber to trace:
diff --git a/app/detekt-baseline.xml b/app/detekt-baseline.xml
deleted file mode 100644
index 9d0bc30..0000000
--- a/app/detekt-baseline.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
- LambdaParameterInRestartableEffect:LibreChatNavHost.kt$onDeepLinkConsumed
- MutableStateAutoboxing:MainActivity.kt$MainActivity$mutableStateOf(0)
- ParameterNaming:LibreChatNavHost.kt$onDeepLinkConsumed
- ViewModelForwarding:TabletLayout.kt$MainContent( navigator = navigator, navHostViewModel = navHostViewModel, isInAuthFlow = false, banners = banners, dismissedBannerIds = dismissedBannerIds, onToggleDrawer = { navHostViewModel.setTabletSidebarOpen(!isSidebarOpen) }, )
- ViewModelForwarding:TabletLayout.kt$MainContent( navigator = navigator, navHostViewModel = navHostViewModel, isInAuthFlow = true, banners = banners, dismissedBannerIds = dismissedBannerIds, onToggleDrawer = {}, modifier = Modifier.fillMaxSize(), )
- ViewModelForwarding:TabletLayout.kt$MainNavDisplay( navigator = navigator, navHostViewModel = navHostViewModel, onMenuClick = onToggleDrawer, modifier = Modifier.fillMaxSize(), )
- ViewModelForwarding:TabletLayout.kt$SidebarScaffold( viewModel = navHostViewModel, onNewChat = { if (navigator.currentRoute !is NewChat) { navigator.navigateToTopLevel(NewChat) } }, onConversationClick = { conversationId -> navigator.navigateToChat(conversationId) }, onSettingsClick = { navigator.navigate(SettingsTabbed) }, onSettingsCategorySelected = { category -> navigator.navigate(category.toRoute()) }, onAgentsClick = { navigator.navigate(AgentMarketplace) }, onFilesClick = { navigator.navigate(Files) }, modifier = Modifier .width(SidebarWidth) .fillMaxHeight(), )
-
-
diff --git a/app/src/androidTest/kotlin/com/garfiec/librechat/AuthFlowTest.kt b/app/src/androidTest/kotlin/com/garfiec/librechat/AuthFlowTest.kt
index 9158299..d4e8ecc 100644
--- a/app/src/androidTest/kotlin/com/garfiec/librechat/AuthFlowTest.kt
+++ b/app/src/androidTest/kotlin/com/garfiec/librechat/AuthFlowTest.kt
@@ -20,7 +20,7 @@ class AuthFlowTest {
composeTestRule.setContent {
LibreChatTheme {
ServerUrlScreen(
- onServerValidated = {},
+ onServerValidate = {},
)
}
}
diff --git a/app/src/main/kotlin/com/garfiec/librechat/MainActivity.kt b/app/src/main/kotlin/com/garfiec/librechat/MainActivity.kt
index 1c4d61c..f2e451b 100644
--- a/app/src/main/kotlin/com/garfiec/librechat/MainActivity.kt
+++ b/app/src/main/kotlin/com/garfiec/librechat/MainActivity.kt
@@ -24,6 +24,7 @@ import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSiz
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
@@ -55,7 +56,7 @@ class MainActivity : ComponentActivity() {
* - Navigates to NewChat if the user is not on a chat screen, or
* - Lets the active ChatViewModel consume the shared content in-place if already on a chat screen.
*/
- private var shareNavigationTrigger by mutableStateOf(0)
+ private var shareNavigationTrigger by mutableIntStateOf(0)
@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
@@ -108,7 +109,7 @@ class MainActivity : ComponentActivity() {
LibreChatNavHost(
windowSizeClass = windowSizeClass,
deepLinkUri = deepLinkUri,
- onDeepLinkConsumed = { deepLinkUri = null },
+ onDeepLinkConsume = { deepLinkUri = null },
shareNavigationTrigger = shareNavigationTrigger,
modifier = Modifier.weight(1f),
)
diff --git a/app/src/main/kotlin/com/garfiec/librechat/navigation/LibreChatNavHost.kt b/app/src/main/kotlin/com/garfiec/librechat/navigation/LibreChatNavHost.kt
index a427840..38d5af4 100644
--- a/app/src/main/kotlin/com/garfiec/librechat/navigation/LibreChatNavHost.kt
+++ b/app/src/main/kotlin/com/garfiec/librechat/navigation/LibreChatNavHost.kt
@@ -5,6 +5,8 @@ import androidx.compose.material3.windowsizeclass.WindowSizeClass
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
import co.touchlab.kermit.Logger
import com.garfiec.librechat.MainActivity
@@ -22,11 +24,12 @@ fun LibreChatNavHost(
modifier: Modifier = Modifier,
windowSizeClass: WindowSizeClass? = null,
deepLinkUri: Uri? = null,
- onDeepLinkConsumed: () -> Unit = {},
+ onDeepLinkConsume: () -> Unit = {},
shareNavigationTrigger: Int = 0,
) {
SharedLibreChatNavHost(modifier = modifier) { navigator, navHostViewModel, mod ->
// Handle deep links
+ val currentOnDeepLinkConsume by rememberUpdatedState(onDeepLinkConsume)
LaunchedEffect(deepLinkUri) {
deepLinkUri?.let { uri ->
if (uri.scheme == "librechat" && uri.host == "conversation") {
@@ -38,7 +41,7 @@ fun LibreChatNavHost(
}
}
}
- onDeepLinkConsumed()
+ currentOnDeepLinkConsume()
}
}
@@ -65,7 +68,6 @@ fun LibreChatNavHost(
} else {
PhoneLayout(
navigator = navigator,
- navHostViewModel = navHostViewModel,
modifier = mod,
)
}
diff --git a/app/src/main/kotlin/com/garfiec/librechat/navigation/TabletLayout.kt b/app/src/main/kotlin/com/garfiec/librechat/navigation/TabletLayout.kt
index d33eb57..2db3ca5 100644
--- a/app/src/main/kotlin/com/garfiec/librechat/navigation/TabletLayout.kt
+++ b/app/src/main/kotlin/com/garfiec/librechat/navigation/TabletLayout.kt
@@ -149,7 +149,6 @@ fun TabletLayout(
// Slot 0: Sidebar -- always 320dp, slides from off-screen left to x=0
Row(modifier = Modifier.fillMaxHeight()) {
SidebarScaffold(
- viewModel = navHostViewModel,
onNewChat = {
if (navigator.currentRoute !is NewChat) {
navigator.navigateToTopLevel(NewChat)
@@ -161,7 +160,7 @@ fun TabletLayout(
onSettingsClick = {
navigator.navigate(SettingsTabbed)
},
- onSettingsCategorySelected = { category ->
+ onSettingsCategorySelect = { category ->
navigator.navigate(category.toRoute())
},
onAgentsClick = {
@@ -181,10 +180,10 @@ fun TabletLayout(
// Slot 1: Main content -- resizes to fill remaining space
MainContent(
navigator = navigator,
- navHostViewModel = navHostViewModel,
isInAuthFlow = false,
banners = banners,
dismissedBannerIds = dismissedBannerIds,
+ onDismissBanner = navHostViewModel::dismissBanner,
onToggleDrawer = {
navHostViewModel.setTabletSidebarOpen(!isSidebarOpen)
},
@@ -212,10 +211,10 @@ fun TabletLayout(
// Auth flow -- no sidebar, just main content
MainContent(
navigator = navigator,
- navHostViewModel = navHostViewModel,
isInAuthFlow = true,
banners = banners,
dismissedBannerIds = dismissedBannerIds,
+ onDismissBanner = navHostViewModel::dismissBanner,
onToggleDrawer = {},
modifier = Modifier.fillMaxSize(),
)
@@ -225,10 +224,10 @@ fun TabletLayout(
@Composable
private fun MainContent(
navigator: Navigator,
- navHostViewModel: NavHostViewModel,
isInAuthFlow: Boolean,
banners: List,
dismissedBannerIds: Set,
+ onDismissBanner: (String) -> Unit,
onToggleDrawer: () -> Unit,
modifier: Modifier = Modifier,
) {
@@ -237,13 +236,12 @@ private fun MainContent(
BannerDisplay(
banners = banners,
dismissedIds = dismissedBannerIds,
- onDismiss = navHostViewModel::dismissBanner,
+ onDismiss = onDismissBanner,
modifier = Modifier.padding(top = 4.dp),
)
}
MainNavDisplay(
navigator = navigator,
- navHostViewModel = navHostViewModel,
onMenuClick = onToggleDrawer,
modifier = Modifier.fillMaxSize(),
)
diff --git a/app/src/test/kotlin/com/garfiec/librechat/KoinGraphVerificationTest.kt b/app/src/test/kotlin/com/garfiec/librechat/KoinGraphVerificationTest.kt
index a86a54f..eb37dc8 100644
--- a/app/src/test/kotlin/com/garfiec/librechat/KoinGraphVerificationTest.kt
+++ b/app/src/test/kotlin/com/garfiec/librechat/KoinGraphVerificationTest.kt
@@ -2,7 +2,6 @@ package com.garfiec.librechat
import android.app.Application
import android.content.Context
-import androidx.lifecycle.SavedStateHandle
import com.garfiec.librechat.core.common.di.commonModule
import com.garfiec.librechat.core.common.network.ConnectivityObserver
import com.garfiec.librechat.core.data.datastore.ConfigCacheDataStore
@@ -105,7 +104,6 @@ class KoinGraphVerificationTest {
// Android framework
Context::class,
Application::class,
- SavedStateHandle::class,
// core:common provides
CoroutineDispatcher::class,
CoroutineScope::class,
diff --git a/build-logic/convention/src/main/kotlin/DetektConventionPlugin.kt b/build-logic/convention/src/main/kotlin/DetektConventionPlugin.kt
index 93a8010..e6873c8 100644
--- a/build-logic/convention/src/main/kotlin/DetektConventionPlugin.kt
+++ b/build-logic/convention/src/main/kotlin/DetektConventionPlugin.kt
@@ -1,8 +1,10 @@
+import io.gitlab.arturbosch.detekt.DetektCreateBaselineTask
import io.gitlab.arturbosch.detekt.extensions.DetektExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.withType
class DetektConventionPlugin : Plugin {
override fun apply(target: Project) {
@@ -14,7 +16,10 @@ class DetektConventionPlugin : Plugin {
buildUponDefaultConfig = true
allRules = false
parallel = true
- baseline = file("detekt-baseline.xml")
+ }
+
+ tasks.withType().configureEach {
+ enabled = false
}
dependencies {
diff --git a/build-logic/convention/src/main/kotlin/KmpComposeConventionPlugin.kt b/build-logic/convention/src/main/kotlin/KmpComposeConventionPlugin.kt
index cbfcbf1..d510fc2 100644
--- a/build-logic/convention/src/main/kotlin/KmpComposeConventionPlugin.kt
+++ b/build-logic/convention/src/main/kotlin/KmpComposeConventionPlugin.kt
@@ -3,6 +3,7 @@ import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.getByType
import org.jetbrains.compose.ComposeExtension
+import org.jetbrains.compose.resources.ResourcesExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
class KmpComposeConventionPlugin : Plugin {
@@ -11,7 +12,16 @@ class KmpComposeConventionPlugin : Plugin {
pluginManager.apply("org.jetbrains.compose")
pluginManager.apply("org.jetbrains.kotlin.plugin.compose")
- val compose = extensions.getByType().dependencies
+ val composeExtension = extensions.getByType()
+ val compose = composeExtension.dependencies
+
+ // Override Compose Resources' default package. ResourcesExtension is a
+ // sub-extension of ComposeExtension — `extensions.configure`
+ // at project level throws "extension does not exist".
+ composeExtension.extensions.configure {
+ val modulePath = project.path.removePrefix(":").replace(":", ".")
+ packageOfResClass = "com.garfiec.librechat.$modulePath.resources"
+ }
extensions.configure {
sourceSets.commonMain.dependencies {
diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml
index 0b82b2a..1fd1584 100644
--- a/config/detekt/detekt.yml
+++ b/config/detekt/detekt.yml
@@ -45,6 +45,8 @@ style:
excludePackageStatements: true
excludeImportStatements: true
excludeRawStrings: true
+ excludes:
+ - "**/build/generated/compose/resourceGenerator/**"
ForbiddenComment:
active: false
UnusedPrivateMember:
@@ -52,11 +54,14 @@ style:
allowedNames: "(_|ignored|expected|serialVersionUID)"
ignoreAnnotated:
- "Preview"
+ UnusedPrivateProperty:
+ active: true
+ allowedNames: "(_|ignored|expected|serialVersionUID)"
WildcardImport:
active: true
excludeImports:
- "kotlinx.coroutines.flow.*"
- - "*.generated.resources.*"
+ - "*.resources.*"
LoopWithTooManyJumpStatements:
maxJumpCount: 3
ThrowsCount:
@@ -70,6 +75,19 @@ naming:
FunctionNaming:
ignoreAnnotated:
- "Composable"
+ # Detekt's `excludes:` REPLACES (does not merge with) the default value, so
+ # the default test-source exemptions must be repeated here alongside the
+ # generated-resources exclude.
+ excludes:
+ - "**/test/**"
+ - "**/androidTest/**"
+ - "**/commonTest/**"
+ - "**/jvmTest/**"
+ - "**/androidUnitTest/**"
+ - "**/androidInstrumentedTest/**"
+ - "**/jsTest/**"
+ - "**/iosTest/**"
+ - "**/build/generated/compose/resourceGenerator/**"
TopLevelPropertyNaming:
constantPattern: "[A-Z][A-Za-z0-9_]*"
MatchingDeclarationName:
@@ -131,3 +149,6 @@ formatting:
active: false
FunctionSignature:
active: false
+ ImportOrdering:
+ excludes:
+ - "**/build/generated/compose/resourceGenerator/**"
diff --git a/core/common/detekt-baseline.xml b/core/common/detekt-baseline.xml
deleted file mode 100644
index 1b8d918..0000000
--- a/core/common/detekt-baseline.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
- ImportOrdering:DateExt.kt$import kotlin.time.Clock import kotlin.time.Instant import kotlinx.datetime.LocalDate import kotlinx.datetime.TimeZone import kotlinx.datetime.daysUntil import kotlinx.datetime.toLocalDateTime
- ImportOrdering:FlowExt.kt$import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.retryWhen import kotlin.time.Clock import kotlin.math.pow
- NoUnusedImports:CommonModule.kt$com.garfiec.librechat.core.common.di.CommonModule.kt
-
-
diff --git a/core/common/src/commonMain/kotlin/com/garfiec/librechat/core/common/di/CommonModule.kt b/core/common/src/commonMain/kotlin/com/garfiec/librechat/core/common/di/CommonModule.kt
index 1898432..3e5a8e4 100644
--- a/core/common/src/commonMain/kotlin/com/garfiec/librechat/core/common/di/CommonModule.kt
+++ b/core/common/src/commonMain/kotlin/com/garfiec/librechat/core/common/di/CommonModule.kt
@@ -1,12 +1,10 @@
package com.garfiec.librechat.core.common.di
-import com.garfiec.librechat.core.common.network.ConnectivityObserver
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import org.koin.core.module.Module
-import org.koin.core.module.dsl.singleOf
import org.koin.dsl.module
expect val commonPlatformModule: Module
diff --git a/core/common/src/commonMain/kotlin/com/garfiec/librechat/core/common/extensions/DateExt.kt b/core/common/src/commonMain/kotlin/com/garfiec/librechat/core/common/extensions/DateExt.kt
index e4d2066..9042192 100644
--- a/core/common/src/commonMain/kotlin/com/garfiec/librechat/core/common/extensions/DateExt.kt
+++ b/core/common/src/commonMain/kotlin/com/garfiec/librechat/core/common/extensions/DateExt.kt
@@ -1,11 +1,11 @@
package com.garfiec.librechat.core.common.extensions
-import kotlin.time.Clock
-import kotlin.time.Instant
import kotlinx.datetime.LocalDate
import kotlinx.datetime.TimeZone
import kotlinx.datetime.daysUntil
import kotlinx.datetime.toLocalDateTime
+import kotlin.time.Clock
+import kotlin.time.Instant
fun String.toInstantOrNull(): Instant? =
try { Instant.parse(this) } catch (_: Exception) { null }
diff --git a/core/common/src/commonMain/kotlin/com/garfiec/librechat/core/common/extensions/FlowExt.kt b/core/common/src/commonMain/kotlin/com/garfiec/librechat/core/common/extensions/FlowExt.kt
index 4c83b80..3a4c5f4 100644
--- a/core/common/src/commonMain/kotlin/com/garfiec/librechat/core/common/extensions/FlowExt.kt
+++ b/core/common/src/commonMain/kotlin/com/garfiec/librechat/core/common/extensions/FlowExt.kt
@@ -4,8 +4,8 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.retryWhen
-import kotlin.time.Clock
import kotlin.math.pow
+import kotlin.time.Clock
fun Flow.retryWithBackoff(
maxRetries: Int = 3,
diff --git a/core/data/detekt-baseline.xml b/core/data/detekt-baseline.xml
deleted file mode 100644
index 8e40f4b..0000000
--- a/core/data/detekt-baseline.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
- ImportOrdering:ConfigCacheDataStore.kt$import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.stringPreferencesKey import com.garfiec.librechat.core.model.EndpointConfig import com.garfiec.librechat.core.model.config.StartupConfig import kotlinx.coroutines.flow.first import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.builtins.MapSerializer import kotlinx.serialization.builtins.serializer import kotlinx.serialization.json.Json import co.touchlab.kermit.Logger
- ImportOrdering:ConfigRepositoryImpl.kt$import com.garfiec.librechat.core.common.BackendVersion import com.garfiec.librechat.core.common.result.ApiException import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.core.common.result.safeApiCall import com.garfiec.librechat.core.data.datastore.ConfigCacheDataStore import com.garfiec.librechat.core.model.EndpointConfig import com.garfiec.librechat.core.model.config.StartupConfig import com.garfiec.librechat.core.network.api.ConfigApi import io.ktor.client.plugins.HttpRequestTimeoutException import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.serialization.SerializationException import co.touchlab.kermit.Logger
- ImportOrdering:ConversationMapper.kt$import com.garfiec.librechat.core.data.db.entity.ConversationEntity import com.garfiec.librechat.core.model.Conversation import com.garfiec.librechat.core.model.EModelEndpoint import kotlin.time.Clock import kotlin.time.Instant import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.json.Json import kotlinx.serialization.serializer
- ImportOrdering:ConversationRepositoryImpl.kt$import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.core.common.result.safeApiCall import com.garfiec.librechat.core.data.db.dao.ConversationDao import com.garfiec.librechat.core.data.mapper.toEntity import com.garfiec.librechat.core.data.mapper.toModel import com.garfiec.librechat.core.data.mapper.toModels import com.garfiec.librechat.core.model.Conversation import com.garfiec.librechat.core.model.request.ForkConversationRequest import com.garfiec.librechat.core.network.api.ConversationsApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map import kotlin.time.Clock import co.touchlab.kermit.Logger
- ImportOrdering:MessageMapper.kt$import com.garfiec.librechat.core.data.db.entity.MessageEntity import com.garfiec.librechat.core.model.Attachment import com.garfiec.librechat.core.model.Feedback import com.garfiec.librechat.core.model.FileReference import com.garfiec.librechat.core.model.Message import com.garfiec.librechat.core.model.content.MessageContentPart import kotlin.time.Clock import kotlin.time.Instant import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject
- ImportOrdering:MessageRepositoryImpl.kt$import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.core.common.result.safeApiCall import com.garfiec.librechat.core.data.db.dao.MessageDao import com.garfiec.librechat.core.data.mapper.toEntity import com.garfiec.librechat.core.data.mapper.toModels import com.garfiec.librechat.core.model.Message import com.garfiec.librechat.core.model.request.BranchMessageRequest import com.garfiec.librechat.core.model.request.UpdateMessageRequest import com.garfiec.librechat.core.network.api.MessagesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import co.touchlab.kermit.Logger
- NoUnusedImports:DataModule.kt$com.garfiec.librechat.core.data.di.DataModule.kt
-
-
diff --git a/core/data/src/androidUnitTest/kotlin/com/garfiec/librechat/core/data/di/DataModuleVerificationTest.kt b/core/data/src/androidUnitTest/kotlin/com/garfiec/librechat/core/data/di/DataModuleVerificationTest.kt
index ff3684e..a24a99f 100644
--- a/core/data/src/androidUnitTest/kotlin/com/garfiec/librechat/core/data/di/DataModuleVerificationTest.kt
+++ b/core/data/src/androidUnitTest/kotlin/com/garfiec/librechat/core/data/di/DataModuleVerificationTest.kt
@@ -3,7 +3,6 @@ package com.garfiec.librechat.core.data.di
import android.app.Application
import android.content.Context
import androidx.datastore.core.DataStore
-import androidx.lifecycle.SavedStateHandle
import com.garfiec.librechat.core.common.network.ConnectivityObserver
import com.garfiec.librechat.core.network.api.AgentsApi
import com.garfiec.librechat.core.network.api.ApiKeysApi
@@ -40,7 +39,6 @@ class DataModuleVerificationTest {
extraTypes = listOf(
Context::class,
Application::class,
- SavedStateHandle::class,
Lazy::class,
HttpClient::class,
Json::class,
diff --git a/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/datastore/ConfigCacheDataStore.kt b/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/datastore/ConfigCacheDataStore.kt
index ea82214..f8ebbd5 100644
--- a/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/datastore/ConfigCacheDataStore.kt
+++ b/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/datastore/ConfigCacheDataStore.kt
@@ -4,6 +4,7 @@ import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.model.EndpointConfig
import com.garfiec.librechat.core.model.config.StartupConfig
import kotlinx.coroutines.flow.first
@@ -11,7 +12,6 @@ import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.builtins.MapSerializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.json.Json
-import co.touchlab.kermit.Logger
class ConfigCacheDataStore(
private val dataStore: DataStore,
diff --git a/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/di/DataModule.kt b/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/di/DataModule.kt
index 9d43699..7155cf2 100644
--- a/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/di/DataModule.kt
+++ b/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/di/DataModule.kt
@@ -3,7 +3,6 @@ package com.garfiec.librechat.core.data.di
import com.garfiec.librechat.core.common.di.KoinQualifiers
import com.garfiec.librechat.core.data.datastore.ConfigCacheDataStore
import com.garfiec.librechat.core.data.datastore.ServerDataStore
-import com.garfiec.librechat.core.data.datastore.ServerUrlKeychainFallback
import com.garfiec.librechat.core.data.datastore.SettingsDataStore
import com.garfiec.librechat.core.data.datastore.ThemeDataStore
import com.garfiec.librechat.core.data.db.LibreChatDatabase
@@ -41,7 +40,6 @@ import com.garfiec.librechat.core.data.repository.PromptRepository
import com.garfiec.librechat.core.data.repository.PromptRepositoryImpl
import com.garfiec.librechat.core.data.repository.SearchRepository
import com.garfiec.librechat.core.data.repository.SearchRepositoryImpl
-import com.garfiec.librechat.core.data.repository.SessionCacheCleaner
import com.garfiec.librechat.core.data.repository.ShareRepository
import com.garfiec.librechat.core.data.repository.ShareRepositoryImpl
import com.garfiec.librechat.core.data.repository.SpeechRepository
diff --git a/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/mapper/ConversationMapper.kt b/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/mapper/ConversationMapper.kt
index 7e2f693..1ebe453 100644
--- a/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/mapper/ConversationMapper.kt
+++ b/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/mapper/ConversationMapper.kt
@@ -3,11 +3,11 @@ package com.garfiec.librechat.core.data.mapper
import com.garfiec.librechat.core.data.db.entity.ConversationEntity
import com.garfiec.librechat.core.model.Conversation
import com.garfiec.librechat.core.model.EModelEndpoint
-import kotlin.time.Clock
-import kotlin.time.Instant
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.json.Json
import kotlinx.serialization.serializer
+import kotlin.time.Clock
+import kotlin.time.Instant
private val json = Json { ignoreUnknownKeys = true }
diff --git a/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/mapper/MessageMapper.kt b/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/mapper/MessageMapper.kt
index 9f08618..748f2e3 100644
--- a/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/mapper/MessageMapper.kt
+++ b/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/mapper/MessageMapper.kt
@@ -6,11 +6,11 @@ import com.garfiec.librechat.core.model.Feedback
import com.garfiec.librechat.core.model.FileReference
import com.garfiec.librechat.core.model.Message
import com.garfiec.librechat.core.model.content.MessageContentPart
-import kotlin.time.Clock
-import kotlin.time.Instant
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
+import kotlin.time.Clock
+import kotlin.time.Instant
private val json = Json { ignoreUnknownKeys = true }
diff --git a/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/repository/ConfigRepositoryImpl.kt b/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/repository/ConfigRepositoryImpl.kt
index 9214d10..e8ab03f 100644
--- a/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/repository/ConfigRepositoryImpl.kt
+++ b/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/repository/ConfigRepositoryImpl.kt
@@ -1,5 +1,6 @@
package com.garfiec.librechat.core.data.repository
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.BackendVersion
import com.garfiec.librechat.core.common.result.ApiException
import com.garfiec.librechat.core.common.result.Result
@@ -13,7 +14,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.serialization.SerializationException
-import co.touchlab.kermit.Logger
class ConfigRepositoryImpl(
private val configApi: ConfigApi,
diff --git a/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/repository/ConversationRepositoryImpl.kt b/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/repository/ConversationRepositoryImpl.kt
index c6ed028..d938f69 100644
--- a/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/repository/ConversationRepositoryImpl.kt
+++ b/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/repository/ConversationRepositoryImpl.kt
@@ -1,5 +1,6 @@
package com.garfiec.librechat.core.data.repository
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.common.result.safeApiCall
import com.garfiec.librechat.core.data.db.dao.ConversationDao
@@ -12,7 +13,6 @@ import com.garfiec.librechat.core.network.api.ConversationsApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlin.time.Clock
-import co.touchlab.kermit.Logger
class ConversationRepositoryImpl(
private val conversationsApi: ConversationsApi,
diff --git a/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/repository/MessageRepositoryImpl.kt b/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/repository/MessageRepositoryImpl.kt
index f15c88f..e7bf1ac 100644
--- a/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/repository/MessageRepositoryImpl.kt
+++ b/core/data/src/commonMain/kotlin/com/garfiec/librechat/core/data/repository/MessageRepositoryImpl.kt
@@ -1,5 +1,6 @@
package com.garfiec.librechat.core.data.repository
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.common.result.safeApiCall
import com.garfiec.librechat.core.data.db.dao.MessageDao
@@ -12,7 +13,6 @@ import com.garfiec.librechat.core.network.api.MessagesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
-import co.touchlab.kermit.Logger
class MessageRepositoryImpl(
private val messagesApi: MessagesApi,
diff --git a/core/data/src/iosMain/kotlin/com/garfiec/librechat/core/data/datastore/IosTokenDataStore.kt b/core/data/src/iosMain/kotlin/com/garfiec/librechat/core/data/datastore/IosTokenDataStore.kt
index dc60e68..271c8f4 100644
--- a/core/data/src/iosMain/kotlin/com/garfiec/librechat/core/data/datastore/IosTokenDataStore.kt
+++ b/core/data/src/iosMain/kotlin/com/garfiec/librechat/core/data/datastore/IosTokenDataStore.kt
@@ -1,5 +1,6 @@
package com.garfiec.librechat.core.data.datastore
+import co.touchlab.kermit.Logger
import io.ktor.client.HttpClient
import kotlinx.cinterop.BetaInteropApi
import kotlinx.cinterop.ExperimentalForeignApi
@@ -9,9 +10,7 @@ import kotlinx.cinterop.ptr
import kotlinx.cinterop.value
import platform.CoreFoundation.CFDictionaryAddValue
import platform.CoreFoundation.CFDictionaryCreateMutable
-import platform.CoreFoundation.CFMutableDictionaryRef
import platform.CoreFoundation.CFRelease
-import platform.CoreFoundation.CFTypeRef
import platform.CoreFoundation.CFTypeRefVar
import platform.CoreFoundation.kCFBooleanTrue
import platform.Foundation.CFBridgingRelease
@@ -35,7 +34,6 @@ import platform.Security.kSecMatchLimit
import platform.Security.kSecMatchLimitOne
import platform.Security.kSecReturnData
import platform.Security.kSecValueData
-import co.touchlab.kermit.Logger
@OptIn(ExperimentalForeignApi::class, BetaInteropApi::class)
class IosTokenDataStore(
diff --git a/core/model/detekt-baseline.xml b/core/model/detekt-baseline.xml
deleted file mode 100644
index 5d3d383..0000000
--- a/core/model/detekt-baseline.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
- NoUnusedImports:StartupConfig.kt$com.garfiec.librechat.core.model.config.StartupConfig.kt
-
-
diff --git a/core/model/src/commonMain/kotlin/com/garfiec/librechat/core/model/config/StartupConfig.kt b/core/model/src/commonMain/kotlin/com/garfiec/librechat/core/model/config/StartupConfig.kt
index 59d6dd3..455ec35 100644
--- a/core/model/src/commonMain/kotlin/com/garfiec/librechat/core/model/config/StartupConfig.kt
+++ b/core/model/src/commonMain/kotlin/com/garfiec/librechat/core/model/config/StartupConfig.kt
@@ -1,6 +1,5 @@
package com.garfiec.librechat.core.model.config
-import com.garfiec.librechat.core.model.Preset
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonObject
diff --git a/core/network/detekt-baseline.xml b/core/network/detekt-baseline.xml
deleted file mode 100644
index 8c7baa4..0000000
--- a/core/network/detekt-baseline.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
- ImportOrdering:AgentsApi.kt$import com.garfiec.librechat.core.model.Agent import com.garfiec.librechat.core.model.AgentAction import com.garfiec.librechat.core.model.AgentCategory import com.garfiec.librechat.core.model.AgentExpanded import com.garfiec.librechat.core.model.AgentTool import com.garfiec.librechat.core.model.ToolAuthStatus import com.garfiec.librechat.core.model.ToolCallRecord import com.garfiec.librechat.core.model.ToolCallResult import com.garfiec.librechat.core.model.request.CreateActionRequest import com.garfiec.librechat.core.model.request.CreateAgentRequest import com.garfiec.librechat.core.model.request.RevertAgentRequest import com.garfiec.librechat.core.model.request.ToolCallRequest import com.garfiec.librechat.core.model.request.UpdateAgentRequest import com.garfiec.librechat.core.model.response.AgentListResponse import io.ktor.client.HttpClient import io.ktor.client.call.body import io.ktor.client.request.delete import io.ktor.client.request.forms.formData import io.ktor.client.request.forms.submitFormWithBinaryData import io.ktor.client.request.get import io.ktor.client.request.parameter import io.ktor.client.request.patch import io.ktor.client.request.post import io.ktor.client.request.setBody import io.ktor.http.Headers import io.ktor.http.HttpHeaders import io.ktor.http.path import kotlinx.serialization.json.JsonArray import co.touchlab.kermit.Logger
- ImportOrdering:AuthApi.kt$import com.garfiec.librechat.core.network.api.dto.LoginResult import com.garfiec.librechat.core.network.api.dto.RefreshResult import com.garfiec.librechat.core.network.api.dto.TwoFactorConfirmRequest import com.garfiec.librechat.core.model.request.LoginRequest import com.garfiec.librechat.core.model.request.OtpVerificationRequest import com.garfiec.librechat.core.model.request.PasswordResetRequest import com.garfiec.librechat.core.model.request.RegisterRequest import com.garfiec.librechat.core.model.request.ResetPasswordRequest import com.garfiec.librechat.core.model.request.TwoFactorDisableRequest import com.garfiec.librechat.core.model.request.TwoFactorVerifyRequest import com.garfiec.librechat.core.model.request.TwoFactorVerifyTempRequest import com.garfiec.librechat.core.model.response.LoginResponse import com.garfiec.librechat.core.model.response.RefreshResponse import com.garfiec.librechat.core.model.response.RegisterResponse import com.garfiec.librechat.core.model.response.TwoFactorSetupResponse import com.garfiec.librechat.core.network.client.CookieHelper import io.ktor.client.HttpClient import io.ktor.client.call.body import io.ktor.client.request.header import io.ktor.client.request.post import io.ktor.client.request.setBody import io.ktor.http.path
- ImportOrdering:LibreChatHttpClient.kt$import co.touchlab.kermit.Logger import io.ktor.client.HttpClient import io.ktor.client.engine.HttpClientEngineFactory import io.ktor.client.plugins.HttpRequestRetry import io.ktor.client.plugins.HttpResponseValidator import io.ktor.client.plugins.HttpTimeout import io.ktor.client.plugins.contentnegotiation.ContentNegotiation import io.ktor.client.plugins.defaultRequest import io.ktor.client.plugins.logging.LogLevel import io.ktor.client.plugins.logging.Logger as KtorLogger import io.ktor.client.plugins.logging.Logging import io.ktor.client.statement.bodyAsText import io.ktor.http.ContentType import io.ktor.http.HttpHeaders import io.ktor.http.contentType import io.ktor.http.isSuccess import io.ktor.http.takeFrom import io.ktor.serialization.kotlinx.json.json import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.jsonObject
- ImportOrdering:SseEventMapper.kt$import com.garfiec.librechat.core.model.Conversation import com.garfiec.librechat.core.model.Message import com.garfiec.librechat.core.model.StreamEvent import com.garfiec.librechat.core.model.content.MessageContentPart import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.booleanOrNull import kotlinx.serialization.json.contentOrNull import kotlinx.serialization.json.intOrNull import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive import co.touchlab.kermit.Logger
- ImportOrdering:UserApi.kt$import com.garfiec.librechat.core.network.api.dto.UpdateFavoritesRequest import com.garfiec.librechat.core.network.api.dto.UpdatePluginsRequest import com.garfiec.librechat.core.network.api.dto.UserUpdateRequest import com.garfiec.librechat.core.model.User import com.garfiec.librechat.core.model.UserFavorite import com.garfiec.librechat.core.model.request.OtpVerificationRequest import com.garfiec.librechat.core.model.request.ResendVerificationRequest import com.garfiec.librechat.core.model.request.VerifyEmailRequest import com.garfiec.librechat.core.model.response.TermsResponse import io.ktor.client.HttpClient import io.ktor.client.call.body import io.ktor.client.request.delete import io.ktor.client.request.forms.formData import io.ktor.client.request.forms.submitFormWithBinaryData import io.ktor.client.request.get import io.ktor.client.request.post import io.ktor.client.request.setBody import io.ktor.http.Headers import io.ktor.http.HttpHeaders import io.ktor.http.path
- MaxLineLength:FilesApi.kt$FilesApi$"uploadFile success: fileId=${response.fileId}, filepath=${response.filepath}, type=${response.type}, width=${response.width}, height=${response.height}"
- NoEmptyFirstLineInMethodBlock:LibreChatHttpClient.kt$LibreChatHttpClient$
-
-
diff --git a/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/api/AgentsApi.kt b/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/api/AgentsApi.kt
index d03a901..eb88c4f 100644
--- a/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/api/AgentsApi.kt
+++ b/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/api/AgentsApi.kt
@@ -1,5 +1,6 @@
package com.garfiec.librechat.core.network.api
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.model.Agent
import com.garfiec.librechat.core.model.AgentAction
import com.garfiec.librechat.core.model.AgentCategory
@@ -28,7 +29,6 @@ import io.ktor.http.Headers
import io.ktor.http.HttpHeaders
import io.ktor.http.path
import kotlinx.serialization.json.JsonArray
-import co.touchlab.kermit.Logger
class AgentsApi constructor(
private val client: HttpClient,
diff --git a/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/api/AuthApi.kt b/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/api/AuthApi.kt
index 935deea..2373147 100644
--- a/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/api/AuthApi.kt
+++ b/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/api/AuthApi.kt
@@ -1,8 +1,5 @@
package com.garfiec.librechat.core.network.api
-import com.garfiec.librechat.core.network.api.dto.LoginResult
-import com.garfiec.librechat.core.network.api.dto.RefreshResult
-import com.garfiec.librechat.core.network.api.dto.TwoFactorConfirmRequest
import com.garfiec.librechat.core.model.request.LoginRequest
import com.garfiec.librechat.core.model.request.OtpVerificationRequest
import com.garfiec.librechat.core.model.request.PasswordResetRequest
@@ -15,6 +12,9 @@ import com.garfiec.librechat.core.model.response.LoginResponse
import com.garfiec.librechat.core.model.response.RefreshResponse
import com.garfiec.librechat.core.model.response.RegisterResponse
import com.garfiec.librechat.core.model.response.TwoFactorSetupResponse
+import com.garfiec.librechat.core.network.api.dto.LoginResult
+import com.garfiec.librechat.core.network.api.dto.RefreshResult
+import com.garfiec.librechat.core.network.api.dto.TwoFactorConfirmRequest
import com.garfiec.librechat.core.network.client.CookieHelper
import io.ktor.client.HttpClient
import io.ktor.client.call.body
diff --git a/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/api/FilesApi.kt b/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/api/FilesApi.kt
index 05aa127..0e4498b 100644
--- a/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/api/FilesApi.kt
+++ b/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/api/FilesApi.kt
@@ -69,7 +69,8 @@ class FilesApi constructor(
}.body()
Logger.d("FilesApi") {
- "uploadFile success: fileId=${response.fileId}, filepath=${response.filepath}, type=${response.type}, width=${response.width}, height=${response.height}"
+ "uploadFile success: fileId=${response.fileId}, filepath=${response.filepath}, " +
+ "type=${response.type}, width=${response.width}, height=${response.height}"
}
return response
}
diff --git a/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/api/UserApi.kt b/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/api/UserApi.kt
index 01d01ed..e27ce57 100644
--- a/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/api/UserApi.kt
+++ b/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/api/UserApi.kt
@@ -1,14 +1,14 @@
package com.garfiec.librechat.core.network.api
-import com.garfiec.librechat.core.network.api.dto.UpdateFavoritesRequest
-import com.garfiec.librechat.core.network.api.dto.UpdatePluginsRequest
-import com.garfiec.librechat.core.network.api.dto.UserUpdateRequest
import com.garfiec.librechat.core.model.User
import com.garfiec.librechat.core.model.UserFavorite
import com.garfiec.librechat.core.model.request.OtpVerificationRequest
import com.garfiec.librechat.core.model.request.ResendVerificationRequest
import com.garfiec.librechat.core.model.request.VerifyEmailRequest
import com.garfiec.librechat.core.model.response.TermsResponse
+import com.garfiec.librechat.core.network.api.dto.UpdateFavoritesRequest
+import com.garfiec.librechat.core.network.api.dto.UpdatePluginsRequest
+import com.garfiec.librechat.core.network.api.dto.UserUpdateRequest
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.request.delete
diff --git a/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/client/LibreChatHttpClient.kt b/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/client/LibreChatHttpClient.kt
index c487ce1..9ae9879 100644
--- a/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/client/LibreChatHttpClient.kt
+++ b/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/client/LibreChatHttpClient.kt
@@ -9,7 +9,6 @@ import io.ktor.client.plugins.HttpTimeout
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.plugins.defaultRequest
import io.ktor.client.plugins.logging.LogLevel
-import io.ktor.client.plugins.logging.Logger as KtorLogger
import io.ktor.client.plugins.logging.Logging
import io.ktor.client.statement.bodyAsText
import io.ktor.http.ContentType
@@ -21,6 +20,7 @@ import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.jsonObject
+import io.ktor.client.plugins.logging.Logger as KtorLogger
object LibreChatHttpClient {
@@ -31,7 +31,6 @@ object LibreChatHttpClient {
serverUrlProvider: ServerUrlProvider,
debug: Boolean = false,
): HttpClient = HttpClient(engineFactory) {
-
install(ContentNegotiation) {
json(json)
}
diff --git a/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/sse/SseEventMapper.kt b/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/sse/SseEventMapper.kt
index ad77ab1..b33bf96 100644
--- a/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/sse/SseEventMapper.kt
+++ b/core/network/src/commonMain/kotlin/com/garfiec/librechat/core/network/sse/SseEventMapper.kt
@@ -1,5 +1,6 @@
package com.garfiec.librechat.core.network.sse
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.model.Conversation
import com.garfiec.librechat.core.model.Message
import com.garfiec.librechat.core.model.StreamEvent
@@ -14,7 +15,6 @@ import kotlinx.serialization.json.intOrNull
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
-import co.touchlab.kermit.Logger
/**
* Maps raw SSE events into domain [StreamEvent]s.
diff --git a/core/ui/detekt-baseline.xml b/core/ui/detekt-baseline.xml
deleted file mode 100644
index 6be447f..0000000
--- a/core/ui/detekt-baseline.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
- ComposableParamOrder:FilterChipBottomSheet.kt$FilterChipBottomSheet
- FunctionNaming:Drawable0.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainDrawable0Resources(map: MutableMap<String, DrawableResource>)
- ImportOrdering:Drawable0.commonMain.kt$import kotlin.OptIn import kotlin.String import kotlin.collections.MutableMap import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.ResourceContentHash import org.jetbrains.compose.resources.ResourceItem
- ImportOrdering:DynamicDropdown.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExposedDropdownMenuBox import androidx.compose.material3.ExposedDropdownMenuDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MenuAnchorType import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import org.jetbrains.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp
- ImportOrdering:DynamicInput.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import org.jetbrains.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp
- ImportOrdering:DynamicTextarea.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import org.jetbrains.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp
- ImportOrdering:ExpectResourceCollectors.kt$import kotlin.String import kotlin.collections.Map import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.FontResource import org.jetbrains.compose.resources.PluralStringResource import org.jetbrains.compose.resources.StringArrayResource import org.jetbrains.compose.resources.StringResource
- ImportOrdering:Res.kt$import kotlin.ByteArray import kotlin.OptIn import kotlin.String import kotlin.Suppress import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.getResourceUri import org.jetbrains.compose.resources.readResourceBytes
- MaxLineLength:Res.kt$Res$public suspend
- MultiLineIfElse:DynamicSlider.kt$str + "0".repeat(decimals - existing)
- MultiLineIfElse:DynamicSlider.kt$str.substring(0, dot + decimals + 1)
- PackageName:Drawable0.commonMain.kt$package librechat_mobile.core.ui.generated.resources
- PackageName:ExpectResourceCollectors.kt$package librechat_mobile.core.ui.generated.resources
- PackageName:Res.kt$package librechat_mobile.core.ui.generated.resources
- PackageNaming:Drawable0.commonMain.kt$package librechat_mobile.core.ui.generated.resources
- PackageNaming:ExpectResourceCollectors.kt$package librechat_mobile.core.ui.generated.resources
- PackageNaming:Res.kt$package librechat_mobile.core.ui.generated.resources
- ParameterNaming:DynamicParameterPanel.kt$onValueChanged
- ParameterNaming:DynamicTagsInput.kt$onTagsChanged
- ParameterNaming:FilterChipBottomSheet.kt$onSelectionChanged
- ParameterNaming:ModelParameterSheet.kt$onParametersChanged
-
-
diff --git a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicDropdown.kt b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicDropdown.kt
index 4285f70..04f7fcd 100644
--- a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicDropdown.kt
+++ b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicDropdown.kt
@@ -18,8 +18,8 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import org.jetbrains.compose.ui.tooling.preview.Preview
/** Labeled dropdown selector using ExposedDropdownMenuBox with read-only text field anchor. */
@OptIn(ExperimentalMaterial3Api::class)
diff --git a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicInput.kt b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicInput.kt
index 2a5150a..7761bd8 100644
--- a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicInput.kt
+++ b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicInput.kt
@@ -13,8 +13,8 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import org.jetbrains.compose.ui.tooling.preview.Preview
/** Single-line text input with label, optional placeholder, and description. */
@Composable
diff --git a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicParameterPanel.kt b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicParameterPanel.kt
index 1686df5..35adabc 100644
--- a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicParameterPanel.kt
+++ b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicParameterPanel.kt
@@ -23,7 +23,7 @@ import org.jetbrains.compose.ui.tooling.preview.Preview
fun DynamicParameterPanel(
definitions: List,
values: Map,
- onValueChanged: (key: String, value: String) -> Unit,
+ onValueChange: (key: String, value: String) -> Unit,
modifier: Modifier = Modifier,
title: String = "Endpoint Parameters",
) {
@@ -50,7 +50,7 @@ fun DynamicParameterPanel(
DynamicSlider(
label = definition.label,
value = floatValue,
- onValueChange = { onValueChanged(definition.key, it.toString()) },
+ onValueChange = { onValueChange(definition.key, it.toString()) },
min = min,
max = max,
step = step,
@@ -63,7 +63,7 @@ fun DynamicParameterPanel(
label = definition.label,
selectedValue = currentValue,
options = definition.options ?: emptyList(),
- onValueChange = { onValueChanged(definition.key, it) },
+ onValueChange = { onValueChange(definition.key, it) },
description = definition.description,
)
}
@@ -73,7 +73,7 @@ fun DynamicParameterPanel(
DynamicCheckbox(
label = definition.label,
checked = checked,
- onCheckedChange = { onValueChanged(definition.key, it.toString()) },
+ onCheckedChange = { onValueChange(definition.key, it.toString()) },
description = definition.description,
)
}
@@ -82,7 +82,7 @@ fun DynamicParameterPanel(
DynamicInput(
label = definition.label,
value = currentValue,
- onValueChange = { onValueChanged(definition.key, it) },
+ onValueChange = { onValueChange(definition.key, it) },
placeholder = definition.default,
description = definition.description,
)
@@ -93,7 +93,7 @@ fun DynamicParameterPanel(
DynamicCheckbox(
label = definition.label,
checked = checked,
- onCheckedChange = { onValueChanged(definition.key, it.toString()) },
+ onCheckedChange = { onValueChange(definition.key, it.toString()) },
description = definition.description,
)
}
@@ -102,7 +102,7 @@ fun DynamicParameterPanel(
DynamicTextarea(
label = definition.label,
value = currentValue,
- onValueChange = { onValueChanged(definition.key, it) },
+ onValueChange = { onValueChange(definition.key, it) },
placeholder = definition.default,
description = definition.description,
)
@@ -116,8 +116,8 @@ fun DynamicParameterPanel(
} else {
currentValue.split("\n").filter { it.isNotBlank() }
},
- onTagsChanged = { tags ->
- onValueChanged(definition.key, tags.joinToString("\n"))
+ onTagsChange = { tags ->
+ onValueChange(definition.key, tags.joinToString("\n"))
},
description = definition.description,
maxTags = definition.max?.toInt() ?: 4,
@@ -167,7 +167,7 @@ private fun DynamicParameterPanelPreview() {
DynamicParameterPanel(
definitions = definitions,
values = values,
- onValueChanged = { key, value ->
+ onValueChange = { key, value ->
values = values.toMutableMap().apply { this[key] = value }
},
)
diff --git a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicSlider.kt b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicSlider.kt
index cc9bc0f..f1319bb 100644
--- a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicSlider.kt
+++ b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicSlider.kt
@@ -99,6 +99,9 @@ private fun roundToDecimals(value: Float, decimals: Int): String {
val dot = str.indexOf('.')
if (dot < 0) return str + "." + "0".repeat(decimals)
val existing = str.length - dot - 1
- return if (existing >= decimals) str.substring(0, dot + decimals + 1)
- else str + "0".repeat(decimals - existing)
+ return if (existing >= decimals) {
+ str.substring(0, dot + decimals + 1)
+ } else {
+ str + "0".repeat(decimals - existing)
+ }
}
diff --git a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicTagsInput.kt b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicTagsInput.kt
index 5814f38..ef47924 100644
--- a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicTagsInput.kt
+++ b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicTagsInput.kt
@@ -34,7 +34,7 @@ import org.jetbrains.compose.ui.tooling.preview.Preview
fun DynamicTagsInput(
label: String,
tags: List,
- onTagsChanged: (List) -> Unit,
+ onTagsChange: (List) -> Unit,
modifier: Modifier = Modifier,
description: String? = null,
maxTags: Int = 4,
@@ -67,7 +67,7 @@ fun DynamicTagsInput(
label = { Text(tag) },
trailingIcon = {
IconButton(
- onClick = { onTagsChanged(tags - tag) },
+ onClick = { onTagsChange(tags - tag) },
modifier = Modifier.size(18.dp),
) {
Icon(
@@ -95,7 +95,7 @@ fun DynamicTagsInput(
onDone = {
val trimmed = inputText.trim()
if (trimmed.isNotEmpty() && tags.size < maxTags) {
- onTagsChanged(tags + trimmed)
+ onTagsChange(tags + trimmed)
inputText = ""
}
},
@@ -112,7 +112,7 @@ private fun DynamicTagsInputPreview() {
DynamicTagsInput(
label = "Stop Sequences",
tags = tags,
- onTagsChanged = { tags = it },
+ onTagsChange = { tags = it },
description = "Up to 4 sequences where the model will stop generating.",
maxTags = 4,
)
diff --git a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicTextarea.kt b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicTextarea.kt
index 48a7dd8..67fafaf 100644
--- a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicTextarea.kt
+++ b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/DynamicTextarea.kt
@@ -13,8 +13,8 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import org.jetbrains.compose.ui.tooling.preview.Preview
/** Multi-line text input with configurable minLines/maxLines, label, and optional description. */
@Composable
diff --git a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/EndpointIcons.kt b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/EndpointIcons.kt
index b3bf854..ddc81dc 100644
--- a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/EndpointIcons.kt
+++ b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/EndpointIcons.kt
@@ -3,13 +3,13 @@ package com.garfiec.librechat.core.ui.components
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.painter.Painter
import com.garfiec.librechat.core.model.EModelEndpoint
-import librechat_mobile.core.ui.generated.resources.Res
-import librechat_mobile.core.ui.generated.resources.ic_agents
-import librechat_mobile.core.ui.generated.resources.ic_anthropic
-import librechat_mobile.core.ui.generated.resources.ic_azure
-import librechat_mobile.core.ui.generated.resources.ic_bedrock
-import librechat_mobile.core.ui.generated.resources.ic_google
-import librechat_mobile.core.ui.generated.resources.ic_openai
+import com.garfiec.librechat.core.ui.resources.Res
+import com.garfiec.librechat.core.ui.resources.ic_agents
+import com.garfiec.librechat.core.ui.resources.ic_anthropic
+import com.garfiec.librechat.core.ui.resources.ic_azure
+import com.garfiec.librechat.core.ui.resources.ic_bedrock
+import com.garfiec.librechat.core.ui.resources.ic_google
+import com.garfiec.librechat.core.ui.resources.ic_openai
import org.jetbrains.compose.resources.painterResource
/**
diff --git a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/FilterChipBottomSheet.kt b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/FilterChipBottomSheet.kt
index f3f2ce8..2523e53 100644
--- a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/FilterChipBottomSheet.kt
+++ b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/FilterChipBottomSheet.kt
@@ -35,7 +35,7 @@ import androidx.compose.ui.unit.dp
*
* @param items All available items to display as chips.
* @param selectedItems Currently selected items.
- * @param onSelectionChanged Called with the final selection when the sheet is dismissed.
+ * @param onSelectionChange Called with the final selection when the sheet is dismissed.
* @param label Extracts a display label from each item.
* @param onDismiss Called when the sheet is dismissed.
* @param title Title displayed at the top of the sheet.
@@ -50,15 +50,15 @@ import androidx.compose.ui.unit.dp
fun FilterChipBottomSheet(
items: List,
selectedItems: Set,
- onSelectionChanged: (Set) -> Unit,
+ onSelectionChange: (Set) -> Unit,
label: (T) -> String,
onDismiss: () -> Unit,
title: String,
+ modifier: Modifier = Modifier,
emptyMessage: String = "",
onAdd: ((String) -> T?)? = null,
addPlaceholder: String = "",
addContentDescription: String = "",
- modifier: Modifier = Modifier,
) {
val sheetState = rememberModalBottomSheetState()
var currentSelection by remember { mutableStateOf(selectedItems) }
@@ -66,7 +66,7 @@ fun FilterChipBottomSheet(
ModalBottomSheet(
onDismissRequest = {
- onSelectionChanged(currentSelection)
+ onSelectionChange(currentSelection)
onDismiss()
},
modifier = modifier,
diff --git a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/ModelParameterSheet.kt b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/ModelParameterSheet.kt
index 9a8757a..4b4f43d 100644
--- a/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/ModelParameterSheet.kt
+++ b/core/ui/src/commonMain/kotlin/com/garfiec/librechat/core/ui/components/ModelParameterSheet.kt
@@ -104,7 +104,7 @@ data class ModelParameters(
@Composable
fun ModelParameterSheet(
parameters: ModelParameters,
- onParametersChanged: (ModelParameters) -> Unit,
+ onParametersChange: (ModelParameters) -> Unit,
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
selectedEndpoint: String = "",
@@ -119,7 +119,7 @@ fun ModelParameterSheet(
) {
ModelParameterContent(
parameters = parameters,
- onParametersChanged = onParametersChanged,
+ onParametersChange = onParametersChange,
selectedEndpoint = selectedEndpoint,
dynamicParameterDefinitions = dynamicParameterDefinitions,
onSaveAsPreset = onSaveAsPreset,
@@ -133,7 +133,7 @@ fun ModelParameterSheet(
@Composable
fun ModelParameterContent(
parameters: ModelParameters,
- onParametersChanged: (ModelParameters) -> Unit,
+ onParametersChange: (ModelParameters) -> Unit,
modifier: Modifier = Modifier,
selectedEndpoint: String = "",
dynamicParameterDefinitions: List? = null,
@@ -170,7 +170,7 @@ fun ModelParameterContent(
label = definition.label,
value = currentValue,
onValueChange = { newValue ->
- onParametersChanged(parameters.withUpdatedKey(definition.key, newValue))
+ onParametersChange(parameters.withUpdatedKey(definition.key, newValue))
},
placeholder = definition.default?.ifEmpty { "Default" } ?: "Default",
description = definition.description,
@@ -182,7 +182,7 @@ fun ModelParameterContent(
label = definition.label,
value = currentValue,
onValueChange = { newValue ->
- onParametersChanged(parameters.withUpdatedKey(definition.key, newValue))
+ onParametersChange(parameters.withUpdatedKey(definition.key, newValue))
},
placeholder = definition.default?.ifEmpty { null },
description = definition.description,
@@ -199,7 +199,7 @@ fun ModelParameterContent(
label = definition.label,
value = floatValue.coerceIn(min, max),
onValueChange = { newValue ->
- onParametersChanged(parameters.withUpdatedKey(definition.key, newValue.toString()))
+ onParametersChange(parameters.withUpdatedKey(definition.key, newValue.toString()))
},
min = min,
max = max,
@@ -216,7 +216,7 @@ fun ModelParameterContent(
label = definition.label,
checked = checked,
onCheckedChange = { newChecked ->
- onParametersChanged(parameters.withUpdatedKey(definition.key, newChecked.toString()))
+ onParametersChange(parameters.withUpdatedKey(definition.key, newChecked.toString()))
},
description = definition.description,
)
@@ -234,7 +234,7 @@ fun ModelParameterContent(
selectedValue = displayValue,
options = definition.options ?: emptyList(),
onValueChange = { newValue ->
- onParametersChanged(parameters.withUpdatedKey(definition.key, newValue))
+ onParametersChange(parameters.withUpdatedKey(definition.key, newValue))
},
description = definition.description,
)
@@ -250,8 +250,8 @@ fun ModelParameterContent(
DynamicTagsInput(
label = definition.label,
tags = tags,
- onTagsChanged = { newTags ->
- onParametersChanged(
+ onTagsChange = { newTags ->
+ onParametersChange(
parameters.withUpdatedKey(definition.key, newTags.joinToString("\n")),
)
},
@@ -265,7 +265,7 @@ fun ModelParameterContent(
// Reset to defaults
OutlinedButton(
onClick = {
- onParametersChanged(ModelParameters.DEFAULT)
+ onParametersChange(ModelParameters.DEFAULT)
},
modifier = Modifier.fillMaxWidth(),
) {
diff --git a/feature/agents/detekt-baseline.xml b/feature/agents/detekt-baseline.xml
deleted file mode 100644
index c9f880a..0000000
--- a/feature/agents/detekt-baseline.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
-
- ComposableParamOrder:AgentDetailScreen.kt$AgentDetailScreen
- ComposableParamOrder:AgentEditorScreen.kt$AgentEditorScreen
- DeprecatedKoinApi:AgentsModule.kt$viewModel { params -> AgentDetailViewModel( savedStateHandle = get(), agentRepository = get(), serverDataStore = get(), initialAgentId = params.getOrNull(), ) }
- DeprecatedKoinApi:AgentsModule.kt$viewModel { params -> AgentEditorViewModel( savedStateHandle = get(), agentRepository = get(), configRepository = get(), mcpRepository = get(), contentReader = get(), initialAgentId = params.getOrNull(), ) }
- FunctionNaming:String0.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString0Resources(map: MutableMap<String, StringResource>)
- FunctionNaming:String1.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString1Resources(map: MutableMap<String, StringResource>)
- ImportOrdering:AgentActionsPanel.kt$import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.clickable import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.ExpandLess import androidx.compose.material.icons.filled.ExpandMore import androidx.compose.material.icons.filled.Lock import androidx.compose.material.icons.filled.Security import androidx.compose.material3.AlertDialog import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.RadioButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import com.garfiec.librechat.core.model.ActionAuth import com.garfiec.librechat.core.model.ActionMetadata import com.garfiec.librechat.core.model.request.FunctionTool import com.garfiec.librechat.feature.agents.AgentActionDisplayData import librechat_mobile.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.* import com.garfiec.librechat.feature.agents.util.OpenApiSpecParser import com.garfiec.librechat.feature.agents.util.ParsedFunctionInfo import kotlinx.coroutines.delay
- ImportOrdering:AgentAdvancedPanel.kt$import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ExpandLess import androidx.compose.material.icons.filled.ExpandMore import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Slider import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import librechat_mobile.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.* import kotlin.math.roundToInt import com.garfiec.librechat.feature.agents.components.model.AgentAdvancedSettings
- ImportOrdering:AgentCapabilitiesSection.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import librechat_mobile.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.* import com.garfiec.librechat.feature.agents.components.model.AgentCapabilities
- ImportOrdering:AgentCategorySelector.kt$import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExposedDropdownMenuBox import androidx.compose.material3.ExposedDropdownMenuDefaults import androidx.compose.material3.MenuAnchorType import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import com.garfiec.librechat.core.model.AgentCategory import librechat_mobile.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.*
- ImportOrdering:AgentCodeInterpreterSection.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.*
- ImportOrdering:AgentDetailScreen.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.Chat import androidx.compose.material.icons.filled.ContentCopy import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material3.AlertDialog import androidx.compose.material3.AssistChip import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.garfiec.librechat.core.model.EModelEndpoint import com.garfiec.librechat.core.ui.components.AvatarImage import com.garfiec.librechat.core.ui.components.endpointIconPainter import com.garfiec.librechat.core.ui.components.ErrorBanner import com.garfiec.librechat.core.ui.components.LoadingIndicator import librechat_mobile.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.* import com.garfiec.librechat.feature.agents.viewmodel.AgentDetailEvent import com.garfiec.librechat.feature.agents.viewmodel.AgentDetailViewModel import org.koin.compose.viewmodel.koinViewModel import org.koin.core.parameter.parametersOf
- ImportOrdering:AgentEditorScreen.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Build import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.ContentCopy import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.History import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.InputChip import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.garfiec.librechat.core.ui.components.ErrorBanner import com.garfiec.librechat.core.ui.components.LoadingIndicator import librechat_mobile.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.* import com.garfiec.librechat.feature.agents.components.AgentActionsPanel import com.garfiec.librechat.feature.agents.components.AgentAdvancedPanel import com.garfiec.librechat.feature.agents.components.AgentAvatarPicker import com.garfiec.librechat.feature.agents.components.AgentCategorySelector import com.garfiec.librechat.feature.agents.components.AgentCodeInterpreterSection import com.garfiec.librechat.feature.agents.components.AgentFileSearchSection import com.garfiec.librechat.feature.agents.components.AgentHandoffConfig import com.garfiec.librechat.feature.agents.components.AgentMcpToolsSelector import com.garfiec.librechat.feature.agents.components.AgentModelPicker import com.garfiec.librechat.feature.agents.components.AgentSharingSection import com.garfiec.librechat.feature.agents.components.AgentSupportContactSection import com.garfiec.librechat.feature.agents.components.AgentVersionHistory import com.garfiec.librechat.feature.agents.components.ToolSelectDialog import com.garfiec.librechat.feature.agents.viewmodel.AgentEditorEvent import com.garfiec.librechat.feature.agents.viewmodel.AgentEditorViewModel import org.koin.compose.viewmodel.koinViewModel import org.koin.core.parameter.parametersOf
- ImportOrdering:AgentEditorViewModel.kt$import androidx.compose.runtime.Immutable import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.garfiec.librechat.feature.agents.util.ContentReader import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.core.data.repository.AgentRepository import com.garfiec.librechat.core.data.repository.ConfigRepository import com.garfiec.librechat.core.data.repository.McpRepository import com.garfiec.librechat.core.model.ActionMetadata import com.garfiec.librechat.core.model.Agent import com.garfiec.librechat.core.model.AgentAction import com.garfiec.librechat.core.model.AgentCategory import com.garfiec.librechat.core.model.AgentTool import com.garfiec.librechat.core.model.SupportContact import com.garfiec.librechat.core.model.mcp.McpTool import com.garfiec.librechat.core.model.request.CreateActionRequest import com.garfiec.librechat.core.model.request.CreateAgentRequest import com.garfiec.librechat.core.model.request.FunctionTool import com.garfiec.librechat.core.model.request.RevertAgentRequest import com.garfiec.librechat.core.model.request.UpdateAgentRequest import com.garfiec.librechat.feature.agents.AgentActionDisplayData import com.garfiec.librechat.feature.agents.AgentHandoffDisplayData import com.garfiec.librechat.feature.agents.AgentToolDisplayData import com.garfiec.librechat.feature.agents.components.ModelOption import com.garfiec.librechat.feature.agents.components.model.AgentAdvancedSettings import com.garfiec.librechat.feature.agents.components.model.AgentCapabilities import com.garfiec.librechat.feature.agents.components.model.AgentSharingState import com.garfiec.librechat.feature.agents.components.model.AgentVersion import com.garfiec.librechat.feature.agents.components.model.AgentVisibility import com.garfiec.librechat.feature.agents.components.model.SupportContactState import com.garfiec.librechat.feature.agents.util.OpenApiSpecParser import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.floatOrNull import kotlinx.serialization.json.intOrNull import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive import co.touchlab.kermit.Logger
- ImportOrdering:AgentFileSearchSection.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.*
- ImportOrdering:AgentHandoffConfig.kt$import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.ExpandLess import androidx.compose.material.icons.filled.ExpandMore import androidx.compose.material3.AlertDialog import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExposedDropdownMenuBox import androidx.compose.material3.ExposedDropdownMenuDefaults import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.InputChip import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MenuAnchorType import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import com.garfiec.librechat.feature.agents.AgentHandoffDisplayData import librechat_mobile.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.*
- ImportOrdering:AgentMarketplaceScreen.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.GridItemSpan import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.lazy.grid.rememberLazyGridState import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.SmartToy import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FilterChip import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.garfiec.librechat.core.model.EModelEndpoint import com.garfiec.librechat.core.ui.components.AvatarImage import com.garfiec.librechat.core.ui.components.endpointIconPainter import com.garfiec.librechat.core.ui.components.EmptyState import com.garfiec.librechat.core.ui.components.ErrorBanner import com.garfiec.librechat.core.ui.components.LibreChatTopBar import com.garfiec.librechat.core.ui.components.LoadingIndicator import com.garfiec.librechat.feature.agents.AgentCardDisplayData import librechat_mobile.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.* import com.garfiec.librechat.feature.agents.viewmodel.AgentMarketplaceViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:AgentMcpToolsSelector.kt$import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ExpandLess import androidx.compose.material.icons.filled.ExpandMore import androidx.compose.material3.Checkbox import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.model.mcp.McpTool import librechat_mobile.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.*
- ImportOrdering:AgentModelPicker.kt$import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExposedDropdownMenuBox import androidx.compose.material3.ExposedDropdownMenuDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MenuAnchorType import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.*
- ImportOrdering:AgentSharingSection.kt$import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ExpandLess import androidx.compose.material.icons.filled.ExpandMore import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExposedDropdownMenuBox import androidx.compose.material3.ExposedDropdownMenuDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MenuAnchorType import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.* import com.garfiec.librechat.feature.agents.components.model.AgentSharingState import com.garfiec.librechat.feature.agents.components.model.AgentVisibility
- ImportOrdering:AgentSupportContactSection.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.* import com.garfiec.librechat.feature.agents.components.model.SupportContactState
- ImportOrdering:AgentVersionHistory.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.SheetState import androidx.compose.material3.Text import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.* import com.garfiec.librechat.feature.agents.components.model.AgentVersion
- ImportOrdering:ExpectResourceCollectors.kt$import kotlin.String import kotlin.collections.Map import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.FontResource import org.jetbrains.compose.resources.PluralStringResource import org.jetbrains.compose.resources.StringArrayResource import org.jetbrains.compose.resources.StringResource
- ImportOrdering:Res.kt$import kotlin.ByteArray import kotlin.OptIn import kotlin.String import kotlin.Suppress import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.getResourceUri import org.jetbrains.compose.resources.readResourceBytes
- ImportOrdering:String0.commonMain.kt$import kotlin.OptIn import kotlin.String import kotlin.collections.MutableMap import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.ResourceContentHash import org.jetbrains.compose.resources.ResourceItem import org.jetbrains.compose.resources.StringResource
- ImportOrdering:String1.commonMain.kt$import kotlin.OptIn import kotlin.String import kotlin.collections.MutableMap import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.ResourceContentHash import org.jetbrains.compose.resources.ResourceItem import org.jetbrains.compose.resources.StringResource
- ImportOrdering:ToolSelectDialog.kt$import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Build import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Remove import androidx.compose.material.icons.filled.Search import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.FilledTonalButton import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import coil3.compose.AsyncImage import com.garfiec.librechat.feature.agents.AgentToolDisplayData import librechat_mobile.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.*
- LambdaParameterInRestartableEffect:AgentDetailScreen.kt$onBack
- LambdaParameterInRestartableEffect:AgentDetailScreen.kt$onDuplicated
- LambdaParameterInRestartableEffect:AgentEditorScreen.kt$onDeleted
- LambdaParameterInRestartableEffect:AgentEditorScreen.kt$onDuplicated
- LambdaParameterInRestartableEffect:AgentEditorScreen.kt$onSaved
- LoopWithTooManyJumpStatements:YamlParser.kt$YamlParser$while
- MaxLineLength:AgentEditorViewModel.kt$AgentEditorViewModel$"name=${agent.name}, description=${agent.description}, instructions=${agent.instructions}, model=${agent.model}, "
- MaxLineLength:AgentEditorViewModel.kt$AgentEditorViewModel$"name=${newState.name}, description=${newState.description}, instructions=${newState.instructions}, model=${newState.model}, "
- MaxLineLength:Res.kt$Res$public suspend
- NoConsecutiveBlankLines:AgentDetailScreen.kt$
- NoConsecutiveBlankLines:AgentMarketplaceScreen.kt$
- NoUnusedImports:OpenApiSpecParser.kt$com.garfiec.librechat.feature.agents.util.OpenApiSpecParser.kt
- PackageName:ExpectResourceCollectors.kt$package librechat_mobile.feature.agents.generated.resources
- PackageName:Res.kt$package librechat_mobile.feature.agents.generated.resources
- PackageName:String0.commonMain.kt$package librechat_mobile.feature.agents.generated.resources
- PackageName:String1.commonMain.kt$package librechat_mobile.feature.agents.generated.resources
- PackageNaming:ExpectResourceCollectors.kt$package librechat_mobile.feature.agents.generated.resources
- PackageNaming:Res.kt$package librechat_mobile.feature.agents.generated.resources
- PackageNaming:String0.commonMain.kt$package librechat_mobile.feature.agents.generated.resources
- PackageNaming:String1.commonMain.kt$package librechat_mobile.feature.agents.generated.resources
- ParameterNaming:AgentAdvancedPanel.kt$onSettingsChanged
- ParameterNaming:AgentAvatarPicker.kt$onImageSelected
- ParameterNaming:AgentCapabilitiesSection.kt$onCapabilitiesChanged
- ParameterNaming:AgentCategorySelector.kt$onCategorySelected
- ParameterNaming:AgentDetailScreen.kt$onDuplicated
- ParameterNaming:AgentEditorScreen.kt$onDeleted
- ParameterNaming:AgentEditorScreen.kt$onDuplicated
- ParameterNaming:AgentEditorScreen.kt$onSaved
- ParameterNaming:AgentMcpToolsSelector.kt$onToolToggled
- ParameterNaming:AgentModelPicker.kt$onModelSelected
- ParameterNaming:AgentSharingSection.kt$onSharingChanged
- ParameterNaming:AgentSupportContactSection.kt$onSupportContactChanged
- ParameterNaming:ToolSelectDialog.kt$onToolAdded
- ParameterNaming:ToolSelectDialog.kt$onToolRemoved
- SpacingBetweenDeclarationsWithAnnotations:AgentsNavigation.kt$AgentDetail : AgentsRoute
- SpacingBetweenDeclarationsWithAnnotations:AgentsNavigation.kt$AgentEditorCreate : AgentsRoute
- SpacingBetweenDeclarationsWithAnnotations:AgentsNavigation.kt$AgentEditorEdit : AgentsRoute
- UnusedPrivateProperty:AgentDetailViewModel.kt$AgentDetailViewModel$savedStateHandle: SavedStateHandle
- UnusedPrivateProperty:AgentEditorViewModel.kt$AgentEditorViewModel$savedStateHandle: SavedStateHandle
-
-
diff --git a/feature/agents/src/androidMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentAvatarPicker.kt b/feature/agents/src/androidMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentAvatarPicker.kt
index 10ce5a3..46cdf87 100644
--- a/feature/agents/src/androidMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentAvatarPicker.kt
+++ b/feature/agents/src/androidMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentAvatarPicker.kt
@@ -18,26 +18,26 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
actual fun AgentAvatarPicker(
avatarUrl: String?,
agentName: String,
- onImageSelected: (Any) -> Unit,
+ onImageSelect: (Any) -> Unit,
modifier: Modifier,
) {
val launcher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.GetContent(),
) { uri: Uri? ->
if (uri != null) {
- onImageSelected(uri)
+ onImageSelect(uri)
}
}
diff --git a/feature/agents/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/agents/di/AgentsModuleVerificationTest.kt b/feature/agents/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/agents/di/AgentsModuleVerificationTest.kt
index fb8879b..a9766ec 100644
--- a/feature/agents/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/agents/di/AgentsModuleVerificationTest.kt
+++ b/feature/agents/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/agents/di/AgentsModuleVerificationTest.kt
@@ -2,7 +2,6 @@ package com.garfiec.librechat.feature.agents.di
import android.app.Application
import android.content.Context
-import androidx.lifecycle.SavedStateHandle
import com.garfiec.librechat.core.data.datastore.ServerDataStore
import com.garfiec.librechat.core.data.repository.AgentRepository
import com.garfiec.librechat.core.data.repository.ConfigRepository
@@ -17,7 +16,6 @@ class AgentsModuleVerificationTest {
extraTypes = listOf(
Context::class,
Application::class,
- SavedStateHandle::class,
AgentRepository::class,
ConfigRepository::class,
McpRepository::class,
diff --git a/feature/agents/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/agents/viewmodel/AgentMarketplaceViewModelTest.kt b/feature/agents/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/agents/viewmodel/AgentMarketplaceViewModelTest.kt
index 3afabdf..1e80391 100644
--- a/feature/agents/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/agents/viewmodel/AgentMarketplaceViewModelTest.kt
+++ b/feature/agents/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/agents/viewmodel/AgentMarketplaceViewModelTest.kt
@@ -1,12 +1,12 @@
package com.garfiec.librechat.feature.agents.viewmodel
-import com.google.common.truth.Truth.assertThat
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.datastore.ServerDataStore
import com.garfiec.librechat.core.data.repository.AgentRepository
import com.garfiec.librechat.core.model.Agent
import com.garfiec.librechat.core.model.AgentCategory
import com.garfiec.librechat.core.model.PaginatedAgents
+import com.google.common.truth.Truth.assertThat
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentActionsPanel.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentActionsPanel.kt
index 6237f0c..83156f3 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentActionsPanel.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentActionsPanel.kt
@@ -45,7 +45,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.PasswordVisualTransformation
@@ -57,11 +56,12 @@ import com.garfiec.librechat.core.model.ActionAuth
import com.garfiec.librechat.core.model.ActionMetadata
import com.garfiec.librechat.core.model.request.FunctionTool
import com.garfiec.librechat.feature.agents.AgentActionDisplayData
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
import com.garfiec.librechat.feature.agents.util.OpenApiSpecParser
import com.garfiec.librechat.feature.agents.util.ParsedFunctionInfo
import kotlinx.coroutines.delay
+import org.jetbrains.compose.resources.stringResource
private const val VALIDATION_DEBOUNCE_MS = 800L
private const val HIDDEN_PLACEHOLDER = ""
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentAdvancedPanel.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentAdvancedPanel.kt
index d0a7997..3e0bc32 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentAdvancedPanel.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentAdvancedPanel.kt
@@ -26,18 +26,18 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
-import kotlin.math.roundToInt
import com.garfiec.librechat.feature.agents.components.model.AgentAdvancedSettings
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
+import org.jetbrains.compose.resources.stringResource
+import kotlin.math.roundToInt
@Composable
fun AgentAdvancedPanel(
settings: AgentAdvancedSettings,
- onSettingsChanged: (AgentAdvancedSettings) -> Unit,
+ onSettingsChange: (AgentAdvancedSettings) -> Unit,
modifier: Modifier = Modifier,
) {
var expanded by remember { mutableStateOf(false) }
@@ -71,7 +71,7 @@ fun AgentAdvancedPanel(
label = stringResource(Res.string.label_temperature),
value = settings.temperature ?: 1.0f,
onValueChange = {
- onSettingsChanged(settings.copy(temperature = roundToStep(it, 0.1f)))
+ onSettingsChange(settings.copy(temperature = roundToStep(it, 0.1f)))
},
valueRange = 0f..2f,
steps = 19,
@@ -83,7 +83,7 @@ fun AgentAdvancedPanel(
label = stringResource(Res.string.label_top_p),
value = settings.topP ?: 1.0f,
onValueChange = {
- onSettingsChanged(settings.copy(topP = roundToStep(it, 0.05f)))
+ onSettingsChange(settings.copy(topP = roundToStep(it, 0.05f)))
},
valueRange = 0f..1f,
steps = 19,
@@ -106,7 +106,7 @@ fun AgentAdvancedPanel(
value = settings.maxTokens?.toString() ?: "",
onValueChange = { newValue ->
val filtered = newValue.filter { it.isDigit() }
- onSettingsChanged(
+ onSettingsChange(
settings.copy(maxTokens = filtered.toIntOrNull()),
)
},
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentAvatarPicker.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentAvatarPicker.kt
index 19ee00a..9bfe8de 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentAvatarPicker.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentAvatarPicker.kt
@@ -7,6 +7,6 @@ import androidx.compose.ui.Modifier
expect fun AgentAvatarPicker(
avatarUrl: String?,
agentName: String,
- onImageSelected: (Any) -> Unit,
+ onImageSelect: (Any) -> Unit,
modifier: Modifier = Modifier,
)
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentCapabilitiesSection.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentCapabilitiesSection.kt
index d64c251..bb6438f 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentCapabilitiesSection.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentCapabilitiesSection.kt
@@ -15,17 +15,17 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
import com.garfiec.librechat.feature.agents.components.model.AgentCapabilities
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
fun AgentCapabilitiesSection(
capabilities: AgentCapabilities,
- onCapabilitiesChanged: (AgentCapabilities) -> Unit,
+ onCapabilitiesChange: (AgentCapabilities) -> Unit,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier.fillMaxWidth()) {
@@ -40,7 +40,7 @@ fun AgentCapabilitiesSection(
description = stringResource(Res.string.artifacts_description),
checked = capabilities.artifacts,
onCheckedChange = {
- onCapabilitiesChanged(capabilities.copy(artifacts = it))
+ onCapabilitiesChange(capabilities.copy(artifacts = it))
},
)
@@ -49,7 +49,7 @@ fun AgentCapabilitiesSection(
description = stringResource(Res.string.end_after_tools_description),
checked = capabilities.endAfterTools,
onCheckedChange = {
- onCapabilitiesChanged(capabilities.copy(endAfterTools = it))
+ onCapabilitiesChange(capabilities.copy(endAfterTools = it))
},
)
@@ -58,7 +58,7 @@ fun AgentCapabilitiesSection(
description = stringResource(Res.string.hide_sequential_description),
checked = capabilities.hideSequentialOutputs,
onCheckedChange = {
- onCapabilitiesChanged(capabilities.copy(hideSequentialOutputs = it))
+ onCapabilitiesChange(capabilities.copy(hideSequentialOutputs = it))
},
)
@@ -80,7 +80,7 @@ fun AgentCapabilitiesSection(
onValueChange = { newValue ->
val filtered = newValue.filter { it.isDigit() }
val intVal = filtered.toIntOrNull() ?: 0
- onCapabilitiesChanged(
+ onCapabilitiesChange(
capabilities.copy(recursionLimit = intVal.coerceIn(1, 100)),
)
},
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentCategorySelector.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentCategorySelector.kt
index aa61d2d..e249629 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentCategorySelector.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentCategorySelector.kt
@@ -14,10 +14,10 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import com.garfiec.librechat.core.model.AgentCategory
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
+import org.jetbrains.compose.resources.stringResource
/**
* Maps category values to human-readable English labels.
@@ -51,7 +51,7 @@ private fun AgentCategory.displayLabel(): String {
fun AgentCategorySelector(
selectedCategory: String,
categories: List,
- onCategorySelected: (String) -> Unit,
+ onCategorySelect: (String) -> Unit,
modifier: Modifier = Modifier,
) {
var expanded by remember { mutableStateOf(false) }
@@ -90,7 +90,7 @@ fun AgentCategorySelector(
DropdownMenuItem(
text = { Text(category.displayLabel()) },
onClick = {
- onCategorySelected(category.value)
+ onCategorySelect(category.value)
expanded = false
},
)
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentCodeInterpreterSection.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentCodeInterpreterSection.kt
index 95bbdb4..b12c055 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentCodeInterpreterSection.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentCodeInterpreterSection.kt
@@ -13,10 +13,10 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
fun AgentCodeInterpreterSection(
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentFileSearchSection.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentFileSearchSection.kt
index 79a98f4..10d55c4 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentFileSearchSection.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentFileSearchSection.kt
@@ -13,10 +13,10 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
fun AgentFileSearchSection(
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentHandoffConfig.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentHandoffConfig.kt
index e2ea5c0..97c8f59 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentHandoffConfig.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentHandoffConfig.kt
@@ -35,11 +35,11 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.feature.agents.AgentHandoffDisplayData
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
fun AgentHandoffConfig(
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentMcpToolsSelector.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentMcpToolsSelector.kt
index d0ee80d..fac6dd7 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentMcpToolsSelector.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentMcpToolsSelector.kt
@@ -21,18 +21,18 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.mcp.McpTool
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
+import org.jetbrains.compose.resources.stringResource
/** Hierarchical MCP tool picker grouped by server with checkbox selection. */
@Composable
fun AgentMcpToolsSelector(
mcpTools: List,
selectedToolNames: Set,
- onToolToggled: (toolName: String) -> Unit,
+ onToolToggle: (toolName: String) -> Unit,
modifier: Modifier = Modifier,
) {
var expanded by remember { mutableStateOf(false) }
@@ -80,7 +80,7 @@ fun AgentMcpToolsSelector(
serverName = serverName,
tools = tools,
selectedToolNames = selectedToolNames,
- onToolToggled = onToolToggled,
+ onToolToggle = onToolToggle,
)
}
}
@@ -94,7 +94,7 @@ private fun McpServerToolsGroup(
serverName: String,
tools: List,
selectedToolNames: Set,
- onToolToggled: (String) -> Unit,
+ onToolToggle: (String) -> Unit,
modifier: Modifier = Modifier,
) {
var serverExpanded by remember { mutableStateOf(true) }
@@ -125,7 +125,7 @@ private fun McpServerToolsGroup(
McpToolRow(
tool = tool,
isSelected = tool.name in selectedToolNames,
- onToggle = { onToolToggled(tool.name) },
+ onToggle = { onToolToggle(tool.name) },
)
}
}
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentModelPicker.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentModelPicker.kt
index 4900722..766c096 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentModelPicker.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentModelPicker.kt
@@ -16,10 +16,10 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
+import org.jetbrains.compose.resources.stringResource
data class ModelOption(
val id: String,
@@ -32,7 +32,7 @@ data class ModelOption(
fun AgentModelPicker(
selectedModel: String,
availableModels: List,
- onModelSelected: (modelId: String, provider: String) -> Unit,
+ onModelSelect: (modelId: String, provider: String) -> Unit,
modifier: Modifier = Modifier,
) {
var expanded by remember { mutableStateOf(false) }
@@ -107,7 +107,7 @@ fun AgentModelPicker(
DropdownMenuItem(
text = { Text(model.name) },
onClick = {
- onModelSelected(model.id, model.endpoint)
+ onModelSelect(model.id, model.endpoint)
expanded = false
searchQuery = ""
},
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentSharingSection.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentSharingSection.kt
index 1d09050..9d9f3a2 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentSharingSection.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentSharingSection.kt
@@ -29,19 +29,19 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
import com.garfiec.librechat.feature.agents.components.model.AgentSharingState
import com.garfiec.librechat.feature.agents.components.model.AgentVisibility
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
+import org.jetbrains.compose.resources.stringResource
/** Visibility (Private/Team/Public) and collaborative toggle; maps to agent model isPublic/isCollaborative. */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AgentSharingSection(
sharingState: AgentSharingState,
- onSharingChanged: (AgentSharingState) -> Unit,
+ onSharingChange: (AgentSharingState) -> Unit,
modifier: Modifier = Modifier,
) {
var expanded by remember { mutableStateOf(false) }
@@ -97,7 +97,7 @@ fun AgentSharingSection(
DropdownMenuItem(
text = { Text(visibility.label) },
onClick = {
- onSharingChanged(sharingState.copy(visibility = visibility))
+ onSharingChange(sharingState.copy(visibility = visibility))
dropdownExpanded = false
},
)
@@ -129,7 +129,7 @@ fun AgentSharingSection(
Switch(
checked = sharingState.isCollaborative,
onCheckedChange = {
- onSharingChanged(sharingState.copy(isCollaborative = it))
+ onSharingChange(sharingState.copy(isCollaborative = it))
},
)
}
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentSupportContactSection.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentSupportContactSection.kt
index 4ed0b6a..42bc648 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentSupportContactSection.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentSupportContactSection.kt
@@ -9,16 +9,16 @@ import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
import com.garfiec.librechat.feature.agents.components.model.SupportContactState
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
fun AgentSupportContactSection(
supportContact: SupportContactState,
- onSupportContactChanged: (SupportContactState) -> Unit,
+ onSupportContactChange: (SupportContactState) -> Unit,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier.fillMaxWidth()) {
@@ -37,7 +37,7 @@ fun AgentSupportContactSection(
OutlinedTextField(
value = supportContact.name,
onValueChange = {
- onSupportContactChanged(supportContact.copy(name = it))
+ onSupportContactChange(supportContact.copy(name = it))
},
placeholder = { Text(stringResource(Res.string.support_contact_placeholder)) },
singleLine = true,
@@ -55,7 +55,7 @@ fun AgentSupportContactSection(
OutlinedTextField(
value = supportContact.email,
onValueChange = {
- onSupportContactChanged(supportContact.copy(email = it))
+ onSupportContactChange(supportContact.copy(email = it))
},
placeholder = { Text("support@example.com") },
singleLine = true,
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentVersionHistory.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentVersionHistory.kt
index 3bb1af8..5d55eb3 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentVersionHistory.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentVersionHistory.kt
@@ -21,11 +21,11 @@ import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
import com.garfiec.librechat.feature.agents.components.model.AgentVersion
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
+import org.jetbrains.compose.resources.stringResource
@OptIn(ExperimentalMaterial3Api::class)
@Composable
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/ToolSelectDialog.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/ToolSelectDialog.kt
index fddc32d..e808c2e 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/ToolSelectDialog.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/components/ToolSelectDialog.kt
@@ -42,15 +42,15 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import coil3.compose.AsyncImage
import com.garfiec.librechat.feature.agents.AgentToolDisplayData
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
+import org.jetbrains.compose.resources.stringResource
/**
* Full-screen dialog for selecting agent tools, matching the web app's ToolSelectDialog.
@@ -60,8 +60,8 @@ import librechat_mobile.feature.agents.generated.resources.*
fun ToolSelectDialog(
tools: List,
selectedToolIds: List,
- onToolAdded: (String) -> Unit,
- onToolRemoved: (String) -> Unit,
+ onToolAdd: (String) -> Unit,
+ onToolRemove: (String) -> Unit,
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
) {
@@ -175,9 +175,9 @@ fun ToolSelectDialog(
isInstalled = isInstalled,
onToggle = {
if (isInstalled) {
- onToolRemoved(toolId)
+ onToolRemove(toolId)
} else {
- onToolAdded(toolId)
+ onToolAdd(toolId)
}
},
)
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/di/AgentsModule.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/di/AgentsModule.kt
index 71b226b..dc61d96 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/di/AgentsModule.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/di/AgentsModule.kt
@@ -14,17 +14,22 @@ val agentsModule = module {
includes(agentsPlatformModule)
viewModelOf(::AgentMarketplaceViewModel)
+ // Koin's constructor-DSL (`viewModelOf`) wires every argument via `get()` and cannot read
+ // values passed through `parametersOf`. Both VMs below receive `initialAgentId` from the
+ // navigation layer via `parametersOf`, so the lambda-form `viewModel { params -> ... }` is
+ // the only DSL that works here. Detekt's `DeprecatedKoinApi` is a blanket stylistic rule,
+ // not a real `@Deprecated` API, so we suppress it in the narrow places it applies.
+ @Suppress("DeprecatedKoinApi")
viewModel { params ->
AgentDetailViewModel(
- savedStateHandle = get(),
agentRepository = get(),
serverDataStore = get(),
initialAgentId = params.getOrNull(),
)
}
+ @Suppress("DeprecatedKoinApi")
viewModel { params ->
AgentEditorViewModel(
- savedStateHandle = get(),
agentRepository = get(),
configRepository = get(),
mcpRepository = get(),
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/navigation/AgentsNavigation.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/navigation/AgentsNavigation.kt
index 32566ff..1347e4f 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/navigation/AgentsNavigation.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/navigation/AgentsNavigation.kt
@@ -13,8 +13,11 @@ import kotlinx.serialization.modules.subclass
@Serializable sealed interface AgentsRoute : NavKey
@Serializable data object AgentMarketplace : AgentsRoute
+
@Serializable data class AgentDetail(val agentId: String) : AgentsRoute
+
@Serializable data object AgentEditorCreate : AgentsRoute
+
@Serializable data class AgentEditorEdit(val agentId: String) : AgentsRoute
fun EntryProviderScope.agentsEntries(
@@ -34,21 +37,21 @@ fun EntryProviderScope.agentsEntries(
onBack = onBack,
onStartChat = onStartChat,
onEdit = { agentId -> onNavigate(AgentEditorEdit(agentId = agentId)) },
- onDuplicated = { agentId -> onNavigate(AgentDetail(agentId = agentId)) },
+ onDuplicate = { agentId -> onNavigate(AgentDetail(agentId = agentId)) },
agentId = key.agentId,
)
}
entry {
AgentEditorScreen(
onBack = onBack,
- onSaved = { agentId -> onNavigate(AgentDetail(agentId = agentId)) },
+ onSave = { agentId -> onNavigate(AgentDetail(agentId = agentId)) },
agentId = null,
)
}
entry { key ->
AgentEditorScreen(
onBack = onBack,
- onSaved = { agentId -> onNavigate(AgentDetail(agentId = agentId)) },
+ onSave = { agentId -> onNavigate(AgentDetail(agentId = agentId)) },
agentId = key.agentId,
)
}
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/screen/AgentDetailScreen.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/screen/AgentDetailScreen.kt
index 6e4528f..95c9044 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/screen/AgentDetailScreen.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/screen/AgentDetailScreen.kt
@@ -39,45 +39,47 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.garfiec.librechat.core.model.EModelEndpoint
import com.garfiec.librechat.core.ui.components.AvatarImage
-import com.garfiec.librechat.core.ui.components.endpointIconPainter
import com.garfiec.librechat.core.ui.components.ErrorBanner
import com.garfiec.librechat.core.ui.components.LoadingIndicator
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
+import com.garfiec.librechat.core.ui.components.endpointIconPainter
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
import com.garfiec.librechat.feature.agents.viewmodel.AgentDetailEvent
import com.garfiec.librechat.feature.agents.viewmodel.AgentDetailViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.koin.core.parameter.parametersOf
-
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@Composable
fun AgentDetailScreen(
onBack: () -> Unit,
onStartChat: (String) -> Unit,
onEdit: (String) -> Unit,
- onDuplicated: (String) -> Unit,
- agentId: String? = null,
+ onDuplicate: (String) -> Unit,
modifier: Modifier = Modifier,
+ agentId: String? = null,
viewModel: AgentDetailViewModel = koinViewModel { parametersOf(agentId) },
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
+ val currentOnBack by rememberUpdatedState(onBack)
+ val currentOnDuplicated by rememberUpdatedState(onDuplicate)
LaunchedEffect(Unit) {
viewModel.events.collect { event ->
when (event) {
- is AgentDetailEvent.Deleted -> onBack()
- is AgentDetailEvent.Duplicated -> onDuplicated(event.agentId)
+ is AgentDetailEvent.Deleted -> currentOnBack()
+ is AgentDetailEvent.Duplicated -> currentOnDuplicated(event.agentId)
}
}
}
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/screen/AgentEditorScreen.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/screen/AgentEditorScreen.kt
index ecc98f4..5752a8b 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/screen/AgentEditorScreen.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/screen/AgentEditorScreen.kt
@@ -44,17 +44,15 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.garfiec.librechat.core.ui.components.ErrorBanner
import com.garfiec.librechat.core.ui.components.LoadingIndicator
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
import com.garfiec.librechat.feature.agents.components.AgentActionsPanel
import com.garfiec.librechat.feature.agents.components.AgentAdvancedPanel
import com.garfiec.librechat.feature.agents.components.AgentAvatarPicker
@@ -68,8 +66,11 @@ import com.garfiec.librechat.feature.agents.components.AgentSharingSection
import com.garfiec.librechat.feature.agents.components.AgentSupportContactSection
import com.garfiec.librechat.feature.agents.components.AgentVersionHistory
import com.garfiec.librechat.feature.agents.components.ToolSelectDialog
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
import com.garfiec.librechat.feature.agents.viewmodel.AgentEditorEvent
import com.garfiec.librechat.feature.agents.viewmodel.AgentEditorViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.koin.core.parameter.parametersOf
@@ -77,22 +78,25 @@ import org.koin.core.parameter.parametersOf
@Composable
fun AgentEditorScreen(
onBack: () -> Unit,
- onSaved: (String) -> Unit,
- agentId: String? = null,
+ onSave: (String) -> Unit,
modifier: Modifier = Modifier,
- onDeleted: () -> Unit = onBack,
- onDuplicated: (String) -> Unit = onSaved,
+ agentId: String? = null,
+ onDelete: () -> Unit = onBack,
+ onDuplicate: (String) -> Unit = onSave,
viewModel: AgentEditorViewModel = koinViewModel { parametersOf(agentId) },
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
var showToolDialog by rememberSaveable { mutableStateOf(false) }
+ val currentOnSaved by rememberUpdatedState(onSave)
+ val currentOnDuplicated by rememberUpdatedState(onDuplicate)
+ val currentOnDeleted by rememberUpdatedState(onDelete)
LaunchedEffect(Unit) {
viewModel.events.collect { event ->
when (event) {
- is AgentEditorEvent.SaveSuccess -> onSaved(event.agentId)
- is AgentEditorEvent.DuplicateSuccess -> onDuplicated(event.agentId)
- is AgentEditorEvent.DeleteSuccess -> onDeleted()
+ is AgentEditorEvent.SaveSuccess -> currentOnSaved(event.agentId)
+ is AgentEditorEvent.DuplicateSuccess -> currentOnDuplicated(event.agentId)
+ is AgentEditorEvent.DeleteSuccess -> currentOnDeleted()
}
}
}
@@ -149,8 +153,8 @@ fun AgentEditorScreen(
ToolSelectDialog(
tools = uiState.availableTools,
selectedToolIds = uiState.selectedTools,
- onToolAdded = viewModel::onToolAdded,
- onToolRemoved = viewModel::onToolRemoved,
+ onToolAdd = viewModel::onToolAdded,
+ onToolRemove = viewModel::onToolRemoved,
onDismiss = { showToolDialog = false },
)
}
@@ -283,7 +287,7 @@ fun AgentEditorScreen(
AgentAvatarPicker(
avatarUrl = uiState.avatarUrl,
agentName = uiState.name,
- onImageSelected = viewModel::uploadAvatar,
+ onImageSelect = viewModel::uploadAvatar,
)
Spacer(modifier = Modifier.height(4.dp))
Text(
@@ -330,7 +334,7 @@ fun AgentEditorScreen(
AgentCategorySelector(
selectedCategory = uiState.category,
categories = uiState.categories,
- onCategorySelected = viewModel::onCategoryChanged,
+ onCategorySelect = viewModel::onCategoryChanged,
modifier = Modifier.fillMaxWidth(),
)
@@ -353,7 +357,7 @@ fun AgentEditorScreen(
AgentModelPicker(
selectedModel = uiState.model,
availableModels = uiState.availableModels,
- onModelSelected = viewModel::onModelSelected,
+ onModelSelect = viewModel::onModelSelected,
modifier = Modifier.fillMaxWidth(),
)
@@ -389,7 +393,7 @@ fun AgentEditorScreen(
AgentMcpToolsSelector(
mcpTools = uiState.mcpTools,
selectedToolNames = uiState.selectedMcpTools,
- onToolToggled = viewModel::onMcpToolToggled,
+ onToolToggle = viewModel::onMcpToolToggled,
)
Spacer(modifier = Modifier.height(12.dp))
@@ -472,7 +476,7 @@ fun AgentEditorScreen(
// 10. Support Contact
AgentSupportContactSection(
supportContact = uiState.supportContact,
- onSupportContactChanged = viewModel::onSupportContactChanged,
+ onSupportContactChange = viewModel::onSupportContactChanged,
)
Spacer(modifier = Modifier.height(16.dp))
@@ -533,7 +537,7 @@ fun AgentEditorScreen(
// Sharing & Permissions
AgentSharingSection(
sharingState = uiState.sharingState,
- onSharingChanged = viewModel::onSharingChanged,
+ onSharingChange = viewModel::onSharingChanged,
)
Spacer(modifier = Modifier.height(8.dp))
@@ -551,7 +555,7 @@ fun AgentEditorScreen(
// 12. Advanced settings (collapsible)
AgentAdvancedPanel(
settings = uiState.advancedSettings,
- onSettingsChanged = viewModel::onAdvancedSettingsChanged,
+ onSettingsChange = viewModel::onAdvancedSettingsChanged,
)
Spacer(modifier = Modifier.height(24.dp))
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/screen/AgentMarketplaceScreen.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/screen/AgentMarketplaceScreen.kt
index c7ebb6b..8e9f9d9 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/screen/AgentMarketplaceScreen.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/screen/AgentMarketplaceScreen.kt
@@ -41,24 +41,23 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.garfiec.librechat.core.model.EModelEndpoint
import com.garfiec.librechat.core.ui.components.AvatarImage
-import com.garfiec.librechat.core.ui.components.endpointIconPainter
import com.garfiec.librechat.core.ui.components.EmptyState
import com.garfiec.librechat.core.ui.components.ErrorBanner
import com.garfiec.librechat.core.ui.components.LibreChatTopBar
import com.garfiec.librechat.core.ui.components.LoadingIndicator
+import com.garfiec.librechat.core.ui.components.endpointIconPainter
import com.garfiec.librechat.feature.agents.AgentCardDisplayData
-import librechat_mobile.feature.agents.generated.resources.Res
-import librechat_mobile.feature.agents.generated.resources.*
+import com.garfiec.librechat.feature.agents.resources.*
+import com.garfiec.librechat.feature.agents.resources.Res
import com.garfiec.librechat.feature.agents.viewmodel.AgentMarketplaceViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
-
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AgentMarketplaceScreen(
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/util/OpenApiSpecParser.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/util/OpenApiSpecParser.kt
index 2967b19..79af642 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/util/OpenApiSpecParser.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/util/OpenApiSpecParser.kt
@@ -5,7 +5,6 @@ import com.garfiec.librechat.core.model.request.FunctionTool
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonElement
-import kotlinx.serialization.json.JsonNull
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.jsonArray
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/util/YamlParser.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/util/YamlParser.kt
index 7f5e034..adef6db 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/util/YamlParser.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/util/YamlParser.kt
@@ -54,19 +54,11 @@ private class YamlParser(input: String) {
val entries = mutableMapOf()
while (pos < lines.size) {
skipBlanksAndComments()
- if (pos >= lines.size) break
- val indent = currentIndent()
- if (indent < baseIndent) break
- if (indent > baseIndent) break // belongs to parent
+ if (shouldStopParsingMap(baseIndent)) break
val line = lines[pos]
val trimmed = line.trimStart()
-
- // Must be a map entry, not a list item
- if (trimmed.startsWith("- ")) break
-
val colonIdx = findKeyColonIndex(trimmed)
- if (colonIdx < 0) break
val key = trimmed.substring(0, colonIdx).trim().unquoteYaml()
val afterColon = trimmed.substring(colonIdx + 1).trim()
@@ -97,17 +89,59 @@ private class YamlParser(input: String) {
return JsonObject(entries)
}
+ /**
+ * Returns true when [parseMap] should stop consuming lines at the current position.
+ * Extracted from the main loop to reduce jump count — preserves the original behaviour
+ * exactly: end-of-input, dedent to parent, indent into child, list item, or a line
+ * without a key colon all terminate the map.
+ */
+ private fun shouldStopParsingMap(baseIndent: Int): Boolean {
+ if (pos >= lines.size) return true
+ val indent = currentIndent()
+ if (indent < baseIndent) return true
+ if (indent > baseIndent) return true // belongs to parent
+ val trimmed = lines[pos].trimStart()
+ if (trimmed.startsWith("- ")) return true // must be a map entry, not a list item
+ if (findKeyColonIndex(trimmed) < 0) return true
+ return false
+ }
+
+ /**
+ * Returns true when [parseList] should stop consuming lines at the current position.
+ * Extracted from the main loop to reduce jump count — preserves the original behaviour
+ * exactly: end-of-input, any indent mismatch, or a line that is not a list item all
+ * terminate the list.
+ */
+ private fun shouldStopParsingList(baseIndent: Int): Boolean {
+ if (pos >= lines.size) return true
+ if (currentIndent() != baseIndent) return true
+ val trimmed = lines[pos].trimStart()
+ if (!trimmed.startsWith("- ") && trimmed != "-") return true
+ return false
+ }
+
+ /**
+ * Returns true when the continuation loop in [parseListItemMap] should stop at the
+ * current position. Extracted from the main loop to reduce jump count — preserves the
+ * original behaviour exactly: end-of-input, dedent below the content indent, next list
+ * item, or a line without a key colon all terminate the continuation.
+ */
+ private fun shouldStopParsingListItemMap(contentIndent: Int): Boolean {
+ if (pos >= lines.size) return true
+ if (currentIndent() < contentIndent) return true
+ val line = lines[pos].trimStart()
+ if (line.startsWith("- ")) return true // next list item
+ if (findKeyColonIndex(line) < 0) return true
+ return false
+ }
+
private fun parseList(baseIndent: Int): JsonArray {
val items = mutableListOf()
while (pos < lines.size) {
skipBlanksAndComments()
- if (pos >= lines.size) break
- val indent = currentIndent()
- if (indent != baseIndent) break
+ if (shouldStopParsingList(baseIndent)) break
val trimmed = lines[pos].trimStart()
- if (!trimmed.startsWith("- ") && trimmed != "-") break
-
val afterDash = if (trimmed == "-") "" else trimmed.substring(2).trim()
pos++
@@ -175,15 +209,11 @@ private class YamlParser(input: String) {
// Continuation lines at contentIndent
while (pos < lines.size) {
skipBlanksAndComments()
- if (pos >= lines.size) break
+ if (shouldStopParsingListItemMap(contentIndent)) break
+
val indent = currentIndent()
- if (indent < contentIndent) break
-
val line = lines[pos].trimStart()
- if (line.startsWith("- ")) break // next list item
-
val ci = findKeyColonIndex(line)
- if (ci < 0) break
val key = line.substring(0, ci).trim().unquoteYaml()
val afterColon = line.substring(ci + 1).trim()
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/viewmodel/AgentDetailViewModel.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/viewmodel/AgentDetailViewModel.kt
index 6eaa69d..6933062 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/viewmodel/AgentDetailViewModel.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/viewmodel/AgentDetailViewModel.kt
@@ -1,7 +1,6 @@
package com.garfiec.librechat.feature.agents.viewmodel
import androidx.compose.runtime.Immutable
-import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.garfiec.librechat.core.common.result.Result
@@ -33,7 +32,6 @@ sealed interface AgentDetailEvent {
}
class AgentDetailViewModel(
- savedStateHandle: SavedStateHandle,
private val agentRepository: AgentRepository,
private val serverDataStore: ServerDataStore,
initialAgentId: String? = null,
diff --git a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/viewmodel/AgentEditorViewModel.kt b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/viewmodel/AgentEditorViewModel.kt
index 1f03c28..3705478 100644
--- a/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/viewmodel/AgentEditorViewModel.kt
+++ b/feature/agents/src/commonMain/kotlin/com/garfiec/librechat/feature/agents/viewmodel/AgentEditorViewModel.kt
@@ -1,10 +1,9 @@
package com.garfiec.librechat.feature.agents.viewmodel
import androidx.compose.runtime.Immutable
-import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import com.garfiec.librechat.feature.agents.util.ContentReader
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.repository.AgentRepository
import com.garfiec.librechat.core.data.repository.ConfigRepository
@@ -31,6 +30,7 @@ import com.garfiec.librechat.feature.agents.components.model.AgentSharingState
import com.garfiec.librechat.feature.agents.components.model.AgentVersion
import com.garfiec.librechat.feature.agents.components.model.AgentVisibility
import com.garfiec.librechat.feature.agents.components.model.SupportContactState
+import com.garfiec.librechat.feature.agents.util.ContentReader
import com.garfiec.librechat.feature.agents.util.OpenApiSpecParser
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -46,7 +46,6 @@ import kotlinx.serialization.json.floatOrNull
import kotlinx.serialization.json.intOrNull
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
-import co.touchlab.kermit.Logger
@Immutable
data class AgentEditorUiState(
@@ -103,7 +102,6 @@ sealed interface AgentEditorEvent {
}
class AgentEditorViewModel(
- savedStateHandle: SavedStateHandle,
private val agentRepository: AgentRepository,
private val configRepository: ConfigRepository,
private val mcpRepository: McpRepository,
@@ -171,7 +169,8 @@ class AgentEditorViewModel(
val agent = result.data
Logger.d {
"AgentEditor: Loaded agent fields BEFORE mapping - " +
- "name=${agent.name}, description=${agent.description}, instructions=${agent.instructions}, model=${agent.model}, " +
+ "name=${agent.name}, description=${agent.description}, " +
+ "instructions=${agent.instructions}, model=${agent.model}, " +
"provider=${agent.provider}, category=${agent.category}, tools=${agent.tools}, " +
"conversationStarters=${agent.conversationStarters}, avatarUrl=${agent.avatarUrl}, " +
"artifacts=${agent.artifacts}, recursionLimit=${agent.recursionLimit}, " +
@@ -185,7 +184,8 @@ class AgentEditorViewModel(
.copy(isLoading = false)
Logger.d {
"AgentEditor: UI state AFTER mapping - " +
- "name=${newState.name}, description=${newState.description}, instructions=${newState.instructions}, model=${newState.model}, " +
+ "name=${newState.name}, description=${newState.description}, " +
+ "instructions=${newState.instructions}, model=${newState.model}, " +
"provider=${newState.provider}, category=${newState.category}, selectedTools=${newState.selectedTools}, " +
"conversationStarters=${newState.conversationStarters}, avatarUrl=${newState.avatarUrl}, " +
"codeInterpreterEnabled=${newState.codeInterpreterEnabled}, fileSearchEnabled=${newState.fileSearchEnabled}, " +
diff --git a/feature/agents/src/iosMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentAvatarPicker.ios.kt b/feature/agents/src/iosMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentAvatarPicker.ios.kt
index 88f8384..674124e 100644
--- a/feature/agents/src/iosMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentAvatarPicker.ios.kt
+++ b/feature/agents/src/iosMain/kotlin/com/garfiec/librechat/feature/agents/components/AgentAvatarPicker.ios.kt
@@ -16,7 +16,7 @@ import androidx.compose.ui.unit.dp
actual fun AgentAvatarPicker(
avatarUrl: String?,
agentName: String,
- onImageSelected: (Any) -> Unit,
+ onImageSelect: (Any) -> Unit,
modifier: Modifier,
) {
// iOS: placeholder avatar display only (no image picker yet)
diff --git a/feature/agents/src/iosMain/kotlin/com/garfiec/librechat/feature/agents/di/AgentsPlatformModule.ios.kt b/feature/agents/src/iosMain/kotlin/com/garfiec/librechat/feature/agents/di/AgentsPlatformModule.ios.kt
index d6e7a1a..ff7a486 100644
--- a/feature/agents/src/iosMain/kotlin/com/garfiec/librechat/feature/agents/di/AgentsPlatformModule.ios.kt
+++ b/feature/agents/src/iosMain/kotlin/com/garfiec/librechat/feature/agents/di/AgentsPlatformModule.ios.kt
@@ -11,7 +11,6 @@ import org.koin.dsl.module
import platform.Foundation.NSData
import platform.Foundation.NSURL
import platform.Foundation.dataWithContentsOfURL
-import platform.Foundation.lastPathComponent
import platform.Foundation.pathExtension
import platform.posix.memcpy
diff --git a/feature/auth/detekt-baseline.xml b/feature/auth/detekt-baseline.xml
deleted file mode 100644
index e54f6e6..0000000
--- a/feature/auth/detekt-baseline.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-
- ComposableParamOrder:ResetPasswordScreen.kt$ResetPasswordScreen
- ComposableParamOrder:TwoFactorScreen.kt$TwoFactorScreen
- ComposableParamOrder:VerifyEmailScreen.kt$VerifyEmailScreen
- DeprecatedKoinApi:AuthModule.kt$viewModel { params -> ResetPasswordViewModel( savedStateHandle = get(), authRepository = get(), initialUserId = params.getOrNull(), initialToken = params.getOrNull(), ) }
- DeprecatedKoinApi:AuthModule.kt$viewModel { params -> TwoFactorViewModel( savedStateHandle = get(), authRepository = get(), initialTempToken = params.getOrNull(), ) }
- DeprecatedKoinApi:AuthModule.kt$viewModel { params -> VerifyEmailViewModel( savedStateHandle = get(), userRepository = get(), initialEmail = params.getOrNull(), ) }
- FunctionNaming:String0.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString0Resources(map: MutableMap<String, StringResource>)
- ImportOrdering:ExpectResourceCollectors.kt$import kotlin.String import kotlin.collections.Map import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.FontResource import org.jetbrains.compose.resources.PluralStringResource import org.jetbrains.compose.resources.StringArrayResource import org.jetbrains.compose.resources.StringResource
- ImportOrdering:ForgotPasswordScreen.kt$import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import librechat_mobile.feature.auth.generated.resources.Res import librechat_mobile.feature.auth.generated.resources.* import com.garfiec.librechat.feature.auth.viewmodel.ForgotPasswordViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:LoginScreen.kt$import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.lifecycle.Lifecycle import androidx.lifecycle.compose.LifecycleEventEffect import androidx.lifecycle.compose.collectAsStateWithLifecycle import librechat_mobile.feature.auth.generated.resources.Res import librechat_mobile.feature.auth.generated.resources.* import com.garfiec.librechat.feature.auth.viewmodel.LoginViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:RegisterScreen.kt$import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import librechat_mobile.feature.auth.generated.resources.Res import librechat_mobile.feature.auth.generated.resources.* import com.garfiec.librechat.feature.auth.viewmodel.RegisterViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:Res.kt$import kotlin.ByteArray import kotlin.OptIn import kotlin.String import kotlin.Suppress import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.getResourceUri import org.jetbrains.compose.resources.readResourceBytes
- ImportOrdering:ResetPasswordScreen.kt$import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import librechat_mobile.feature.auth.generated.resources.Res import librechat_mobile.feature.auth.generated.resources.* import com.garfiec.librechat.feature.auth.viewmodel.ResetPasswordViewModel import org.koin.compose.viewmodel.koinViewModel import org.koin.core.parameter.parametersOf
- ImportOrdering:ServerUrlScreen.kt$import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import librechat_mobile.feature.auth.generated.resources.Res import librechat_mobile.feature.auth.generated.resources.* import com.garfiec.librechat.feature.auth.viewmodel.ServerUrlViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:String0.commonMain.kt$import kotlin.OptIn import kotlin.String import kotlin.collections.MutableMap import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.ResourceContentHash import org.jetbrains.compose.resources.ResourceItem import org.jetbrains.compose.resources.StringResource
- ImportOrdering:TermsScreen.kt$import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import librechat_mobile.feature.auth.generated.resources.Res import librechat_mobile.feature.auth.generated.resources.* import com.garfiec.librechat.feature.auth.viewmodel.TermsViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:TwoFactorScreen.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import librechat_mobile.feature.auth.generated.resources.Res import librechat_mobile.feature.auth.generated.resources.* import com.garfiec.librechat.feature.auth.viewmodel.TwoFactorViewModel import org.koin.compose.viewmodel.koinViewModel import org.koin.core.parameter.parametersOf
- ImportOrdering:VerifyEmailScreen.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import librechat_mobile.feature.auth.generated.resources.Res import librechat_mobile.feature.auth.generated.resources.* import com.garfiec.librechat.feature.auth.viewmodel.VerifyEmailViewModel import org.koin.compose.viewmodel.koinViewModel import org.koin.core.parameter.parametersOf
- LambdaParameterInRestartableEffect:LoginScreen.kt$onLoginSuccess
- LambdaParameterInRestartableEffect:LoginScreen.kt$onNavigateToTwoFactor
- LambdaParameterInRestartableEffect:RegisterScreen.kt$onRegistered
- LambdaParameterInRestartableEffect:ServerUrlScreen.kt$onServerValidated
- LambdaParameterInRestartableEffect:TermsScreen.kt$onAccepted
- LambdaParameterInRestartableEffect:TwoFactorScreen.kt$onVerified
- LambdaParameterInRestartableEffect:VerifyEmailScreen.kt$onVerified
- MaxLineLength:Res.kt$Res$public suspend
- MaxLineLength:TwoFactorScreen.kt$if (uiState.isBackupMode) stringResource(Res.string.use_authenticator_code) else stringResource(Res.string.use_backup_code)
- ModifierNotUsedAtRoot:ForgotPasswordScreen.kt$modifier = modifier .fillMaxSize() .background(MaterialTheme.colorScheme.background) .padding(padding) .padding(24.dp)
- NoBlankLineBeforeRbrace:ServerUrlViewModel.kt$ServerUrlViewModel$
- PackageName:ExpectResourceCollectors.kt$package librechat_mobile.feature.auth.generated.resources
- PackageName:Res.kt$package librechat_mobile.feature.auth.generated.resources
- PackageName:String0.commonMain.kt$package librechat_mobile.feature.auth.generated.resources
- PackageNaming:ExpectResourceCollectors.kt$package librechat_mobile.feature.auth.generated.resources
- PackageNaming:Res.kt$package librechat_mobile.feature.auth.generated.resources
- PackageNaming:String0.commonMain.kt$package librechat_mobile.feature.auth.generated.resources
- ParameterNaming:RegisterScreen.kt$onRegistered
- ParameterNaming:ServerUrlScreen.kt$onServerValidated
- ParameterNaming:TermsScreen.kt$onAccepted
- ParameterNaming:TwoFactorScreen.kt$onCodeChanged
- ParameterNaming:TwoFactorScreen.kt$onDigitChanged
- ParameterNaming:TwoFactorScreen.kt$onVerified
- ParameterNaming:VerifyEmailScreen.kt$onVerified
- SpacingBetweenDeclarationsWithAnnotations:AuthNavigation.kt$ForgotPassword : AuthRoute
- SpacingBetweenDeclarationsWithAnnotations:AuthNavigation.kt$Login : AuthRoute
- SpacingBetweenDeclarationsWithAnnotations:AuthNavigation.kt$Register : AuthRoute
- SpacingBetweenDeclarationsWithAnnotations:AuthNavigation.kt$ResetPassword : AuthRoute
- SpacingBetweenDeclarationsWithAnnotations:AuthNavigation.kt$Terms : AuthRoute
- SpacingBetweenDeclarationsWithAnnotations:AuthNavigation.kt$TwoFactor : AuthRoute
- SpacingBetweenDeclarationsWithAnnotations:AuthNavigation.kt$VerifyEmail : AuthRoute
- UnusedPrivateProperty:ResetPasswordViewModel.kt$ResetPasswordViewModel$savedStateHandle: SavedStateHandle
- UnusedPrivateProperty:TwoFactorViewModel.kt$TwoFactorViewModel$savedStateHandle: SavedStateHandle
- UnusedPrivateProperty:VerifyEmailViewModel.kt$VerifyEmailViewModel$savedStateHandle: SavedStateHandle
-
-
diff --git a/feature/auth/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/auth/di/AuthModuleVerificationTest.kt b/feature/auth/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/auth/di/AuthModuleVerificationTest.kt
index 297ea6b..423b99d 100644
--- a/feature/auth/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/auth/di/AuthModuleVerificationTest.kt
+++ b/feature/auth/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/auth/di/AuthModuleVerificationTest.kt
@@ -2,7 +2,6 @@ package com.garfiec.librechat.feature.auth.di
import android.app.Application
import android.content.Context
-import androidx.lifecycle.SavedStateHandle
import com.garfiec.librechat.core.data.datastore.ServerDataStore
import com.garfiec.librechat.core.data.repository.AuthRepository
import com.garfiec.librechat.core.data.repository.ConfigRepository
@@ -19,7 +18,6 @@ class AuthModuleVerificationTest {
extraTypes = listOf(
Context::class,
Application::class,
- SavedStateHandle::class,
ServerDataStore::class,
AuthRepository::class,
ConfigRepository::class,
diff --git a/feature/auth/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/auth/viewmodel/LoginViewModelTest.kt b/feature/auth/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/auth/viewmodel/LoginViewModelTest.kt
index 6c62fd4..76e8400 100644
--- a/feature/auth/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/auth/viewmodel/LoginViewModelTest.kt
+++ b/feature/auth/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/auth/viewmodel/LoginViewModelTest.kt
@@ -1,14 +1,14 @@
package com.garfiec.librechat.feature.auth.viewmodel
-import com.google.common.truth.Truth.assertThat
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.datastore.ServerDataStore
import com.garfiec.librechat.core.data.repository.AuthRepository
import com.garfiec.librechat.core.data.repository.ConfigRepository
import com.garfiec.librechat.core.model.LoginOutcome
-import com.garfiec.librechat.core.model.config.StartupConfig
import com.garfiec.librechat.core.model.User
+import com.garfiec.librechat.core.model.config.StartupConfig
import com.garfiec.librechat.feature.auth.oauth.OAuthLauncher
+import com.google.common.truth.Truth.assertThat
import io.mockk.coEvery
import io.mockk.every
import io.mockk.mockk
diff --git a/feature/auth/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/auth/viewmodel/RegisterViewModelTest.kt b/feature/auth/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/auth/viewmodel/RegisterViewModelTest.kt
index 2994d4c..618df95 100644
--- a/feature/auth/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/auth/viewmodel/RegisterViewModelTest.kt
+++ b/feature/auth/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/auth/viewmodel/RegisterViewModelTest.kt
@@ -1,10 +1,10 @@
package com.garfiec.librechat.feature.auth.viewmodel
-import com.google.common.truth.Truth.assertThat
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.repository.AuthRepository
import com.garfiec.librechat.core.data.repository.ConfigRepository
import com.garfiec.librechat.core.model.config.StartupConfig
+import com.google.common.truth.Truth.assertThat
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
diff --git a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/di/AuthModule.kt b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/di/AuthModule.kt
index 27d7a6e..eb15a49 100644
--- a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/di/AuthModule.kt
+++ b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/di/AuthModule.kt
@@ -20,25 +20,31 @@ val authModule = module {
viewModelOf(::ServerUrlViewModel)
viewModelOf(::LoginViewModel)
viewModelOf(::RegisterViewModel)
+ // Koin's constructor-DSL (`viewModelOf`) wires every argument via `get()` and cannot read
+ // values passed through `parametersOf`. The VMs below receive initial seeds (email, user
+ // id, token, temp token) from the navigation layer via `parametersOf`, so the lambda-form
+ // `viewModel { params -> ... }` is the only DSL that works here. Detekt's `DeprecatedKoinApi`
+ // is a blanket stylistic rule, not a real `@Deprecated` API, so we suppress it in the
+ // narrow places it applies.
+ @Suppress("DeprecatedKoinApi")
viewModel { params ->
VerifyEmailViewModel(
- savedStateHandle = get(),
userRepository = get(),
initialEmail = params.getOrNull(),
)
}
viewModelOf(::ForgotPasswordViewModel)
+ @Suppress("DeprecatedKoinApi")
viewModel { params ->
ResetPasswordViewModel(
- savedStateHandle = get(),
authRepository = get(),
initialUserId = params.getOrNull(),
initialToken = params.getOrNull(),
)
}
+ @Suppress("DeprecatedKoinApi")
viewModel { params ->
TwoFactorViewModel(
- savedStateHandle = get(),
authRepository = get(),
initialTempToken = params.getOrNull(),
)
diff --git a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/navigation/AuthNavigation.kt b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/navigation/AuthNavigation.kt
index 1a81623..2269f59 100644
--- a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/navigation/AuthNavigation.kt
+++ b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/navigation/AuthNavigation.kt
@@ -18,12 +18,19 @@ import kotlinx.serialization.modules.subclass
@Serializable sealed interface AuthRoute : NavKey
@Serializable data object ServerUrl : AuthRoute
+
@Serializable data object Login : AuthRoute
+
@Serializable data object Register : AuthRoute
+
@Serializable data object ForgotPassword : AuthRoute
+
@Serializable data class TwoFactor(val tempToken: String) : AuthRoute
+
@Serializable data class VerifyEmail(val email: String) : AuthRoute
+
@Serializable data object Terms : AuthRoute
+
@Serializable data class ResetPassword(val userId: String, val token: String) : AuthRoute
fun EntryProviderScope.authEntries(
@@ -33,7 +40,7 @@ fun EntryProviderScope.authEntries(
) {
entry {
ServerUrlScreen(
- onServerValidated = { onNavigate(Login) },
+ onServerValidate = { onNavigate(Login) },
)
}
entry {
@@ -48,7 +55,7 @@ fun EntryProviderScope.authEntries(
}
entry {
RegisterScreen(
- onRegistered = onBack,
+ onRegister = onBack,
onNavigateToLogin = onBack,
)
}
@@ -59,21 +66,21 @@ fun EntryProviderScope.authEntries(
}
entry { key ->
TwoFactorScreen(
- onVerified = onAuthComplete,
+ onVerify = onAuthComplete,
onBack = onBack,
tempToken = key.tempToken,
)
}
entry { key ->
VerifyEmailScreen(
- onVerified = onBack,
+ onVerify = onBack,
onBack = onBack,
email = key.email,
)
}
entry {
TermsScreen(
- onAccepted = onAuthComplete,
+ onAccept = onAuthComplete,
onBack = onBack,
)
}
diff --git a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/ForgotPasswordScreen.kt b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/ForgotPasswordScreen.kt
index 9694690..4c0eaf7 100644
--- a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/ForgotPasswordScreen.kt
+++ b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/ForgotPasswordScreen.kt
@@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.Button
@@ -24,16 +25,15 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
-import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import librechat_mobile.feature.auth.generated.resources.Res
-import librechat_mobile.feature.auth.generated.resources.*
+import com.garfiec.librechat.feature.auth.resources.*
+import com.garfiec.librechat.feature.auth.resources.Res
import com.garfiec.librechat.feature.auth.viewmodel.ForgotPasswordViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@OptIn(ExperimentalMaterial3Api::class)
@@ -46,6 +46,7 @@ fun ForgotPasswordScreen(
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
Scaffold(
+ modifier = modifier,
containerColor = MaterialTheme.colorScheme.background,
topBar = {
TopAppBar(
@@ -59,7 +60,7 @@ fun ForgotPasswordScreen(
},
) { padding ->
Column(
- modifier = modifier
+ modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
.padding(padding)
diff --git a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/LoginScreen.kt b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/LoginScreen.kt
index 1d69d67..8f32d8f 100644
--- a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/LoginScreen.kt
+++ b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/LoginScreen.kt
@@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.HorizontalDivider
@@ -19,21 +20,21 @@ import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
-import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.LifecycleEventEffect
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import librechat_mobile.feature.auth.generated.resources.Res
-import librechat_mobile.feature.auth.generated.resources.*
+import com.garfiec.librechat.feature.auth.resources.*
+import com.garfiec.librechat.feature.auth.resources.Res
import com.garfiec.librechat.feature.auth.viewmodel.LoginViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@Composable
@@ -46,6 +47,8 @@ fun LoginScreen(
viewModel: LoginViewModel = koinViewModel(),
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
+ val currentOnLoginSuccess by rememberUpdatedState(onLoginSuccess)
+ val currentOnNavigateToTwoFactor by rememberUpdatedState(onNavigateToTwoFactor)
// Check for OAuth result when returning from Chrome Custom Tab
LifecycleEventEffect(Lifecycle.Event.ON_RESUME) {
@@ -54,14 +57,14 @@ fun LoginScreen(
LaunchedEffect(uiState.isLoggedIn) {
if (uiState.isLoggedIn) {
- onLoginSuccess()
+ currentOnLoginSuccess()
}
}
LaunchedEffect(uiState.twoFactorTempToken) {
val tempToken = uiState.twoFactorTempToken
if (tempToken != null) {
- onNavigateToTwoFactor(tempToken)
+ currentOnNavigateToTwoFactor(tempToken)
}
}
diff --git a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/RegisterScreen.kt b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/RegisterScreen.kt
index 6f2e51d..19f678c 100644
--- a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/RegisterScreen.kt
+++ b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/RegisterScreen.kt
@@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
@@ -19,32 +20,33 @@ import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
-import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import librechat_mobile.feature.auth.generated.resources.Res
-import librechat_mobile.feature.auth.generated.resources.*
+import com.garfiec.librechat.feature.auth.resources.*
+import com.garfiec.librechat.feature.auth.resources.Res
import com.garfiec.librechat.feature.auth.viewmodel.RegisterViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@Composable
fun RegisterScreen(
- onRegistered: () -> Unit,
+ onRegister: () -> Unit,
onNavigateToLogin: () -> Unit,
modifier: Modifier = Modifier,
viewModel: RegisterViewModel = koinViewModel(),
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
+ val currentOnRegister by rememberUpdatedState(onRegister)
LaunchedEffect(uiState.isRegistered) {
if (uiState.isRegistered) {
- onRegistered()
+ currentOnRegister()
}
}
diff --git a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/ResetPasswordScreen.kt b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/ResetPasswordScreen.kt
index 4cc0ee8..40464c1 100644
--- a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/ResetPasswordScreen.kt
+++ b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/ResetPasswordScreen.kt
@@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.Button
@@ -24,16 +25,15 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
-import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import librechat_mobile.feature.auth.generated.resources.Res
-import librechat_mobile.feature.auth.generated.resources.*
+import com.garfiec.librechat.feature.auth.resources.*
+import com.garfiec.librechat.feature.auth.resources.Res
import com.garfiec.librechat.feature.auth.viewmodel.ResetPasswordViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.koin.core.parameter.parametersOf
@@ -42,9 +42,9 @@ import org.koin.core.parameter.parametersOf
fun ResetPasswordScreen(
onResetComplete: () -> Unit,
onBack: () -> Unit,
+ modifier: Modifier = Modifier,
userId: String? = null,
token: String? = null,
- modifier: Modifier = Modifier,
viewModel: ResetPasswordViewModel = koinViewModel { parametersOf(userId, token) },
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
diff --git a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/ServerUrlScreen.kt b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/ServerUrlScreen.kt
index d07f3f0..b9b85c8 100644
--- a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/ServerUrlScreen.kt
+++ b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/ServerUrlScreen.kt
@@ -18,29 +18,31 @@ import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import librechat_mobile.feature.auth.generated.resources.Res
-import librechat_mobile.feature.auth.generated.resources.*
+import com.garfiec.librechat.feature.auth.resources.*
+import com.garfiec.librechat.feature.auth.resources.Res
import com.garfiec.librechat.feature.auth.viewmodel.ServerUrlViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@Composable
fun ServerUrlScreen(
- onServerValidated: () -> Unit,
+ onServerValidate: () -> Unit,
modifier: Modifier = Modifier,
viewModel: ServerUrlViewModel = koinViewModel(),
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
+ val currentOnServerValidated by rememberUpdatedState(onServerValidate)
LaunchedEffect(uiState.isValidated) {
if (uiState.isValidated) {
- onServerValidated()
+ currentOnServerValidated()
}
}
diff --git a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/TermsScreen.kt b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/TermsScreen.kt
index ee3fcd1..69ce4ed 100644
--- a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/TermsScreen.kt
+++ b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/TermsScreen.kt
@@ -24,34 +24,36 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import librechat_mobile.feature.auth.generated.resources.Res
-import librechat_mobile.feature.auth.generated.resources.*
+import com.garfiec.librechat.feature.auth.resources.*
+import com.garfiec.librechat.feature.auth.resources.Res
import com.garfiec.librechat.feature.auth.viewmodel.TermsViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
/** Displays server terms of service loaded from the backend; gates navigation on user acceptance. */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TermsScreen(
- onAccepted: () -> Unit,
+ onAccept: () -> Unit,
onBack: () -> Unit,
modifier: Modifier = Modifier,
viewModel: TermsViewModel = koinViewModel(),
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
+ val currentOnAccepted by rememberUpdatedState(onAccept)
LaunchedEffect(uiState.isAccepted) {
if (uiState.isAccepted) {
viewModel.consumeAccepted()
- onAccepted()
+ currentOnAccepted()
}
}
diff --git a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/TwoFactorScreen.kt b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/TwoFactorScreen.kt
index 92c6b68..8982d6f 100644
--- a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/TwoFactorScreen.kt
+++ b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/TwoFactorScreen.kt
@@ -27,36 +27,38 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import librechat_mobile.feature.auth.generated.resources.Res
-import librechat_mobile.feature.auth.generated.resources.*
+import com.garfiec.librechat.feature.auth.resources.*
+import com.garfiec.librechat.feature.auth.resources.Res
import com.garfiec.librechat.feature.auth.viewmodel.TwoFactorViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.koin.core.parameter.parametersOf
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TwoFactorScreen(
- onVerified: () -> Unit,
+ onVerify: () -> Unit,
onBack: () -> Unit,
- tempToken: String? = null,
modifier: Modifier = Modifier,
+ tempToken: String? = null,
viewModel: TwoFactorViewModel = koinViewModel { parametersOf(tempToken) },
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
+ val currentOnVerify by rememberUpdatedState(onVerify)
LaunchedEffect(uiState.isVerified) {
- if (uiState.isVerified) onVerified()
+ if (uiState.isVerified) currentOnVerify()
}
Scaffold(
@@ -111,13 +113,13 @@ fun TwoFactorScreen(
if (uiState.isBackupMode) {
BackupCodeInput(
code = uiState.backupCode,
- onCodeChanged = viewModel::onBackupCodeChanged,
+ onCodeChange = viewModel::onBackupCodeChanged,
enabled = !uiState.isLoading,
)
} else {
DigitBoxes(
digits = uiState.digits,
- onDigitChanged = viewModel::onDigitChanged,
+ onDigitChange = viewModel::onDigitChanged,
enabled = !uiState.isLoading,
)
}
@@ -155,7 +157,11 @@ fun TwoFactorScreen(
TextButton(onClick = viewModel::toggleBackupMode) {
Text(
- if (uiState.isBackupMode) stringResource(Res.string.use_authenticator_code) else stringResource(Res.string.use_backup_code),
+ if (uiState.isBackupMode) {
+ stringResource(Res.string.use_authenticator_code)
+ } else {
+ stringResource(Res.string.use_backup_code)
+ },
)
}
}
@@ -165,7 +171,7 @@ fun TwoFactorScreen(
@Composable
private fun DigitBoxes(
digits: List,
- onDigitChanged: (Int, String) -> Unit,
+ onDigitChange: (Int, String) -> Unit,
enabled: Boolean,
modifier: Modifier = Modifier,
) {
@@ -181,7 +187,7 @@ private fun DigitBoxes(
value = digit,
onValueChange = { value ->
val filtered = value.filter { it.isDigit() }.take(1)
- onDigitChanged(index, filtered)
+ onDigitChange(index, filtered)
if (filtered.isNotEmpty() && index < 5) {
focusRequesters[index + 1].requestFocus()
}
@@ -208,13 +214,13 @@ private fun DigitBoxes(
@Composable
private fun BackupCodeInput(
code: String,
- onCodeChanged: (String) -> Unit,
+ onCodeChange: (String) -> Unit,
enabled: Boolean,
modifier: Modifier = Modifier,
) {
OutlinedTextField(
value = code,
- onValueChange = onCodeChanged,
+ onValueChange = onCodeChange,
modifier = modifier.fillMaxWidth(),
enabled = enabled,
singleLine = true,
diff --git a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/VerifyEmailScreen.kt b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/VerifyEmailScreen.kt
index 31af0f3..8a31455 100644
--- a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/VerifyEmailScreen.kt
+++ b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/screen/VerifyEmailScreen.kt
@@ -22,36 +22,38 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import librechat_mobile.feature.auth.generated.resources.Res
-import librechat_mobile.feature.auth.generated.resources.*
+import com.garfiec.librechat.feature.auth.resources.*
+import com.garfiec.librechat.feature.auth.resources.Res
import com.garfiec.librechat.feature.auth.viewmodel.VerifyEmailViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.koin.core.parameter.parametersOf
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun VerifyEmailScreen(
- onVerified: () -> Unit,
+ onVerify: () -> Unit,
onBack: () -> Unit,
- email: String? = null,
modifier: Modifier = Modifier,
+ email: String? = null,
viewModel: VerifyEmailViewModel = koinViewModel { parametersOf(email) },
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
- val email = uiState.email
+ val displayEmail = uiState.email
+ val currentOnVerify by rememberUpdatedState(onVerify)
LaunchedEffect(uiState.isVerified) {
if (uiState.isVerified) {
viewModel.consumeVerified()
- onVerified()
+ currentOnVerify()
}
}
@@ -94,10 +96,10 @@ fun VerifyEmailScreen(
textAlign = TextAlign.Center,
)
- if (email.isNotBlank()) {
+ if (displayEmail.isNotBlank()) {
Spacer(modifier = Modifier.height(4.dp))
Text(
- text = email,
+ text = displayEmail,
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.primary,
textAlign = TextAlign.Center,
diff --git a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/viewmodel/ResetPasswordViewModel.kt b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/viewmodel/ResetPasswordViewModel.kt
index 650cbcf..dc351dc 100644
--- a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/viewmodel/ResetPasswordViewModel.kt
+++ b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/viewmodel/ResetPasswordViewModel.kt
@@ -1,7 +1,6 @@
package com.garfiec.librechat.feature.auth.viewmodel
import androidx.compose.runtime.Immutable
-import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.garfiec.librechat.core.common.result.Result
@@ -21,7 +20,6 @@ data class ResetPasswordUiState(
)
class ResetPasswordViewModel(
- savedStateHandle: SavedStateHandle,
private val authRepository: AuthRepository,
initialUserId: String? = null,
initialToken: String? = null,
diff --git a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/viewmodel/ServerUrlViewModel.kt b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/viewmodel/ServerUrlViewModel.kt
index 7f33bea..ecb2041 100644
--- a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/viewmodel/ServerUrlViewModel.kt
+++ b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/viewmodel/ServerUrlViewModel.kt
@@ -106,5 +106,4 @@ class ServerUrlViewModel(
}
}
}
-
}
diff --git a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/viewmodel/TwoFactorViewModel.kt b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/viewmodel/TwoFactorViewModel.kt
index 2b429de..448104c 100644
--- a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/viewmodel/TwoFactorViewModel.kt
+++ b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/viewmodel/TwoFactorViewModel.kt
@@ -1,7 +1,6 @@
package com.garfiec.librechat.feature.auth.viewmodel
import androidx.compose.runtime.Immutable
-import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.garfiec.librechat.core.common.result.Result
@@ -22,7 +21,6 @@ data class TwoFactorUiState(
)
class TwoFactorViewModel(
- savedStateHandle: SavedStateHandle,
private val authRepository: AuthRepository,
initialTempToken: String? = null,
) : ViewModel() {
diff --git a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/viewmodel/VerifyEmailViewModel.kt b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/viewmodel/VerifyEmailViewModel.kt
index 016f001..f7a0a50 100644
--- a/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/viewmodel/VerifyEmailViewModel.kt
+++ b/feature/auth/src/commonMain/kotlin/com/garfiec/librechat/feature/auth/viewmodel/VerifyEmailViewModel.kt
@@ -1,7 +1,6 @@
package com.garfiec.librechat.feature.auth.viewmodel
import androidx.compose.runtime.Immutable
-import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.garfiec.librechat.core.common.result.Result
@@ -24,7 +23,6 @@ data class VerifyEmailUiState(
)
class VerifyEmailViewModel(
- savedStateHandle: SavedStateHandle,
private val userRepository: UserRepository,
initialEmail: String? = null,
) : ViewModel() {
diff --git a/feature/auth/src/iosMain/kotlin/com/garfiec/librechat/feature/auth/oauth/IosOAuthLauncher.kt b/feature/auth/src/iosMain/kotlin/com/garfiec/librechat/feature/auth/oauth/IosOAuthLauncher.kt
index 2421dd0..6a5db37 100644
--- a/feature/auth/src/iosMain/kotlin/com/garfiec/librechat/feature/auth/oauth/IosOAuthLauncher.kt
+++ b/feature/auth/src/iosMain/kotlin/com/garfiec/librechat/feature/auth/oauth/IosOAuthLauncher.kt
@@ -56,6 +56,7 @@ class IosOAuthLauncher : OAuthLauncher {
override fun extractTokenFromCookies(serverUrl: String): String? {
val url = NSURL.URLWithString(serverUrl) ?: return null
val cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage.cookiesForURL(url) ?: return null
+
@Suppress("UNCHECKED_CAST")
val cookieList = cookies as List
return cookieList.firstOrNull { it.name == "refreshToken" }?.value
@@ -64,6 +65,7 @@ class IosOAuthLauncher : OAuthLauncher {
override fun clearOAuthCookie(serverUrl: String) {
val url = NSURL.URLWithString(serverUrl) ?: return
val cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage.cookiesForURL(url) ?: return
+
@Suppress("UNCHECKED_CAST")
val cookieList = cookies as List
cookieList.filter { it.name == "refreshToken" }.forEach {
diff --git a/feature/chat/detekt-baseline.xml b/feature/chat/detekt-baseline.xml
deleted file mode 100644
index 80459c3..0000000
--- a/feature/chat/detekt-baseline.xml
+++ /dev/null
@@ -1,118 +0,0 @@
-
-
-
-
- ComposableParamOrder:CommonChatInputCore.kt$CommonChatInputCore
- DeprecatedKoinApi:ChatModule.kt$viewModel { params -> PromptEditorViewModel( promptRepository = get(), savedStateHandle = get(), initialGroupId = params.getOrNull(), ) }
- FunctionNaming:String0.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString0Resources(map: MutableMap<String, StringResource>)
- FunctionNaming:String1.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString1Resources(map: MutableMap<String, StringResource>)
- FunctionNaming:String2.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString2Resources(map: MutableMap<String, StringResource>)
- ImportOrdering:AgentHandoffCard.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.SmartToy import androidx.compose.material.icons.filled.SwapHoriz import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:ArtifactButton.kt$import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer 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.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.Article import androidx.compose.material.icons.automirrored.filled.OpenInNew import androidx.compose.material.icons.filled.AccountTree import androidx.compose.material.icons.filled.Code import androidx.compose.material.icons.filled.Image import androidx.compose.material.icons.filled.Web import androidx.compose.material.icons.filled.Widgets import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:ArtifactVersionNav.kt$import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:AttachmentChipsRow.kt$import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.expandVertically import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.background import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.InsertDriveFile import androidx.compose.material.icons.filled.AttachFile import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Code import androidx.compose.material.icons.filled.Extension import androidx.compose.material.icons.filled.FindInPage import androidx.compose.material.icons.filled.TravelExplore import androidx.compose.material3.AssistChip import androidx.compose.material3.AssistChipDefaults import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.role import androidx.compose.ui.semantics.semantics import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage import com.garfiec.librechat.core.common.ToolConstants import com.garfiec.librechat.feature.chat.model.McpServerDisplayData import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:ChatInputToolbar.kt$import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer 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.rememberScrollState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Code import androidx.compose.material.icons.filled.FindInPage import androidx.compose.material.icons.filled.MoreHoriz import androidx.compose.material.icons.filled.Search import androidx.compose.material3.FilterChip import androidx.compose.material3.FilterChipDefaults import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.common.ToolConstants import com.garfiec.librechat.feature.chat.model.McpServerDisplayData import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:ChatToolsBottomSheet.kt$import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight import androidx.compose.material.icons.filled.AttachFile import androidx.compose.material.icons.filled.Code import androidx.compose.material.icons.filled.Extension import androidx.compose.material.icons.filled.FindInPage import androidx.compose.material.icons.filled.PhotoCamera import androidx.compose.material.icons.filled.PhotoLibrary import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.SmartToy import androidx.compose.material.icons.filled.Tune import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Checkbox import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.Switch import androidx.compose.material3.SwitchDefaults import androidx.compose.material3.Text import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.role import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.common.ToolConstants import com.garfiec.librechat.feature.chat.model.McpServerDisplayData import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:ChatViewModel.kt$import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.garfiec.librechat.core.common.EndpointConstants import com.garfiec.librechat.core.common.ToolConstants import com.garfiec.librechat.core.common.network.ConnectivityObserver import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.core.common.result.getOrNull import com.garfiec.librechat.core.data.datastore.LatexRenderer import com.garfiec.librechat.core.data.datastore.ServerDataStore import com.garfiec.librechat.core.data.datastore.SettingsDataStore import com.garfiec.librechat.core.data.repository.AgentRepository import com.garfiec.librechat.core.data.repository.ChatRepository import com.garfiec.librechat.core.data.repository.ConfigRepository import com.garfiec.librechat.core.data.repository.ConversationRepository import com.garfiec.librechat.core.data.repository.DraftRepository import com.garfiec.librechat.core.data.repository.McpRepository import com.garfiec.librechat.core.data.repository.MessageRepository import com.garfiec.librechat.core.data.repository.PresetRepository import com.garfiec.librechat.core.data.repository.PromptRepository import com.garfiec.librechat.core.data.repository.ShareRepository import com.garfiec.librechat.core.data.repository.UserRepository import com.garfiec.librechat.core.model.Attachment import com.garfiec.librechat.core.model.EModelEndpoint import com.garfiec.librechat.core.model.Message import com.garfiec.librechat.core.model.Preset import com.garfiec.librechat.core.model.StreamEvent import com.garfiec.librechat.core.model.request.EphemeralAgent import com.garfiec.librechat.core.ui.components.ModelParameters import com.garfiec.librechat.feature.chat.model.PresetDisplayData import com.garfiec.librechat.feature.chat.model.PromptMentionDisplayData import com.garfiec.librechat.feature.chat.components.AttachedFile import com.garfiec.librechat.feature.chat.util.NEW_CHAT_DRAFT_KEY import com.garfiec.librechat.feature.chat.util.buildActiveMessagePath import com.garfiec.librechat.feature.chat.viewmodel.delegate.ConversationActionsDelegate import com.garfiec.librechat.feature.chat.viewmodel.delegate.InConversationSearchDelegate import com.garfiec.librechat.feature.chat.viewmodel.delegate.ModelSelectionDelegate import com.garfiec.librechat.feature.chat.viewmodel.delegate.PlatformDelegateFactory import com.garfiec.librechat.feature.chat.viewmodel.delegate.PresetPromptDelegate import com.garfiec.librechat.feature.chat.viewmodel.delegate.toSerialName import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import co.touchlab.kermit.Logger import kotlin.time.Clock import kotlin.uuid.ExperimentalUuidApi import kotlin.uuid.Uuid
- ImportOrdering:CitationChip.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.ClickableText import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.OpenInNew import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalUriHandler import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.ui.window.Popup import androidx.compose.ui.window.PopupProperties import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:CodeBlock.kt$import androidx.compose.animation.AnimatedContent import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.togetherWith import androidx.compose.foundation.background import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.ContentCopy import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import com.garfiec.librechat.feature.chat.util.copyToClipboard import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.* import kotlinx.coroutines.delay
- ImportOrdering:CodeExecutionCard.kt$import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.expandVertically import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Cancel import androidx.compose.material.icons.filled.CheckCircle import androidx.compose.material.icons.filled.Code import androidx.compose.material.icons.filled.ExpandLess import androidx.compose.material.icons.filled.ExpandMore import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SuggestionChip import androidx.compose.material3.SuggestionChipDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.role import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:ComparisonDualPane.kt$import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.VerticalDivider import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:ComparisonTabBar.kt$import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Tab import androidx.compose.material3.TabRow import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.* import kotlinx.coroutines.launch
- ImportOrdering:ExpectResourceCollectors.kt$import kotlin.String import kotlin.collections.Map import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.FontResource import org.jetbrains.compose.resources.PluralStringResource import org.jetbrains.compose.resources.StringArrayResource import org.jetbrains.compose.resources.StringResource
- ImportOrdering:FeedbackCommentDialog.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.AlertDialog import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:ForkOptionsBottomSheet.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.CallSplit import androidx.compose.material.icons.filled.AccountTree import androidx.compose.material.icons.filled.LinearScale import androidx.compose.material3.Checkbox import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.Text import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.model.request.ForkOption import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:ImageGenCard.kt$import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.BrokenImage import androidx.compose.material.icons.filled.Image import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.role import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import coil3.compose.SubcomposeAsyncImage import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:InConvoSearchBar.kt$import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material.icons.filled.KeyboardArrowUp import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalSoftwareKeyboardController import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.* import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.filter
- ImportOrdering:InlineEditInput.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.Button import androidx.compose.material3.FilledTonalButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:LandingContent.kt$import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ChatBubbleOutline import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.* import kotlin.time.Clock import kotlinx.datetime.DayOfWeek import kotlinx.datetime.TimeZone import kotlinx.datetime.toLocalDateTime
- ImportOrdering:LogContentCard.kt$import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.expandVertically import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.clickable import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ExpandLess import androidx.compose.material.icons.filled.ExpandMore import androidx.compose.material.icons.filled.Terminal import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.role import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:McpResourceCarousel.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Extension import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:McpServerSelector.kt$import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer 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.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Hub import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material3.Checkbox import androidx.compose.material3.DropdownMenu import androidx.compose.material3.FilterChip import androidx.compose.material3.FilterChipDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.garfiec.librechat.feature.chat.model.McpServerDisplayData import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:MemoryArtifactCard.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SuggestionChip import androidx.compose.material3.SuggestionChipDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:MessageContentAndActions.kt$import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.CallSplit import androidx.compose.material.icons.automirrored.filled.VolumeUp import androidx.compose.material.icons.filled.ContentCopy import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.Refresh import androidx.compose.material.icons.filled.Stop import androidx.compose.material.icons.filled.ThumbDown import androidx.compose.material.icons.filled.ThumbUp import androidx.compose.material.icons.outlined.ThumbDown import androidx.compose.material.icons.outlined.ThumbUp import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.LayoutCoordinates import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.model.Message import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.* import org.jetbrains.compose.resources.stringResource
- ImportOrdering:MessageFiles.kt$import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.InsertDriveFile import androidx.compose.material.icons.filled.AttachFile import androidx.compose.material.icons.filled.BrokenImage import androidx.compose.material.icons.filled.Description import androidx.compose.material.icons.filled.PictureAsPdf import androidx.compose.material.icons.filled.TableChart import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.role import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import coil3.compose.SubcomposeAsyncImage import com.garfiec.librechat.core.model.FileReference import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:MessageList.kt$import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.foundation.gestures.animateScrollBy import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FloatingActionButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SmallFloatingActionButton import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.pointer.PointerEventPass import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.layout.boundsInRoot import androidx.compose.ui.platform.LocalDensity import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.common.ChatLayoutConstants import com.garfiec.librechat.core.model.FeedbackRating import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.* import com.garfiec.librechat.feature.chat.util.MessageNode import com.garfiec.librechat.feature.chat.viewmodel.ActiveToolCall import com.garfiec.librechat.feature.chat.viewmodel.SearchMatch import kotlinx.coroutines.delay import kotlinx.coroutines.launch
- ImportOrdering:ModelSelectionDelegate.kt$import com.garfiec.librechat.core.common.EndpointConstants import com.garfiec.librechat.core.common.ToolConstants import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.core.data.datastore.SettingsDataStore import com.garfiec.librechat.core.data.repository.AgentRepository import com.garfiec.librechat.core.data.repository.ConfigRepository import com.garfiec.librechat.core.data.repository.McpRepository import com.garfiec.librechat.core.model.EModelEndpoint import com.garfiec.librechat.core.model.mcp.McpServer import com.garfiec.librechat.core.model.request.AddedConversation import com.garfiec.librechat.core.ui.components.ModelParameters import com.garfiec.librechat.feature.chat.model.McpServerDisplayData import com.garfiec.librechat.feature.chat.viewmodel.ChatScreenState import com.garfiec.librechat.feature.chat.viewmodel.ChatStateHandle import com.garfiec.librechat.feature.chat.viewmodel.ComparisonState import kotlinx.coroutines.launch import co.touchlab.kermit.Logger
- ImportOrdering:ModelSelectorButton.kt$import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowDropDown import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:ModelSelectorSheet.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.Clear import androidx.compose.material.icons.filled.ExpandLess import androidx.compose.material.icons.filled.ExpandMore import androidx.compose.material.icons.outlined.AutoAwesome import androidx.compose.material.icons.outlined.Create import androidx.compose.material.icons.outlined.Public import androidx.compose.material.icons.outlined.SmartToy import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage import com.garfiec.librechat.core.common.EndpointConstants import com.garfiec.librechat.core.model.Agent import com.garfiec.librechat.core.model.EndpointConfig import com.garfiec.librechat.core.ui.components.endpointIconPainter import com.garfiec.librechat.core.ui.components.isMonochromeEndpointIcon import com.garfiec.librechat.feature.chat.util.FuzzyMatch import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.* import org.jetbrains.compose.resources.stringResource
- ImportOrdering:PlatformFileHandler.kt$import com.garfiec.librechat.feature.chat.components.AttachedFile import com.garfiec.librechat.core.model.FileReference import kotlinx.coroutines.Job import kotlinx.coroutines.flow.StateFlow
- ImportOrdering:PresetPicker.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Edit import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.Text import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.garfiec.librechat.feature.chat.model.PresetDisplayData import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:PresetPromptDelegate.kt$import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.core.data.repository.PresetRepository import com.garfiec.librechat.core.data.repository.PromptRepository import com.garfiec.librechat.core.model.EModelEndpoint import com.garfiec.librechat.core.model.Preset import com.garfiec.librechat.core.model.PromptGroup import com.garfiec.librechat.feature.chat.model.PresetDisplayData import com.garfiec.librechat.feature.chat.model.PromptMentionDisplayData import com.garfiec.librechat.feature.chat.viewmodel.ChatStateHandle import kotlinx.coroutines.launch import co.touchlab.kermit.Logger
- ImportOrdering:PromptDetailScreen.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.Share import androidx.compose.material.icons.outlined.Description import androidx.compose.material3.Button import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.ui.components.LibreChatTopBar import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.* import com.garfiec.librechat.feature.chat.prompts.components.PromptPreviewPanel
- ImportOrdering:PromptEditorScreen.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.History import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.garfiec.librechat.core.ui.components.LoadingIndicator import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.* import org.koin.compose.viewmodel.koinViewModel import org.koin.core.parameter.parametersOf
- ImportOrdering:PromptFilterSheet.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FilterChip import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.SheetState import androidx.compose.material3.Text import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:PromptPreviewPanel.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:PromptShareDialog.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ContentCopy import androidx.compose.material3.AlertDialog import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.RadioButton import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import com.garfiec.librechat.feature.chat.util.copyToClipboard import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:PromptVariablesSection.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:PromptVersionsSheet.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.material3.Badge import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.model.Prompt import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:PromptsLibraryScreen.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.FilterList import androidx.compose.material.icons.filled.Share import androidx.compose.material.icons.outlined.Description import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FilterChip import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.garfiec.librechat.core.ui.components.EmptyState import com.garfiec.librechat.core.ui.components.ErrorBanner import com.garfiec.librechat.core.ui.components.LibreChatTopBar import com.garfiec.librechat.core.ui.components.LoadingIndicator import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.* import com.garfiec.librechat.feature.chat.prompts.components.PromptFilterSheet import com.garfiec.librechat.feature.chat.prompts.components.PromptShareDialog import com.garfiec.librechat.feature.chat.prompts.components.PromptSortOrder import com.garfiec.librechat.feature.chat.prompts.components.VariableInputDialog import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:PromptsViewModel.kt$import androidx.compose.runtime.Immutable import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.core.data.repository.PromptRepository import com.garfiec.librechat.core.model.PromptGroup import com.garfiec.librechat.core.model.request.AddPromptToGroupRequest import com.garfiec.librechat.core.model.request.CreatePromptData import com.garfiec.librechat.core.model.request.CreatePromptGroupData import com.garfiec.librechat.core.model.request.CreatePromptRequest import com.garfiec.librechat.core.model.request.UpdatePromptGroupRequest import com.garfiec.librechat.core.model.request.UpdatePromptTagRequest import com.garfiec.librechat.feature.chat.prompts.components.PromptSortOrder import com.garfiec.librechat.feature.chat.prompts.components.extractVariables import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import co.touchlab.kermit.Logger
- ImportOrdering:Res.kt$import kotlin.ByteArray import kotlin.OptIn import kotlin.String import kotlin.Suppress import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.getResourceUri import org.jetbrains.compose.resources.readResourceBytes
- ImportOrdering:SavePresetDialog.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.material3.AlertDialog import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:SecondaryMessageList.kt$import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.common.ChatLayoutConstants import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.* import com.garfiec.librechat.feature.chat.util.MessageNode import com.garfiec.librechat.feature.chat.viewmodel.ActiveToolCall
- ImportOrdering:SharedContentParts.kt$import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.expandVertically import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.BrokenImage import androidx.compose.material.icons.filled.Build import androidx.compose.material.icons.filled.ExpandLess import androidx.compose.material.icons.filled.ExpandMore import androidx.compose.material.icons.filled.Psychology import androidx.compose.material.icons.filled.Videocam import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.LayoutCoordinates import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.role import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import coil3.compose.SubcomposeAsyncImage import com.garfiec.librechat.core.common.ToolConstants import com.garfiec.librechat.core.model.Attachment import com.garfiec.librechat.core.model.ContentType import com.garfiec.librechat.core.model.content.MessageContentPart import com.garfiec.librechat.feature.chat.components.artifact.Artifact import com.garfiec.librechat.feature.chat.components.artifact.ArtifactButton import com.garfiec.librechat.feature.chat.components.artifact.ArtifactPanel import com.garfiec.librechat.feature.chat.components.artifact.ArtifactSegment import com.garfiec.librechat.feature.chat.components.artifact.detectArtifacts import com.garfiec.librechat.feature.chat.components.artifact.groupArtifactVersions import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.* import org.jetbrains.compose.resources.stringResource
- ImportOrdering:SiblingNavigator.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:StreamingIndicator.kt$import androidx.compose.animation.core.LinearEasing import androidx.compose.animation.core.RepeatMode import androidx.compose.animation.core.animateFloat import androidx.compose.animation.core.infiniteRepeatable import androidx.compose.animation.core.rememberInfiniteTransition import androidx.compose.animation.core.tween import androidx.compose.foundation.layout.padding import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:StreamingToolCallCard.kt$import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.expandVertically import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Build import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.ExpandLess import androidx.compose.material.icons.filled.ExpandMore import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.* import com.garfiec.librechat.feature.chat.viewmodel.ActiveToolCall
- ImportOrdering:String0.commonMain.kt$import kotlin.OptIn import kotlin.String import kotlin.collections.MutableMap import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.ResourceContentHash import org.jetbrains.compose.resources.ResourceItem import org.jetbrains.compose.resources.StringResource
- ImportOrdering:String1.commonMain.kt$import kotlin.OptIn import kotlin.String import kotlin.collections.MutableMap import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.ResourceContentHash import org.jetbrains.compose.resources.ResourceItem import org.jetbrains.compose.resources.StringResource
- ImportOrdering:String2.commonMain.kt$import kotlin.OptIn import kotlin.String import kotlin.collections.MutableMap import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.ResourceContentHash import org.jetbrains.compose.resources.ResourceItem import org.jetbrains.compose.resources.StringResource
- ImportOrdering:ToolCallParsing.kt$import com.garfiec.librechat.core.model.content.AgentToolCall import com.garfiec.librechat.core.model.Attachment import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonArray import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.contentOrNull import kotlinx.serialization.json.intOrNull import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive import co.touchlab.kermit.Logger
- ImportOrdering:ToolsDropdownMenu.kt$import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.Code import androidx.compose.material.icons.filled.Image import androidx.compose.material.icons.filled.Search import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import org.jetbrains.compose.resources.stringResource import com.garfiec.librechat.core.common.ToolConstants import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:VariableInputDialog.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.AlertDialog import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- ImportOrdering:WebSearchResultCard.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Language import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalUriHandler import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.role import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import coil3.compose.SubcomposeAsyncImage import librechat_mobile.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.*
- LambdaParameterInRestartableEffect:MessageList.kt$onSearchScrollHandled
- LambdaParameterInRestartableEffect:PromptEditorScreen.kt$onBack
- MaxLineLength:ChatViewModel.kt$ChatViewModel$Logger.d { "sendMessage: webSearch=$webSearchEnabled, endpoint=${_uiState.value.selectedEndpoint}, model=${_uiState.value.selectedModel}, files=${fileRefs.size}, ephemeralAgent=$ephemeralAgent" }
- MaxLineLength:ModelSelectorSheet.kt$contentDescription = stringResource(if (isExpanded) Res.string.cd_collapse_section else Res.string.cd_expand_section, displayLabel)
- MaxLineLength:Res.kt$Res$public suspend
- MaxLineLength:SharedContentParts.kt$Icon(Icons.Default.BrokenImage, stringResource(Res.string.cd_failed_to_load_image), Modifier.size(32.dp), tint = MaterialTheme.colorScheme.onSurfaceVariant)
- MaxLineLength:SharedContentParts.kt$Icon(Icons.Default.Build, stringResource(Res.string.cd_tool_call), Modifier.size(16.dp), tint = MaterialTheme.colorScheme.onSurfaceVariant)
- MaxLineLength:SharedContentParts.kt$Icon(Icons.Default.Psychology, stringResource(Res.string.cd_thinking_indicator), Modifier.size(18.dp), tint = MaterialTheme.colorScheme.primary)
- MaxLineLength:SharedContentParts.kt$Icon(Icons.Filled.Videocam, contentDescription = null, tint = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.size(18.dp))
- MaxLineLength:SharedContentParts.kt$MarkdownContent(segment.text, Modifier.fillMaxWidth(), fontSizeMultiplier, useKatex, searchQuery, searchFocusedOccurrence, onFocusedOccurrencePositioned)
- MaxLineLength:SharedContentParts.kt$MarkdownContent(thinkingText, fontSizeMultiplier = fontSizeMultiplier, useKatex = useKatex, searchQuery = searchQuery, searchFocusedOccurrence = searchFocusedOccurrence, onFocusedOccurrencePositioned = onFocusedOccurrencePositioned)
- MaxLineLength:SharedContentParts.kt$Text(stringResource(Res.string.label_input), style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
- MaxLineLength:SharedContentParts.kt$Text(stringResource(Res.string.label_output), style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
- MaxLineLength:SharedContentParts.kt$Text(stringResource(Res.string.label_thinking), style = MaterialTheme.typography.titleSmall, color = MaterialTheme.colorScheme.primary, modifier = Modifier.weight(1f))
- MaxLineLength:SharedContentParts.kt$Text(stringResource(Res.string.video_not_supported), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant)
- MaxLineLength:SharedContentParts.kt$Text(toolName, style = MaterialTheme.typography.titleSmall, color = MaterialTheme.colorScheme.onSurface, modifier = Modifier.weight(1f))
- ModifierMissing:CommonChatInputCore.kt$ChatInputPlaceholder
- ModifierWithoutDefault:SharedContentParts.kt$modifier
- NoConsecutiveBlankLines:MarkdownParsing.kt$
- PackageName:ExpectResourceCollectors.kt$package librechat_mobile.feature.chat.generated.resources
- PackageName:Res.kt$package librechat_mobile.feature.chat.generated.resources
- PackageName:String0.commonMain.kt$package librechat_mobile.feature.chat.generated.resources
- PackageName:String1.commonMain.kt$package librechat_mobile.feature.chat.generated.resources
- PackageName:String2.commonMain.kt$package librechat_mobile.feature.chat.generated.resources
- PackageNaming:ExpectResourceCollectors.kt$package librechat_mobile.feature.chat.generated.resources
- PackageNaming:Res.kt$package librechat_mobile.feature.chat.generated.resources
- PackageNaming:String0.commonMain.kt$package librechat_mobile.feature.chat.generated.resources
- PackageNaming:String1.commonMain.kt$package librechat_mobile.feature.chat.generated.resources
- PackageNaming:String2.commonMain.kt$package librechat_mobile.feature.chat.generated.resources
- ParameterNaming:ComparisonTabBar.kt$onTabChanged
- ParameterNaming:InConvoSearchBar.kt$onQueryChanged
- ParameterNaming:InlineEditInput.kt$onTextChanged
- ParameterNaming:MessageContentAndActions.kt$onEditTextChanged
- ParameterNaming:MessageContentAndActions.kt$onFocusedOccurrencePositioned
- ParameterNaming:MessageList.kt$onEditTextChanged
- ParameterNaming:MessageList.kt$onSearchScrollHandled
- ParameterNaming:ModelSelectorSheet.kt$onModelSelected
- ParameterNaming:PlatformChatComponents.kt$onEditTextChanged
- ParameterNaming:PlatformChatComponents.kt$onFocusedOccurrencePositioned
- ParameterNaming:PlatformScreens.kt$onConversationStarted
- ParameterNaming:PresetPicker.kt$onPresetSelected
- ParameterNaming:PromptFilterSheet.kt$onCategorySelected
- ParameterNaming:PromptFilterSheet.kt$onSortOrderChanged
- ParameterNaming:PromptShareDialog.kt$onShareToggled
- ParameterNaming:PromptVariablesSection.kt$onVariableChanged
- ParameterNaming:SharedContentParts.kt$onFocusedOccurrencePositioned
- ParameterNaming:SlashCommandMenu.kt$onCommandSelected
- SpacingBetweenDeclarationsWithAnnotations:ChatNavigation.kt$Chat : ChatRoute
- SpacingBetweenDeclarationsWithAnnotations:ChatNavigation.kt$PromptEditor : ChatRoute
- SpacingBetweenDeclarationsWithAnnotations:ChatNavigation.kt$PromptsLibrary : ChatRoute
- UnusedPrivateProperty:ChatViewModel.kt$ChatViewModel$savedStateHandle: SavedStateHandle
- UnusedPrivateProperty:PromptEditorViewModel.kt$PromptEditorViewModel$savedStateHandle: SavedStateHandle
-
-
diff --git a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/AudioContentPlayer.kt b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/AudioContentPlayer.kt
index dbd7877..731afff 100644
--- a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/AudioContentPlayer.kt
+++ b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/AudioContentPlayer.kt
@@ -32,12 +32,12 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
-import kotlinx.coroutines.delay
import co.touchlab.kermit.Logger
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import kotlinx.coroutines.delay
+import org.jetbrains.compose.resources.stringResource
import java.io.File
import java.util.Locale
diff --git a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/ChatInput.kt b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/ChatInput.kt
index 155531c..dba7834 100644
--- a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/ChatInput.kt
+++ b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/ChatInput.kt
@@ -40,7 +40,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalContext
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.role
@@ -53,8 +52,9 @@ import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import com.garfiec.librechat.feature.chat.model.McpServerDisplayData
import com.garfiec.librechat.feature.chat.model.PromptMentionDisplayData
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
import java.io.File
@Composable
@@ -371,7 +371,7 @@ fun ChatInput(
// Slash command dropdown
SlashCommandMenu(
filteredCommands = filteredSlashCommands,
- onCommandSelected = onSlashCommandSelected,
+ onCommandSelect = onSlashCommandSelected,
)
}
},
diff --git a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/ContentPartRenderer.kt b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/ContentPartRenderer.kt
index 3616c56..4b9fa16 100644
--- a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/ContentPartRenderer.kt
+++ b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/ContentPartRenderer.kt
@@ -17,7 +17,7 @@ actual fun ContentPartRenderer(
showImageDescriptions: Boolean,
searchQuery: String?,
searchFocusedOccurrence: Int,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)?,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)?,
) {
ContentPartDispatcher(
part = part,
@@ -29,6 +29,6 @@ actual fun ContentPartRenderer(
showImageDescriptions = showImageDescriptions,
searchQuery = searchQuery,
searchFocusedOccurrence = searchFocusedOccurrence,
- onFocusedOccurrencePositioned = onFocusedOccurrencePositioned,
+ onFocusedOccurrencePosition = onFocusedOccurrencePosition,
)
}
diff --git a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/FullscreenImageViewer.kt b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/FullscreenImageViewer.kt
index 6650d3e..b9f13dd 100644
--- a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/FullscreenImageViewer.kt
+++ b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/FullscreenImageViewer.kt
@@ -43,21 +43,21 @@ import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
-import coil3.compose.AsyncImage
import coil3.SingletonImageLoader
+import coil3.compose.AsyncImage
import coil3.request.ImageRequest
import coil3.toBitmap
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
+import org.jetbrains.compose.resources.stringResource
import java.io.File
@Composable
diff --git a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/MarkdownContent.kt b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/MarkdownContent.kt
index 6c2a064..20f7841 100644
--- a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/MarkdownContent.kt
+++ b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/MarkdownContent.kt
@@ -44,7 +44,6 @@ import androidx.compose.ui.layout.LayoutCoordinates
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalUriHandler
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.TextStyle
@@ -60,11 +59,12 @@ import androidx.compose.ui.unit.isSpecified
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
import com.mikepenz.markdown.m3.Markdown
import com.mikepenz.markdown.m3.markdownColor
import com.mikepenz.markdown.m3.markdownTypography
+import org.jetbrains.compose.resources.stringResource
/**
* Markdown content rendering with full CommonMark support. Uses a hybrid approach:
@@ -82,7 +82,7 @@ import com.mikepenz.markdown.m3.markdownTypography
* @param searchFocusedOccurrence When >= 0, the occurrence at this index (counted
* across all text segments in this message, 0-based) is highlighted in orange
* instead of yellow to indicate the currently focused search result.
- * @param onFocusedOccurrencePositioned Callback invoked with the [LayoutCoordinates]
+ * @param onFocusedOccurrencePosition Callback invoked with the [LayoutCoordinates]
* of the text segment containing the focused search occurrence, after it has been
* laid out. Used by the parent to fine-tune scroll position within a long message.
*/
@@ -94,7 +94,7 @@ actual fun MarkdownContent(
useKatex: Boolean,
searchQuery: String?,
searchFocusedOccurrence: Int,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)?,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)?,
) {
val segments = remember(text) { parseMarkdownSegments(text) }
val isSearchActive = !searchQuery.isNullOrBlank()
@@ -155,7 +155,7 @@ actual fun MarkdownContent(
searchQuery = searchQuery,
focusedOccurrence = focusedInSegment,
fontSizeMultiplier = fontSizeMultiplier,
- onPositioned = if (hasFocus) onFocusedOccurrencePositioned else null,
+ onPositioned = if (hasFocus) onFocusedOccurrencePosition else null,
)
occurrenceOffset += segmentOccurrences
} else {
@@ -201,7 +201,7 @@ actual fun MarkdownContent(
searchQuery = searchQuery,
focusedOccurrence = focusedInSegment,
fontSizeMultiplier = fontSizeMultiplier,
- onPositioned = if (hasFocus) onFocusedOccurrencePositioned else null,
+ onPositioned = if (hasFocus) onFocusedOccurrencePosition else null,
)
occurrenceOffset += segmentOccurrences
} else {
@@ -326,7 +326,6 @@ private fun MarkdownTextSegment(
}
}
-
/**
* Wraps a [MarkdownTable] in a [Box] with a fullscreen expand button overlaid on
* the top-right corner. Tapping the button opens a [FullscreenTableDialog].
@@ -590,4 +589,3 @@ private fun TableCell(
)
}
}
-
diff --git a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/MermaidDiagram.kt b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/MermaidDiagram.kt
index 7c2cc43..374ec52 100644
--- a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/MermaidDiagram.kt
+++ b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/MermaidDiagram.kt
@@ -42,14 +42,14 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.toArgb
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
import co.touchlab.kermit.Logger
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
actual fun MermaidDiagram(
diff --git a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/MessageBubble.kt b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/MessageBubble.kt
index d146494..d5c7358 100644
--- a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/MessageBubble.kt
+++ b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/MessageBubble.kt
@@ -23,7 +23,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.layout.LayoutCoordinates
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.common.ChatLayoutConstants
@@ -31,9 +30,10 @@ import com.garfiec.librechat.core.model.Message
import com.garfiec.librechat.core.ui.components.AvatarImage
import com.garfiec.librechat.core.ui.components.endpointIconPainter
import com.garfiec.librechat.core.ui.components.isMonochromeEndpointIcon
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
import kotlinx.coroutines.delay
+import org.jetbrains.compose.resources.stringResource
private const val ACTION_AUTO_HIDE_MILLIS = 30_000L
@@ -57,7 +57,7 @@ actual fun MessageBubble(
currentFeedback: String?,
isEditing: Boolean,
editText: String,
- onEditTextChanged: ((String) -> Unit)?,
+ onEditTextChange: ((String) -> Unit)?,
onEditSaveAndSubmit: (() -> Unit)?,
onEditSaveOnly: (() -> Unit)?,
onEditCancel: (() -> Unit)?,
@@ -70,7 +70,7 @@ actual fun MessageBubble(
isSearchMatch: Boolean,
isCurrentSearchMatch: Boolean,
searchFocusedOccurrence: Int,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)?,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)?,
useKatex: Boolean,
chatLayoutStyle: String,
showAvatars: Boolean,
@@ -97,7 +97,7 @@ actual fun MessageBubble(
currentFeedback = currentFeedback,
isEditing = isEditing,
editText = editText,
- onEditTextChanged = onEditTextChanged,
+ onEditTextChange = onEditTextChange,
onEditSaveAndSubmit = onEditSaveAndSubmit,
onEditSaveOnly = onEditSaveOnly,
onEditCancel = onEditCancel,
@@ -110,7 +110,7 @@ actual fun MessageBubble(
isSearchMatch = isSearchMatch,
isCurrentSearchMatch = isCurrentSearchMatch,
searchFocusedOccurrence = searchFocusedOccurrence,
- onFocusedOccurrencePositioned = onFocusedOccurrencePositioned,
+ onFocusedOccurrencePosition = onFocusedOccurrencePosition,
showAvatars = showAvatars,
showBubbles = showBubbles,
)
@@ -135,7 +135,7 @@ actual fun MessageBubble(
currentFeedback = currentFeedback,
isEditing = isEditing,
editText = editText,
- onEditTextChanged = onEditTextChanged,
+ onEditTextChange = onEditTextChange,
onEditSaveAndSubmit = onEditSaveAndSubmit,
onEditSaveOnly = onEditSaveOnly,
onEditCancel = onEditCancel,
@@ -148,7 +148,7 @@ actual fun MessageBubble(
isSearchMatch = isSearchMatch,
isCurrentSearchMatch = isCurrentSearchMatch,
searchFocusedOccurrence = searchFocusedOccurrence,
- onFocusedOccurrencePositioned = onFocusedOccurrencePositioned,
+ onFocusedOccurrencePosition = onFocusedOccurrencePosition,
showAvatars = showAvatars,
showBubbles = showBubbles,
)
@@ -179,7 +179,7 @@ private fun ThreadMessageBubble(
currentFeedback: String?,
isEditing: Boolean,
editText: String,
- onEditTextChanged: ((String) -> Unit)?,
+ onEditTextChange: ((String) -> Unit)?,
onEditSaveAndSubmit: (() -> Unit)?,
onEditSaveOnly: (() -> Unit)?,
onEditCancel: (() -> Unit)?,
@@ -192,7 +192,7 @@ private fun ThreadMessageBubble(
isSearchMatch: Boolean,
isCurrentSearchMatch: Boolean,
searchFocusedOccurrence: Int,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)?,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)?,
showAvatars: Boolean,
showBubbles: Boolean,
) {
@@ -326,7 +326,7 @@ private fun ThreadMessageBubble(
isUser = isUser,
isEditing = isEditing,
editText = editText,
- onEditTextChanged = onEditTextChanged,
+ onEditTextChange = onEditTextChange,
onEditSaveAndSubmit = onEditSaveAndSubmit,
onEditSaveOnly = onEditSaveOnly,
onEditCancel = onEditCancel,
@@ -338,7 +338,7 @@ private fun ThreadMessageBubble(
isSearchMatch = isSearchMatch,
isCurrentSearchMatch = isCurrentSearchMatch,
searchFocusedOccurrence = searchFocusedOccurrence,
- onFocusedOccurrencePositioned = onFocusedOccurrencePositioned,
+ onFocusedOccurrencePosition = onFocusedOccurrencePosition,
showActions = showActions,
siblingIndex = siblingIndex,
siblingCount = siblingCount,
@@ -382,7 +382,7 @@ private fun TwoSidedMessageBubble(
currentFeedback: String?,
isEditing: Boolean,
editText: String,
- onEditTextChanged: ((String) -> Unit)?,
+ onEditTextChange: ((String) -> Unit)?,
onEditSaveAndSubmit: (() -> Unit)?,
onEditSaveOnly: (() -> Unit)?,
onEditCancel: (() -> Unit)?,
@@ -395,7 +395,7 @@ private fun TwoSidedMessageBubble(
isSearchMatch: Boolean,
isCurrentSearchMatch: Boolean,
searchFocusedOccurrence: Int,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)?,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)?,
showAvatars: Boolean,
showBubbles: Boolean,
) {
@@ -538,7 +538,7 @@ private fun TwoSidedMessageBubble(
isUser = isUser,
isEditing = isEditing,
editText = editText,
- onEditTextChanged = onEditTextChanged,
+ onEditTextChange = onEditTextChange,
onEditSaveAndSubmit = onEditSaveAndSubmit,
onEditSaveOnly = onEditSaveOnly,
onEditCancel = onEditCancel,
@@ -550,7 +550,7 @@ private fun TwoSidedMessageBubble(
isSearchMatch = isSearchMatch,
isCurrentSearchMatch = isCurrentSearchMatch,
searchFocusedOccurrence = searchFocusedOccurrence,
- onFocusedOccurrencePositioned = onFocusedOccurrencePositioned,
+ onFocusedOccurrencePosition = onFocusedOccurrencePosition,
showActions = showActions,
siblingIndex = siblingIndex,
siblingCount = siblingCount,
@@ -580,4 +580,3 @@ private fun TwoSidedMessageBubble(
}
}
}
-
diff --git a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/VideoContent.kt b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/VideoContent.kt
index 303f8e7..3066596 100644
--- a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/VideoContent.kt
+++ b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/VideoContent.kt
@@ -23,14 +23,14 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.media3.common.MediaItem
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.ui.PlayerView
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
actual fun VideoContent(
diff --git a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/VideoContentPlayer.kt b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/VideoContentPlayer.kt
index 9afcbaa..7a75a81 100644
--- a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/VideoContentPlayer.kt
+++ b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/VideoContentPlayer.kt
@@ -24,15 +24,15 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.ui.PlayerView
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
/** Plays video via ExoPlayer (media3) in a 16:9 card. Releases player on dispose via DisposableEffect. */
@Composable
diff --git a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/artifact/ArtifactPanel.kt b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/artifact/ArtifactPanel.kt
index 4a199e9..79bf148 100644
--- a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/artifact/ArtifactPanel.kt
+++ b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/components/artifact/ArtifactPanel.kt
@@ -58,16 +58,16 @@ import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
-import com.garfiec.librechat.feature.chat.components.CodeBlock
-import kotlinx.coroutines.launch
import co.touchlab.kermit.Logger
+import com.garfiec.librechat.feature.chat.components.CodeBlock
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import kotlinx.coroutines.launch
+import org.jetbrains.compose.resources.stringResource
@OptIn(ExperimentalMaterial3Api::class)
@Composable
diff --git a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/di/ChatPlatformModule.android.kt b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/di/ChatPlatformModule.android.kt
index c93240d..e4d12b9 100644
--- a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/di/ChatPlatformModule.android.kt
+++ b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/di/ChatPlatformModule.android.kt
@@ -20,7 +20,6 @@ actual val chatPlatformModule: Module = module {
viewModel { params ->
ChatViewModel(
- savedStateHandle = get(),
initialConversationId = params.getOrNull(),
agentRepository = get(),
chatRepository = get(),
diff --git a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/screen/ChatScreen.kt b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/screen/ChatScreen.kt
index 412ae49..1cfff72 100644
--- a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/screen/ChatScreen.kt
+++ b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/screen/ChatScreen.kt
@@ -64,7 +64,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
@@ -78,8 +77,6 @@ import com.garfiec.librechat.core.model.ContentType
import com.garfiec.librechat.core.model.content.MessageContentPart
import com.garfiec.librechat.core.ui.components.LoadingIndicator
import com.garfiec.librechat.core.ui.components.ModelParameterSheet
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
import com.garfiec.librechat.feature.chat.components.ChatInput
import com.garfiec.librechat.feature.chat.components.ComparisonDualPane
import com.garfiec.librechat.feature.chat.components.ComparisonTabBar
@@ -93,10 +90,13 @@ import com.garfiec.librechat.feature.chat.components.PresetPicker
import com.garfiec.librechat.feature.chat.components.SavePresetDialog
import com.garfiec.librechat.feature.chat.components.SecondaryMessageList
import com.garfiec.librechat.feature.chat.components.TempChatToggle
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
import com.garfiec.librechat.feature.chat.util.MessageNode
import com.garfiec.librechat.feature.chat.viewmodel.ChatScreenState
import com.garfiec.librechat.feature.chat.viewmodel.ChatViewModel
import kotlinx.coroutines.launch
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.koin.core.parameter.parametersOf
@@ -105,7 +105,7 @@ import org.koin.core.parameter.parametersOf
actual fun ChatScreen(
modifier: Modifier,
conversationId: String?,
- onConversationStarted: ((String) -> Unit)?,
+ onConversationStart: ((String) -> Unit)?,
onNavigateToConversation: ((String) -> Unit)?,
onOpenDrawer: (() -> Unit)?,
onNavigateToPromptsLibrary: (() -> Unit)?,
@@ -241,8 +241,8 @@ actual fun ChatScreen(
// onPendingNavigationHandled() resets this ViewModel to a fresh landing state.
LaunchedEffect(uiState.pendingNavigationConversationId) {
val pendingId = uiState.pendingNavigationConversationId
- if (pendingId != null && onConversationStarted != null) {
- onConversationStarted(pendingId)
+ if (pendingId != null && onConversationStart != null) {
+ onConversationStart(pendingId)
viewModel.onPendingNavigationHandled()
}
}
@@ -270,8 +270,8 @@ actual fun ChatScreen(
viewModel.onForkedConversationHandled()
if (onNavigateToConversation != null) {
onNavigateToConversation(forkId)
- } else if (onConversationStarted != null) {
- onConversationStarted(forkId)
+ } else if (onConversationStart != null) {
+ onConversationStart(forkId)
}
}
}
@@ -283,8 +283,8 @@ actual fun ChatScreen(
viewModel.onDuplicatedConversationHandled()
if (onNavigateToConversation != null) {
onNavigateToConversation(dupId)
- } else if (onConversationStarted != null) {
- onConversationStarted(dupId)
+ } else if (onConversationStart != null) {
+ onConversationStart(dupId)
}
}
}
@@ -338,7 +338,7 @@ actual fun ChatScreen(
if (uiState.isSearchOpen) {
InConvoSearchBar(
query = uiState.searchQuery,
- onQueryChanged = viewModel::onSearchQueryChanged,
+ onQueryChange = viewModel::onSearchQueryChanged,
currentMatchIndex = uiState.currentSearchMatchIndex,
totalMatches = uiState.searchMatchIndices.size,
onPreviousMatch = viewModel::previousSearchMatch,
@@ -453,7 +453,7 @@ actual fun ChatScreen(
currentlyReadingMessageId = uiState.currentlyReadingMessageId,
editingMessageId = uiState.editingMessageId,
editingText = uiState.editingText,
- onEditTextChanged = viewModel::onEditTextChanged,
+ onEditTextChange = viewModel::onEditTextChanged,
onEditSaveAndSubmit = viewModel::submitEdit,
onEditSaveOnly = viewModel::saveEditOnly,
onEditCancel = viewModel::cancelEditing,
@@ -474,7 +474,7 @@ actual fun ChatScreen(
searchMatchIndices = uiState.searchMatchIndices,
currentSearchMatchIndex = uiState.currentSearchMatchIndex,
searchScrollToIndex = uiState.searchScrollToIndex,
- onSearchScrollHandled = viewModel::onSearchScrollHandled,
+ onSearchScrollHandle = viewModel::onSearchScrollHandled,
modifier = Modifier.fillMaxSize(),
)
}
@@ -545,7 +545,7 @@ actual fun ChatScreen(
secondaryContent = secondaryMessageList,
onContinueWithPrimary = onContinuePrimary,
onContinueWithSecondary = onContinueSecondary,
- onTabChanged = { activeComparisonTab = it },
+ onTabChange = { activeComparisonTab = it },
modifier = Modifier.weight(1f),
)
}
@@ -573,7 +573,7 @@ actual fun ChatScreen(
currentlyReadingMessageId = uiState.currentlyReadingMessageId,
editingMessageId = uiState.editingMessageId,
editingText = uiState.editingText,
- onEditTextChanged = viewModel::onEditTextChanged,
+ onEditTextChange = viewModel::onEditTextChanged,
onEditSaveAndSubmit = viewModel::submitEdit,
onEditSaveOnly = viewModel::saveEditOnly,
onEditCancel = viewModel::cancelEditing,
@@ -601,7 +601,7 @@ actual fun ChatScreen(
searchMatchIndices = uiState.searchMatchIndices,
currentSearchMatchIndex = uiState.currentSearchMatchIndex,
searchScrollToIndex = uiState.searchScrollToIndex,
- onSearchScrollHandled = viewModel::onSearchScrollHandled,
+ onSearchScrollHandle = viewModel::onSearchScrollHandled,
modifier = Modifier.weight(1f),
)
}
@@ -663,7 +663,7 @@ actual fun ChatScreen(
if (showPresetPicker) {
PresetPicker(
presets = uiState.presets,
- onPresetSelected = { preset ->
+ onPresetSelect = { preset ->
viewModel.loadPreset(preset)
showPresetPicker = false
},
@@ -706,7 +706,7 @@ actual fun ChatScreen(
if (uiState.showModelParameters) {
ModelParameterSheet(
parameters = uiState.modelParameters,
- onParametersChanged = viewModel::updateModelParameters,
+ onParametersChange = viewModel::updateModelParameters,
onDismiss = viewModel::hideModelParameters,
selectedEndpoint = uiState.selectedEndpoint,
)
@@ -735,7 +735,7 @@ actual fun ChatScreen(
agents = uiState.agents,
selectedEndpoint = uiState.selectedEndpoint,
selectedModel = uiState.selectedModel,
- onModelSelected = { endpoint, model ->
+ onModelSelect = { endpoint, model ->
viewModel.onModelSelected(endpoint, model)
showModelSheet = false
},
@@ -752,7 +752,7 @@ actual fun ChatScreen(
agents = uiState.agents,
selectedEndpoint = uiState.comparisonState.secondaryEndpoint,
selectedModel = uiState.comparisonState.secondaryModel,
- onModelSelected = { endpoint, model ->
+ onModelSelect = { endpoint, model ->
viewModel.setSecondaryModel(endpoint, model)
showSecondaryModelSheet = false
},
diff --git a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/screen/NewChatScreen.kt b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/screen/NewChatScreen.kt
index 279ee9f..129a4b9 100644
--- a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/screen/NewChatScreen.kt
+++ b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/screen/NewChatScreen.kt
@@ -5,20 +5,20 @@ import androidx.compose.ui.Modifier
/**
* Thin wrapper that shows ChatScreen with no conversationId.
- * When a conversation starts via streaming, the [onConversationStarted]
+ * When a conversation starts via streaming, the [onConversationStart]
* callback is invoked with the new conversationId, allowing navigation
* to the full chat route.
*/
@Composable
actual fun NewChatScreen(
- onConversationStarted: (String) -> Unit,
+ onConversationStart: (String) -> Unit,
modifier: Modifier,
onOpenDrawer: (() -> Unit)?,
onNavigateToPromptsLibrary: (() -> Unit)?,
) {
ChatScreen(
modifier = modifier,
- onConversationStarted = onConversationStarted,
+ onConversationStart = onConversationStart,
onOpenDrawer = onOpenDrawer,
onNavigateToPromptsLibrary = onNavigateToPromptsLibrary,
)
diff --git a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/AndroidFileHandler.kt b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/AndroidFileHandler.kt
index 752b242..71cf993 100644
--- a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/AndroidFileHandler.kt
+++ b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/AndroidFileHandler.kt
@@ -1,8 +1,8 @@
package com.garfiec.librechat.feature.chat.viewmodel.delegate
import android.net.Uri
-import com.garfiec.librechat.feature.chat.components.AttachedFile
import com.garfiec.librechat.core.model.FileReference
+import com.garfiec.librechat.feature.chat.components.AttachedFile
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.StateFlow
diff --git a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/FileAttachmentDelegate.kt b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/FileAttachmentDelegate.kt
index 5871d5b..67ecf2b 100644
--- a/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/FileAttachmentDelegate.kt
+++ b/feature/chat/src/androidMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/FileAttachmentDelegate.kt
@@ -3,6 +3,7 @@ package com.garfiec.librechat.feature.chat.viewmodel.delegate
import android.content.Context
import android.graphics.BitmapFactory
import android.net.Uri
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.EndpointConstants
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.repository.FileRepository
@@ -21,7 +22,6 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
-import co.touchlab.kermit.Logger
import java.util.UUID
class FileAttachmentDelegate(
@@ -143,7 +143,7 @@ class FileAttachmentDelegate(
imageWidth = options.outWidth
imageHeight = options.outHeight
}
- Logger.d { "uploadFile: image dimensions ${imageWidth}x${imageHeight} for $uploadFilename" }
+ Logger.d { "uploadFile: image dimensions ${imageWidth}x$imageHeight for $uploadFilename" }
} catch (e: Exception) {
Logger.w(e) { "uploadFile: could not read image dimensions for $uploadFilename" }
}
diff --git a/feature/chat/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/chat/di/ChatModuleVerificationTest.kt b/feature/chat/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/chat/di/ChatModuleVerificationTest.kt
index 804b381..9bb5d54 100644
--- a/feature/chat/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/chat/di/ChatModuleVerificationTest.kt
+++ b/feature/chat/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/chat/di/ChatModuleVerificationTest.kt
@@ -2,7 +2,6 @@ package com.garfiec.librechat.feature.chat.di
import android.app.Application
import android.content.Context
-import androidx.lifecycle.SavedStateHandle
import com.garfiec.librechat.core.common.network.ConnectivityObserver
import com.garfiec.librechat.core.data.datastore.ServerDataStore
import com.garfiec.librechat.core.data.datastore.SettingsDataStore
@@ -29,7 +28,6 @@ class ChatModuleVerificationTest {
extraTypes = listOf(
Context::class,
Application::class,
- SavedStateHandle::class,
AgentRepository::class,
ChatRepository::class,
MessageRepository::class,
diff --git a/feature/chat/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/chat/util/MessageTreeTest.kt b/feature/chat/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/chat/util/MessageTreeTest.kt
index 80adfc5..4c6aff3 100644
--- a/feature/chat/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/chat/util/MessageTreeTest.kt
+++ b/feature/chat/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/chat/util/MessageTreeTest.kt
@@ -1,7 +1,7 @@
package com.garfiec.librechat.feature.chat.util
-import com.google.common.truth.Truth.assertThat
import com.garfiec.librechat.core.model.Message
+import com.google.common.truth.Truth.assertThat
import org.junit.Test
class MessageTreeTest {
diff --git a/feature/chat/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/chat/viewmodel/DetectMimeTypeTest.kt b/feature/chat/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/chat/viewmodel/DetectMimeTypeTest.kt
index c131d2a..bf89cc7 100644
--- a/feature/chat/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/chat/viewmodel/DetectMimeTypeTest.kt
+++ b/feature/chat/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/chat/viewmodel/DetectMimeTypeTest.kt
@@ -1,7 +1,7 @@
package com.garfiec.librechat.feature.chat.viewmodel
-import com.google.common.truth.Truth.assertThat
import com.garfiec.librechat.feature.chat.util.detectMimeTypeFromBytes
+import com.google.common.truth.Truth.assertThat
import org.junit.Test
class DetectMimeTypeTest {
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/AgentHandoffCard.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/AgentHandoffCard.kt
index 93f64cf..8681fea 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/AgentHandoffCard.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/AgentHandoffCard.kt
@@ -21,14 +21,14 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
/**
* Data class representing an agent handoff event.
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/AttachmentChipsRow.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/AttachmentChipsRow.kt
index 0167dca..eb4e996 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/AttachmentChipsRow.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/AttachmentChipsRow.kt
@@ -42,20 +42,20 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
-import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
import com.garfiec.librechat.core.common.ToolConstants
import com.garfiec.librechat.feature.chat.model.McpServerDisplayData
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
/**
* Floating row of Material 3 chips above the chat input field.
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ChatInputToolbar.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ChatInputToolbar.kt
index 57ea795..c373142 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ChatInputToolbar.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ChatInputToolbar.kt
@@ -30,14 +30,14 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.common.ToolConstants
import com.garfiec.librechat.feature.chat.model.McpServerDisplayData
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
data class ToolToggle(
val id: String,
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ChatToolsBottomSheet.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ChatToolsBottomSheet.kt
index 195cb22..988d238 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ChatToolsBottomSheet.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ChatToolsBottomSheet.kt
@@ -46,7 +46,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.role
@@ -55,8 +54,9 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.common.ToolConstants
import com.garfiec.librechat.feature.chat.model.McpServerDisplayData
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
@OptIn(ExperimentalMaterial3Api::class)
@Composable
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/CitationChip.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/CitationChip.kt
index baddf88..28fc145 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/CitationChip.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/CitationChip.kt
@@ -23,7 +23,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
@@ -35,8 +34,9 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupProperties
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
/**
* Parsed citation found in message text.
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/CodeBlock.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/CodeBlock.kt
index 577b217..de48a75 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/CodeBlock.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/CodeBlock.kt
@@ -32,8 +32,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
-import com.garfiec.librechat.feature.chat.util.copyToClipboard
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.AnnotatedString
@@ -44,9 +42,11 @@ import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import com.garfiec.librechat.feature.chat.util.copyToClipboard
import kotlinx.coroutines.delay
+import org.jetbrains.compose.resources.stringResource
@Composable
fun CodeBlock(
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/CodeExecutionCard.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/CodeExecutionCard.kt
index 7a8b586..cedbd04 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/CodeExecutionCard.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/CodeExecutionCard.kt
@@ -35,15 +35,15 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
/**
* Data class representing a code execution result parsed from tool call output.
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/CommonChatInputCore.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/CommonChatInputCore.kt
index 88b42b7..30118f5 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/CommonChatInputCore.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/CommonChatInputCore.kt
@@ -43,13 +43,13 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.feature.chat.model.McpServerDisplayData
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.cd_send_message
-import librechat_mobile.feature.chat.generated.resources.cd_start_voice_recording
-import librechat_mobile.feature.chat.generated.resources.cd_stop_generation
-import librechat_mobile.feature.chat.generated.resources.hint_message
-import librechat_mobile.feature.chat.generated.resources.hint_message_model
-import librechat_mobile.feature.chat.generated.resources.recording
+import com.garfiec.librechat.feature.chat.resources.Res
+import com.garfiec.librechat.feature.chat.resources.cd_send_message
+import com.garfiec.librechat.feature.chat.resources.cd_start_voice_recording
+import com.garfiec.librechat.feature.chat.resources.cd_stop_generation
+import com.garfiec.librechat.feature.chat.resources.hint_message
+import com.garfiec.librechat.feature.chat.resources.hint_message_model
+import com.garfiec.librechat.feature.chat.resources.recording
import org.jetbrains.compose.resources.stringResource
@Immutable
@@ -81,9 +81,9 @@ fun CommonChatInputCore(
onRemoveFile: (AttachedFile) -> Unit,
modifier: Modifier = Modifier,
leadingButtons: @Composable RowScope.() -> Unit = {},
- textFieldContent: @Composable RowScope.() -> Unit,
trailingSpacer: @Composable RowScope.() -> Unit = {},
bottomContent: @Composable BoxScope.() -> Unit = {},
+ textFieldContent: @Composable RowScope.() -> Unit,
) {
val surfaceColor = MaterialTheme.colorScheme.surface
Box(
@@ -255,6 +255,7 @@ fun VoiceMicIndicator(
fun ChatInputPlaceholder(
isRecording: Boolean,
selectedModelDisplay: String?,
+ modifier: Modifier = Modifier,
) {
Text(
text = if (isRecording) {
@@ -268,5 +269,6 @@ fun ChatInputPlaceholder(
color = MaterialTheme.colorScheme.onSurfaceVariant,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
+ modifier = modifier,
)
}
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ComparisonDualPane.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ComparisonDualPane.kt
index f84fbdd..bbe986c 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ComparisonDualPane.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ComparisonDualPane.kt
@@ -15,10 +15,10 @@ import androidx.compose.material3.VerticalDivider
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
/**
* Tablet-layout comparison view with two side-by-side panes.
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ComparisonTabBar.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ComparisonTabBar.kt
index ef43550..23d9474 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ComparisonTabBar.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ComparisonTabBar.kt
@@ -19,12 +19,12 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
import kotlinx.coroutines.launch
+import org.jetbrains.compose.resources.stringResource
/**
* Phone-layout comparison view with tabs and a horizontal pager.
@@ -46,14 +46,14 @@ fun ComparisonTabBar(
modifier: Modifier = Modifier,
onContinueWithPrimary: (() -> Unit)? = null,
onContinueWithSecondary: (() -> Unit)? = null,
- onTabChanged: ((Int) -> Unit)? = null,
+ onTabChange: ((Int) -> Unit)? = null,
) {
val pagerState = rememberPagerState(pageCount = { 2 })
val coroutineScope = rememberCoroutineScope()
LaunchedEffect(pagerState) {
snapshotFlow { pagerState.currentPage }.collect { page ->
- onTabChanged?.invoke(page)
+ onTabChange?.invoke(page)
}
}
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/FeedbackCommentDialog.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/FeedbackCommentDialog.kt
index 7249639..73cf409 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/FeedbackCommentDialog.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/FeedbackCommentDialog.kt
@@ -16,11 +16,11 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
/**
* Dialog shown when a user taps thumbs-down on an AI message.
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ForkOptionsBottomSheet.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ForkOptionsBottomSheet.kt
index ec2b400..b39cc41 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ForkOptionsBottomSheet.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ForkOptionsBottomSheet.kt
@@ -28,11 +28,11 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.request.ForkOption
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
@OptIn(ExperimentalMaterial3Api::class)
@Composable
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ImageGenCard.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ImageGenCard.kt
index 068f9f9..23f72d8 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ImageGenCard.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ImageGenCard.kt
@@ -31,15 +31,15 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import coil3.compose.SubcomposeAsyncImage
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
data class ImageGenResult(
val imageUrl: String? = null,
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/InConvoSearchBar.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/InConvoSearchBar.kt
index b49756a..fb1e658 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/InConvoSearchBar.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/InConvoSearchBar.kt
@@ -25,16 +25,16 @@ import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.filter
+import org.jetbrains.compose.resources.stringResource
/**
* Search overlay bar for finding text within the current conversation.
@@ -44,7 +44,7 @@ import kotlinx.coroutines.flow.filter
@Composable
fun InConvoSearchBar(
query: String,
- onQueryChanged: (String) -> Unit,
+ onQueryChange: (String) -> Unit,
currentMatchIndex: Int,
totalMatches: Int,
onPreviousMatch: () -> Unit,
@@ -77,7 +77,7 @@ fun InConvoSearchBar(
val searchCd = stringResource(Res.string.cd_search_in_conversation)
OutlinedTextField(
value = query,
- onValueChange = onQueryChanged,
+ onValueChange = onQueryChange,
modifier = Modifier
.weight(1f)
.height(48.dp)
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/InlineEditInput.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/InlineEditInput.kt
index f47a43d..38b2950 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/InlineEditInput.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/InlineEditInput.kt
@@ -20,17 +20,17 @@ import androidx.compose.material3.OutlinedTextFieldDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
fun InlineEditInput(
text: String,
- onTextChanged: (String) -> Unit,
+ onTextChange: (String) -> Unit,
onSaveAndSubmit: () -> Unit,
onSaveOnly: () -> Unit,
onCancel: () -> Unit,
@@ -39,7 +39,7 @@ fun InlineEditInput(
Column(modifier = modifier.fillMaxWidth()) {
OutlinedTextField(
value = text,
- onValueChange = onTextChanged,
+ onValueChange = onTextChange,
modifier = Modifier
.fillMaxWidth()
.heightIn(min = 56.dp, max = 200.dp),
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/LandingContent.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/LandingContent.kt
index c5aea36..24e7b82 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/LandingContent.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/LandingContent.kt
@@ -20,18 +20,18 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
-import kotlin.time.Clock
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
import kotlinx.datetime.DayOfWeek
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
+import org.jetbrains.compose.resources.stringResource
+import kotlin.time.Clock
@Composable
fun LandingContent(
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/LogContentCard.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/LogContentCard.kt
index 11fa4dc..72a3ecc 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/LogContentCard.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/LogContentCard.kt
@@ -31,15 +31,15 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
data class LogContent(
val title: String = "Log Output",
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/MarkdownParsing.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/MarkdownParsing.kt
index 7d948ed..e5307c1 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/MarkdownParsing.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/MarkdownParsing.kt
@@ -325,5 +325,3 @@ internal fun parseAlignments(separatorLine: String, columnCount: Int): List Unit)?,
+ onEditTextChange: ((String) -> Unit)?,
onEditSaveAndSubmit: (() -> Unit)?,
onEditSaveOnly: (() -> Unit)?,
onEditCancel: (() -> Unit)?,
@@ -178,7 +178,7 @@ internal fun MessageContentAndActions(
isSearchMatch: Boolean,
isCurrentSearchMatch: Boolean,
searchFocusedOccurrence: Int,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)?,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)?,
showActions: Boolean,
siblingIndex: Int,
siblingCount: Int,
@@ -194,10 +194,10 @@ internal fun MessageContentAndActions(
currentFeedback: String?,
onShowFeedbackDialog: () -> Unit,
) {
- if (isEditing && onEditTextChanged != null && onEditSaveAndSubmit != null && onEditSaveOnly != null && onEditCancel != null) {
+ if (isEditing && onEditTextChange != null && onEditSaveAndSubmit != null && onEditSaveOnly != null && onEditCancel != null) {
InlineEditInput(
text = editText,
- onTextChanged = onEditTextChanged,
+ onTextChange = onEditTextChange,
onSaveAndSubmit = onEditSaveAndSubmit,
onSaveOnly = onEditSaveOnly,
onCancel = onEditCancel,
@@ -225,7 +225,7 @@ internal fun MessageContentAndActions(
showImageDescriptions = showImageDescriptions,
searchQuery = if (isSearchMatch) searchQuery else null,
searchFocusedOccurrence = if (isCurrentSearchMatch) searchFocusedOccurrence else -1,
- onFocusedOccurrencePositioned = if (isCurrentSearchMatch) onFocusedOccurrencePositioned else null,
+ onFocusedOccurrencePosition = if (isCurrentSearchMatch) onFocusedOccurrencePosition else null,
modifier = Modifier.padding(vertical = 2.dp),
)
}
@@ -236,7 +236,7 @@ internal fun MessageContentAndActions(
useKatex = useKatex,
searchQuery = if (isSearchMatch) searchQuery else null,
searchFocusedOccurrence = if (isCurrentSearchMatch) searchFocusedOccurrence else -1,
- onFocusedOccurrencePositioned = if (isCurrentSearchMatch) onFocusedOccurrencePositioned else null,
+ onFocusedOccurrencePosition = if (isCurrentSearchMatch) onFocusedOccurrencePosition else null,
)
}
}
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/MessageFiles.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/MessageFiles.kt
index 7cc2098..2354000 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/MessageFiles.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/MessageFiles.kt
@@ -38,7 +38,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.role
@@ -47,8 +46,9 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import coil3.compose.SubcomposeAsyncImage
import com.garfiec.librechat.core.model.FileReference
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
/**
* Renders files attached to a message. Splits files into images (shown as
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/MessageList.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/MessageList.kt
index 1e97e28..8e84ea7 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/MessageList.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/MessageList.kt
@@ -35,17 +35,17 @@ import androidx.compose.ui.input.pointer.PointerEventPass
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.boundsInRoot
import androidx.compose.ui.platform.LocalDensity
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.common.ChatLayoutConstants
import com.garfiec.librechat.core.model.FeedbackRating
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
import com.garfiec.librechat.feature.chat.util.MessageNode
import com.garfiec.librechat.feature.chat.viewmodel.ActiveToolCall
import com.garfiec.librechat.feature.chat.viewmodel.SearchMatch
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
+import org.jetbrains.compose.resources.stringResource
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -66,7 +66,7 @@ fun MessageList(
currentlyReadingMessageId: String? = null,
editingMessageId: String? = null,
editingText: String = "",
- onEditTextChanged: (String) -> Unit = {},
+ onEditTextChange: (String) -> Unit = {},
onEditSaveAndSubmit: () -> Unit = {},
onEditSaveOnly: () -> Unit = {},
onEditCancel: () -> Unit = {},
@@ -87,7 +87,7 @@ fun MessageList(
searchMatchIndices: List = emptyList(),
currentSearchMatchIndex: Int = 0,
searchScrollToIndex: Int? = null,
- onSearchScrollHandled: () -> Unit = {},
+ onSearchScrollHandle: () -> Unit = {},
) {
val listState = rememberLazyListState()
val coroutineScope = rememberCoroutineScope()
@@ -171,6 +171,7 @@ fun MessageList(
// When the focused occurrence's HighlightedTextSegment reports its layout position,
// we compare it against the viewport and animateScrollBy the delta if needed.
var pendingFineTuneScroll by remember { mutableStateOf(false) }
+ val currentOnSearchScrollHandled by rememberUpdatedState(onSearchScrollHandle)
// Scroll to search match when navigating prev/next
LaunchedEffect(searchScrollToIndex) {
@@ -180,7 +181,7 @@ fun MessageList(
listState.animateScrollToItem(index)
// After scroll completes, the focused segment will report its position
// via onGloballyPositioned, and the fine-tune scroll will happen there.
- onSearchScrollHandled()
+ currentOnSearchScrollHandled()
}
}
@@ -369,7 +370,7 @@ fun MessageList(
currentFeedback = currentFeedbackStr,
isEditing = editingMessageId == node.message.messageId,
editText = if (editingMessageId == node.message.messageId) editingText else "",
- onEditTextChanged = onEditTextChanged,
+ onEditTextChange = onEditTextChange,
onEditSaveAndSubmit = onEditSaveAndSubmit,
onEditSaveOnly = onEditSaveOnly,
onEditCancel = onEditCancel,
@@ -385,7 +386,7 @@ fun MessageList(
isSearchMatch = isMatch,
isCurrentSearchMatch = isCurrent,
searchFocusedOccurrence = focusedOccurrenceInMessage,
- onFocusedOccurrencePositioned = if (isCurrent) {
+ onFocusedOccurrencePosition = if (isCurrent) {
{ coordinates ->
if (!pendingFineTuneScroll) return@MessageBubble
pendingFineTuneScroll = false
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ModelSelectorButton.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ModelSelectorButton.kt
index 1b3726f..903a3ce 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ModelSelectorButton.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ModelSelectorButton.kt
@@ -13,11 +13,11 @@ import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
fun ModelSelectorButton(
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ModelSelectorSheet.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ModelSelectorSheet.kt
index 9e24e0e..fa3c96e 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ModelSelectorSheet.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ModelSelectorSheet.kt
@@ -50,9 +50,9 @@ import com.garfiec.librechat.core.model.Agent
import com.garfiec.librechat.core.model.EndpointConfig
import com.garfiec.librechat.core.ui.components.endpointIconPainter
import com.garfiec.librechat.core.ui.components.isMonochromeEndpointIcon
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
import com.garfiec.librechat.feature.chat.util.FuzzyMatch
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
import org.jetbrains.compose.resources.stringResource
private val IconSize = 20.dp
@@ -92,7 +92,7 @@ fun ModelSelectorSheet(
agents: List,
selectedEndpoint: String?,
selectedModel: String?,
- onModelSelected: (endpoint: String, model: String) -> Unit,
+ onModelSelect: (endpoint: String, model: String) -> Unit,
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
serverUrl: String = "",
@@ -193,7 +193,7 @@ fun ModelSelectorSheet(
agent = agent,
isSelected = selectedEndpoint == EndpointConstants.AGENTS && agent.id == selectedModel,
serverUrl = serverUrl,
- onClick = { onModelSelected(EndpointConstants.AGENTS, agent.id) },
+ onClick = { onModelSelect(EndpointConstants.AGENTS, agent.id) },
)
}
}
@@ -232,7 +232,7 @@ fun ModelSelectorSheet(
Row(
modifier = Modifier
.fillMaxWidth()
- .clickable { onModelSelected(endpointName, model) }
+ .clickable { onModelSelect(endpointName, model) }
.padding(vertical = 12.dp, horizontal = 8.dp)
.animateItem(),
verticalAlignment = Alignment.CenterVertically,
@@ -289,7 +289,10 @@ private fun EndpointGroupHeader(
)
Icon(
imageVector = if (isExpanded) Icons.Default.ExpandLess else Icons.Default.ExpandMore,
- contentDescription = stringResource(if (isExpanded) Res.string.cd_collapse_section else Res.string.cd_expand_section, displayLabel),
+ contentDescription = stringResource(
+ if (isExpanded) Res.string.cd_collapse_section else Res.string.cd_expand_section,
+ displayLabel,
+ ),
tint = MaterialTheme.colorScheme.onSurface,
)
}
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/PlatformChatComponents.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/PlatformChatComponents.kt
index defbf9f..1d4f471 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/PlatformChatComponents.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/PlatformChatComponents.kt
@@ -29,7 +29,7 @@ expect fun MessageBubble(
currentFeedback: String? = null,
isEditing: Boolean = false,
editText: String = "",
- onEditTextChanged: ((String) -> Unit)? = null,
+ onEditTextChange: ((String) -> Unit)? = null,
onEditSaveAndSubmit: (() -> Unit)? = null,
onEditSaveOnly: (() -> Unit)? = null,
onEditCancel: (() -> Unit)? = null,
@@ -42,7 +42,7 @@ expect fun MessageBubble(
isSearchMatch: Boolean = false,
isCurrentSearchMatch: Boolean = false,
searchFocusedOccurrence: Int = -1,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)? = null,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)? = null,
useKatex: Boolean = false,
chatLayoutStyle: String = ChatLayoutConstants.THREAD,
showAvatars: Boolean = true,
@@ -61,7 +61,7 @@ expect fun ContentPartRenderer(
showImageDescriptions: Boolean = true,
searchQuery: String? = null,
searchFocusedOccurrence: Int = -1,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)? = null,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)? = null,
)
/** Platform-specific markdown content rendering. */
@@ -73,5 +73,5 @@ expect fun MarkdownContent(
useKatex: Boolean = false,
searchQuery: String? = null,
searchFocusedOccurrence: Int = -1,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)? = null,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)? = null,
)
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/PresetPicker.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/PresetPicker.kt
index 6ee9f44..5b797e9 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/PresetPicker.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/PresetPicker.kt
@@ -25,18 +25,18 @@ import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.feature.chat.model.PresetDisplayData
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PresetPicker(
presets: List,
- onPresetSelected: (PresetDisplayData) -> Unit,
+ onPresetSelect: (PresetDisplayData) -> Unit,
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
onEditPreset: (PresetDisplayData) -> Unit = {},
@@ -74,7 +74,7 @@ fun PresetPicker(
items(presets, key = { it.presetId ?: it.title }, contentType = { "preset" }) { preset ->
PresetItem(
preset = preset,
- onClick = { onPresetSelected(preset) },
+ onClick = { onPresetSelect(preset) },
onEdit = { onEditPreset(preset) },
onDelete = { onDeletePreset(preset) },
)
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SavePresetDialog.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SavePresetDialog.kt
index c3678cf..2b45c89 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SavePresetDialog.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SavePresetDialog.kt
@@ -15,10 +15,10 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
fun SavePresetDialog(
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SecondaryMessageList.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SecondaryMessageList.kt
index 6e8979a..021799a 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SecondaryMessageList.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SecondaryMessageList.kt
@@ -13,13 +13,13 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.common.ChatLayoutConstants
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
import com.garfiec.librechat.feature.chat.util.MessageNode
import com.garfiec.librechat.feature.chat.viewmodel.ActiveToolCall
+import org.jetbrains.compose.resources.stringResource
/**
* Simplified message list for the secondary comparison pane.
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SharedContentParts.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SharedContentParts.kt
index 12b9d26..966aa12 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SharedContentParts.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SharedContentParts.kt
@@ -55,8 +55,8 @@ import com.garfiec.librechat.feature.chat.components.artifact.ArtifactPanel
import com.garfiec.librechat.feature.chat.components.artifact.ArtifactSegment
import com.garfiec.librechat.feature.chat.components.artifact.detectArtifacts
import com.garfiec.librechat.feature.chat.components.artifact.groupArtifactVersions
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
import org.jetbrains.compose.resources.stringResource
// ─── ContentPartDispatcher ──────────────────────────────────────────
@@ -77,7 +77,7 @@ internal fun ContentPartDispatcher(
showImageDescriptions: Boolean = true,
searchQuery: String? = null,
searchFocusedOccurrence: Int = -1,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)? = null,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)? = null,
) {
val mod = modifier.fillMaxWidth()
when (part.type) {
@@ -89,7 +89,7 @@ internal fun ContentPartDispatcher(
useKatex = useKatex,
searchQuery = searchQuery,
searchFocusedOccurrence = searchFocusedOccurrence,
- onFocusedOccurrencePositioned = onFocusedOccurrencePositioned,
+ onFocusedOccurrencePosition = onFocusedOccurrencePosition,
)
}
ContentType.THINK -> {
@@ -100,7 +100,7 @@ internal fun ContentPartDispatcher(
useKatex = useKatex,
searchQuery = searchQuery,
searchFocusedOccurrence = searchFocusedOccurrence,
- onFocusedOccurrencePositioned = onFocusedOccurrencePositioned,
+ onFocusedOccurrencePosition = onFocusedOccurrencePosition,
)
}
ContentType.TOOL_CALL -> {
@@ -134,9 +134,18 @@ internal fun ContentPartDispatcher(
VideoContent(url = videoUrl, modifier = mod)
} else {
Row(verticalAlignment = Alignment.CenterVertically, modifier = mod) {
- Icon(Icons.Filled.Videocam, contentDescription = null, tint = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.size(18.dp))
+ Icon(
+ Icons.Filled.Videocam,
+ contentDescription = null,
+ tint = MaterialTheme.colorScheme.onSurfaceVariant,
+ modifier = Modifier.size(18.dp),
+ )
Spacer(modifier = Modifier.width(6.dp))
- Text(stringResource(Res.string.video_not_supported), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant)
+ Text(
+ stringResource(Res.string.video_not_supported),
+ style = MaterialTheme.typography.bodyMedium,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
}
}
}
@@ -170,10 +179,10 @@ internal fun ContentPartDispatcher(
@Composable
private fun ToolCallDispatcher(
part: MessageContentPart,
- modifier: Modifier,
baseUrl: String,
attachments: List,
showImageDescriptions: Boolean,
+ modifier: Modifier = Modifier,
) {
val toolCall = part.toolCall
val toolName = toolCall?.name ?: toolCall?.function?.name ?: "Tool Call"
@@ -234,12 +243,12 @@ private fun ToolCallDispatcher(
@Composable
private fun TextContentPart(
text: String,
- modifier: Modifier,
+ modifier: Modifier = Modifier,
fontSizeMultiplier: Float = 1.0f,
useKatex: Boolean = false,
searchQuery: String? = null,
searchFocusedOccurrence: Int = -1,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)? = null,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)? = null,
) {
if (text.isBlank()) return
@@ -247,7 +256,7 @@ private fun TextContentPart(
val hasArtifacts = remember(segments) { segments.any { it is ArtifactSegment.ArtifactReference } }
if (!hasArtifacts) {
- MarkdownContent(text, modifier, fontSizeMultiplier, useKatex, searchQuery, searchFocusedOccurrence, onFocusedOccurrencePositioned)
+ MarkdownContent(text, modifier, fontSizeMultiplier, useKatex, searchQuery, searchFocusedOccurrence, onFocusedOccurrencePosition)
} else {
val versionMap = remember(segments) { groupArtifactVersions(segments) }
var activeArtifact by remember {
@@ -257,7 +266,15 @@ private fun TextContentPart(
segments.forEach { segment ->
when (segment) {
is ArtifactSegment.Text -> {
- MarkdownContent(segment.text, Modifier.fillMaxWidth(), fontSizeMultiplier, useKatex, searchQuery, searchFocusedOccurrence, onFocusedOccurrencePositioned)
+ MarkdownContent(
+ segment.text,
+ Modifier.fillMaxWidth(),
+ fontSizeMultiplier,
+ useKatex,
+ searchQuery,
+ searchFocusedOccurrence,
+ onFocusedOccurrencePosition,
+ )
}
is ArtifactSegment.ArtifactReference -> {
val versions = versionMap[segment.artifact.identifier] ?: listOf(segment.artifact)
@@ -288,12 +305,12 @@ private fun TextContentPart(
@Composable
private fun ThinkingContentPart(
thinkingText: String,
- modifier: Modifier,
+ modifier: Modifier = Modifier,
fontSizeMultiplier: Float = 1.0f,
useKatex: Boolean = false,
searchQuery: String? = null,
searchFocusedOccurrence: Int = -1,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)? = null,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)? = null,
) {
var isExpanded by remember { mutableStateOf(false) }
val thinkingToggleCd =
@@ -317,9 +334,19 @@ private fun ThinkingContentPart(
},
verticalAlignment = Alignment.CenterVertically,
) {
- Icon(Icons.Default.Psychology, stringResource(Res.string.cd_thinking_indicator), Modifier.size(18.dp), tint = MaterialTheme.colorScheme.primary)
+ Icon(
+ Icons.Default.Psychology,
+ stringResource(Res.string.cd_thinking_indicator),
+ Modifier.size(18.dp),
+ tint = MaterialTheme.colorScheme.primary,
+ )
Spacer(modifier = Modifier.width(8.dp))
- Text(stringResource(Res.string.label_thinking), style = MaterialTheme.typography.titleSmall, color = MaterialTheme.colorScheme.primary, modifier = Modifier.weight(1f))
+ Text(
+ stringResource(Res.string.label_thinking),
+ style = MaterialTheme.typography.titleSmall,
+ color = MaterialTheme.colorScheme.primary,
+ modifier = Modifier.weight(1f),
+ )
Icon(
if (isExpanded) Icons.Default.ExpandLess else Icons.Default.ExpandMore,
stringResource(if (isExpanded) Res.string.cd_collapse else Res.string.cd_expand),
@@ -330,7 +357,14 @@ private fun ThinkingContentPart(
AnimatedVisibility(visible = isExpanded, enter = expandVertically(), exit = shrinkVertically()) {
Column(modifier = Modifier.padding(start = 12.dp, end = 12.dp, bottom = 12.dp)) {
Spacer(modifier = Modifier.height(8.dp))
- MarkdownContent(thinkingText, fontSizeMultiplier = fontSizeMultiplier, useKatex = useKatex, searchQuery = searchQuery, searchFocusedOccurrence = searchFocusedOccurrence, onFocusedOccurrencePositioned = onFocusedOccurrencePositioned)
+ MarkdownContent(
+ thinkingText,
+ fontSizeMultiplier = fontSizeMultiplier,
+ useKatex = useKatex,
+ searchQuery = searchQuery,
+ searchFocusedOccurrence = searchFocusedOccurrence,
+ onFocusedOccurrencePosition = onFocusedOccurrencePosition,
+ )
}
}
}
@@ -365,9 +399,19 @@ internal fun GenericToolCallCard(
},
verticalAlignment = Alignment.CenterVertically,
) {
- Icon(Icons.Default.Build, stringResource(Res.string.cd_tool_call), Modifier.size(16.dp), tint = MaterialTheme.colorScheme.onSurfaceVariant)
+ Icon(
+ Icons.Default.Build,
+ stringResource(Res.string.cd_tool_call),
+ Modifier.size(16.dp),
+ tint = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
Spacer(modifier = Modifier.width(8.dp))
- Text(toolName, style = MaterialTheme.typography.titleSmall, color = MaterialTheme.colorScheme.onSurface, modifier = Modifier.weight(1f))
+ Text(
+ toolName,
+ style = MaterialTheme.typography.titleSmall,
+ color = MaterialTheme.colorScheme.onSurface,
+ modifier = Modifier.weight(1f),
+ )
Icon(
if (isExpanded) Icons.Default.ExpandLess else Icons.Default.ExpandMore,
stringResource(if (isExpanded) Res.string.cd_collapse else Res.string.cd_expand),
@@ -379,13 +423,21 @@ internal fun GenericToolCallCard(
Column {
if (!args.isNullOrBlank()) {
Spacer(modifier = Modifier.height(8.dp))
- Text(stringResource(Res.string.label_input), style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
+ Text(
+ stringResource(Res.string.label_input),
+ style = MaterialTheme.typography.labelSmall,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
Spacer(modifier = Modifier.height(4.dp))
CodeBlock(code = args, language = "json")
}
if (!output.isNullOrBlank()) {
Spacer(modifier = Modifier.height(8.dp))
- Text(stringResource(Res.string.label_output), style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
+ Text(
+ stringResource(Res.string.label_output),
+ style = MaterialTheme.typography.labelSmall,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
Spacer(modifier = Modifier.height(4.dp))
CodeBlock(code = output, language = null)
}
@@ -435,7 +487,12 @@ internal fun ImageContentPart(
.background(MaterialTheme.colorScheme.surfaceContainerHigh, RoundedCornerShape(12.dp)),
contentAlignment = Alignment.Center,
) {
- Icon(Icons.Default.BrokenImage, stringResource(Res.string.cd_failed_to_load_image), Modifier.size(32.dp), tint = MaterialTheme.colorScheme.onSurfaceVariant)
+ Icon(
+ Icons.Default.BrokenImage,
+ stringResource(Res.string.cd_failed_to_load_image),
+ Modifier.size(32.dp),
+ tint = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
}
},
)
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SiblingNavigator.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SiblingNavigator.kt
index 31c4c0c..f07caee 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SiblingNavigator.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SiblingNavigator.kt
@@ -13,12 +13,12 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.stateDescription
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
fun SiblingNavigator(
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SlashCommandMenu.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SlashCommandMenu.kt
index 89bf3bf..e2246ff 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SlashCommandMenu.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/SlashCommandMenu.kt
@@ -20,7 +20,7 @@ import com.garfiec.librechat.feature.chat.model.PromptMentionDisplayData
@Composable
fun SlashCommandMenu(
filteredCommands: List,
- onCommandSelected: (PromptMentionDisplayData) -> Unit,
+ onCommandSelect: (PromptMentionDisplayData) -> Unit,
modifier: Modifier = Modifier,
) {
DropdownMenu(
@@ -48,7 +48,7 @@ fun SlashCommandMenu(
}
}
},
- onClick = { onCommandSelected(group) },
+ onClick = { onCommandSelect(group) },
)
}
}
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/StreamingIndicator.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/StreamingIndicator.kt
index 6e6b336..f6df039 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/StreamingIndicator.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/StreamingIndicator.kt
@@ -13,14 +13,14 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
/**
* Blinking cursor indicator shown during streaming. Displays a pipe character (|)
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/StreamingToolCallCard.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/StreamingToolCallCard.kt
index d2892d1..a59302e 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/StreamingToolCallCard.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/StreamingToolCallCard.kt
@@ -31,11 +31,11 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
import com.garfiec.librechat.feature.chat.viewmodel.ActiveToolCall
+import org.jetbrains.compose.resources.stringResource
@Composable
fun StreamingToolCallCard(
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ToolCallParsing.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ToolCallParsing.kt
index 2e15b36..4270fe4 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ToolCallParsing.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ToolCallParsing.kt
@@ -1,7 +1,8 @@
package com.garfiec.librechat.feature.chat.components
-import com.garfiec.librechat.core.model.content.AgentToolCall
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.model.Attachment
+import com.garfiec.librechat.core.model.content.AgentToolCall
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonObject
@@ -11,7 +12,6 @@ import kotlinx.serialization.json.intOrNull
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
-import co.touchlab.kermit.Logger
private val log = Logger.withTag("ToolCallParsing")
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ToolsDropdownMenu.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ToolsDropdownMenu.kt
index 130a42c..0dd40c7 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ToolsDropdownMenu.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/ToolsDropdownMenu.kt
@@ -14,10 +14,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
-import org.jetbrains.compose.resources.stringResource
import com.garfiec.librechat.core.common.ToolConstants
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
private data class ToolMenuItem(
val id: String,
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/WebSearchResultCard.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/WebSearchResultCard.kt
index 6c7f380..22e63e2 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/WebSearchResultCard.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/WebSearchResultCard.kt
@@ -27,7 +27,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalUriHandler
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.role
@@ -36,8 +35,9 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import coil3.compose.SubcomposeAsyncImage
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
/**
* Data class representing a single web search result parsed from tool call output.
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/artifact/ArtifactButton.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/artifact/ArtifactButton.kt
index 2f81ae3..3dc073c 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/artifact/ArtifactButton.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/artifact/ArtifactButton.kt
@@ -28,12 +28,12 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
fun ArtifactButton(
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/artifact/ArtifactVersionNav.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/artifact/ArtifactVersionNav.kt
index bdfc48f..fac1eb6 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/artifact/ArtifactVersionNav.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/components/artifact/ArtifactVersionNav.kt
@@ -14,10 +14,10 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
/** Prev/next version navigation for artifacts. [currentIndex] is 0-based; display shows 1-based "v1/N". */
@Composable
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/di/ChatModule.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/di/ChatModule.kt
index a9b2593..1084438 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/di/ChatModule.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/di/ChatModule.kt
@@ -10,10 +10,15 @@ import org.koin.dsl.module
val chatModule = module {
includes(chatPlatformModule)
viewModelOf(::PromptsViewModel)
+ // Koin's constructor-DSL (`viewModelOf`) wires every argument via `get()` and cannot read
+ // values passed through `parametersOf`. This VM receives its `initialGroupId` from the
+ // navigation layer via `parametersOf`, so the lambda-form `viewModel { params -> ... }` is
+ // the only DSL that works here. Detekt's `DeprecatedKoinApi` is a blanket stylistic rule,
+ // not a real `@Deprecated` API, so we suppress it in the narrow place it applies.
+ @Suppress("DeprecatedKoinApi")
viewModel { params ->
PromptEditorViewModel(
promptRepository = get(),
- savedStateHandle = get(),
initialGroupId = params.getOrNull(),
)
}
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/navigation/ChatNavigation.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/navigation/ChatNavigation.kt
index 2267513..e572002 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/navigation/ChatNavigation.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/navigation/ChatNavigation.kt
@@ -14,8 +14,11 @@ import kotlinx.serialization.modules.subclass
@Serializable sealed interface ChatRoute : NavKey
@Serializable data object NewChat : ChatRoute
+
@Serializable data class Chat(val conversationId: String? = null) : ChatRoute
+
@Serializable data object PromptsLibrary : ChatRoute
+
@Serializable data class PromptEditor(val groupId: String? = null) : ChatRoute
fun EntryProviderScope.chatEntries(
@@ -26,7 +29,7 @@ fun EntryProviderScope.chatEntries(
) {
entry {
NewChatScreen(
- onConversationStarted = { conversationId ->
+ onConversationStart = { conversationId ->
onNavigateToChat(conversationId)
},
onOpenDrawer = onOpenDrawer,
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptDetailScreen.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptDetailScreen.kt
index ef99716..bf66925 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptDetailScreen.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptDetailScreen.kt
@@ -28,12 +28,12 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.ui.components.LibreChatTopBar
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
import com.garfiec.librechat.feature.chat.prompts.components.PromptPreviewPanel
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
@OptIn(ExperimentalMaterial3Api::class)
@Composable
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptEditorScreen.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptEditorScreen.kt
index d9cae53..c3cf156 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptEditorScreen.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptEditorScreen.kt
@@ -29,14 +29,15 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.garfiec.librechat.core.ui.components.LoadingIndicator
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.koin.core.parameter.parametersOf
@@ -50,6 +51,7 @@ fun PromptEditorScreen(
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
val snackbarHostState = remember { SnackbarHostState() }
+ val currentOnBack by rememberUpdatedState(onBack)
LaunchedEffect(uiState.error) {
val error = uiState.error
@@ -62,7 +64,7 @@ fun PromptEditorScreen(
LaunchedEffect(uiState.saved) {
if (uiState.saved) {
viewModel.consumeSaved()
- onBack()
+ currentOnBack()
}
}
@@ -180,7 +182,7 @@ fun PromptEditorScreen(
PromptVariablesSection(
promptText = uiState.promptText,
variableValues = uiState.variableValues,
- onVariableChanged = viewModel::updateVariable,
+ onVariableChange = viewModel::updateVariable,
modifier = Modifier.fillMaxWidth(),
)
}
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptEditorViewModel.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptEditorViewModel.kt
index 84e9c35..e984500 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptEditorViewModel.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptEditorViewModel.kt
@@ -1,7 +1,6 @@
package com.garfiec.librechat.feature.chat.prompts
import androidx.compose.runtime.Immutable
-import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.garfiec.librechat.core.common.result.Result
@@ -39,7 +38,6 @@ data class PromptEditorUiState(
class PromptEditorViewModel(
private val promptRepository: PromptRepository,
- savedStateHandle: SavedStateHandle,
initialGroupId: String? = null,
) : ViewModel() {
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptVariablesSection.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptVariablesSection.kt
index 82c77c7..89ef9bd 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptVariablesSection.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptVariablesSection.kt
@@ -13,10 +13,10 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
private val VARIABLE_REGEX = Regex("\\{\\{\\s*(\\w+)\\s*\\}\\}")
@@ -51,7 +51,7 @@ fun substituteVariables(promptText: String, variableValues: Map)
fun PromptVariablesSection(
promptText: String,
variableValues: Map,
- onVariableChanged: (name: String, value: String) -> Unit,
+ onVariableChange: (name: String, value: String) -> Unit,
modifier: Modifier = Modifier,
) {
val variables = remember(promptText) { extractVariables(promptText) }
@@ -68,7 +68,7 @@ fun PromptVariablesSection(
variables.forEach { varName ->
OutlinedTextField(
value = variableValues[varName] ?: "",
- onValueChange = { onVariableChanged(varName, it) },
+ onValueChange = { onVariableChange(varName, it) },
label = { Text(varName) },
singleLine = true,
modifier = Modifier
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptVersionsSheet.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptVersionsSheet.kt
index 60b09da..12f967e 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptVersionsSheet.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptVersionsSheet.kt
@@ -22,12 +22,12 @@ import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.Prompt
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
/**
* A ModalBottomSheet that shows the version history of prompts within a group.
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptsLibraryScreen.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptsLibraryScreen.kt
index 8fa6c1d..13f9798 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptsLibraryScreen.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptsLibraryScreen.kt
@@ -41,7 +41,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -49,12 +48,13 @@ import com.garfiec.librechat.core.ui.components.EmptyState
import com.garfiec.librechat.core.ui.components.ErrorBanner
import com.garfiec.librechat.core.ui.components.LibreChatTopBar
import com.garfiec.librechat.core.ui.components.LoadingIndicator
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
import com.garfiec.librechat.feature.chat.prompts.components.PromptFilterSheet
import com.garfiec.librechat.feature.chat.prompts.components.PromptShareDialog
import com.garfiec.librechat.feature.chat.prompts.components.PromptSortOrder
import com.garfiec.librechat.feature.chat.prompts.components.VariableInputDialog
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@@ -117,7 +117,7 @@ fun PromptsLibraryScreen(
PromptShareDialog(
promptName = selectedGroup.name,
isCurrentlyShared = false,
- onShareToggled = { _, _ -> viewModel.dismissShareDialog() },
+ onShareToggle = { _, _ -> viewModel.dismissShareDialog() },
onDismiss = viewModel::dismissShareDialog,
)
}
@@ -130,9 +130,9 @@ fun PromptsLibraryScreen(
PromptFilterSheet(
categories = uiState.availableCategories,
selectedCategory = uiState.selectedCategory,
- onCategorySelected = viewModel::onCategorySelected,
+ onCategorySelect = viewModel::onCategorySelected,
sortOrder = uiState.sortOrder,
- onSortOrderChanged = viewModel::onSortOrderChanged,
+ onSortOrderChange = viewModel::onSortOrderChanged,
onDismiss = viewModel::dismissFilterSheet,
)
}
@@ -269,7 +269,7 @@ fun PromptsLibraryScreen(
PromptShareDialog(
promptName = shareGroup?.name ?: "",
isCurrentlyShared = false,
- onShareToggled = { _, _ -> viewModel.dismissShareDialog() },
+ onShareToggle = { _, _ -> viewModel.dismissShareDialog() },
onDismiss = viewModel::dismissShareDialog,
)
}
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptsViewModel.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptsViewModel.kt
index 39f6b99..76ef068 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptsViewModel.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/PromptsViewModel.kt
@@ -3,6 +3,7 @@ package com.garfiec.librechat.feature.chat.prompts
import androidx.compose.runtime.Immutable
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.repository.PromptRepository
import com.garfiec.librechat.core.model.PromptGroup
@@ -18,7 +19,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
-import co.touchlab.kermit.Logger
@Immutable
data class PromptsUiState(
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/components/PromptFilterSheet.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/components/PromptFilterSheet.kt
index 0dc80cb..99dcffa 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/components/PromptFilterSheet.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/components/PromptFilterSheet.kt
@@ -18,10 +18,10 @@ import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
enum class PromptSortOrder(val label: String) {
RECENT("Recent"),
@@ -34,9 +34,9 @@ enum class PromptSortOrder(val label: String) {
fun PromptFilterSheet(
categories: List,
selectedCategory: String?,
- onCategorySelected: (String?) -> Unit,
+ onCategorySelect: (String?) -> Unit,
sortOrder: PromptSortOrder,
- onSortOrderChanged: (PromptSortOrder) -> Unit,
+ onSortOrderChange: (PromptSortOrder) -> Unit,
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
sheetState: SheetState = rememberModalBottomSheetState(),
@@ -72,14 +72,14 @@ fun PromptFilterSheet(
) {
FilterChip(
selected = selectedCategory == null,
- onClick = { onCategorySelected(null) },
+ onClick = { onCategorySelect(null) },
label = { Text(stringResource(Res.string.label_all)) },
)
categories.forEach { category ->
FilterChip(
selected = selectedCategory == category,
onClick = {
- onCategorySelected(
+ onCategorySelect(
if (selectedCategory == category) null else category,
)
},
@@ -105,7 +105,7 @@ fun PromptFilterSheet(
PromptSortOrder.entries.forEach { order ->
FilterChip(
selected = sortOrder == order,
- onClick = { onSortOrderChanged(order) },
+ onClick = { onSortOrderChange(order) },
label = { Text(order.label) },
)
}
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/components/PromptPreviewPanel.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/components/PromptPreviewPanel.kt
index a71cb25..b05e9ab 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/components/PromptPreviewPanel.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/components/PromptPreviewPanel.kt
@@ -9,10 +9,10 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
fun PromptPreviewPanel(
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/components/PromptShareDialog.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/components/PromptShareDialog.kt
index d770a7c..04d2df6 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/components/PromptShareDialog.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/components/PromptShareDialog.kt
@@ -24,11 +24,11 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
import com.garfiec.librechat.feature.chat.util.copyToClipboard
import org.jetbrains.compose.resources.stringResource
-import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
enum class SharePermission(val label: String) {
VIEW_ONLY("View only"),
@@ -39,7 +39,7 @@ enum class SharePermission(val label: String) {
fun PromptShareDialog(
promptName: String,
isCurrentlyShared: Boolean,
- onShareToggled: (shared: Boolean, permission: SharePermission) -> Unit,
+ onShareToggle: (shared: Boolean, permission: SharePermission) -> Unit,
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
) {
@@ -117,7 +117,7 @@ fun PromptShareDialog(
},
confirmButton = {
TextButton(
- onClick = { onShareToggled(isShared, permission) },
+ onClick = { onShareToggle(isShared, permission) },
) {
Text(stringResource(Res.string.save))
}
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/components/VariableInputDialog.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/components/VariableInputDialog.kt
index fe4fd0c..89c693e 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/components/VariableInputDialog.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/prompts/components/VariableInputDialog.kt
@@ -26,10 +26,10 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
+import org.jetbrains.compose.resources.stringResource
private val VARIABLE_PATTERN = Regex("\\{\\{(\\w+)\\}\\}")
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/screen/PlatformScreens.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/screen/PlatformScreens.kt
index f6939b1..1368679 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/screen/PlatformScreens.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/screen/PlatformScreens.kt
@@ -8,7 +8,7 @@ import androidx.compose.ui.Modifier
expect fun ChatScreen(
modifier: Modifier = Modifier,
conversationId: String? = null,
- onConversationStarted: ((String) -> Unit)? = null,
+ onConversationStart: ((String) -> Unit)? = null,
onNavigateToConversation: ((String) -> Unit)? = null,
onOpenDrawer: (() -> Unit)? = null,
onNavigateToPromptsLibrary: (() -> Unit)? = null,
@@ -18,7 +18,7 @@ expect fun ChatScreen(
/** Platform-specific new chat screen. */
@Composable
expect fun NewChatScreen(
- onConversationStarted: (String) -> Unit,
+ onConversationStart: (String) -> Unit,
modifier: Modifier = Modifier,
onOpenDrawer: (() -> Unit)? = null,
onNavigateToPromptsLibrary: (() -> Unit)? = null,
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/ChatViewModel.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/ChatViewModel.kt
index a45d27e..a6eb534 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/ChatViewModel.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/ChatViewModel.kt
@@ -1,8 +1,8 @@
package com.garfiec.librechat.feature.chat.viewmodel
-import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.EndpointConstants
import com.garfiec.librechat.core.common.ToolConstants
import com.garfiec.librechat.core.common.network.ConnectivityObserver
@@ -29,9 +29,9 @@ import com.garfiec.librechat.core.model.Preset
import com.garfiec.librechat.core.model.StreamEvent
import com.garfiec.librechat.core.model.request.EphemeralAgent
import com.garfiec.librechat.core.ui.components.ModelParameters
+import com.garfiec.librechat.feature.chat.components.AttachedFile
import com.garfiec.librechat.feature.chat.model.PresetDisplayData
import com.garfiec.librechat.feature.chat.model.PromptMentionDisplayData
-import com.garfiec.librechat.feature.chat.components.AttachedFile
import com.garfiec.librechat.feature.chat.util.NEW_CHAT_DRAFT_KEY
import com.garfiec.librechat.feature.chat.util.buildActiveMessagePath
import com.garfiec.librechat.feature.chat.viewmodel.delegate.ConversationActionsDelegate
@@ -54,13 +54,11 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
-import co.touchlab.kermit.Logger
import kotlin.time.Clock
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid
class ChatViewModel(
- savedStateHandle: SavedStateHandle,
initialConversationId: String? = null,
private val agentRepository: AgentRepository,
private val chatRepository: ChatRepository,
@@ -509,7 +507,13 @@ class ChatViewModel(
val isAgent = _uiState.value.selectedEndpoint == EndpointConstants.AGENTS
val webSearchEnabled = _uiState.value.modelParameters.webSearch
val ephemeralAgent = buildEphemeralAgent()
- Logger.d { "sendMessage: webSearch=$webSearchEnabled, endpoint=${_uiState.value.selectedEndpoint}, model=${_uiState.value.selectedModel}, files=${fileRefs.size}, ephemeralAgent=$ephemeralAgent" }
+ Logger.d {
+ "sendMessage: webSearch=$webSearchEnabled, " +
+ "endpoint=${_uiState.value.selectedEndpoint}, " +
+ "model=${_uiState.value.selectedModel}, " +
+ "files=${fileRefs.size}, " +
+ "ephemeralAgent=$ephemeralAgent"
+ }
// Build addedConvo if comparison mode is enabled
val addedConvo = if (_uiState.value.comparisonState.isEnabled) {
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/ModelSelectionDelegate.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/ModelSelectionDelegate.kt
index 9306312..f660b3e 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/ModelSelectionDelegate.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/ModelSelectionDelegate.kt
@@ -1,5 +1,6 @@
package com.garfiec.librechat.feature.chat.viewmodel.delegate
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.EndpointConstants
import com.garfiec.librechat.core.common.ToolConstants
import com.garfiec.librechat.core.common.result.Result
@@ -16,7 +17,6 @@ import com.garfiec.librechat.feature.chat.viewmodel.ChatScreenState
import com.garfiec.librechat.feature.chat.viewmodel.ChatStateHandle
import com.garfiec.librechat.feature.chat.viewmodel.ComparisonState
import kotlinx.coroutines.launch
-import co.touchlab.kermit.Logger
class ModelSelectionDelegate(
private val stateHandle: ChatStateHandle,
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/PlatformFileHandler.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/PlatformFileHandler.kt
index 2ed0925..05c4ace 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/PlatformFileHandler.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/PlatformFileHandler.kt
@@ -1,7 +1,7 @@
package com.garfiec.librechat.feature.chat.viewmodel.delegate
-import com.garfiec.librechat.feature.chat.components.AttachedFile
import com.garfiec.librechat.core.model.FileReference
+import com.garfiec.librechat.feature.chat.components.AttachedFile
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.StateFlow
diff --git a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/PresetPromptDelegate.kt b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/PresetPromptDelegate.kt
index 9f1a1a7..24b122b 100644
--- a/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/PresetPromptDelegate.kt
+++ b/feature/chat/src/commonMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/PresetPromptDelegate.kt
@@ -1,5 +1,6 @@
package com.garfiec.librechat.feature.chat.viewmodel.delegate
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.repository.PresetRepository
import com.garfiec.librechat.core.data.repository.PromptRepository
@@ -10,7 +11,6 @@ import com.garfiec.librechat.feature.chat.model.PresetDisplayData
import com.garfiec.librechat.feature.chat.model.PromptMentionDisplayData
import com.garfiec.librechat.feature.chat.viewmodel.ChatStateHandle
import kotlinx.coroutines.launch
-import co.touchlab.kermit.Logger
class PresetPromptDelegate(
private val stateHandle: ChatStateHandle,
diff --git a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/components/IosChatInput.kt b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/components/IosChatInput.kt
index 838ca67..5c518cb 100644
--- a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/components/IosChatInput.kt
+++ b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/components/IosChatInput.kt
@@ -19,17 +19,17 @@ import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.feature.chat.model.McpServerDisplayData
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.cd_attach_file
-import librechat_mobile.feature.chat.generated.resources.cd_paste_image
+import com.garfiec.librechat.feature.chat.resources.Res
+import com.garfiec.librechat.feature.chat.resources.cd_attach_file
+import com.garfiec.librechat.feature.chat.resources.cd_paste_image
import org.jetbrains.compose.resources.stringResource
@Composable
diff --git a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/components/PlatformChatComponents.ios.kt b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/components/PlatformChatComponents.ios.kt
index 321eeec..f683430 100644
--- a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/components/PlatformChatComponents.ios.kt
+++ b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/components/PlatformChatComponents.ios.kt
@@ -28,9 +28,9 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
-import androidx.compose.material3.Text
import androidx.compose.material3.VerticalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@@ -66,17 +66,17 @@ import com.garfiec.librechat.core.model.content.MessageContentPart
import com.garfiec.librechat.core.ui.components.AvatarImage
import com.garfiec.librechat.core.ui.components.endpointIconPainter
import com.garfiec.librechat.core.ui.components.isMonochromeEndpointIcon
+import com.garfiec.librechat.feature.chat.resources.Res
+import com.garfiec.librechat.feature.chat.resources.cd_close
+import com.garfiec.librechat.feature.chat.resources.cd_expand_table
+import com.garfiec.librechat.feature.chat.resources.dialog_table
+import com.garfiec.librechat.feature.chat.resources.sender_assistant
+import com.garfiec.librechat.feature.chat.resources.sender_you
import com.mikepenz.markdown.m3.Markdown
import com.mikepenz.markdown.m3.markdownColor
import com.mikepenz.markdown.m3.markdownTypography
-import org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor
import kotlinx.coroutines.delay
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.cd_expand_table
-import librechat_mobile.feature.chat.generated.resources.cd_close
-import librechat_mobile.feature.chat.generated.resources.dialog_table
-import librechat_mobile.feature.chat.generated.resources.sender_assistant
-import librechat_mobile.feature.chat.generated.resources.sender_you
+import org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor
import org.jetbrains.compose.resources.stringResource
private const val ACTION_AUTO_HIDE_MILLIS = 30_000L
@@ -105,7 +105,7 @@ actual fun MessageBubble(
currentFeedback: String?,
isEditing: Boolean,
editText: String,
- onEditTextChanged: ((String) -> Unit)?,
+ onEditTextChange: ((String) -> Unit)?,
onEditSaveAndSubmit: (() -> Unit)?,
onEditSaveOnly: (() -> Unit)?,
onEditCancel: (() -> Unit)?,
@@ -118,7 +118,7 @@ actual fun MessageBubble(
isSearchMatch: Boolean,
isCurrentSearchMatch: Boolean,
searchFocusedOccurrence: Int,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)?,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)?,
useKatex: Boolean,
chatLayoutStyle: String,
showAvatars: Boolean,
@@ -131,18 +131,18 @@ actual fun MessageBubble(
TwoSidedBubble(
message, modifier, siblingIndex, siblingCount, onSiblingNavigation, onEdit, onRegenerate, onCopy, onFeedback,
onContinue, onReadAloud, onFork, baseUrl, fontSizeMultiplier, useKatex, isReading, currentFeedback,
- isEditing, editText, onEditTextChanged, onEditSaveAndSubmit, onEditSaveOnly, onEditCancel,
+ isEditing, editText, onEditTextChange, onEditSaveAndSubmit, onEditSaveOnly, onEditCancel,
userAvatarUrl, userName, resolvedEndpoint, tintEndpointIcon, showImageDescriptions, showActionsInitially,
- searchQuery, isSearchMatch, isCurrentSearchMatch, searchFocusedOccurrence, onFocusedOccurrencePositioned,
+ searchQuery, isSearchMatch, isCurrentSearchMatch, searchFocusedOccurrence, onFocusedOccurrencePosition,
showAvatars, showBubbles,
)
} else {
ThreadBubble(
message, modifier, siblingIndex, siblingCount, onSiblingNavigation, onEdit, onRegenerate, onCopy, onFeedback,
onContinue, onReadAloud, onFork, baseUrl, fontSizeMultiplier, useKatex, isReading, currentFeedback,
- isEditing, editText, onEditTextChanged, onEditSaveAndSubmit, onEditSaveOnly, onEditCancel,
+ isEditing, editText, onEditTextChange, onEditSaveAndSubmit, onEditSaveOnly, onEditCancel,
userAvatarUrl, userName, resolvedEndpoint, tintEndpointIcon, showImageDescriptions, showActionsInitially,
- searchQuery, isSearchMatch, isCurrentSearchMatch, searchFocusedOccurrence, onFocusedOccurrencePositioned,
+ searchQuery, isSearchMatch, isCurrentSearchMatch, searchFocusedOccurrence, onFocusedOccurrencePosition,
showAvatars, showBubbles,
)
}
@@ -156,12 +156,12 @@ private fun ThreadBubble(
onCopy: (() -> Unit)?, onFeedback: ((String?) -> Unit)?, onContinue: (() -> Unit)?,
onReadAloud: (() -> Unit)?, onFork: (() -> Unit)?, baseUrl: String, fontSizeMultiplier: Float,
useKatex: Boolean, isReading: Boolean, currentFeedback: String?, isEditing: Boolean, editText: String,
- onEditTextChanged: ((String) -> Unit)?, onEditSaveAndSubmit: (() -> Unit)?, onEditSaveOnly: (() -> Unit)?,
+ onEditTextChange: ((String) -> Unit)?, onEditSaveAndSubmit: (() -> Unit)?, onEditSaveOnly: (() -> Unit)?,
onEditCancel: (() -> Unit)?, userAvatarUrl: String?, userName: String?,
resolvedEndpoint: String?, tintEndpointIcon: Boolean,
showImageDescriptions: Boolean, showActionsInitially: Boolean, searchQuery: String?,
isSearchMatch: Boolean, isCurrentSearchMatch: Boolean, searchFocusedOccurrence: Int,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)?, showAvatars: Boolean, showBubbles: Boolean,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)?, showAvatars: Boolean, showBubbles: Boolean,
) {
val isUser = message.isCreatedByUser
var showActions by remember(message.messageId) { mutableStateOf(showActionsInitially) }
@@ -192,8 +192,11 @@ private fun ThreadBubble(
if (showAvatars) {
AvatarImage(
imageUrl = if (isUser) userAvatarUrl else message.iconURL,
- fallbackText = if (isUser) userName ?: stringResource(Res.string.sender_you)
- else message.sender ?: stringResource(Res.string.sender_assistant),
+ fallbackText = if (isUser) {
+ userName ?: stringResource(Res.string.sender_you)
+ } else {
+ message.sender ?: stringResource(Res.string.sender_assistant)
+ },
fallbackIconPainter = if (!isUser && message.iconURL == null) endpointIconPainter(resolvedEndpoint) else null,
showPersonIcon = isUser && userAvatarUrl == null,
tintIcon = if (!isUser && message.iconURL == null) tintEndpointIcon else false,
@@ -202,8 +205,11 @@ private fun ThreadBubble(
Spacer(Modifier.width(8.dp))
}
Text(
- text = if (isUser) userName ?: stringResource(Res.string.sender_you)
- else message.sender ?: stringResource(Res.string.sender_assistant),
+ text = if (isUser) {
+ userName ?: stringResource(Res.string.sender_you)
+ } else {
+ message.sender ?: stringResource(Res.string.sender_assistant)
+ },
style = MaterialTheme.typography.titleSmall.copy(fontWeight = FontWeight.SemiBold),
color = MaterialTheme.colorScheme.onSurface,
)
@@ -215,7 +221,9 @@ private fun ThreadBubble(
val contentPad = if (showAvatars) 36.dp else 0.dp
val bubbleBg = if (showBubbles) {
if (isUser) MaterialTheme.colorScheme.secondaryContainer else MaterialTheme.colorScheme.surfaceVariant
- } else null
+ } else {
+ null
+ }
Column(
modifier = Modifier.padding(start = contentPad).then(
@@ -223,9 +231,9 @@ private fun ThreadBubble(
),
) {
MessageContentAndActions(
- message, isUser, isEditing, editText, onEditTextChanged, onEditSaveAndSubmit, onEditSaveOnly, onEditCancel,
+ message, isUser, isEditing, editText, onEditTextChange, onEditSaveAndSubmit, onEditSaveOnly, onEditCancel,
baseUrl, fontSizeMultiplier, useKatex, showImageDescriptions, searchQuery, isSearchMatch,
- isCurrentSearchMatch, searchFocusedOccurrence, onFocusedOccurrencePositioned, showActions,
+ isCurrentSearchMatch, searchFocusedOccurrence, onFocusedOccurrencePosition, showActions,
siblingIndex, siblingCount, onSiblingNavigation, onEdit, onRegenerate, onCopy, onFeedback,
onContinue, onReadAloud, onFork, isReading, currentFeedback, { showFeedbackDialog = true },
)
@@ -241,12 +249,12 @@ private fun TwoSidedBubble(
onCopy: (() -> Unit)?, onFeedback: ((String?) -> Unit)?, onContinue: (() -> Unit)?,
onReadAloud: (() -> Unit)?, onFork: (() -> Unit)?, baseUrl: String, fontSizeMultiplier: Float,
useKatex: Boolean, isReading: Boolean, currentFeedback: String?, isEditing: Boolean, editText: String,
- onEditTextChanged: ((String) -> Unit)?, onEditSaveAndSubmit: (() -> Unit)?, onEditSaveOnly: (() -> Unit)?,
+ onEditTextChange: ((String) -> Unit)?, onEditSaveAndSubmit: (() -> Unit)?, onEditSaveOnly: (() -> Unit)?,
onEditCancel: (() -> Unit)?, userAvatarUrl: String?, userName: String?,
resolvedEndpoint: String?, tintEndpointIcon: Boolean,
showImageDescriptions: Boolean, showActionsInitially: Boolean, searchQuery: String?,
isSearchMatch: Boolean, isCurrentSearchMatch: Boolean, searchFocusedOccurrence: Int,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)?, showAvatars: Boolean, showBubbles: Boolean,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)?, showAvatars: Boolean, showBubbles: Boolean,
) {
val isUser = message.isCreatedByUser
var showActions by remember(message.messageId) { mutableStateOf(showActionsInitially) }
@@ -268,9 +276,14 @@ private fun TwoSidedBubble(
}
val bubbleBg = if (showBubbles) {
if (isUser) MaterialTheme.colorScheme.secondaryContainer else MaterialTheme.colorScheme.surfaceVariant
- } else null
- val effectiveBg = if (searchBg != null && bubbleBg != null) searchBg.compositeOver(bubbleBg)
- else searchBg ?: bubbleBg
+ } else {
+ null
+ }
+ val effectiveBg = if (searchBg != null && bubbleBg != null) {
+ searchBg.compositeOver(bubbleBg)
+ } else {
+ searchBg ?: bubbleBg
+ }
Row(
modifier = modifier.fillMaxWidth()
@@ -292,28 +305,36 @@ private fun TwoSidedBubble(
Column(
modifier = Modifier.weight(1f).then(
- if (effectiveBg != null) Modifier.background(effectiveBg, BubbleShape).padding(12.dp)
- else Modifier.padding(horizontal = 4.dp, vertical = 8.dp),
+ if (effectiveBg != null) {
+ Modifier.background(effectiveBg, BubbleShape).padding(12.dp)
+ } else {
+ Modifier.padding(horizontal = 4.dp, vertical = 8.dp)
+ },
),
horizontalAlignment = if (isUser) Alignment.End else Alignment.Start,
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
- text = if (isUser) userName ?: stringResource(Res.string.sender_you)
- else message.sender ?: stringResource(Res.string.sender_assistant),
+ text = if (isUser) {
+ userName ?: stringResource(Res.string.sender_you)
+ } else {
+ message.sender ?: stringResource(Res.string.sender_assistant)
+ },
style = MaterialTheme.typography.labelSmall.copy(fontWeight = FontWeight.SemiBold),
color = if (showBubbles) {
if (isUser) MaterialTheme.colorScheme.onSecondaryContainer else MaterialTheme.colorScheme.onSurfaceVariant
- } else MaterialTheme.colorScheme.onSurface,
+ } else {
+ MaterialTheme.colorScheme.onSurface
+ },
)
message.createdAt?.let { ts -> Spacer(Modifier.width(6.dp)); MessageTimestamp(isoTimestamp = ts) }
}
Spacer(Modifier.height(4.dp))
MessageContentAndActions(
- message, isUser, isEditing, editText, onEditTextChanged, onEditSaveAndSubmit, onEditSaveOnly, onEditCancel,
+ message, isUser, isEditing, editText, onEditTextChange, onEditSaveAndSubmit, onEditSaveOnly, onEditCancel,
baseUrl, fontSizeMultiplier, useKatex, showImageDescriptions, searchQuery, isSearchMatch,
- isCurrentSearchMatch, searchFocusedOccurrence, onFocusedOccurrencePositioned, showActions,
+ isCurrentSearchMatch, searchFocusedOccurrence, onFocusedOccurrencePosition, showActions,
siblingIndex, siblingCount, onSiblingNavigation, onEdit, onRegenerate, onCopy, onFeedback,
onContinue, onReadAloud, onFork, isReading, currentFeedback, { showFeedbackDialog = true },
)
@@ -331,7 +352,6 @@ private fun TwoSidedBubble(
}
}
-
// ─── ContentPartRenderer ─────────────────────────────────────────────
@Composable
@@ -339,7 +359,7 @@ actual fun ContentPartRenderer(
part: MessageContentPart, modifier: Modifier, baseUrl: String, fontSizeMultiplier: Float,
useKatex: Boolean, attachments: List,
showImageDescriptions: Boolean, searchQuery: String?, searchFocusedOccurrence: Int,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)?,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)?,
) {
ContentPartDispatcher(
part = part,
@@ -351,7 +371,7 @@ actual fun ContentPartRenderer(
showImageDescriptions = showImageDescriptions,
searchQuery = searchQuery,
searchFocusedOccurrence = searchFocusedOccurrence,
- onFocusedOccurrencePositioned = onFocusedOccurrencePositioned,
+ onFocusedOccurrencePosition = onFocusedOccurrencePosition,
)
}
@@ -361,7 +381,7 @@ actual fun ContentPartRenderer(
actual fun MarkdownContent(
text: String, modifier: Modifier, fontSizeMultiplier: Float, useKatex: Boolean,
searchQuery: String?, searchFocusedOccurrence: Int,
- onFocusedOccurrencePositioned: ((LayoutCoordinates) -> Unit)?,
+ onFocusedOccurrencePosition: ((LayoutCoordinates) -> Unit)?,
) {
val segments = remember(text) { parseMarkdownSegments(text) }
@@ -656,4 +676,3 @@ private fun TextStyle.scale(m: Float): TextStyle {
lineHeight = if (lineHeight.isSpecified) (lineHeight.value * m).sp else lineHeight,
)
}
-
diff --git a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/components/PlatformMediaComponents.ios.kt b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/components/PlatformMediaComponents.ios.kt
index 42efc8a..87c2014 100644
--- a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/components/PlatformMediaComponents.ios.kt
+++ b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/components/PlatformMediaComponents.ios.kt
@@ -1,6 +1,11 @@
package com.garfiec.librechat.feature.chat.components
+import androidx.compose.animation.AnimatedContent
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
+import androidx.compose.animation.togetherWith
import androidx.compose.foundation.background
+import androidx.compose.foundation.gestures.detectTransformGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -11,6 +16,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
@@ -21,10 +27,12 @@ import androidx.compose.material.icons.filled.Image
import androidx.compose.material.icons.filled.MusicNote
import androidx.compose.material.icons.filled.Pause
import androidx.compose.material.icons.filled.PlayArrow
+import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
+import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@@ -40,34 +48,38 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
+import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.interop.UIKitView
-import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import co.touchlab.kermit.Logger
import coil3.compose.AsyncImage
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
import kotlinx.cinterop.BetaInteropApi
import kotlinx.cinterop.ExperimentalForeignApi
+import kotlinx.cinterop.addressOf
import kotlinx.cinterop.cValue
+import kotlinx.cinterop.usePinned
import kotlinx.coroutines.delay
+import org.jetbrains.compose.resources.stringResource
import platform.AVFAudio.AVAudioPlayer
import platform.AVFoundation.AVLayerVideoGravityResizeAspect
import platform.AVFoundation.AVPlayer
-import platform.AVFoundation.AVPlayerItem
import platform.AVFoundation.AVPlayerLayer
+import platform.AVFoundation.AVPlayerTimeControlStatusPlaying
import platform.AVFoundation.currentItem
+import platform.AVFoundation.currentTime
import platform.AVFoundation.duration
import platform.AVFoundation.pause
import platform.AVFoundation.play
-import platform.AVFoundation.currentTime
-import platform.AVFoundation.seekToTime
import platform.AVFoundation.timeControlStatus
-import platform.AVFoundation.AVPlayerTimeControlStatusPlaying
-import platform.CoreMedia.CMTimeMakeWithSeconds
import platform.CoreMedia.CMTimeGetSeconds
import platform.Foundation.NSData
import platform.Foundation.NSFileManager
@@ -75,9 +87,8 @@ import platform.Foundation.NSTemporaryDirectory
import platform.Foundation.NSURL
import platform.Foundation.create
import platform.Foundation.writeToFile
-import kotlinx.cinterop.addressOf
-import kotlinx.cinterop.usePinned
-import platform.QuartzCore.CALayer
+import platform.UIKit.UIActivityViewController
+import platform.UIKit.UIApplication
import platform.UIKit.UIColor
import platform.UIKit.UIView
import platform.UIKit.UIViewController
@@ -87,24 +98,6 @@ import platform.WebKit.WKNavigationDelegateProtocol
import platform.WebKit.WKWebView
import platform.WebKit.WKWebViewConfiguration
import platform.darwin.NSObject
-import org.jetbrains.compose.resources.stringResource
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
-import androidx.compose.animation.AnimatedContent
-import androidx.compose.animation.fadeIn
-import androidx.compose.animation.fadeOut
-import androidx.compose.animation.togetherWith
-import androidx.compose.foundation.gestures.detectTransformGestures
-import androidx.compose.foundation.layout.statusBarsPadding
-import androidx.compose.material.icons.filled.Share
-import androidx.compose.material.icons.outlined.SaveAlt
-import androidx.compose.material3.IconButtonDefaults
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.graphics.graphicsLayer
-import androidx.compose.ui.input.pointer.pointerInput
-import androidx.compose.ui.layout.ContentScale
-import platform.UIKit.UIActivityViewController
-import platform.UIKit.UIApplication
@OptIn(ExperimentalForeignApi::class, BetaInteropApi::class)
@Composable
diff --git a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/components/artifact/PlatformArtifactPanel.ios.kt b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/components/artifact/PlatformArtifactPanel.ios.kt
index 601dec6..1dc2164 100644
--- a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/components/artifact/PlatformArtifactPanel.ios.kt
+++ b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/components/artifact/PlatformArtifactPanel.ios.kt
@@ -4,16 +4,13 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
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.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Share
-import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
@@ -21,7 +18,6 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
diff --git a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/di/ChatPlatformModule.ios.kt b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/di/ChatPlatformModule.ios.kt
index fa18e03..477784d 100644
--- a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/di/ChatPlatformModule.ios.kt
+++ b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/di/ChatPlatformModule.ios.kt
@@ -18,7 +18,6 @@ actual val chatPlatformModule: Module = module {
viewModel { params ->
ChatViewModel(
- savedStateHandle = get(),
initialConversationId = params.getOrNull(),
agentRepository = get(),
chatRepository = get(),
diff --git a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/screen/PlatformScreens.ios.kt b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/screen/PlatformScreens.ios.kt
index ff660ea..98222da 100644
--- a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/screen/PlatformScreens.ios.kt
+++ b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/screen/PlatformScreens.ios.kt
@@ -8,6 +8,8 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
@@ -27,13 +29,9 @@ import androidx.compose.material.icons.outlined.Edit
import androidx.compose.material.icons.outlined.FileOpen
import androidx.compose.material.icons.outlined.SaveAs
import androidx.compose.material.icons.outlined.Share
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.DropdownMenu
-import androidx.compose.material3.SnackbarHost
-import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
@@ -42,6 +40,8 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
+import androidx.compose.material3.SnackbarHost
+import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBar
@@ -70,6 +70,8 @@ import com.garfiec.librechat.feature.chat.components.ModelSelectorSheet
import com.garfiec.librechat.feature.chat.components.PresetPicker
import com.garfiec.librechat.feature.chat.components.SavePresetDialog
import com.garfiec.librechat.feature.chat.components.TempChatToggle
+import com.garfiec.librechat.feature.chat.resources.*
+import com.garfiec.librechat.feature.chat.resources.Res
import com.garfiec.librechat.feature.chat.util.clipboardHasImage
import com.garfiec.librechat.feature.chat.util.openCamera
import com.garfiec.librechat.feature.chat.util.openDocumentPicker
@@ -77,8 +79,6 @@ import com.garfiec.librechat.feature.chat.util.openPhotoPicker
import com.garfiec.librechat.feature.chat.util.readClipboardImage
import com.garfiec.librechat.feature.chat.viewmodel.ChatScreenState
import com.garfiec.librechat.feature.chat.viewmodel.ChatViewModel
-import librechat_mobile.feature.chat.generated.resources.Res
-import librechat_mobile.feature.chat.generated.resources.*
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.koin.core.parameter.parametersOf
@@ -88,7 +88,7 @@ import org.koin.core.parameter.parametersOf
actual fun ChatScreen(
modifier: Modifier,
conversationId: String?,
- onConversationStarted: ((String) -> Unit)?,
+ onConversationStart: ((String) -> Unit)?,
onNavigateToConversation: ((String) -> Unit)?,
onOpenDrawer: (() -> Unit)?,
onNavigateToPromptsLibrary: (() -> Unit)?,
@@ -121,11 +121,11 @@ actual fun ChatScreen(
// Navigate when a new conversation is created from landing page.
// Navigate first, then reset — matches Android order so the new
// ViewModel can resume the active stream before the old one cancels it.
- if (onConversationStarted != null) {
+ if (onConversationStart != null) {
LaunchedEffect(uiState.pendingNavigationConversationId) {
val navId = uiState.pendingNavigationConversationId
if (navId != null) {
- onConversationStarted(navId)
+ onConversationStart(navId)
viewModel.onPendingNavigationHandled()
}
}
@@ -375,7 +375,7 @@ actual fun ChatScreen(
) {
InConvoSearchBar(
query = uiState.searchQuery,
- onQueryChanged = viewModel::onSearchQueryChanged,
+ onQueryChange = viewModel::onSearchQueryChanged,
currentMatchIndex = uiState.currentSearchMatchIndex,
totalMatches = uiState.searchMatchIndices.size,
onPreviousMatch = viewModel::previousSearchMatch,
@@ -428,7 +428,7 @@ actual fun ChatScreen(
currentlyReadingMessageId = uiState.currentlyReadingMessageId,
editingMessageId = uiState.editingMessageId,
editingText = uiState.editingText,
- onEditTextChanged = viewModel::onEditTextChanged,
+ onEditTextChange = viewModel::onEditTextChanged,
onEditSaveAndSubmit = viewModel::submitEdit,
onEditSaveOnly = viewModel::saveEditOnly,
onEditCancel = viewModel::cancelEditing,
@@ -456,7 +456,7 @@ actual fun ChatScreen(
searchMatchIndices = uiState.searchMatchIndices,
currentSearchMatchIndex = uiState.currentSearchMatchIndex,
searchScrollToIndex = uiState.searchScrollToIndex,
- onSearchScrollHandled = viewModel::onSearchScrollHandled,
+ onSearchScrollHandle = viewModel::onSearchScrollHandled,
modifier = Modifier.fillMaxSize(),
)
}
@@ -529,7 +529,7 @@ actual fun ChatScreen(
agents = uiState.agents,
selectedEndpoint = uiState.selectedEndpoint,
selectedModel = uiState.selectedModel,
- onModelSelected = { endpoint, model ->
+ onModelSelect = { endpoint, model ->
viewModel.onModelSelected(endpoint, model)
showModelSheet = false
},
@@ -542,7 +542,7 @@ actual fun ChatScreen(
if (showPresetPicker) {
PresetPicker(
presets = uiState.presets,
- onPresetSelected = { preset ->
+ onPresetSelect = { preset ->
viewModel.loadPreset(preset)
showPresetPicker = false
},
@@ -610,14 +610,14 @@ actual fun ChatScreen(
@Composable
actual fun NewChatScreen(
- onConversationStarted: (String) -> Unit,
+ onConversationStart: (String) -> Unit,
modifier: Modifier,
onOpenDrawer: (() -> Unit)?,
onNavigateToPromptsLibrary: (() -> Unit)?,
) {
ChatScreen(
modifier = modifier,
- onConversationStarted = onConversationStarted,
+ onConversationStart = onConversationStart,
onOpenDrawer = onOpenDrawer,
onNavigateToPromptsLibrary = onNavigateToPromptsLibrary,
)
diff --git a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/util/IosClipboardImageReader.kt b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/util/IosClipboardImageReader.kt
index f9f414f..048dee1 100644
--- a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/util/IosClipboardImageReader.kt
+++ b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/util/IosClipboardImageReader.kt
@@ -42,7 +42,7 @@ fun readClipboardImage(): IosImageData? {
return IosImageData(
bytes = bytes,
- filename = "clipboard_${timestamp}.png",
+ filename = "clipboard_$timestamp.png",
mimeType = "image/png",
width = width,
height = height,
diff --git a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/util/IosFilePicker.kt b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/util/IosFilePicker.kt
index 1ffd240..b192bb2 100644
--- a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/util/IosFilePicker.kt
+++ b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/util/IosFilePicker.kt
@@ -219,7 +219,9 @@ private class PhotoPickerDelegate(
width = cgImage?.let { CGImageGetWidth(it).toInt() },
height = cgImage?.let { CGImageGetHeight(it).toInt() },
)
- } else null
+ } else {
+ null
+ }
}
if (imageData == null) {
Logger.e { "PHPicker: failed to load image: ${error?.localizedDescription}" }
@@ -321,4 +323,3 @@ private fun guessMimeType(filename: String): String {
else -> "application/octet-stream"
}
}
-
diff --git a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/util/TimestampFormatter.ios.kt b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/util/TimestampFormatter.ios.kt
index a3b8fdc..20e19ea 100644
--- a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/util/TimestampFormatter.ios.kt
+++ b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/util/TimestampFormatter.ios.kt
@@ -1,12 +1,12 @@
package com.garfiec.librechat.feature.chat.util
-import platform.Foundation.NSDateFormatter
import platform.Foundation.NSDate
+import platform.Foundation.NSDateFormatter
import platform.Foundation.NSLocale
import platform.Foundation.NSTimeZone
+import platform.Foundation.localeWithLocaleIdentifier
import platform.Foundation.timeIntervalSince1970
import platform.Foundation.timeZoneWithName
-import platform.Foundation.localeWithLocaleIdentifier
actual fun formatRelativeTimestamp(isoTimestamp: String): String {
val date = parseTimestamp(isoTimestamp) ?: return ""
diff --git a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/IosFileHandler.kt b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/IosFileHandler.kt
index 495ac59..a06e985 100644
--- a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/IosFileHandler.kt
+++ b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/IosFileHandler.kt
@@ -91,7 +91,9 @@ class IosFileHandler(
width = fileObject.width,
height = fileObject.height,
)
- } else f
+ } else {
+ f
+ }
}
}
}
@@ -167,7 +169,9 @@ class IosFileHandler(
filepath = fileObject.filepath,
type = fileObject.type,
)
- } else f
+ } else {
+ f
+ }
}
}
}
diff --git a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/IosVoiceInput.kt b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/IosVoiceInput.kt
index 7231379..94d2fa7 100644
--- a/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/IosVoiceInput.kt
+++ b/feature/chat/src/iosMain/kotlin/com/garfiec/librechat/feature/chat/viewmodel/delegate/IosVoiceInput.kt
@@ -1,5 +1,6 @@
package com.garfiec.librechat.feature.chat.viewmodel.delegate
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.feature.chat.viewmodel.ChatStateHandle
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.coroutines.launch
@@ -16,7 +17,6 @@ import platform.Speech.SFSpeechAudioBufferRecognitionRequest
import platform.Speech.SFSpeechRecognitionTask
import platform.Speech.SFSpeechRecognizer
import platform.Speech.SFSpeechRecognizerAuthorizationStatus
-import co.touchlab.kermit.Logger
/**
* iOS implementation of [PlatformVoiceInput] using AVAudioEngine + SFSpeechRecognizer
diff --git a/feature/conversations/detekt-baseline.xml b/feature/conversations/detekt-baseline.xml
deleted file mode 100644
index 331af8b..0000000
--- a/feature/conversations/detekt-baseline.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
- FunctionNaming:String0.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString0Resources(map: MutableMap<String, StringResource>)
- ImportOrdering:ArchivedConversationsScreen.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Archive import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Unarchive import androidx.compose.material3.AlertDialog import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.garfiec.librechat.core.ui.components.EmptyState import com.garfiec.librechat.core.ui.components.ErrorBanner import com.garfiec.librechat.core.ui.components.LoadingIndicator import com.garfiec.librechat.feature.conversations.ArchivedConversationDisplayData import librechat_mobile.feature.conversations.generated.resources.Res import librechat_mobile.feature.conversations.generated.resources.* import com.garfiec.librechat.feature.conversations.viewmodel.ArchivedConversationsEvent import com.garfiec.librechat.feature.conversations.viewmodel.ArchivedConversationsViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:ArchivedConversationsViewModel.kt$import androidx.compose.runtime.Immutable import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.core.data.repository.ConversationRepository import com.garfiec.librechat.core.model.Conversation import com.garfiec.librechat.feature.conversations.ArchivedConversationDisplayData import com.garfiec.librechat.feature.conversations.toArchivedDisplayData import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import co.touchlab.kermit.Logger
- ImportOrdering:ConversationActions.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Archive import androidx.compose.material.icons.filled.Bookmark import androidx.compose.material.icons.filled.BookmarkBorder import androidx.compose.material.icons.filled.ContentCopy import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.FileDownload import androidx.compose.material.icons.filled.Share import androidx.compose.material3.AlertDialog import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.model.Conversation import librechat_mobile.feature.conversations.generated.resources.Res import librechat_mobile.feature.conversations.generated.resources.*
- ImportOrdering:ConversationExporter.kt$import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.core.data.repository.ConversationRepository import com.garfiec.librechat.core.data.repository.MessageRepository import com.garfiec.librechat.core.model.ConversationExport import com.garfiec.librechat.core.model.Message import kotlin.time.Clock import kotlinx.datetime.TimeZone import kotlinx.datetime.toLocalDateTime import kotlinx.serialization.json.Json
- ImportOrdering:ConversationItem.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer 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.material.icons.Icons import androidx.compose.material.icons.filled.Bookmark import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.filled.SmartToy import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.common.extensions.toInstantOrNull import com.garfiec.librechat.core.model.EModelEndpoint import com.garfiec.librechat.core.ui.components.endpointIconPainter import com.garfiec.librechat.core.ui.components.isMonochromeIcon import librechat_mobile.feature.conversations.generated.resources.Res import librechat_mobile.feature.conversations.generated.resources.* import kotlin.time.Clock import kotlin.time.Instant import kotlinx.datetime.TimeZone import kotlinx.datetime.toLocalDateTime
- ImportOrdering:ConversationListScreen.kt$import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues 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.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Archive import androidx.compose.material.icons.filled.Forum import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.garfiec.librechat.core.model.Conversation import com.garfiec.librechat.core.ui.components.EmptyState import com.garfiec.librechat.core.ui.components.ErrorBanner import com.garfiec.librechat.core.ui.components.LoadingIndicator import librechat_mobile.feature.conversations.generated.resources.Res import librechat_mobile.feature.conversations.generated.resources.* import com.garfiec.librechat.feature.conversations.components.ConversationActions import com.garfiec.librechat.feature.conversations.components.ConversationItem import com.garfiec.librechat.feature.conversations.components.ConversationSearchBar import com.garfiec.librechat.feature.conversations.components.DateGroupHeader import com.garfiec.librechat.feature.conversations.components.TagFilterBar import com.garfiec.librechat.feature.conversations.components.TagPicker import com.garfiec.librechat.feature.conversations.export.ExportFormat import com.garfiec.librechat.feature.conversations.export.ExportFormatPicker import com.garfiec.librechat.feature.conversations.platform.FileSaver import com.garfiec.librechat.feature.conversations.platform.copyToClipboard import com.garfiec.librechat.feature.conversations.platform.showToast import com.garfiec.librechat.feature.conversations.viewmodel.ConversationListEvent import com.garfiec.librechat.feature.conversations.viewmodel.ConversationListViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:ConversationListViewModel.kt$import androidx.compose.runtime.Immutable import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.garfiec.librechat.core.common.extensions.toInstantOrNull import com.garfiec.librechat.core.common.extensions.toRelativeDateGroup import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.core.data.datastore.SettingsDataStore import com.garfiec.librechat.core.data.repository.ConversationRepository import com.garfiec.librechat.core.data.repository.SearchRepository import com.garfiec.librechat.core.data.repository.ShareRepository import com.garfiec.librechat.core.data.repository.TagRepository import com.garfiec.librechat.core.model.Conversation import com.garfiec.librechat.core.model.ConversationTag import com.garfiec.librechat.feature.conversations.components.ConversationDisplayData import com.garfiec.librechat.feature.conversations.components.toDisplayData import com.garfiec.librechat.feature.conversations.export.ConversationExporter import com.garfiec.librechat.feature.conversations.export.ConversationImporter import com.garfiec.librechat.feature.conversations.export.ExportFormat import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import co.touchlab.kermit.Logger
- ImportOrdering:ConversationSearchBar.kt$import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Search import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.material3.TextFieldDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.conversations.generated.resources.Res import librechat_mobile.feature.conversations.generated.resources.*
- ImportOrdering:ExpectResourceCollectors.kt$import kotlin.String import kotlin.collections.Map import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.FontResource import org.jetbrains.compose.resources.PluralStringResource import org.jetbrains.compose.resources.StringArrayResource import org.jetbrains.compose.resources.StringResource
- ImportOrdering:ExportFormatPicker.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Code import androidx.compose.material.icons.filled.Description import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.Text import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.conversations.generated.resources.Res import librechat_mobile.feature.conversations.generated.resources.*
- ImportOrdering:Res.kt$import kotlin.ByteArray import kotlin.OptIn import kotlin.String import kotlin.Suppress import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.getResourceUri import org.jetbrains.compose.resources.readResourceBytes
- ImportOrdering:String0.commonMain.kt$import kotlin.OptIn import kotlin.String import kotlin.collections.MutableMap import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.ResourceContentHash import org.jetbrains.compose.resources.ResourceItem import org.jetbrains.compose.resources.StringResource
- ImportOrdering:TagFilterBar.kt$import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.expandVertically import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.rememberScrollState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.BookmarkBorder import androidx.compose.material.icons.filled.Close import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FilterChip import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.model.ConversationTag import librechat_mobile.feature.conversations.generated.resources.Res import librechat_mobile.feature.conversations.generated.resources.*
- ImportOrdering:TagPicker.kt$import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import com.garfiec.librechat.core.model.ConversationTag import com.garfiec.librechat.core.ui.components.FilterChipBottomSheet import librechat_mobile.feature.conversations.generated.resources.Res import librechat_mobile.feature.conversations.generated.resources.* import org.jetbrains.compose.resources.stringResource
- LambdaParameterInRestartableEffect:ConversationListScreen.kt$onConversationClick
- MaxLineLength:ConversationExporter.kt$ConversationExporter$val exportDate = "${now.year}-${now.monthNumber.toString().padStart(2, '0')}-${now.dayOfMonth.toString().padStart(2, '0')} ${now.hour.toString().padStart(2, '0')}:${now.minute.toString().padStart(2, '0')}"
- MaxLineLength:Res.kt$Res$public
- MaxLineLength:Res.kt$Res$public suspend
- PackageName:ExpectResourceCollectors.kt$package librechat_mobile.feature.conversations.generated.resources
- PackageName:Res.kt$package librechat_mobile.feature.conversations.generated.resources
- PackageName:String0.commonMain.kt$package librechat_mobile.feature.conversations.generated.resources
- PackageNaming:ExpectResourceCollectors.kt$package librechat_mobile.feature.conversations.generated.resources
- PackageNaming:Res.kt$package librechat_mobile.feature.conversations.generated.resources
- PackageNaming:String0.commonMain.kt$package librechat_mobile.feature.conversations.generated.resources
- ParameterNaming:ConversationListScreen.kt$onNavigateToArchived
- ParameterNaming:ConversationSearchBar.kt$onQueryChanged
- ParameterNaming:ExportFormatPicker.kt$onFormatSelected
- ParameterNaming:TagPicker.kt$onTagsChanged
- SpacingBetweenDeclarationsWithAnnotations:ConversationsNavigation.kt$ArchivedConversations : ConversationsRoute
-
-
diff --git a/feature/conversations/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/conversations/di/ConversationsModuleVerificationTest.kt b/feature/conversations/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/conversations/di/ConversationsModuleVerificationTest.kt
index 007f513..dcc0520 100644
--- a/feature/conversations/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/conversations/di/ConversationsModuleVerificationTest.kt
+++ b/feature/conversations/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/conversations/di/ConversationsModuleVerificationTest.kt
@@ -2,7 +2,6 @@ package com.garfiec.librechat.feature.conversations.di
import android.app.Application
import android.content.Context
-import androidx.lifecycle.SavedStateHandle
import com.garfiec.librechat.core.data.datastore.ServerDataStore
import com.garfiec.librechat.core.data.datastore.SettingsDataStore
import com.garfiec.librechat.core.data.repository.ConfigRepository
@@ -21,7 +20,6 @@ class ConversationsModuleVerificationTest {
extraTypes = listOf(
Context::class,
Application::class,
- SavedStateHandle::class,
ConversationRepository::class,
MessageRepository::class,
TagRepository::class,
diff --git a/feature/conversations/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/conversations/viewmodel/ConversationListViewModelTest.kt b/feature/conversations/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/conversations/viewmodel/ConversationListViewModelTest.kt
index 7f188b7..24a5d7b 100644
--- a/feature/conversations/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/conversations/viewmodel/ConversationListViewModelTest.kt
+++ b/feature/conversations/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/conversations/viewmodel/ConversationListViewModelTest.kt
@@ -1,6 +1,5 @@
package com.garfiec.librechat.feature.conversations.viewmodel
-import com.google.common.truth.Truth.assertThat
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.datastore.SettingsDataStore
import com.garfiec.librechat.core.data.repository.ConversationRepository
@@ -11,6 +10,7 @@ import com.garfiec.librechat.core.model.Conversation
import com.garfiec.librechat.core.model.ConversationTag
import com.garfiec.librechat.feature.conversations.export.ConversationExporter
import com.garfiec.librechat.feature.conversations.export.ConversationImporter
+import com.google.common.truth.Truth.assertThat
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
diff --git a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/ConversationActions.kt b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/ConversationActions.kt
index 6e041ca..ca237f4 100644
--- a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/ConversationActions.kt
+++ b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/ConversationActions.kt
@@ -35,11 +35,11 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.Conversation
-import librechat_mobile.feature.conversations.generated.resources.Res
-import librechat_mobile.feature.conversations.generated.resources.*
+import com.garfiec.librechat.feature.conversations.resources.*
+import com.garfiec.librechat.feature.conversations.resources.Res
+import org.jetbrains.compose.resources.stringResource
@OptIn(ExperimentalMaterial3Api::class)
@Composable
diff --git a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/ConversationItem.kt b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/ConversationItem.kt
index 5e705eb..3c5f4d6 100644
--- a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/ConversationItem.kt
+++ b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/ConversationItem.kt
@@ -21,20 +21,19 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.common.extensions.toInstantOrNull
import com.garfiec.librechat.core.model.EModelEndpoint
import com.garfiec.librechat.core.ui.components.endpointIconPainter
import com.garfiec.librechat.core.ui.components.isMonochromeIcon
-import librechat_mobile.feature.conversations.generated.resources.Res
-import librechat_mobile.feature.conversations.generated.resources.*
-import kotlin.time.Clock
-import kotlin.time.Instant
+import com.garfiec.librechat.feature.conversations.resources.*
+import com.garfiec.librechat.feature.conversations.resources.Res
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
+import org.jetbrains.compose.resources.stringResource
+import kotlin.time.Clock
+import kotlin.time.Instant
@Composable
fun ConversationItem(
diff --git a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/ConversationSearchBar.kt b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/ConversationSearchBar.kt
index 1ec8591..deaa92d 100644
--- a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/ConversationSearchBar.kt
+++ b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/ConversationSearchBar.kt
@@ -16,20 +16,20 @@ import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.conversations.generated.resources.Res
-import librechat_mobile.feature.conversations.generated.resources.*
+import com.garfiec.librechat.feature.conversations.resources.*
+import com.garfiec.librechat.feature.conversations.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
fun ConversationSearchBar(
query: String,
- onQueryChanged: (String) -> Unit,
+ onQueryChange: (String) -> Unit,
modifier: Modifier = Modifier,
) {
TextField(
value = query,
- onValueChange = onQueryChanged,
+ onValueChange = onQueryChange,
leadingIcon = {
Icon(
imageVector = Icons.Default.Search,
@@ -39,7 +39,7 @@ fun ConversationSearchBar(
},
trailingIcon = {
if (query.isNotEmpty()) {
- IconButton(onClick = { onQueryChanged("") }) {
+ IconButton(onClick = { onQueryChange("") }) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = stringResource(Res.string.cd_clear_search),
diff --git a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/TagFilterBar.kt b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/TagFilterBar.kt
index 704b62e..3ee7170 100644
--- a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/TagFilterBar.kt
+++ b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/TagFilterBar.kt
@@ -26,11 +26,11 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.ConversationTag
-import librechat_mobile.feature.conversations.generated.resources.Res
-import librechat_mobile.feature.conversations.generated.resources.*
+import com.garfiec.librechat.feature.conversations.resources.*
+import com.garfiec.librechat.feature.conversations.resources.Res
+import org.jetbrains.compose.resources.stringResource
@OptIn(ExperimentalMaterial3Api::class)
@Composable
diff --git a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/TagPicker.kt b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/TagPicker.kt
index 3818e22..c3331d8 100644
--- a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/TagPicker.kt
+++ b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/components/TagPicker.kt
@@ -5,15 +5,15 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import com.garfiec.librechat.core.model.ConversationTag
import com.garfiec.librechat.core.ui.components.FilterChipBottomSheet
-import librechat_mobile.feature.conversations.generated.resources.Res
-import librechat_mobile.feature.conversations.generated.resources.*
+import com.garfiec.librechat.feature.conversations.resources.*
+import com.garfiec.librechat.feature.conversations.resources.Res
import org.jetbrains.compose.resources.stringResource
@Composable
fun TagPicker(
availableTags: List,
currentTags: List,
- onTagsChanged: (List) -> Unit,
+ onTagsChange: (List) -> Unit,
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
) {
@@ -27,7 +27,7 @@ fun TagPicker(
FilterChipBottomSheet(
items = allTagStrings,
selectedItems = currentTags.toSet(),
- onSelectionChanged = { onTagsChanged(it.toList()) },
+ onSelectionChange = { onTagsChange(it.toList()) },
label = { it },
onDismiss = onDismiss,
title = stringResource(Res.string.tags),
diff --git a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/export/ConversationExporter.kt b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/export/ConversationExporter.kt
index 935bcf9..1976784 100644
--- a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/export/ConversationExporter.kt
+++ b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/export/ConversationExporter.kt
@@ -5,10 +5,10 @@ import com.garfiec.librechat.core.data.repository.ConversationRepository
import com.garfiec.librechat.core.data.repository.MessageRepository
import com.garfiec.librechat.core.model.ConversationExport
import com.garfiec.librechat.core.model.Message
-import kotlin.time.Clock
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
import kotlinx.serialization.json.Json
+import kotlin.time.Clock
class ConversationExporter(
private val conversationRepository: ConversationRepository,
@@ -52,7 +52,11 @@ class ConversationExporter(
}
val now = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
- val exportDate = "${now.year}-${now.monthNumber.toString().padStart(2, '0')}-${now.dayOfMonth.toString().padStart(2, '0')} ${now.hour.toString().padStart(2, '0')}:${now.minute.toString().padStart(2, '0')}"
+ val month = now.monthNumber.toString().padStart(2, '0')
+ val day = now.dayOfMonth.toString().padStart(2, '0')
+ val hour = now.hour.toString().padStart(2, '0')
+ val minute = now.minute.toString().padStart(2, '0')
+ val exportDate = "${now.year}-$month-$day $hour:$minute"
val sb = StringBuilder()
sb.appendLine("# ${conversation.title ?: "Untitled Conversation"}")
diff --git a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/export/ExportFormatPicker.kt b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/export/ExportFormatPicker.kt
index d4e4304..5b0f395 100644
--- a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/export/ExportFormatPicker.kt
+++ b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/export/ExportFormatPicker.kt
@@ -20,15 +20,15 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.conversations.generated.resources.Res
-import librechat_mobile.feature.conversations.generated.resources.*
+import com.garfiec.librechat.feature.conversations.resources.*
+import com.garfiec.librechat.feature.conversations.resources.Res
+import org.jetbrains.compose.resources.stringResource
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ExportFormatPicker(
- onFormatSelected: (ExportFormat) -> Unit,
+ onFormatSelect: (ExportFormat) -> Unit,
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
) {
@@ -55,7 +55,7 @@ fun ExportFormatPicker(
description = stringResource(Res.string.format_json_description),
onClick = {
onDismiss()
- onFormatSelected(ExportFormat.JSON)
+ onFormatSelect(ExportFormat.JSON)
},
)
@@ -65,7 +65,7 @@ fun ExportFormatPicker(
description = stringResource(Res.string.format_markdown_description),
onClick = {
onDismiss()
- onFormatSelected(ExportFormat.MARKDOWN)
+ onFormatSelect(ExportFormat.MARKDOWN)
},
)
}
diff --git a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/navigation/ConversationsNavigation.kt b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/navigation/ConversationsNavigation.kt
index d02b101..dae126b 100644
--- a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/navigation/ConversationsNavigation.kt
+++ b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/navigation/ConversationsNavigation.kt
@@ -12,17 +12,18 @@ import kotlinx.serialization.modules.subclass
@Serializable sealed interface ConversationsRoute : NavKey
@Serializable data object Conversations : ConversationsRoute
+
@Serializable data object ArchivedConversations : ConversationsRoute
fun EntryProviderScope.conversationsEntries(
onConversationClick: (String) -> Unit,
- onNavigateToArchived: () -> Unit = {},
+ onNavigateToArchive: () -> Unit = {},
onBack: () -> Unit = {},
) {
entry {
ConversationListScreen(
onConversationClick = onConversationClick,
- onNavigateToArchived = onNavigateToArchived,
+ onNavigateToArchive = onNavigateToArchive,
)
}
entry {
diff --git a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/screen/ArchivedConversationsScreen.kt b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/screen/ArchivedConversationsScreen.kt
index 7b4e918..e64908e 100644
--- a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/screen/ArchivedConversationsScreen.kt
+++ b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/screen/ArchivedConversationsScreen.kt
@@ -35,7 +35,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -43,10 +42,11 @@ import com.garfiec.librechat.core.ui.components.EmptyState
import com.garfiec.librechat.core.ui.components.ErrorBanner
import com.garfiec.librechat.core.ui.components.LoadingIndicator
import com.garfiec.librechat.feature.conversations.ArchivedConversationDisplayData
-import librechat_mobile.feature.conversations.generated.resources.Res
-import librechat_mobile.feature.conversations.generated.resources.*
+import com.garfiec.librechat.feature.conversations.resources.*
+import com.garfiec.librechat.feature.conversations.resources.Res
import com.garfiec.librechat.feature.conversations.viewmodel.ArchivedConversationsEvent
import com.garfiec.librechat.feature.conversations.viewmodel.ArchivedConversationsViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@OptIn(ExperimentalMaterial3Api::class)
diff --git a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/screen/ConversationListScreen.kt b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/screen/ConversationListScreen.kt
index 289fcbf..5cdc633 100644
--- a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/screen/ConversationListScreen.kt
+++ b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/screen/ConversationListScreen.kt
@@ -31,19 +31,17 @@ import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.garfiec.librechat.core.model.Conversation
import com.garfiec.librechat.core.ui.components.EmptyState
import com.garfiec.librechat.core.ui.components.ErrorBanner
import com.garfiec.librechat.core.ui.components.LoadingIndicator
-import librechat_mobile.feature.conversations.generated.resources.Res
-import librechat_mobile.feature.conversations.generated.resources.*
import com.garfiec.librechat.feature.conversations.components.ConversationActions
import com.garfiec.librechat.feature.conversations.components.ConversationItem
import com.garfiec.librechat.feature.conversations.components.ConversationSearchBar
@@ -55,8 +53,11 @@ import com.garfiec.librechat.feature.conversations.export.ExportFormatPicker
import com.garfiec.librechat.feature.conversations.platform.FileSaver
import com.garfiec.librechat.feature.conversations.platform.copyToClipboard
import com.garfiec.librechat.feature.conversations.platform.showToast
+import com.garfiec.librechat.feature.conversations.resources.*
+import com.garfiec.librechat.feature.conversations.resources.Res
import com.garfiec.librechat.feature.conversations.viewmodel.ConversationListEvent
import com.garfiec.librechat.feature.conversations.viewmodel.ConversationListViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@OptIn(ExperimentalMaterial3Api::class)
@@ -65,7 +66,7 @@ fun ConversationListScreen(
onConversationClick: (String) -> Unit,
modifier: Modifier = Modifier,
onNewChatClick: () -> Unit = {},
- onNavigateToArchived: () -> Unit = {},
+ onNavigateToArchive: () -> Unit = {},
viewModel: ConversationListViewModel = koinViewModel(),
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
@@ -81,6 +82,7 @@ fun ConversationListScreen(
var pendingExportContent by remember { mutableStateOf(null) }
val snackbarHostState = remember { SnackbarHostState() }
+ val currentOnConversationClick by rememberUpdatedState(onConversationClick)
val copyOfPrefix = stringResource(Res.string.copy_of)
val newChatLabel = stringResource(Res.string.new_chat)
@@ -114,7 +116,7 @@ fun ConversationListScreen(
snackbarHostState.showSnackbar(linkCopiedMsg)
}
is ConversationListEvent.NavigateToConversation -> {
- onConversationClick(event.conversationId)
+ currentOnConversationClick(event.conversationId)
}
is ConversationListEvent.ShowError -> {
snackbarHostState.showSnackbar(event.message)
@@ -188,10 +190,10 @@ fun ConversationListScreen(
) {
ConversationSearchBar(
query = uiState.searchQuery,
- onQueryChanged = viewModel::onSearchQueryChanged,
+ onQueryChange = viewModel::onSearchQueryChanged,
modifier = Modifier.weight(1f),
)
- IconButton(onClick = onNavigateToArchived) {
+ IconButton(onClick = onNavigateToArchive) {
Icon(
imageVector = Icons.Default.Archive,
contentDescription = stringResource(Res.string.cd_archived_conversations),
@@ -382,7 +384,7 @@ fun ConversationListScreen(
TagPicker(
availableTags = uiState.tags,
currentTags = tagPickerConversation?.tags ?: emptyList(),
- onTagsChanged = { newTags ->
+ onTagsChange = { newTags ->
tagPickerConversation?.conversationId?.let { id ->
viewModel.updateConversationTags(id, newTags)
}
@@ -397,7 +399,7 @@ fun ConversationListScreen(
// Export format picker
if (showExportFormatPicker && exportConversation != null) {
ExportFormatPicker(
- onFormatSelected = { format ->
+ onFormatSelect = { format ->
exportConversation?.conversationId?.let { id ->
viewModel.exportConversation(id, exportConversation?.title, format)
}
diff --git a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/viewmodel/ArchivedConversationsViewModel.kt b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/viewmodel/ArchivedConversationsViewModel.kt
index 1929a86..d6f4bb5 100644
--- a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/viewmodel/ArchivedConversationsViewModel.kt
+++ b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/viewmodel/ArchivedConversationsViewModel.kt
@@ -3,6 +3,7 @@ package com.garfiec.librechat.feature.conversations.viewmodel
import androidx.compose.runtime.Immutable
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.repository.ConversationRepository
import com.garfiec.librechat.core.model.Conversation
@@ -15,7 +16,6 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
-import co.touchlab.kermit.Logger
@Immutable
data class ArchivedConversationsUiState(
diff --git a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/viewmodel/ConversationListViewModel.kt b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/viewmodel/ConversationListViewModel.kt
index 68f61e5..d746966 100644
--- a/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/viewmodel/ConversationListViewModel.kt
+++ b/feature/conversations/src/commonMain/kotlin/com/garfiec/librechat/feature/conversations/viewmodel/ConversationListViewModel.kt
@@ -3,6 +3,7 @@ package com.garfiec.librechat.feature.conversations.viewmodel
import androidx.compose.runtime.Immutable
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.extensions.toInstantOrNull
import com.garfiec.librechat.core.common.extensions.toRelativeDateGroup
import com.garfiec.librechat.core.common.result.Result
@@ -27,7 +28,6 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
-import co.touchlab.kermit.Logger
@Immutable
data class ConversationListUiState(
diff --git a/feature/files/detekt-baseline.xml b/feature/files/detekt-baseline.xml
deleted file mode 100644
index 57577fa..0000000
--- a/feature/files/detekt-baseline.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
- Filename:FilePicker.kt$com.garfiec.librechat.feature.files.platform.FilePicker.kt
- FunctionNaming:String0.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString0Resources(map: MutableMap<String, StringResource>)
- ImportOrdering:ExpectResourceCollectors.kt$import kotlin.String import kotlin.collections.Map import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.FontResource import org.jetbrains.compose.resources.PluralStringResource import org.jetbrains.compose.resources.StringArrayResource import org.jetbrains.compose.resources.StringResource
- ImportOrdering:FilePreviewDialog.kt$import androidx.compose.foundation.gestures.rememberTransformableState import androidx.compose.foundation.gestures.transformable import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.AudioFile import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Description import androidx.compose.material.icons.filled.ErrorOutline import androidx.compose.material.icons.filled.Image import androidx.compose.material.icons.filled.PictureAsPdf import androidx.compose.material.icons.filled.VideoFile import androidx.compose.material3.Card import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import coil3.compose.AsyncImage import co.touchlab.kermit.Logger import com.garfiec.librechat.feature.files.FilePreviewDisplayData import com.garfiec.librechat.feature.files.platform.PdfPreview import org.jetbrains.compose.resources.stringResource import librechat_mobile.feature.files.generated.resources.Res import librechat_mobile.feature.files.generated.resources.*
- ImportOrdering:FileSortMenu.kt$import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowDownward import androidx.compose.material.icons.filled.ArrowUpward import androidx.compose.material.icons.filled.Check import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource import librechat_mobile.feature.files.generated.resources.Res import librechat_mobile.feature.files.generated.resources.* import com.garfiec.librechat.feature.files.viewmodel.FileSortField import com.garfiec.librechat.feature.files.viewmodel.FileSortOrder
- ImportOrdering:FilesScreen.kt$import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.InsertDriveFile import androidx.compose.material.icons.automirrored.filled.Sort import androidx.compose.material.icons.automirrored.filled.ViewList import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.AudioFile import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Code import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Description import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.Folder import androidx.compose.material.icons.filled.GridView import androidx.compose.material.icons.filled.Image import androidx.compose.material.icons.filled.PictureAsPdf import androidx.compose.material.icons.filled.SelectAll import androidx.compose.material.icons.filled.VideoFile import androidx.compose.material3.AlertDialog import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Checkbox import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.ScrollableTabRow import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Tab import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import coil3.compose.AsyncImage import com.garfiec.librechat.core.ui.components.EmptyState import com.garfiec.librechat.core.ui.components.ErrorBanner import com.garfiec.librechat.feature.files.FileDisplayData import com.garfiec.librechat.feature.files.components.UploadProgressCard import com.garfiec.librechat.feature.files.platform.rememberFilePickerLauncher import com.garfiec.librechat.feature.files.viewmodel.FileTypeFilter import com.garfiec.librechat.feature.files.viewmodel.FileViewMode import com.garfiec.librechat.feature.files.viewmodel.FilesViewModel import org.jetbrains.compose.resources.stringResource import librechat_mobile.feature.files.generated.resources.Res import librechat_mobile.feature.files.generated.resources.* import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:FilesViewModel.kt$import androidx.compose.runtime.Immutable import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.core.data.datastore.ServerDataStore import com.garfiec.librechat.core.data.repository.FileRepository import com.garfiec.librechat.core.model.FileObject import com.garfiec.librechat.core.model.request.DeleteFileEntry import com.garfiec.librechat.feature.files.FileDisplayData import com.garfiec.librechat.feature.files.FilePreviewDisplayData import com.garfiec.librechat.feature.files.platform.FileReader import com.garfiec.librechat.feature.files.platform.formatFileSize import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import co.touchlab.kermit.Logger import kotlin.uuid.ExperimentalUuidApi import kotlin.uuid.Uuid
- ImportOrdering:Res.kt$import kotlin.ByteArray import kotlin.OptIn import kotlin.String import kotlin.Suppress import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.getResourceUri import org.jetbrains.compose.resources.readResourceBytes
- ImportOrdering:String0.commonMain.kt$import kotlin.OptIn import kotlin.String import kotlin.collections.MutableMap import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.ResourceContentHash import org.jetbrains.compose.resources.ResourceItem import org.jetbrains.compose.resources.StringResource
- ImportOrdering:UploadProgressCard.kt$import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideOutVertically import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.UploadFile import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource import librechat_mobile.feature.files.generated.resources.Res import librechat_mobile.feature.files.generated.resources.*
- MaxLineLength:Res.kt$Res$public suspend
- PackageName:ExpectResourceCollectors.kt$package librechat_mobile.feature.files.generated.resources
- PackageName:Res.kt$package librechat_mobile.feature.files.generated.resources
- PackageName:String0.commonMain.kt$package librechat_mobile.feature.files.generated.resources
- PackageNaming:ExpectResourceCollectors.kt$package librechat_mobile.feature.files.generated.resources
- PackageNaming:Res.kt$package librechat_mobile.feature.files.generated.resources
- PackageNaming:String0.commonMain.kt$package librechat_mobile.feature.files.generated.resources
- ParameterNaming:FilePicker.kt$onFilePicked
- ParameterNaming:FileSortMenu.kt$onSortSelected
-
-
diff --git a/feature/files/src/androidMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePicker.android.kt b/feature/files/src/androidMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePickerLauncher.android.kt
similarity index 91%
rename from feature/files/src/androidMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePicker.android.kt
rename to feature/files/src/androidMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePickerLauncher.android.kt
index 854ae5d..db397ef 100644
--- a/feature/files/src/androidMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePicker.android.kt
+++ b/feature/files/src/androidMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePickerLauncher.android.kt
@@ -7,13 +7,13 @@ import androidx.compose.runtime.remember
@Composable
actual fun rememberFilePickerLauncher(
- onFilePicked: (fileRef: Any) -> Unit,
+ onFilePick: (fileRef: Any) -> Unit,
): FilePickerLauncher {
val launcher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.GetContent(),
) { uri ->
if (uri != null) {
- onFilePicked(uri)
+ onFilePick(uri)
}
}
return remember(launcher) {
diff --git a/feature/files/src/androidMain/kotlin/com/garfiec/librechat/feature/files/platform/PdfPreview.android.kt b/feature/files/src/androidMain/kotlin/com/garfiec/librechat/feature/files/platform/PdfPreview.android.kt
index 315d07e..65686a3 100644
--- a/feature/files/src/androidMain/kotlin/com/garfiec/librechat/feature/files/platform/PdfPreview.android.kt
+++ b/feature/files/src/androidMain/kotlin/com/garfiec/librechat/feature/files/platform/PdfPreview.android.kt
@@ -10,7 +10,6 @@ import androidx.compose.foundation.gestures.transformable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
@@ -43,10 +42,10 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import co.touchlab.kermit.Logger
import com.garfiec.librechat.feature.files.FilePreviewDisplayData
+import com.garfiec.librechat.feature.files.resources.*
+import com.garfiec.librechat.feature.files.resources.Res
import com.garfiec.librechat.feature.files.screen.InfoRow
import org.jetbrains.compose.resources.stringResource
-import librechat_mobile.feature.files.generated.resources.Res
-import librechat_mobile.feature.files.generated.resources.*
import java.io.File
private sealed interface PdfLoadState {
diff --git a/feature/files/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/files/di/FilesModuleVerificationTest.kt b/feature/files/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/files/di/FilesModuleVerificationTest.kt
index 5223e4e..1edeccd 100644
--- a/feature/files/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/files/di/FilesModuleVerificationTest.kt
+++ b/feature/files/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/files/di/FilesModuleVerificationTest.kt
@@ -2,7 +2,6 @@ package com.garfiec.librechat.feature.files.di
import android.app.Application
import android.content.Context
-import androidx.lifecycle.SavedStateHandle
import com.garfiec.librechat.core.data.datastore.ServerDataStore
import com.garfiec.librechat.core.data.repository.FileRepository
import com.garfiec.librechat.feature.files.platform.FileReader
@@ -16,7 +15,6 @@ class FilesModuleVerificationTest {
extraTypes = listOf(
Context::class,
Application::class,
- SavedStateHandle::class,
FileRepository::class,
ServerDataStore::class,
FileReader::class,
diff --git a/feature/files/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/files/viewmodel/FilesViewModelTest.kt b/feature/files/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/files/viewmodel/FilesViewModelTest.kt
index e24bfdd..0282473 100644
--- a/feature/files/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/files/viewmodel/FilesViewModelTest.kt
+++ b/feature/files/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/files/viewmodel/FilesViewModelTest.kt
@@ -1,11 +1,11 @@
package com.garfiec.librechat.feature.files.viewmodel
-import com.google.common.truth.Truth.assertThat
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.datastore.ServerDataStore
import com.garfiec.librechat.core.data.repository.FileRepository
import com.garfiec.librechat.core.model.FileObject
import com.garfiec.librechat.feature.files.platform.FileReader
+import com.google.common.truth.Truth.assertThat
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
diff --git a/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/components/UploadProgressCard.kt b/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/components/UploadProgressCard.kt
index 190b8a4..a2c4ffa 100644
--- a/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/components/UploadProgressCard.kt
+++ b/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/components/UploadProgressCard.kt
@@ -27,9 +27,9 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
+import com.garfiec.librechat.feature.files.resources.*
+import com.garfiec.librechat.feature.files.resources.Res
import org.jetbrains.compose.resources.stringResource
-import librechat_mobile.feature.files.generated.resources.Res
-import librechat_mobile.feature.files.generated.resources.*
/** Animated card showing upload filename, progress bar, and cancel button with slide/fade visibility transitions. */
@Composable
diff --git a/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePicker.kt b/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePickerLauncher.kt
similarity index 75%
rename from feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePicker.kt
rename to feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePickerLauncher.kt
index 86bd60e..458cfcc 100644
--- a/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePicker.kt
+++ b/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePickerLauncher.kt
@@ -5,12 +5,12 @@ import androidx.compose.runtime.Composable
/**
* Platform file picker composable.
* When [launch] is called, shows the platform's native file picker.
- * On file selection, calls [onFilePicked] with a platform-specific file reference
+ * On file selection, calls [onFilePick] with a platform-specific file reference
* (Android Uri, iOS NSURL).
*/
@Composable
expect fun rememberFilePickerLauncher(
- onFilePicked: (fileRef: Any) -> Unit,
+ onFilePick: (fileRef: Any) -> Unit,
): FilePickerLauncher
expect class FilePickerLauncher {
diff --git a/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/screen/FilePreviewDialog.kt b/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/screen/FilePreviewDialog.kt
index 65a29b8..b46ad55 100644
--- a/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/screen/FilePreviewDialog.kt
+++ b/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/screen/FilePreviewDialog.kt
@@ -53,13 +53,13 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
-import coil3.compose.AsyncImage
import co.touchlab.kermit.Logger
+import coil3.compose.AsyncImage
import com.garfiec.librechat.feature.files.FilePreviewDisplayData
import com.garfiec.librechat.feature.files.platform.PdfPreview
+import com.garfiec.librechat.feature.files.resources.*
+import com.garfiec.librechat.feature.files.resources.Res
import org.jetbrains.compose.resources.stringResource
-import librechat_mobile.feature.files.generated.resources.Res
-import librechat_mobile.feature.files.generated.resources.*
@OptIn(ExperimentalMaterial3Api::class)
@Composable
diff --git a/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/screen/FileSortMenu.kt b/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/screen/FileSortMenu.kt
index d6df39d..f4fc2f4 100644
--- a/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/screen/FileSortMenu.kt
+++ b/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/screen/FileSortMenu.kt
@@ -16,18 +16,18 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.resources.stringResource
-import librechat_mobile.feature.files.generated.resources.Res
-import librechat_mobile.feature.files.generated.resources.*
+import com.garfiec.librechat.feature.files.resources.*
+import com.garfiec.librechat.feature.files.resources.Res
import com.garfiec.librechat.feature.files.viewmodel.FileSortField
import com.garfiec.librechat.feature.files.viewmodel.FileSortOrder
+import org.jetbrains.compose.resources.stringResource
@Composable
fun FileSortMenu(
expanded: Boolean,
currentSortField: FileSortField,
currentSortOrder: FileSortOrder,
- onSortSelected: (FileSortField, FileSortOrder) -> Unit,
+ onSortSelect: (FileSortField, FileSortOrder) -> Unit,
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
) {
@@ -64,9 +64,9 @@ fun FileSortMenu(
} else {
FileSortOrder.ASCENDING
}
- onSortSelected(field, newOrder)
+ onSortSelect(field, newOrder)
} else {
- onSortSelected(field, FileSortOrder.DESCENDING)
+ onSortSelect(field, FileSortOrder.DESCENDING)
}
onDismiss()
},
diff --git a/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/screen/FilesScreen.kt b/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/screen/FilesScreen.kt
index 975c7bb..e753623 100644
--- a/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/screen/FilesScreen.kt
+++ b/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/screen/FilesScreen.kt
@@ -79,12 +79,12 @@ import com.garfiec.librechat.core.ui.components.ErrorBanner
import com.garfiec.librechat.feature.files.FileDisplayData
import com.garfiec.librechat.feature.files.components.UploadProgressCard
import com.garfiec.librechat.feature.files.platform.rememberFilePickerLauncher
+import com.garfiec.librechat.feature.files.resources.*
+import com.garfiec.librechat.feature.files.resources.Res
import com.garfiec.librechat.feature.files.viewmodel.FileTypeFilter
import com.garfiec.librechat.feature.files.viewmodel.FileViewMode
import com.garfiec.librechat.feature.files.viewmodel.FilesViewModel
import org.jetbrains.compose.resources.stringResource
-import librechat_mobile.feature.files.generated.resources.Res
-import librechat_mobile.feature.files.generated.resources.*
import org.koin.compose.viewmodel.koinViewModel
@OptIn(ExperimentalMaterial3Api::class)
@@ -101,7 +101,7 @@ fun FilesScreen(
var showSortMenu by remember { mutableStateOf(false) }
val filePickerLauncher = rememberFilePickerLauncher(
- onFilePicked = { fileRef -> viewModel.uploadFile(fileRef) },
+ onFilePick = { fileRef -> viewModel.uploadFile(fileRef) },
)
LaunchedEffect(uiState.error) {
@@ -205,7 +205,7 @@ fun FilesScreen(
expanded = showSortMenu,
currentSortField = uiState.sortField,
currentSortOrder = uiState.sortOrder,
- onSortSelected = { field, order ->
+ onSortSelect = { field, order ->
viewModel.setSort(field, order)
},
onDismiss = { showSortMenu = false },
diff --git a/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/viewmodel/FilesViewModel.kt b/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/viewmodel/FilesViewModel.kt
index 6a66e7e..f2d8831 100644
--- a/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/viewmodel/FilesViewModel.kt
+++ b/feature/files/src/commonMain/kotlin/com/garfiec/librechat/feature/files/viewmodel/FilesViewModel.kt
@@ -3,6 +3,7 @@ package com.garfiec.librechat.feature.files.viewmodel
import androidx.compose.runtime.Immutable
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.datastore.ServerDataStore
import com.garfiec.librechat.core.data.repository.FileRepository
@@ -19,7 +20,6 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
-import co.touchlab.kermit.Logger
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid
diff --git a/feature/files/src/iosMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePicker.ios.kt b/feature/files/src/iosMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePickerLauncher.ios.kt
similarity index 92%
rename from feature/files/src/iosMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePicker.ios.kt
rename to feature/files/src/iosMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePickerLauncher.ios.kt
index 45ee289..29569a4 100644
--- a/feature/files/src/iosMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePicker.ios.kt
+++ b/feature/files/src/iosMain/kotlin/com/garfiec/librechat/feature/files/platform/FilePickerLauncher.ios.kt
@@ -5,7 +5,7 @@ import androidx.compose.runtime.remember
@Composable
actual fun rememberFilePickerLauncher(
- onFilePicked: (fileRef: Any) -> Unit,
+ onFilePick: (fileRef: Any) -> Unit,
): FilePickerLauncher {
// iOS file picker — stub for now.
// A proper implementation would use UIDocumentPickerViewController.
diff --git a/feature/settings/detekt-baseline.xml b/feature/settings/detekt-baseline.xml
deleted file mode 100644
index 3e33ea6..0000000
--- a/feature/settings/detekt-baseline.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
-
- DeprecatedKoinApi:SettingsModule.kt$viewModel { SettingsViewModel( contentReader = get(), cacheCleaner = get(), userRepository = get(), authRepository = get(), conversationRepository = get(), themeDataStore = get(), serverDataStore = get(), settingsDataStore = get(), mcpRepository = get(), memoryRepository = get(), speechSettingsFactory = get(), balanceRepository = get(), shareRepository = get(), keyRepository = get(), ) }
- FunctionNaming:String0.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString0Resources(map: MutableMap<String, StringResource>)
- FunctionNaming:String1.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString1Resources(map: MutableMap<String, StringResource>)
- FunctionNaming:String2.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString2Resources(map: MutableMap<String, StringResource>)
- ImportOrdering:AccountSection.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer 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.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.CameraAlt import androidx.compose.material.icons.filled.Person import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:AccountSettingsScreen.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight import androidx.compose.material.icons.filled.CameraAlt import androidx.compose.material.icons.filled.Key import androidx.compose.material.icons.filled.Person import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarResult import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import coil3.compose.AsyncImage import com.garfiec.librechat.core.ui.components.ErrorBanner import com.garfiec.librechat.core.ui.components.LoadingIndicator import com.garfiec.librechat.core.ui.components.OtpVerificationDialog import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.* import com.garfiec.librechat.feature.settings.screen.sections.BackupCodesDialog import com.garfiec.librechat.feature.settings.screen.sections.TwoFactorCodeDialog import com.garfiec.librechat.feature.settings.screen.sections.TwoFactorSetupDialog import com.garfiec.librechat.feature.settings.viewmodel.SettingsViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:ApiKeyCreateDialog.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ContentCopy import androidx.compose.material3.AlertDialog import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import com.garfiec.librechat.feature.settings.util.copyToClipboard import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.model.ApiKey import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:ApiKeysScreen.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Key import androidx.compose.material3.AlertDialog import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.garfiec.librechat.core.model.ApiKey import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.* import com.garfiec.librechat.feature.settings.viewmodel.ApiKeysViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:AppearanceSection.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer 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.selection.selectable import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Tablet import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.RadioButton import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.data.datastore.ThemeMode import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:BalanceSection.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer 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.material.icons.Icons import androidx.compose.material.icons.filled.AccountBalanceWallet import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:ChatPreferencesSection.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:ChatSettingsScreen.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.Chat import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight import androidx.compose.material.icons.filled.Brush import androidx.compose.material.icons.filled.Terminal import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.* import com.garfiec.librechat.feature.settings.viewmodel.SettingsViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:ChatSettingsSection.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.RadioButton import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.common.ChatLayoutConstants import com.garfiec.librechat.core.data.datastore.ChatFontSize import com.garfiec.librechat.core.data.datastore.LatexRenderer import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:CommandsConfigScreen.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:DataManagementDelegate.kt$import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.feature.settings.util.PlatformCacheCleaner import com.garfiec.librechat.core.data.repository.ConversationRepository import com.garfiec.librechat.core.data.repository.KeyRepository import com.garfiec.librechat.core.data.repository.ShareRepository import com.garfiec.librechat.core.model.SharedLink import com.garfiec.librechat.feature.settings.model.SharedLinkDisplayData import com.garfiec.librechat.feature.settings.viewmodel.SettingsStateHandle import kotlinx.coroutines.launch
- ImportOrdering:DataManagementSection.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:DataSettingsScreen.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight import androidx.compose.material3.AlertDialog import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.* import com.garfiec.librechat.feature.settings.viewmodel.SettingsViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:DataSettingsSection.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight import androidx.compose.material.icons.filled.Archive import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:ExpectResourceCollectors.kt$import kotlin.String import kotlin.collections.Map import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.FontResource import org.jetbrains.compose.resources.PluralStringResource import org.jetbrains.compose.resources.StringArrayResource import org.jetbrains.compose.resources.StringResource
- ImportOrdering:ForkSettingsDialog.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.AlertDialog import androidx.compose.material3.MaterialTheme import androidx.compose.material3.RadioButton import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.model.request.ForkOption import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:GeneralSettingsScreen.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight import androidx.compose.material.icons.filled.Language import androidx.compose.material.icons.filled.Person import androidx.compose.material.icons.filled.Tablet import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.RadioButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.vector.ImageVector import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.garfiec.librechat.core.data.datastore.ThemeMode import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.* import com.garfiec.librechat.feature.settings.viewmodel.SettingsViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:LanguageSelectorDialog.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Check import androidx.compose.material3.AlertDialog import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:McpServerDelegate.kt$import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.core.data.repository.McpRepository import com.garfiec.librechat.core.model.mcp.McpApiKeyConfig import com.garfiec.librechat.core.model.mcp.McpOAuthConfig import com.garfiec.librechat.core.model.mcp.McpServer import com.garfiec.librechat.core.model.mcp.McpServerType import com.garfiec.librechat.feature.settings.viewmodel.SettingsStateHandle import kotlinx.coroutines.launch import co.touchlab.kermit.Logger
- ImportOrdering:McpServersScreen.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Build import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.Refresh import androidx.compose.material3.AlertDialog import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarResult import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.garfiec.librechat.core.model.mcp.McpServer import com.garfiec.librechat.core.model.mcp.McpServerStatus import com.garfiec.librechat.core.ui.components.ErrorBanner import com.garfiec.librechat.core.ui.components.LoadingIndicator import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.* import com.garfiec.librechat.feature.settings.viewmodel.McpViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:McpSettingsSection.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.Refresh import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.model.mcp.McpServer import com.garfiec.librechat.core.model.mcp.McpServerStatus import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:McpToolList.kt$import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.expandVertically import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Build import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material.icons.filled.KeyboardArrowUp import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.model.mcp.McpTool import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:McpToolsSheet.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.model.mcp.McpTool import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:McpViewModel.kt$import androidx.compose.runtime.Immutable import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.core.data.repository.McpRepository import com.garfiec.librechat.core.model.mcp.McpApiKeyConfig import com.garfiec.librechat.core.model.mcp.McpOAuthConfig import com.garfiec.librechat.core.model.mcp.McpServer import com.garfiec.librechat.core.model.mcp.McpServerStatus import com.garfiec.librechat.core.model.mcp.McpServerType import com.garfiec.librechat.core.model.mcp.McpTool import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import co.touchlab.kermit.Logger
- ImportOrdering:MemoriesScreen.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Edit import androidx.compose.material3.AlertDialog import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarResult import androidx.compose.material3.Surface import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.garfiec.librechat.core.model.Memory import com.garfiec.librechat.core.ui.components.ErrorBanner import com.garfiec.librechat.core.ui.components.LoadingIndicator import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.* import com.garfiec.librechat.feature.settings.viewmodel.MemoriesViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:MemoriesSettingsSection.kt$import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Edit import androidx.compose.material3.AlertDialog import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.model.Memory import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:MemoryEditDialog.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.material3.AlertDialog import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.model.Memory import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:MemoryManagementDelegate.kt$import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.core.data.repository.MemoryRepository import com.garfiec.librechat.core.model.Memory import com.garfiec.librechat.core.model.request.CreateMemoryRequest import com.garfiec.librechat.core.model.request.UpdateMemoryPreferencesRequest import com.garfiec.librechat.core.model.request.UpdateMemoryRequest import com.garfiec.librechat.feature.settings.viewmodel.SettingsStateHandle import kotlinx.coroutines.launch import co.touchlab.kermit.Logger
- ImportOrdering:PersonalizationDialog.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.width import androidx.compose.material3.AlertDialog import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:PresetManagerScreen.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Tune import androidx.compose.material3.AlertDialog import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.garfiec.librechat.core.ui.components.EmptyState import com.garfiec.librechat.core.ui.components.LoadingIndicator import com.garfiec.librechat.feature.settings.model.PresetManagerDisplayData import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.* import com.garfiec.librechat.feature.settings.viewmodel.PresetManagerViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:Res.kt$import kotlin.ByteArray import kotlin.OptIn import kotlin.String import kotlin.Suppress import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.getResourceUri import org.jetbrains.compose.resources.readResourceBytes
- ImportOrdering:SecuritySection.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.CheckCircle import androidx.compose.material.icons.filled.Warning import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:SecuritySection.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.material3.AlertDialog import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:SettingsScreen.kt$import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.Chat import androidx.compose.material.icons.filled.Key import androidx.compose.material.icons.filled.Language import androidx.compose.material.icons.filled.Person import androidx.compose.material.icons.filled.Terminal import androidx.compose.material3.AlertDialog import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarResult import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.garfiec.librechat.core.ui.components.ErrorBanner import com.garfiec.librechat.core.ui.components.LoadingIndicator import com.garfiec.librechat.core.ui.components.OtpVerificationDialog import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.* import com.garfiec.librechat.feature.settings.screen.sections.AboutInfo import com.garfiec.librechat.feature.settings.screen.sections.AccountInfo import com.garfiec.librechat.feature.settings.screen.sections.BackupCodesDialog import com.garfiec.librechat.feature.settings.screen.sections.DangerZone import com.garfiec.librechat.feature.settings.screen.sections.DataExtraActions import com.garfiec.librechat.feature.settings.screen.sections.SettingsRow import com.garfiec.librechat.feature.settings.screen.sections.SpeechDetailButtons import com.garfiec.librechat.feature.settings.screen.sections.TabletSidebarGestureToggle import com.garfiec.librechat.feature.settings.screen.sections.ThemeSelector import com.garfiec.librechat.feature.settings.screen.sections.TwoFactorCodeDialog import com.garfiec.librechat.feature.settings.screen.sections.TwoFactorSetupDialog import com.garfiec.librechat.feature.settings.viewmodel.SettingsViewModel import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:SettingsViewModel.kt$import androidx.compose.runtime.Immutable import com.garfiec.librechat.feature.settings.util.ContentReader import com.garfiec.librechat.feature.settings.util.PlatformCacheCleaner import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.garfiec.librechat.core.common.ChatLayoutConstants import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.core.data.datastore.ChatFontSize import com.garfiec.librechat.core.data.datastore.LatexRenderer import com.garfiec.librechat.core.data.datastore.ServerDataStore import com.garfiec.librechat.core.data.datastore.SettingsDataStore import com.garfiec.librechat.core.data.datastore.ThemeDataStore import com.garfiec.librechat.core.data.datastore.ThemeMode import com.garfiec.librechat.core.data.repository.AuthRepository import com.garfiec.librechat.core.data.repository.BalanceRepository import com.garfiec.librechat.core.data.repository.ConversationRepository import com.garfiec.librechat.core.data.repository.KeyRepository import com.garfiec.librechat.core.data.repository.McpRepository import com.garfiec.librechat.core.data.repository.MemoryRepository import com.garfiec.librechat.core.data.repository.ShareRepository import com.garfiec.librechat.core.data.repository.SpeechRepository import com.garfiec.librechat.core.data.repository.UserRepository import com.garfiec.librechat.core.model.Memory import com.garfiec.librechat.core.model.User import com.garfiec.librechat.core.model.mcp.McpApiKeyConfig import com.garfiec.librechat.core.model.mcp.McpOAuthConfig import com.garfiec.librechat.core.model.mcp.McpServer import com.garfiec.librechat.core.model.mcp.McpServerStatus import com.garfiec.librechat.core.model.mcp.McpServerType import com.garfiec.librechat.core.model.speech.TtsVoice import com.garfiec.librechat.feature.settings.model.SharedLinkDisplayData import com.garfiec.librechat.feature.settings.model.UserDisplayData import com.garfiec.librechat.feature.settings.screen.DeviceVoiceInfo import com.garfiec.librechat.feature.settings.viewmodel.delegate.DataManagementDelegate import com.garfiec.librechat.feature.settings.viewmodel.delegate.McpServerDelegate import com.garfiec.librechat.feature.settings.viewmodel.delegate.MemoryManagementDelegate import com.garfiec.librechat.feature.settings.viewmodel.delegate.SpeechSettingsFactory import com.garfiec.librechat.feature.settings.viewmodel.delegate.TwoFactorSecurityDelegate import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import co.touchlab.kermit.Logger
- ImportOrdering:SharedLinksScreen.kt$import com.garfiec.librechat.feature.settings.util.copyToClipboard import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.ContentCopy import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Link import androidx.compose.material.icons.filled.Visibility import androidx.compose.material.icons.filled.VisibilityOff import androidx.compose.material3.AlertDialog import androidx.compose.material3.Card import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.ui.components.EmptyState import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.* import com.garfiec.librechat.feature.settings.model.SharedLinkDisplayData
- ImportOrdering:SpeechDetailDialogs.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.PlayArrow import androidx.compose.material.icons.filled.Stop import androidx.compose.material3.AlertDialog import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExposedDropdownMenuBox import androidx.compose.material3.ExposedDropdownMenuDefaults import androidx.compose.material3.FilledTonalButton import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MenuAnchorType import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Slider import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:SpeechSection.kt$import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.unit.dp import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:SpeechSettingsSection.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.material3.Button import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExposedDropdownMenuBox import androidx.compose.material3.ExposedDropdownMenuDefaults import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MenuAnchorType import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import com.garfiec.librechat.core.model.speech.TtsVoice import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.*
- ImportOrdering:String0.commonMain.kt$import kotlin.OptIn import kotlin.String import kotlin.collections.MutableMap import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.ResourceContentHash import org.jetbrains.compose.resources.ResourceItem import org.jetbrains.compose.resources.StringResource
- ImportOrdering:String1.commonMain.kt$import kotlin.OptIn import kotlin.String import kotlin.collections.MutableMap import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.ResourceContentHash import org.jetbrains.compose.resources.ResourceItem import org.jetbrains.compose.resources.StringResource
- ImportOrdering:String2.commonMain.kt$import kotlin.OptIn import kotlin.String import kotlin.collections.MutableMap import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.ResourceContentHash import org.jetbrains.compose.resources.ResourceItem import org.jetbrains.compose.resources.StringResource
- ImportOrdering:TabbedSettingsScreen.kt$import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Scaffold import androidx.compose.material3.SecondaryTabRow import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Tab import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import librechat_mobile.feature.settings.generated.resources.Res import librechat_mobile.feature.settings.generated.resources.* import com.garfiec.librechat.feature.settings.viewmodel.SettingsViewModel import kotlinx.coroutines.launch import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:TwoFactorSecurityDelegate.kt$import com.garfiec.librechat.core.common.result.Result import com.garfiec.librechat.feature.settings.viewmodel.isHttpStatus import com.garfiec.librechat.core.data.repository.AuthRepository import com.garfiec.librechat.feature.settings.viewmodel.SettingsStateHandle import kotlinx.coroutines.launch
- LambdaParameterInRestartableEffect:AccountSettingsScreen.kt$onLogout
- LambdaParameterInRestartableEffect:SettingsScreen.kt$onLogout
- LambdaParameterInRestartableEffect:SharedLinksScreen.kt$onLoadMore
- MaxLineLength:Res.kt$Res$public suspend
- ModifierNotUsedAtRoot:AccountSettingsScreen.kt$modifier = modifier
- ModifierNotUsedAtRoot:AccountSettingsScreen.kt$modifier = modifier.fillMaxSize()
- ModifierNotUsedAtRoot:ChatSettingsScreen.kt$modifier = modifier.fillMaxSize()
- ModifierNotUsedAtRoot:DataSettingsScreen.kt$modifier = modifier.fillMaxSize()
- ModifierNotUsedAtRoot:GeneralSettingsScreen.kt$modifier = modifier.fillMaxSize()
- NoUnusedImports:SettingsViewModel.kt$com.garfiec.librechat.feature.settings.viewmodel.SettingsViewModel.kt
- PackageName:ExpectResourceCollectors.kt$package librechat_mobile.feature.settings.generated.resources
- PackageName:Res.kt$package librechat_mobile.feature.settings.generated.resources
- PackageName:String0.commonMain.kt$package librechat_mobile.feature.settings.generated.resources
- PackageName:String1.commonMain.kt$package librechat_mobile.feature.settings.generated.resources
- PackageName:String2.commonMain.kt$package librechat_mobile.feature.settings.generated.resources
- PackageNaming:ExpectResourceCollectors.kt$package librechat_mobile.feature.settings.generated.resources
- PackageNaming:Res.kt$package librechat_mobile.feature.settings.generated.resources
- PackageNaming:String0.commonMain.kt$package librechat_mobile.feature.settings.generated.resources
- PackageNaming:String1.commonMain.kt$package librechat_mobile.feature.settings.generated.resources
- PackageNaming:String2.commonMain.kt$package librechat_mobile.feature.settings.generated.resources
- ParameterNaming:DataSettingsScreen.kt$onNavigateToArchived
- ParameterNaming:DataSettingsSection.kt$onViewArchived
- ParameterNaming:ForkSettingsDialog.kt$onModeSelected
- ParameterNaming:LanguageSelectorDialog.kt$onLanguageSelected
- ParameterNaming:MemoriesSettingsSection.kt$onToggleEnabled
- ParameterNaming:SettingsScreen.kt$onNavigateToArchived
- ParameterNaming:SpeechSettingsSection.kt$onVoiceSelected
- ParameterNaming:TabbedSettingsScreen.kt$onNavigateToArchived
- SpacingBetweenDeclarationsWithAnnotations:SettingsNavigation.kt$ApiKeys : SettingsRoute
- SpacingBetweenDeclarationsWithAnnotations:SettingsNavigation.kt$PresetManager : SettingsRoute
- SpacingBetweenDeclarationsWithAnnotations:SettingsNavigation.kt$SettingsAccount : SettingsRoute
- SpacingBetweenDeclarationsWithAnnotations:SettingsNavigation.kt$SettingsChat : SettingsRoute
- SpacingBetweenDeclarationsWithAnnotations:SettingsNavigation.kt$SettingsData : SettingsRoute
- SpacingBetweenDeclarationsWithAnnotations:SettingsNavigation.kt$SettingsGeneral : SettingsRoute
- SpacingBetweenDeclarationsWithAnnotations:SettingsNavigation.kt$SharedLinks : SettingsRoute
- ViewModelForwarding:AccountSettingsScreen.kt$AccountSettingsContent( onLogout = onLogout, onNavigateToApiKeys = onNavigateToApiKeys, snackbarHostState = snackbarHostState, modifier = Modifier .fillMaxSize() .padding(innerPadding), viewModel = viewModel, )
- ViewModelForwarding:ChatSettingsScreen.kt$ChatSettingsContent( onNavigateToPresets = onNavigateToPresets, modifier = Modifier .fillMaxSize() .padding(innerPadding), viewModel = viewModel, )
- ViewModelForwarding:DataSettingsScreen.kt$DataSettingsContent( onNavigateToArchived = onNavigateToArchived, onNavigateToSharedLinks = onNavigateToSharedLinks, snackbarHostState = snackbarHostState, modifier = Modifier .fillMaxSize() .padding(innerPadding), viewModel = viewModel, )
- ViewModelForwarding:GeneralSettingsScreen.kt$GeneralSettingsContent( modifier = Modifier .fillMaxSize() .padding(innerPadding), viewModel = viewModel, )
- ViewModelForwarding:TabbedSettingsScreen.kt$AccountSettingsContent( onLogout = onLogout, onNavigateToApiKeys = onNavigateToApiKeys, snackbarHostState = snackbarHostState, modifier = Modifier.fillMaxSize(), viewModel = viewModel, )
- ViewModelForwarding:TabbedSettingsScreen.kt$ChatSettingsContent( onNavigateToPresets = onNavigateToPresets, modifier = Modifier.fillMaxSize(), viewModel = viewModel, )
- ViewModelForwarding:TabbedSettingsScreen.kt$DataSettingsContent( onNavigateToArchived = onNavigateToArchived, onNavigateToSharedLinks = onNavigateToSharedLinks, snackbarHostState = snackbarHostState, modifier = Modifier.fillMaxSize(), viewModel = viewModel, )
- ViewModelForwarding:TabbedSettingsScreen.kt$GeneralSettingsContent( modifier = Modifier.fillMaxSize(), viewModel = viewModel, )
-
-
diff --git a/feature/settings/src/androidMain/kotlin/com/garfiec/librechat/feature/settings/screen/AvatarUploadDialog.kt b/feature/settings/src/androidMain/kotlin/com/garfiec/librechat/feature/settings/screen/AvatarUploadDialog.kt
index 21d8518..b2ba3ad 100644
--- a/feature/settings/src/androidMain/kotlin/com/garfiec/librechat/feature/settings/screen/AvatarUploadDialog.kt
+++ b/feature/settings/src/androidMain/kotlin/com/garfiec/librechat/feature/settings/screen/AvatarUploadDialog.kt
@@ -30,13 +30,13 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
internal actual fun AvatarUploadDialog(
diff --git a/feature/settings/src/androidMain/kotlin/com/garfiec/librechat/feature/settings/util/PlatformClipboard.android.kt b/feature/settings/src/androidMain/kotlin/com/garfiec/librechat/feature/settings/util/PlatformClipboard.android.kt
index 4798218..fe64f49 100644
--- a/feature/settings/src/androidMain/kotlin/com/garfiec/librechat/feature/settings/util/PlatformClipboard.android.kt
+++ b/feature/settings/src/androidMain/kotlin/com/garfiec/librechat/feature/settings/util/PlatformClipboard.android.kt
@@ -3,8 +3,6 @@ package com.garfiec.librechat.feature.settings.util
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
-import org.koin.core.component.KoinComponent
-import org.koin.core.component.inject
import org.koin.mp.KoinPlatformTools
actual fun copyToClipboard(text: String, label: String) {
diff --git a/feature/settings/src/androidMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/SpeechSettingsDelegate.kt b/feature/settings/src/androidMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/SpeechSettingsDelegate.kt
index c272bb6..a633063 100644
--- a/feature/settings/src/androidMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/SpeechSettingsDelegate.kt
+++ b/feature/settings/src/androidMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/SpeechSettingsDelegate.kt
@@ -4,6 +4,7 @@ import android.content.Context
import android.media.MediaPlayer
import android.speech.tts.TextToSpeech
import android.speech.tts.UtteranceProgressListener
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.datastore.SettingsDataStore
import com.garfiec.librechat.core.data.repository.SpeechRepository
@@ -11,7 +12,6 @@ import com.garfiec.librechat.core.model.speech.TtsVoice
import com.garfiec.librechat.feature.settings.screen.DeviceVoiceInfo
import com.garfiec.librechat.feature.settings.viewmodel.SettingsStateHandle
import kotlinx.coroutines.launch
-import co.touchlab.kermit.Logger
import java.io.File
/**
diff --git a/feature/settings/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/settings/di/SettingsModuleVerificationTest.kt b/feature/settings/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/settings/di/SettingsModuleVerificationTest.kt
index 8de0844..0fc47d7 100644
--- a/feature/settings/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/settings/di/SettingsModuleVerificationTest.kt
+++ b/feature/settings/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/settings/di/SettingsModuleVerificationTest.kt
@@ -2,7 +2,6 @@ package com.garfiec.librechat.feature.settings.di
import android.app.Application
import android.content.Context
-import androidx.lifecycle.SavedStateHandle
import com.garfiec.librechat.core.data.datastore.ServerDataStore
import com.garfiec.librechat.core.data.datastore.SettingsDataStore
import com.garfiec.librechat.core.data.datastore.ThemeDataStore
@@ -30,7 +29,6 @@ class SettingsModuleVerificationTest {
extraTypes = listOf(
Context::class,
Application::class,
- SavedStateHandle::class,
UserRepository::class,
AuthRepository::class,
ConversationRepository::class,
diff --git a/feature/settings/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/settings/viewmodel/SettingsViewModelTest.kt b/feature/settings/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/settings/viewmodel/SettingsViewModelTest.kt
index f1aa865..a08a215 100644
--- a/feature/settings/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/settings/viewmodel/SettingsViewModelTest.kt
+++ b/feature/settings/src/androidUnitTest/kotlin/com/garfiec/librechat/feature/settings/viewmodel/SettingsViewModelTest.kt
@@ -1,10 +1,5 @@
package com.garfiec.librechat.feature.settings.viewmodel
-import com.google.common.truth.Truth.assertThat
-import com.garfiec.librechat.feature.settings.util.ContentReader
-import com.garfiec.librechat.feature.settings.util.PlatformCacheCleaner
-import com.garfiec.librechat.feature.settings.viewmodel.delegate.SpeechSettingsContract
-import com.garfiec.librechat.feature.settings.viewmodel.delegate.SpeechSettingsFactory
import com.garfiec.librechat.core.common.ChatLayoutConstants
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.datastore.ChatFontSize
@@ -23,6 +18,11 @@ import com.garfiec.librechat.core.data.repository.ShareRepository
import com.garfiec.librechat.core.data.repository.SpeechRepository
import com.garfiec.librechat.core.data.repository.UserRepository
import com.garfiec.librechat.core.model.User
+import com.garfiec.librechat.feature.settings.util.ContentReader
+import com.garfiec.librechat.feature.settings.util.PlatformCacheCleaner
+import com.garfiec.librechat.feature.settings.viewmodel.delegate.SpeechSettingsContract
+import com.garfiec.librechat.feature.settings.viewmodel.delegate.SpeechSettingsFactory
+import com.google.common.truth.Truth.assertThat
import io.mockk.Ordering
import io.mockk.coEvery
import io.mockk.coVerify
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/di/SettingsModule.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/di/SettingsModule.kt
index 39438d6..76c1ae8 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/di/SettingsModule.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/di/SettingsModule.kt
@@ -6,7 +6,6 @@ import com.garfiec.librechat.feature.settings.viewmodel.MemoriesViewModel
import com.garfiec.librechat.feature.settings.viewmodel.PresetManagerViewModel
import com.garfiec.librechat.feature.settings.viewmodel.SettingsViewModel
import org.koin.core.module.Module
-import org.koin.core.module.dsl.viewModel
import org.koin.core.module.dsl.viewModelOf
import org.koin.dsl.module
@@ -15,24 +14,7 @@ expect val settingsPlatformModule: Module
val settingsModule = module {
includes(settingsPlatformModule)
- viewModel {
- SettingsViewModel(
- contentReader = get(),
- cacheCleaner = get(),
- userRepository = get(),
- authRepository = get(),
- conversationRepository = get(),
- themeDataStore = get(),
- serverDataStore = get(),
- settingsDataStore = get(),
- mcpRepository = get(),
- memoryRepository = get(),
- speechSettingsFactory = get(),
- balanceRepository = get(),
- shareRepository = get(),
- keyRepository = get(),
- )
- }
+ viewModelOf(::SettingsViewModel)
viewModelOf(::ApiKeysViewModel)
viewModelOf(::MemoriesViewModel)
viewModelOf(::McpViewModel)
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/navigation/SettingsNavigation.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/navigation/SettingsNavigation.kt
index 3db073d..0349a5d 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/navigation/SettingsNavigation.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/navigation/SettingsNavigation.kt
@@ -22,25 +22,32 @@ import org.koin.compose.viewmodel.koinViewModel
@Serializable sealed interface SettingsRoute : NavKey
@Serializable data object SettingsTabbed : SettingsRoute
+
@Serializable data object SettingsGeneral : SettingsRoute
+
@Serializable data object SettingsChat : SettingsRoute
+
@Serializable data object SettingsAccount : SettingsRoute
+
@Serializable data object SettingsData : SettingsRoute
+
@Serializable data object SharedLinks : SettingsRoute
+
@Serializable data object PresetManager : SettingsRoute
+
@Serializable data object ApiKeys : SettingsRoute
fun EntryProviderScope.settingsEntries(
onNavigate: (NavKey) -> Unit,
onBack: () -> Unit,
onLogout: () -> Unit,
- onNavigateToArchived: () -> Unit = {},
+ onNavigateToArchive: () -> Unit = {},
) {
entry {
TabbedSettingsScreen(
onNavigateBack = onBack,
onLogout = onLogout,
- onNavigateToArchived = onNavigateToArchived,
+ onNavigateToArchive = onNavigateToArchive,
onNavigateToSharedLinks = { onNavigate(SharedLinks) },
onNavigateToPresets = { onNavigate(PresetManager) },
onNavigateToApiKeys = { onNavigate(ApiKeys) },
@@ -67,7 +74,7 @@ fun EntryProviderScope.settingsEntries(
entry {
DataSettingsScreen(
onNavigateBack = onBack,
- onNavigateToArchived = onNavigateToArchived,
+ onNavigateToArchive = onNavigateToArchive,
onNavigateToSharedLinks = { onNavigate(SharedLinks) },
)
}
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/AccountSettingsScreen.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/AccountSettingsScreen.kt
index e5dd1dc..50ae947 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/AccountSettingsScreen.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/AccountSettingsScreen.kt
@@ -40,13 +40,13 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextOverflow
@@ -56,12 +56,13 @@ import coil3.compose.AsyncImage
import com.garfiec.librechat.core.ui.components.ErrorBanner
import com.garfiec.librechat.core.ui.components.LoadingIndicator
import com.garfiec.librechat.core.ui.components.OtpVerificationDialog
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
import com.garfiec.librechat.feature.settings.screen.sections.BackupCodesDialog
import com.garfiec.librechat.feature.settings.screen.sections.TwoFactorCodeDialog
import com.garfiec.librechat.feature.settings.screen.sections.TwoFactorSetupDialog
import com.garfiec.librechat.feature.settings.viewmodel.SettingsViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@OptIn(ExperimentalMaterial3Api::class)
@@ -71,7 +72,6 @@ fun AccountSettingsScreen(
onNavigateBack: () -> Unit,
onNavigateToApiKeys: () -> Unit,
modifier: Modifier = Modifier,
- viewModel: SettingsViewModel = koinViewModel(),
) {
val snackbarHostState = remember { SnackbarHostState() }
@@ -99,7 +99,6 @@ fun AccountSettingsScreen(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding),
- viewModel = viewModel,
)
}
}
@@ -117,6 +116,7 @@ fun AccountSettingsContent(
viewModel: SettingsViewModel = koinViewModel(),
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
+ val currentOnLogout by rememberUpdatedState(onLogout)
var showDeleteDialog by remember { mutableStateOf(false) }
var showLogoutDialog by remember { mutableStateOf(false) }
@@ -135,22 +135,21 @@ fun AccountSettingsContent(
LaunchedEffect(uiState.isLoggedOut, uiState.isAccountDeleted) {
if (uiState.isLoggedOut || uiState.isAccountDeleted) {
- onLogout()
+ currentOnLogout()
}
}
- Column {
+ Column(modifier = modifier) {
if (uiState.isLoading && uiState.user == null) {
LoadingIndicator()
} else if (uiState.error != null && uiState.user == null) {
ErrorBanner(
message = uiState.error ?: stringResource(Res.string.error_could_not_load_settings),
- modifier = modifier,
onRetry = { viewModel.retry() },
)
} else {
LazyColumn(
- modifier = modifier.fillMaxSize(),
+ modifier = Modifier.fillMaxSize(),
) {
// Account section
item(key = "account_header") {
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ApiKeyCreateDialog.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ApiKeyCreateDialog.kt
index f193ff9..09840bc 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ApiKeyCreateDialog.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ApiKeyCreateDialog.kt
@@ -22,14 +22,14 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
-import com.garfiec.librechat.feature.settings.util.copyToClipboard
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.ApiKey
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import com.garfiec.librechat.feature.settings.util.copyToClipboard
+import org.jetbrains.compose.resources.stringResource
/**
* Two-phase API key creation dialog.
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ApiKeysScreen.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ApiKeysScreen.kt
index 0cc6db9..3bad53e 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ApiKeysScreen.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ApiKeysScreen.kt
@@ -20,6 +20,7 @@ import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Key
import androidx.compose.material3.AlertDialog
+import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator
@@ -31,7 +32,6 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
-import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBar
@@ -44,14 +44,14 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.garfiec.librechat.core.model.ApiKey
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
import com.garfiec.librechat.feature.settings.viewmodel.ApiKeysViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
/** Lists user API keys with create (FAB), delete, and pull-to-refresh. */
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/BalanceSection.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/BalanceSection.kt
index 3833628..f353eb1 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/BalanceSection.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/BalanceSection.kt
@@ -20,12 +20,12 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
internal fun BalanceSection(
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ChatSettingsScreen.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ChatSettingsScreen.kt
index 066ff9f..49392cf 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ChatSettingsScreen.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ChatSettingsScreen.kt
@@ -33,14 +33,14 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
import com.garfiec.librechat.feature.settings.viewmodel.SettingsViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@OptIn(ExperimentalMaterial3Api::class)
@@ -49,7 +49,6 @@ fun ChatSettingsScreen(
onNavigateBack: () -> Unit,
onNavigateToPresets: () -> Unit,
modifier: Modifier = Modifier,
- viewModel: SettingsViewModel = koinViewModel(),
) {
Scaffold(
modifier = modifier,
@@ -72,7 +71,6 @@ fun ChatSettingsScreen(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding),
- viewModel = viewModel,
)
}
}
@@ -89,9 +87,9 @@ fun ChatSettingsContent(
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
- Box {
+ Box(modifier = modifier) {
LazyColumn(
- modifier = modifier.fillMaxSize(),
+ modifier = Modifier.fillMaxSize(),
) {
// Chat Preferences section
item(key = "chat_header") {
@@ -167,7 +165,7 @@ fun ChatSettingsContent(
ttsSource = uiState.ttsSource,
onAutoSendAfterSttChange = viewModel::setAutoSendAfterStt,
onAutoReadChange = viewModel::setAutoReadEnabled,
- onVoiceSelected = viewModel::selectVoice,
+ onVoiceSelect = viewModel::selectVoice,
onTestVoice = viewModel::testVoice,
)
}
@@ -186,7 +184,7 @@ fun ChatSettingsContent(
if (uiState.showForkSettingsDialog) {
ForkSettingsDialog(
selectedMode = ForkMode.fromApiValue(uiState.forkMode),
- onModeSelected = { mode ->
+ onModeSelect = { mode ->
viewModel.setForkMode(mode.apiValue)
},
onDismiss = viewModel::dismissForkSettingsDialog,
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ChatSettingsSection.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ChatSettingsSection.kt
index 5c638eb..f197ea0 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ChatSettingsSection.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ChatSettingsSection.kt
@@ -18,14 +18,14 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.common.ChatLayoutConstants
import com.garfiec.librechat.core.data.datastore.ChatFontSize
import com.garfiec.librechat.core.data.datastore.LatexRenderer
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
internal fun ChatSettingsSection(
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/CommandsConfigScreen.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/CommandsConfigScreen.kt
index f41e346..084c007 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/CommandsConfigScreen.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/CommandsConfigScreen.kt
@@ -23,10 +23,10 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
data class CommandConfig(
val name: String,
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/DataSettingsScreen.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/DataSettingsScreen.kt
index ea3ce11..a6220b3 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/DataSettingsScreen.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/DataSettingsScreen.kt
@@ -35,24 +35,23 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
import com.garfiec.librechat.feature.settings.viewmodel.SettingsViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DataSettingsScreen(
onNavigateBack: () -> Unit,
- onNavigateToArchived: () -> Unit,
+ onNavigateToArchive: () -> Unit,
onNavigateToSharedLinks: () -> Unit,
modifier: Modifier = Modifier,
- viewModel: SettingsViewModel = koinViewModel(),
) {
val snackbarHostState = remember { SnackbarHostState() }
@@ -74,13 +73,12 @@ fun DataSettingsScreen(
},
) { innerPadding ->
DataSettingsContent(
- onNavigateToArchived = onNavigateToArchived,
+ onNavigateToArchive = onNavigateToArchive,
onNavigateToSharedLinks = onNavigateToSharedLinks,
snackbarHostState = snackbarHostState,
modifier = Modifier
.fillMaxSize()
.padding(innerPadding),
- viewModel = viewModel,
)
}
}
@@ -91,7 +89,7 @@ fun DataSettingsScreen(
*/
@Composable
fun DataSettingsContent(
- onNavigateToArchived: () -> Unit,
+ onNavigateToArchive: () -> Unit,
onNavigateToSharedLinks: () -> Unit,
modifier: Modifier = Modifier,
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
@@ -121,9 +119,9 @@ fun DataSettingsContent(
viewModel.dismissMcpReinitializeMessage()
}
- Column {
+ Column(modifier = modifier) {
LazyColumn(
- modifier = modifier.fillMaxSize(),
+ modifier = Modifier.fillMaxSize(),
) {
// Conversations section
item(key = "conversations_header") {
@@ -134,7 +132,7 @@ fun DataSettingsContent(
archivedCount = uiState.archivedCount,
isClearing = uiState.isClearing,
onClearAllChats = viewModel::clearAllChats,
- onViewArchived = onNavigateToArchived,
+ onViewArchive = onNavigateToArchive,
onExportAllData = viewModel::exportAllData,
)
}
@@ -158,7 +156,7 @@ fun DataSettingsContent(
memoriesEnabled = uiState.memoriesEnabled,
showMemoryDialog = uiState.showMemoryDialog,
editingMemory = uiState.editingMemory,
- onToggleEnabled = viewModel::toggleMemoriesEnabled,
+ onToggleEnable = viewModel::toggleMemoriesEnabled,
onAddMemory = viewModel::showAddMemoryDialog,
onEditMemory = viewModel::showEditMemoryDialog,
onDeleteMemory = viewModel::deleteMemory,
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/DataSettingsSection.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/DataSettingsSection.kt
index 6666e18..36dd3e5 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/DataSettingsSection.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/DataSettingsSection.kt
@@ -27,17 +27,17 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
internal fun DataSettingsSection(
archivedCount: Int,
isClearing: Boolean,
onClearAllChats: () -> Unit,
- onViewArchived: () -> Unit,
+ onViewArchive: () -> Unit,
onExportAllData: () -> Unit,
modifier: Modifier = Modifier,
) {
@@ -65,7 +65,7 @@ internal fun DataSettingsSection(
// Archived conversations
OutlinedButton(
- onClick = onViewArchived,
+ onClick = onViewArchive,
modifier = Modifier.fillMaxWidth(),
) {
Row(
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ForkSettingsDialog.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ForkSettingsDialog.kt
index 448022b..6d8d8b5 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ForkSettingsDialog.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/ForkSettingsDialog.kt
@@ -21,12 +21,12 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.request.ForkOption
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
enum class ForkMode(val label: String, val description: String, val apiValue: String) {
DIRECT_PATH(
@@ -54,7 +54,7 @@ enum class ForkMode(val label: String, val description: String, val apiValue: St
@Composable
internal fun ForkSettingsDialog(
selectedMode: ForkMode,
- onModeSelected: (ForkMode) -> Unit,
+ onModeSelect: (ForkMode) -> Unit,
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
) {
@@ -100,7 +100,7 @@ internal fun ForkSettingsDialog(
}
},
confirmButton = {
- TextButton(onClick = { onModeSelected(currentMode) }) {
+ TextButton(onClick = { onModeSelect(currentMode) }) {
Text(stringResource(Res.string.action_save))
}
},
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/GeneralSettingsScreen.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/GeneralSettingsScreen.kt
index 1e4a171..233ee8e 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/GeneralSettingsScreen.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/GeneralSettingsScreen.kt
@@ -36,7 +36,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.ImageVector
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
@@ -44,9 +43,10 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.garfiec.librechat.core.data.datastore.ThemeMode
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
import com.garfiec.librechat.feature.settings.viewmodel.SettingsViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@OptIn(ExperimentalMaterial3Api::class)
@@ -54,7 +54,6 @@ import org.koin.compose.viewmodel.koinViewModel
fun GeneralSettingsScreen(
onNavigateBack: () -> Unit,
modifier: Modifier = Modifier,
- viewModel: SettingsViewModel = koinViewModel(),
) {
Scaffold(
modifier = modifier,
@@ -76,7 +75,6 @@ fun GeneralSettingsScreen(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding),
- viewModel = viewModel,
)
}
}
@@ -92,9 +90,9 @@ fun GeneralSettingsContent(
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
- Column {
+ Column(modifier = modifier) {
LazyColumn(
- modifier = modifier.fillMaxSize(),
+ modifier = Modifier.fillMaxSize(),
) {
// Appearance section
item(key = "appearance_header") {
@@ -164,7 +162,7 @@ fun GeneralSettingsContent(
if (uiState.showLanguageDialog) {
LanguageSelectorDialog(
selectedLanguage = uiState.selectedLanguage,
- onLanguageSelected = viewModel::setLanguage,
+ onLanguageSelect = viewModel::setLanguage,
onDismiss = viewModel::dismissLanguageDialog,
)
}
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/LanguageSelectorDialog.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/LanguageSelectorDialog.kt
index 93b4e15..944ee5d 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/LanguageSelectorDialog.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/LanguageSelectorDialog.kt
@@ -25,10 +25,10 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
data class LanguageOption(
val code: String,
@@ -80,7 +80,7 @@ private val SUPPORTED_LANGUAGES = listOf(
@Composable
internal fun LanguageSelectorDialog(
selectedLanguage: String,
- onLanguageSelected: (String) -> Unit,
+ onLanguageSelect: (String) -> Unit,
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
) {
@@ -120,7 +120,7 @@ internal fun LanguageSelectorDialog(
Row(
modifier = Modifier
.fillMaxWidth()
- .clickable { onLanguageSelected(language.code) }
+ .clickable { onLanguageSelect(language.code) }
.padding(vertical = 12.dp, horizontal = 4.dp),
verticalAlignment = Alignment.CenterVertically,
) {
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpServerDialog.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpServerDialog.kt
index ad9f597..ca7cc51 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpServerDialog.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpServerDialog.kt
@@ -37,8 +37,8 @@ import com.garfiec.librechat.core.model.mcp.McpAuthorizationType
import com.garfiec.librechat.core.model.mcp.McpOAuthConfig
import com.garfiec.librechat.core.model.mcp.McpServer
import com.garfiec.librechat.core.model.mcp.McpServerType
-import librechat_mobile.feature.settings.generated.resources.*
-import librechat_mobile.feature.settings.generated.resources.Res
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
import org.jetbrains.compose.resources.stringResource
/** Add/edit MCP server dialog with server type dropdown and auth configuration. */
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpServersScreen.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpServersScreen.kt
index 22ec819..953f572 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpServersScreen.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpServersScreen.kt
@@ -45,7 +45,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -53,9 +52,10 @@ import com.garfiec.librechat.core.model.mcp.McpServer
import com.garfiec.librechat.core.model.mcp.McpServerStatus
import com.garfiec.librechat.core.ui.components.ErrorBanner
import com.garfiec.librechat.core.ui.components.LoadingIndicator
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
import com.garfiec.librechat.feature.settings.viewmodel.McpViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
/** Manages MCP server connections with status indicators, CRUD, and tool browsing. */
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpSettingsSection.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpSettingsSection.kt
index d62a26c..44a5255 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpSettingsSection.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpSettingsSection.kt
@@ -25,13 +25,13 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.mcp.McpServer
import com.garfiec.librechat.core.model.mcp.McpServerStatus
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
internal fun McpSettingsSection(
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpToolList.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpToolList.kt
index 289dda4..6137518 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpToolList.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpToolList.kt
@@ -27,11 +27,11 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.mcp.McpTool
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
internal fun McpToolList(
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpToolsSheet.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpToolsSheet.kt
index 0601ddf..fffbd45 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpToolsSheet.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/McpToolsSheet.kt
@@ -16,13 +16,13 @@ import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.mcp.McpTool
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
/** Bottom sheet listing MCP tools grouped by server; optional serverFilter narrows to one server. */
@OptIn(ExperimentalMaterial3Api::class)
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/MemoriesScreen.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/MemoriesScreen.kt
index 39dabef..a56bad4 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/MemoriesScreen.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/MemoriesScreen.kt
@@ -43,7 +43,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextOverflow
@@ -52,9 +51,10 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.garfiec.librechat.core.model.Memory
import com.garfiec.librechat.core.ui.components.ErrorBanner
import com.garfiec.librechat.core.ui.components.LoadingIndicator
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
import com.garfiec.librechat.feature.settings.viewmodel.MemoriesViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
/** Full memory CRUD screen with PullToRefresh and dedicated MemoriesViewModel. */
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/MemoriesSettingsSection.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/MemoriesSettingsSection.kt
index db65c7a..870cad2 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/MemoriesSettingsSection.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/MemoriesSettingsSection.kt
@@ -31,14 +31,14 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.Memory
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
internal fun MemoriesSettingsSection(
@@ -46,7 +46,7 @@ internal fun MemoriesSettingsSection(
memoriesEnabled: Boolean,
showMemoryDialog: Boolean,
editingMemory: Memory?,
- onToggleEnabled: (Boolean) -> Unit,
+ onToggleEnable: (Boolean) -> Unit,
onAddMemory: () -> Unit,
onEditMemory: (Memory) -> Unit,
onDeleteMemory: (String) -> Unit,
@@ -81,7 +81,7 @@ internal fun MemoriesSettingsSection(
val toggleMemoriesCd = stringResource(Res.string.cd_toggle_memories)
Switch(
checked = memoriesEnabled,
- onCheckedChange = onToggleEnabled,
+ onCheckedChange = onToggleEnable,
modifier = Modifier.semantics {
contentDescription = toggleMemoriesCd
},
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/MemoryEditDialog.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/MemoryEditDialog.kt
index 2d530ba..1d0d3cb 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/MemoryEditDialog.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/MemoryEditDialog.kt
@@ -14,11 +14,11 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.Memory
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
/** Add/edit memory dialog; key field is immutable when editing an existing memory. */
@Composable
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/PersonalizationDialog.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/PersonalizationDialog.kt
index 00e1186..5ebee6d 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/PersonalizationDialog.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/PersonalizationDialog.kt
@@ -20,10 +20,10 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
/** "About you" and "Response style" text areas with enable toggle; fields disabled when off. */
@Composable
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/PresetManagerScreen.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/PresetManagerScreen.kt
index d6b9242..bf8920f 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/PresetManagerScreen.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/PresetManagerScreen.kt
@@ -35,16 +35,16 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.garfiec.librechat.core.ui.components.EmptyState
import com.garfiec.librechat.core.ui.components.LoadingIndicator
import com.garfiec.librechat.feature.settings.model.PresetManagerDisplayData
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
import com.garfiec.librechat.feature.settings.viewmodel.PresetManagerViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
/** Lists saved presets with delete-only management; editing reuses SavePresetDialog in chat. */
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SecuritySection.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SecuritySection.kt
index 7c79632..52361b6 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SecuritySection.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SecuritySection.kt
@@ -20,10 +20,10 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
internal fun SecuritySection(
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SettingsScreen.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SettingsScreen.kt
index 9947a4e..a16dae8 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SettingsScreen.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SettingsScreen.kt
@@ -30,9 +30,9 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
@@ -40,8 +40,8 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.garfiec.librechat.core.ui.components.ErrorBanner
import com.garfiec.librechat.core.ui.components.LoadingIndicator
import com.garfiec.librechat.core.ui.components.OtpVerificationDialog
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
import com.garfiec.librechat.feature.settings.screen.sections.AboutInfo
import com.garfiec.librechat.feature.settings.screen.sections.AccountInfo
import com.garfiec.librechat.feature.settings.screen.sections.BackupCodesDialog
@@ -54,6 +54,7 @@ import com.garfiec.librechat.feature.settings.screen.sections.ThemeSelector
import com.garfiec.librechat.feature.settings.screen.sections.TwoFactorCodeDialog
import com.garfiec.librechat.feature.settings.screen.sections.TwoFactorSetupDialog
import com.garfiec.librechat.feature.settings.viewmodel.SettingsViewModel
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@OptIn(ExperimentalMaterial3Api::class)
@@ -61,13 +62,14 @@ import org.koin.compose.viewmodel.koinViewModel
fun SettingsScreen(
onLogout: () -> Unit,
onNavigateBack: () -> Unit,
- onNavigateToArchived: () -> Unit,
+ onNavigateToArchive: () -> Unit,
modifier: Modifier = Modifier,
onNavigateToSharedLinks: () -> Unit = {},
onNavigateToApiKeys: () -> Unit = {},
viewModel: SettingsViewModel = koinViewModel(),
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
+ val currentOnLogout by rememberUpdatedState(onLogout)
var showDeleteDialog by remember { mutableStateOf(false) }
var showLogoutDialog by remember { mutableStateOf(false) }
@@ -102,7 +104,7 @@ fun SettingsScreen(
LaunchedEffect(uiState.isLoggedOut, uiState.isAccountDeleted) {
if (uiState.isLoggedOut || uiState.isAccountDeleted) {
- onLogout()
+ currentOnLogout()
}
}
@@ -269,7 +271,7 @@ fun SettingsScreen(
ttsSource = uiState.ttsSource,
onAutoSendAfterSttChange = viewModel::setAutoSendAfterStt,
onAutoReadChange = viewModel::setAutoReadEnabled,
- onVoiceSelected = viewModel::selectVoice,
+ onVoiceSelect = viewModel::selectVoice,
onTestVoice = viewModel::testVoice,
)
}
@@ -290,7 +292,7 @@ fun SettingsScreen(
memoriesEnabled = uiState.memoriesEnabled,
showMemoryDialog = uiState.showMemoryDialog,
editingMemory = uiState.editingMemory,
- onToggleEnabled = viewModel::toggleMemoriesEnabled,
+ onToggleEnable = viewModel::toggleMemoriesEnabled,
onAddMemory = viewModel::showAddMemoryDialog,
onEditMemory = viewModel::showEditMemoryDialog,
onDeleteMemory = viewModel::deleteMemory,
@@ -308,7 +310,7 @@ fun SettingsScreen(
archivedCount = uiState.archivedCount,
isClearing = uiState.isClearing,
onClearAllChats = viewModel::clearAllChats,
- onViewArchived = onNavigateToArchived,
+ onViewArchive = onNavigateToArchive,
onExportAllData = viewModel::exportAllData,
)
}
@@ -634,7 +636,7 @@ fun SettingsScreen(
if (uiState.showLanguageDialog) {
LanguageSelectorDialog(
selectedLanguage = uiState.selectedLanguage,
- onLanguageSelected = viewModel::setLanguage,
+ onLanguageSelect = viewModel::setLanguage,
onDismiss = viewModel::dismissLanguageDialog,
)
}
@@ -643,7 +645,7 @@ fun SettingsScreen(
if (uiState.showForkSettingsDialog) {
ForkSettingsDialog(
selectedMode = ForkMode.fromApiValue(uiState.forkMode),
- onModeSelected = { mode ->
+ onModeSelect = { mode ->
viewModel.setForkMode(mode.apiValue)
},
onDismiss = viewModel::dismissForkSettingsDialog,
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SharedLinksScreen.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SharedLinksScreen.kt
index d60c156..60b94db 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SharedLinksScreen.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SharedLinksScreen.kt
@@ -1,6 +1,5 @@
package com.garfiec.librechat.feature.settings.screen
-import com.garfiec.librechat.feature.settings.util.copyToClipboard
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -41,17 +40,19 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.ui.components.EmptyState
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
import com.garfiec.librechat.feature.settings.model.SharedLinkDisplayData
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import com.garfiec.librechat.feature.settings.util.copyToClipboard
+import org.jetbrains.compose.resources.stringResource
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -69,6 +70,7 @@ fun SharedLinksScreen(
val snackbarHostState = remember { SnackbarHostState() }
val listState = rememberLazyListState()
var deleteTarget by remember { mutableStateOf(null) }
+ val currentOnLoadMore by rememberUpdatedState(onLoadMore)
// Pagination: load more when near the end
LaunchedEffect(listState) {
@@ -79,7 +81,7 @@ fun SharedLinksScreen(
lastVisible >= totalItems - 3
}.collect { shouldLoad ->
if (shouldLoad && hasNextPage && !isLoading) {
- onLoadMore()
+ currentOnLoadMore()
}
}
}
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SpeechDetailDialogs.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SpeechDetailDialogs.kt
index d05f00d..181c904 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SpeechDetailDialogs.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SpeechDetailDialogs.kt
@@ -33,12 +33,12 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
@OptIn(ExperimentalMaterial3Api::class)
@Composable
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SpeechSettingsSection.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SpeechSettingsSection.kt
index b698cba..b7eb664 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SpeechSettingsSection.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/SpeechSettingsSection.kt
@@ -25,13 +25,13 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.speech.TtsVoice
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -43,7 +43,7 @@ internal fun SpeechSettingsSection(
ttsSource: String,
onAutoSendAfterSttChange: (Boolean) -> Unit,
onAutoReadChange: (Boolean) -> Unit,
- onVoiceSelected: (TtsVoice) -> Unit,
+ onVoiceSelect: (TtsVoice) -> Unit,
onTestVoice: () -> Unit,
modifier: Modifier = Modifier,
) {
@@ -162,7 +162,7 @@ internal fun SpeechSettingsSection(
}
},
onClick = {
- onVoiceSelected(voice)
+ onVoiceSelect(voice)
expanded = false
},
)
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/TabbedSettingsScreen.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/TabbedSettingsScreen.kt
index 01d96cc..f56f06b 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/TabbedSettingsScreen.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/TabbedSettingsScreen.kt
@@ -22,12 +22,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
-import com.garfiec.librechat.feature.settings.viewmodel.SettingsViewModel
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
import kotlinx.coroutines.launch
-import org.koin.compose.viewmodel.koinViewModel
+import org.jetbrains.compose.resources.stringResource
private val SettingsTabs = listOf("General", "Chat", "Account", "Data")
@@ -41,12 +39,11 @@ private val SettingsTabs = listOf("General", "Chat", "Account", "Data")
fun TabbedSettingsScreen(
onNavigateBack: () -> Unit,
onLogout: () -> Unit,
- onNavigateToArchived: () -> Unit,
+ onNavigateToArchive: () -> Unit,
onNavigateToSharedLinks: () -> Unit,
onNavigateToPresets: () -> Unit,
onNavigateToApiKeys: () -> Unit,
modifier: Modifier = Modifier,
- viewModel: SettingsViewModel = koinViewModel(),
) {
val pagerState = rememberPagerState(pageCount = { SettingsTabs.size })
val scope = rememberCoroutineScope()
@@ -97,26 +94,22 @@ fun TabbedSettingsScreen(
when (page) {
0 -> GeneralSettingsContent(
modifier = Modifier.fillMaxSize(),
- viewModel = viewModel,
)
1 -> ChatSettingsContent(
onNavigateToPresets = onNavigateToPresets,
modifier = Modifier.fillMaxSize(),
- viewModel = viewModel,
)
2 -> AccountSettingsContent(
onLogout = onLogout,
onNavigateToApiKeys = onNavigateToApiKeys,
snackbarHostState = snackbarHostState,
modifier = Modifier.fillMaxSize(),
- viewModel = viewModel,
)
3 -> DataSettingsContent(
- onNavigateToArchived = onNavigateToArchived,
+ onNavigateToArchive = onNavigateToArchive,
onNavigateToSharedLinks = onNavigateToSharedLinks,
snackbarHostState = snackbarHostState,
modifier = Modifier.fillMaxSize(),
- viewModel = viewModel,
)
}
}
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/AccountSection.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/AccountSection.kt
index a45320f..6efd945 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/AccountSection.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/AccountSection.kt
@@ -22,12 +22,12 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
internal fun AccountInfo(
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/AppearanceSection.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/AppearanceSection.kt
index 3fa45fb..676976d 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/AppearanceSection.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/AppearanceSection.kt
@@ -21,12 +21,12 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.data.datastore.ThemeMode
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
internal fun ThemeSelector(
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/ChatPreferencesSection.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/ChatPreferencesSection.kt
index e4b6418..2fbde6b 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/ChatPreferencesSection.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/ChatPreferencesSection.kt
@@ -23,11 +23,11 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
internal fun AboutInfo(serverUrl: String) {
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/DataManagementSection.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/DataManagementSection.kt
index 59f6cba..fcfbf19 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/DataManagementSection.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/DataManagementSection.kt
@@ -17,10 +17,10 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
internal fun DataExtraActions(
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/SecuritySection.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/SecuritySection.kt
index 7f563bd..9f8ace7 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/SecuritySection.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/SecuritySection.kt
@@ -19,11 +19,11 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
internal fun TwoFactorSetupDialog(
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/SpeechSection.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/SpeechSection.kt
index 0af7a78..6820f3f 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/SpeechSection.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/screen/sections/SpeechSection.kt
@@ -15,10 +15,10 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp
-import librechat_mobile.feature.settings.generated.resources.Res
-import librechat_mobile.feature.settings.generated.resources.*
+import com.garfiec.librechat.feature.settings.resources.*
+import com.garfiec.librechat.feature.settings.resources.Res
+import org.jetbrains.compose.resources.stringResource
@Composable
internal fun SpeechDetailButtons(
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/McpViewModel.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/McpViewModel.kt
index 7c40be4..cfe00a6 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/McpViewModel.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/McpViewModel.kt
@@ -3,6 +3,7 @@ package com.garfiec.librechat.feature.settings.viewmodel
import androidx.compose.runtime.Immutable
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.repository.McpRepository
import com.garfiec.librechat.core.model.mcp.McpApiKeyConfig
@@ -15,7 +16,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
-import co.touchlab.kermit.Logger
@Immutable
data class McpUiState(
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/SettingsViewModel.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/SettingsViewModel.kt
index 1b1b414..213a186 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/SettingsViewModel.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/SettingsViewModel.kt
@@ -1,10 +1,9 @@
package com.garfiec.librechat.feature.settings.viewmodel
import androidx.compose.runtime.Immutable
-import com.garfiec.librechat.feature.settings.util.ContentReader
-import com.garfiec.librechat.feature.settings.util.PlatformCacheCleaner
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.ChatLayoutConstants
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.datastore.ChatFontSize
@@ -20,7 +19,6 @@ import com.garfiec.librechat.core.data.repository.KeyRepository
import com.garfiec.librechat.core.data.repository.McpRepository
import com.garfiec.librechat.core.data.repository.MemoryRepository
import com.garfiec.librechat.core.data.repository.ShareRepository
-import com.garfiec.librechat.core.data.repository.SpeechRepository
import com.garfiec.librechat.core.data.repository.UserRepository
import com.garfiec.librechat.core.model.Memory
import com.garfiec.librechat.core.model.User
@@ -33,6 +31,8 @@ import com.garfiec.librechat.core.model.speech.TtsVoice
import com.garfiec.librechat.feature.settings.model.SharedLinkDisplayData
import com.garfiec.librechat.feature.settings.model.UserDisplayData
import com.garfiec.librechat.feature.settings.screen.DeviceVoiceInfo
+import com.garfiec.librechat.feature.settings.util.ContentReader
+import com.garfiec.librechat.feature.settings.util.PlatformCacheCleaner
import com.garfiec.librechat.feature.settings.viewmodel.delegate.DataManagementDelegate
import com.garfiec.librechat.feature.settings.viewmodel.delegate.McpServerDelegate
import com.garfiec.librechat.feature.settings.viewmodel.delegate.MemoryManagementDelegate
@@ -45,7 +45,6 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
-import co.touchlab.kermit.Logger
data class SettingsCommand(
val name: String,
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/DataManagementDelegate.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/DataManagementDelegate.kt
index 7533235..2e92087 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/DataManagementDelegate.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/DataManagementDelegate.kt
@@ -1,12 +1,12 @@
package com.garfiec.librechat.feature.settings.viewmodel.delegate
import com.garfiec.librechat.core.common.result.Result
-import com.garfiec.librechat.feature.settings.util.PlatformCacheCleaner
import com.garfiec.librechat.core.data.repository.ConversationRepository
import com.garfiec.librechat.core.data.repository.KeyRepository
import com.garfiec.librechat.core.data.repository.ShareRepository
import com.garfiec.librechat.core.model.SharedLink
import com.garfiec.librechat.feature.settings.model.SharedLinkDisplayData
+import com.garfiec.librechat.feature.settings.util.PlatformCacheCleaner
import com.garfiec.librechat.feature.settings.viewmodel.SettingsStateHandle
import kotlinx.coroutines.launch
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/McpServerDelegate.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/McpServerDelegate.kt
index d8a2b10..2566685 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/McpServerDelegate.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/McpServerDelegate.kt
@@ -1,5 +1,6 @@
package com.garfiec.librechat.feature.settings.viewmodel.delegate
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.repository.McpRepository
import com.garfiec.librechat.core.model.mcp.McpApiKeyConfig
@@ -8,7 +9,6 @@ import com.garfiec.librechat.core.model.mcp.McpServer
import com.garfiec.librechat.core.model.mcp.McpServerType
import com.garfiec.librechat.feature.settings.viewmodel.SettingsStateHandle
import kotlinx.coroutines.launch
-import co.touchlab.kermit.Logger
/**
* Handles MCP server management, connection status, and reinitialization.
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/MemoryManagementDelegate.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/MemoryManagementDelegate.kt
index 961c3b0..1727cec 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/MemoryManagementDelegate.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/MemoryManagementDelegate.kt
@@ -1,5 +1,6 @@
package com.garfiec.librechat.feature.settings.viewmodel.delegate
+import co.touchlab.kermit.Logger
import com.garfiec.librechat.core.common.result.Result
import com.garfiec.librechat.core.data.repository.MemoryRepository
import com.garfiec.librechat.core.model.Memory
@@ -8,7 +9,6 @@ import com.garfiec.librechat.core.model.request.UpdateMemoryPreferencesRequest
import com.garfiec.librechat.core.model.request.UpdateMemoryRequest
import com.garfiec.librechat.feature.settings.viewmodel.SettingsStateHandle
import kotlinx.coroutines.launch
-import co.touchlab.kermit.Logger
/**
* Handles memory CRUD operations and memory preferences.
diff --git a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/TwoFactorSecurityDelegate.kt b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/TwoFactorSecurityDelegate.kt
index fcbb1b3..0d88913 100644
--- a/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/TwoFactorSecurityDelegate.kt
+++ b/feature/settings/src/commonMain/kotlin/com/garfiec/librechat/feature/settings/viewmodel/delegate/TwoFactorSecurityDelegate.kt
@@ -1,9 +1,9 @@
package com.garfiec.librechat.feature.settings.viewmodel.delegate
import com.garfiec.librechat.core.common.result.Result
-import com.garfiec.librechat.feature.settings.viewmodel.isHttpStatus
import com.garfiec.librechat.core.data.repository.AuthRepository
import com.garfiec.librechat.feature.settings.viewmodel.SettingsStateHandle
+import com.garfiec.librechat.feature.settings.viewmodel.isHttpStatus
import kotlinx.coroutines.launch
/**
diff --git a/shared/detekt-baseline.xml b/shared/detekt-baseline.xml
deleted file mode 100644
index 248b25b..0000000
--- a/shared/detekt-baseline.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
- ComposableParamOrder:LibreChatNavHost.kt$MainNavDisplay
- FunctionNaming:String0.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString0Resources(map: MutableMap<String, StringResource>)
- ImportOrdering:DrawerDisplayMapping.kt$import com.garfiec.librechat.core.common.extensions.toInstantOrNull import com.garfiec.librechat.core.common.extensions.formatMonthAbbrev import com.garfiec.librechat.core.model.Conversation import kotlin.time.Clock import kotlin.time.Instant import kotlinx.datetime.TimeZone import kotlinx.datetime.toLocalDateTime
- ImportOrdering:ExpectResourceCollectors.kt$import kotlin.String import kotlin.collections.Map import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.FontResource import org.jetbrains.compose.resources.PluralStringResource import org.jetbrains.compose.resources.StringArrayResource import org.jetbrains.compose.resources.StringResource
- ImportOrdering:LibreChatNavHost.kt$import androidx.compose.animation.core.FastOutSlowInEasing import androidx.compose.animation.core.LinearEasing import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.scaleIn import androidx.compose.animation.scaleOut import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideOutHorizontally import androidx.compose.animation.togetherWith import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.AlertDialog import androidx.compose.material3.DrawerValue import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalDrawerSheet import androidx.compose.material3.ModalNavigationDrawer import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.rememberDrawerState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation3.runtime.NavKey import androidx.navigation3.runtime.entryProvider import androidx.navigation3.runtime.rememberNavBackStack import androidx.navigation3.ui.NavDisplay import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator import com.garfiec.librechat.core.ui.components.BannerDisplay import com.garfiec.librechat.feature.agents.navigation.AgentMarketplace import com.garfiec.librechat.feature.agents.navigation.agentsEntries import com.garfiec.librechat.feature.auth.navigation.AuthRoute import com.garfiec.librechat.feature.auth.navigation.ServerUrl import com.garfiec.librechat.feature.auth.navigation.authEntries import com.garfiec.librechat.feature.chat.navigation.Chat import com.garfiec.librechat.feature.chat.navigation.NewChat import com.garfiec.librechat.feature.chat.navigation.chatEntries import com.garfiec.librechat.feature.conversations.navigation.ArchivedConversations import com.garfiec.librechat.feature.conversations.navigation.conversationsEntries import com.garfiec.librechat.feature.files.navigation.Files import com.garfiec.librechat.feature.files.navigation.filesEntries import com.garfiec.librechat.feature.settings.navigation.SettingsTabbed import com.garfiec.librechat.feature.settings.navigation.memoriesEntry import com.garfiec.librechat.feature.settings.navigation.mcpServersEntry import com.garfiec.librechat.feature.settings.navigation.settingsEntries import kotlinx.coroutines.launch import librechat_mobile.shared.generated.resources.Res import librechat_mobile.shared.generated.resources.dismiss import librechat_mobile.shared.generated.resources.dont_warn_again import librechat_mobile.shared.generated.resources.version_mismatch_message import librechat_mobile.shared.generated.resources.version_mismatch_title import org.jetbrains.compose.resources.stringResource import org.koin.compose.viewmodel.koinViewModel
- ImportOrdering:NavHostViewModel.kt$import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.garfiec.librechat.core.data.repository.AuthRepository import com.garfiec.librechat.core.data.repository.BannerRepository import com.garfiec.librechat.core.data.datastore.SettingsDataStore import com.garfiec.librechat.core.data.repository.ConfigRepository import com.garfiec.librechat.core.data.repository.ConversationRepository import com.garfiec.librechat.core.model.Banner import com.garfiec.librechat.core.network.client.TokenManager 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 import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import co.touchlab.kermit.Logger import com.garfiec.librechat.core.common.extensions.firstBlocking
- ImportOrdering:Res.kt$import kotlin.ByteArray import kotlin.OptIn import kotlin.String import kotlin.Suppress import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.getResourceUri import org.jetbrains.compose.resources.readResourceBytes
- ImportOrdering:String0.commonMain.kt$import kotlin.OptIn import kotlin.String import kotlin.collections.MutableMap import org.jetbrains.compose.resources.InternalResourceApi import org.jetbrains.compose.resources.ResourceContentHash import org.jetbrains.compose.resources.ResourceItem import org.jetbrains.compose.resources.StringResource
- LambdaParameterInRestartableEffect:DrawerContent.kt$onLoadMore
- MaxLineLength:NavHostViewModel.kt$NavHostViewModel$private val favoritesStateHolder = FavoritesStateHolder(settingsDataStore, conversationListStateHolder.recentConversations, viewModelScope)
- MaxLineLength:Res.kt$Res$public suspend
- NoUnusedImports:LibreChatNavHost.kt$com.garfiec.librechat.shared.navigation.LibreChatNavHost.kt
- PackageName:ExpectResourceCollectors.kt$package librechat_mobile.shared.generated.resources
- PackageName:Res.kt$package librechat_mobile.shared.generated.resources
- PackageName:String0.commonMain.kt$package librechat_mobile.shared.generated.resources
- PackageNaming:ExpectResourceCollectors.kt$package librechat_mobile.shared.generated.resources
- PackageNaming:Res.kt$package librechat_mobile.shared.generated.resources
- PackageNaming:String0.commonMain.kt$package librechat_mobile.shared.generated.resources
- ParameterNaming:DrawerContent.kt$onSearchQueryChanged
- ParameterNaming:SettingsSidebarContent.kt$onCategorySelected
- ParameterNaming:SidebarScaffold.kt$onSettingsCategorySelected
- PropertyWrapping:NavHostViewModel.kt$NavHostViewModel$private val favoritesStateHolder = FavoritesStateHolder(settingsDataStore, conversationListStateHolder.recentConversations, viewModelScope)
- ViewModelForwarding:LibreChatNavHost.kt$MainNavDisplay( navigator = navigator, navHostViewModel = navHostViewModel, onMenuClick = { scope.launch { drawerState.open() } }, modifier = Modifier.fillMaxSize(), )
- ViewModelForwarding:LibreChatNavHost.kt$PhoneLayout( navigator = navigator, navHostViewModel = navHostViewModel, modifier = modifier, )
- ViewModelForwarding:LibreChatNavHost.kt$SidebarScaffold( viewModel = navHostViewModel, onNewChat = { scope.launch { drawerState.close() } if (navigator.currentRoute !is NewChat) { navigator.navigateToTopLevel(NewChat) } }, onConversationClick = { conversationId -> scope.launch { drawerState.close() } navigator.navigateToChat(conversationId) }, onSettingsClick = { scope.launch { drawerState.close() } navigator.navigate(SettingsTabbed) }, onSettingsCategorySelected = { category -> navigator.navigate(category.toRoute()) }, onAgentsClick = { scope.launch { drawerState.close() } navigator.navigate(AgentMarketplace) }, onFilesClick = { scope.launch { drawerState.close() } navigator.navigate(Files) }, )
- ViewModelForwarding:SidebarScaffold.kt$DrawerContent( viewModel = viewModel, onNewChat = onNewChat, onConversationClick = onConversationClick, onSettingsClick = onSettingsClick, onAgentsClick = onAgentsClick, onFilesClick = onFilesClick, )
-
-
diff --git a/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/DrawerContent.kt b/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/DrawerContent.kt
index 926b01b..83480a7 100644
--- a/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/DrawerContent.kt
+++ b/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/DrawerContent.kt
@@ -42,6 +42,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -53,19 +54,20 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.garfiec.librechat.core.ui.components.endpointIconPainter
import com.garfiec.librechat.core.ui.components.isMonochromeIcon
-import librechat_mobile.shared.generated.resources.Res
-import librechat_mobile.shared.generated.resources.agents
-import librechat_mobile.shared.generated.resources.bookmark
-import librechat_mobile.shared.generated.resources.cd_clear_search
-import librechat_mobile.shared.generated.resources.cd_search
-import librechat_mobile.shared.generated.resources.favorites
-import librechat_mobile.shared.generated.resources.files
-import librechat_mobile.shared.generated.resources.new_chat
-import librechat_mobile.shared.generated.resources.no_conversations_found
-import librechat_mobile.shared.generated.resources.remove_bookmark
-import librechat_mobile.shared.generated.resources.search_conversations_placeholder
-import librechat_mobile.shared.generated.resources.settings
+import com.garfiec.librechat.shared.resources.Res
+import com.garfiec.librechat.shared.resources.agents
+import com.garfiec.librechat.shared.resources.bookmark
+import com.garfiec.librechat.shared.resources.cd_clear_search
+import com.garfiec.librechat.shared.resources.cd_search
+import com.garfiec.librechat.shared.resources.favorites
+import com.garfiec.librechat.shared.resources.files
+import com.garfiec.librechat.shared.resources.new_chat
+import com.garfiec.librechat.shared.resources.no_conversations_found
+import com.garfiec.librechat.shared.resources.remove_bookmark
+import com.garfiec.librechat.shared.resources.search_conversations_placeholder
+import com.garfiec.librechat.shared.resources.settings
import org.jetbrains.compose.resources.stringResource
+import org.koin.compose.viewmodel.koinViewModel
// Pre-computed shapes to avoid creating new ones per item per frame
private val ItemShape = RoundedCornerShape(8.dp)
@@ -76,18 +78,18 @@ private val ActiveIndicatorShape = RoundedCornerShape(2.dp)
*/
@Composable
fun DrawerContent(
- viewModel: NavHostViewModel,
onNewChat: () -> Unit,
onConversationClick: (String) -> Unit,
onSettingsClick: () -> Unit,
onAgentsClick: () -> Unit,
onFilesClick: () -> Unit,
modifier: Modifier = Modifier,
+ viewModel: NavHostViewModel = koinViewModel(),
) {
val uiState by viewModel.drawerUiState.collectAsStateWithLifecycle()
DrawerContent(
uiState = uiState,
- onSearchQueryChanged = viewModel::onSearchQueryChanged,
+ onSearchQueryChange = viewModel::onSearchQueryChanged,
onNewChat = onNewChat,
onConversationClick = onConversationClick,
onSettingsClick = onSettingsClick,
@@ -104,7 +106,7 @@ fun DrawerContent(
@Composable
fun DrawerContent(
uiState: DrawerUiState,
- onSearchQueryChanged: (String) -> Unit,
+ onSearchQueryChange: (String) -> Unit,
onNewChat: () -> Unit,
onConversationClick: (String) -> Unit,
onSettingsClick: () -> Unit,
@@ -154,7 +156,7 @@ fun DrawerContent(
// Search bar
OutlinedTextField(
value = uiState.searchQuery,
- onValueChange = onSearchQueryChanged,
+ onValueChange = onSearchQueryChange,
leadingIcon = {
Icon(
imageVector = Icons.Default.Search,
@@ -165,7 +167,7 @@ fun DrawerContent(
},
trailingIcon = {
if (uiState.searchQuery.isNotEmpty()) {
- IconButton(onClick = { onSearchQueryChanged("") }) {
+ IconButton(onClick = { onSearchQueryChange("") }) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = stringResource(Res.string.cd_clear_search),
@@ -192,6 +194,7 @@ fun DrawerContent(
// Conversation list with favorites section and date groups
val listState = rememberLazyListState()
+ val currentOnLoadMore by rememberUpdatedState(onLoadMore)
val shouldLoadMore = remember {
derivedStateOf {
@@ -203,7 +206,7 @@ fun DrawerContent(
LaunchedEffect(shouldLoadMore.value) {
if (shouldLoadMore.value && uiState.hasMore && !uiState.isLoadingMore) {
- onLoadMore()
+ currentOnLoadMore()
}
}
diff --git a/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/DrawerDisplayMapping.kt b/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/DrawerDisplayMapping.kt
index 643c470..41ecbf1 100644
--- a/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/DrawerDisplayMapping.kt
+++ b/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/DrawerDisplayMapping.kt
@@ -1,12 +1,12 @@
package com.garfiec.librechat.shared.navigation
-import com.garfiec.librechat.core.common.extensions.toInstantOrNull
import com.garfiec.librechat.core.common.extensions.formatMonthAbbrev
+import com.garfiec.librechat.core.common.extensions.toInstantOrNull
import com.garfiec.librechat.core.model.Conversation
-import kotlin.time.Clock
-import kotlin.time.Instant
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
+import kotlin.time.Clock
+import kotlin.time.Instant
internal data class DrawerDataSnapshot(
val grouped: List>>,
diff --git a/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/LibreChatNavHost.kt b/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/LibreChatNavHost.kt
index 51725b9..4e91974 100644
--- a/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/LibreChatNavHost.kt
+++ b/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/LibreChatNavHost.kt
@@ -29,17 +29,14 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import androidx.navigation3.runtime.NavKey
+import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator
import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.runtime.rememberNavBackStack
-import androidx.navigation3.ui.NavDisplay
import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
-import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator
+import androidx.navigation3.ui.NavDisplay
import com.garfiec.librechat.core.ui.components.BannerDisplay
import com.garfiec.librechat.feature.agents.navigation.AgentMarketplace
import com.garfiec.librechat.feature.agents.navigation.agentsEntries
-import com.garfiec.librechat.feature.auth.navigation.AuthRoute
-import com.garfiec.librechat.feature.auth.navigation.ServerUrl
import com.garfiec.librechat.feature.auth.navigation.authEntries
import com.garfiec.librechat.feature.chat.navigation.Chat
import com.garfiec.librechat.feature.chat.navigation.NewChat
@@ -49,15 +46,15 @@ import com.garfiec.librechat.feature.conversations.navigation.conversationsEntri
import com.garfiec.librechat.feature.files.navigation.Files
import com.garfiec.librechat.feature.files.navigation.filesEntries
import com.garfiec.librechat.feature.settings.navigation.SettingsTabbed
-import com.garfiec.librechat.feature.settings.navigation.memoriesEntry
import com.garfiec.librechat.feature.settings.navigation.mcpServersEntry
+import com.garfiec.librechat.feature.settings.navigation.memoriesEntry
import com.garfiec.librechat.feature.settings.navigation.settingsEntries
+import com.garfiec.librechat.shared.resources.Res
+import com.garfiec.librechat.shared.resources.dismiss
+import com.garfiec.librechat.shared.resources.dont_warn_again
+import com.garfiec.librechat.shared.resources.version_mismatch_message
+import com.garfiec.librechat.shared.resources.version_mismatch_title
import kotlinx.coroutines.launch
-import librechat_mobile.shared.generated.resources.Res
-import librechat_mobile.shared.generated.resources.dismiss
-import librechat_mobile.shared.generated.resources.dont_warn_again
-import librechat_mobile.shared.generated.resources.version_mismatch_message
-import librechat_mobile.shared.generated.resources.version_mismatch_title
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@@ -106,7 +103,6 @@ fun LibreChatNavHost(
} else {
PhoneLayout(
navigator = navigator,
- navHostViewModel = navHostViewModel,
modifier = modifier,
)
}
@@ -161,8 +157,8 @@ private fun VersionMismatchDialog(
@Composable
fun PhoneLayout(
navigator: Navigator,
- navHostViewModel: NavHostViewModel,
modifier: Modifier = Modifier,
+ navHostViewModel: NavHostViewModel = koinViewModel(),
) {
val drawerState = rememberDrawerState(DrawerValue.Closed)
val scope = rememberCoroutineScope()
@@ -182,7 +178,6 @@ fun PhoneLayout(
drawerContent = {
ModalDrawerSheet {
SidebarScaffold(
- viewModel = navHostViewModel,
onNewChat = {
scope.launch { drawerState.close() }
if (navigator.currentRoute !is NewChat) {
@@ -197,7 +192,7 @@ fun PhoneLayout(
scope.launch { drawerState.close() }
navigator.navigate(SettingsTabbed)
},
- onSettingsCategorySelected = { category ->
+ onSettingsCategorySelect = { category ->
navigator.navigate(category.toRoute())
},
onAgentsClick = {
@@ -223,7 +218,6 @@ fun PhoneLayout(
}
MainNavDisplay(
navigator = navigator,
- navHostViewModel = navHostViewModel,
onMenuClick = { scope.launch { drawerState.open() } },
modifier = Modifier.fillMaxSize(),
)
@@ -235,9 +229,9 @@ fun PhoneLayout(
@Composable
fun MainNavDisplay(
navigator: Navigator,
- navHostViewModel: NavHostViewModel,
- onMenuClick: (() -> Unit)? = null,
modifier: Modifier = Modifier,
+ onMenuClick: (() -> Unit)? = null,
+ navHostViewModel: NavHostViewModel = koinViewModel(),
) {
NavDisplay(
backStack = navigator.backStack,
@@ -290,7 +284,7 @@ fun MainNavDisplay(
)
conversationsEntries(
onConversationClick = { navigator.navigateToChat(it) },
- onNavigateToArchived = { navigator.navigate(ArchivedConversations) },
+ onNavigateToArchive = { navigator.navigate(ArchivedConversations) },
onBack = { navigator.goBack() },
)
agentsEntries(
@@ -310,7 +304,7 @@ fun MainNavDisplay(
navHostViewModel.logout()
navigator.navigateToAuth()
},
- onNavigateToArchived = { navigator.navigate(ArchivedConversations) },
+ onNavigateToArchive = { navigator.navigate(ArchivedConversations) },
)
memoriesEntry(
onBack = { navigator.goBack() },
diff --git a/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/NavHostViewModel.kt b/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/NavHostViewModel.kt
index 7c13c04..3384fe7 100644
--- a/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/NavHostViewModel.kt
+++ b/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/NavHostViewModel.kt
@@ -2,9 +2,11 @@ package com.garfiec.librechat.shared.navigation
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import co.touchlab.kermit.Logger
+import com.garfiec.librechat.core.common.extensions.firstBlocking
+import com.garfiec.librechat.core.data.datastore.SettingsDataStore
import com.garfiec.librechat.core.data.repository.AuthRepository
import com.garfiec.librechat.core.data.repository.BannerRepository
-import com.garfiec.librechat.core.data.datastore.SettingsDataStore
import com.garfiec.librechat.core.data.repository.ConfigRepository
import com.garfiec.librechat.core.data.repository.ConversationRepository
import com.garfiec.librechat.core.model.Banner
@@ -17,8 +19,6 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
-import co.touchlab.kermit.Logger
-import com.garfiec.librechat.core.common.extensions.firstBlocking
class NavHostViewModel(
private val authRepository: AuthRepository,
@@ -32,7 +32,8 @@ class NavHostViewModel(
private val bannerStateHolder = BannerStateHolder(bannerRepository, viewModelScope)
private val versionCheckStateHolder = VersionCheckStateHolder(configRepository, settingsDataStore, viewModelScope)
private val conversationListStateHolder = ConversationListStateHolder(conversationRepository, viewModelScope)
- private val favoritesStateHolder = FavoritesStateHolder(settingsDataStore, conversationListStateHolder.recentConversations, viewModelScope)
+ private val favoritesStateHolder =
+ FavoritesStateHolder(settingsDataStore, conversationListStateHolder.recentConversations, viewModelScope)
private val _isLoggedIn = MutableStateFlow(tokenManager.isAuthenticated)
val isLoggedIn: StateFlow = _isLoggedIn.asStateFlow()
diff --git a/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/SettingsSidebarContent.kt b/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/SettingsSidebarContent.kt
index bdf4669..bcedde6 100644
--- a/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/SettingsSidebarContent.kt
+++ b/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/SettingsSidebarContent.kt
@@ -29,9 +29,9 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
-import librechat_mobile.shared.generated.resources.Res
-import librechat_mobile.shared.generated.resources.cd_back_to_conversations
-import librechat_mobile.shared.generated.resources.settings
+import com.garfiec.librechat.shared.resources.Res
+import com.garfiec.librechat.shared.resources.cd_back_to_conversations
+import com.garfiec.librechat.shared.resources.settings
import org.jetbrains.compose.resources.stringResource
private val CategoryItemShape = RoundedCornerShape(12.dp)
@@ -43,7 +43,7 @@ private val CategoryItemShape = RoundedCornerShape(12.dp)
fun SettingsSidebarContent(
selectedCategory: SettingsCategory?,
onBackToConversations: () -> Unit,
- onCategorySelected: (SettingsCategory) -> Unit,
+ onCategorySelect: (SettingsCategory) -> Unit,
modifier: Modifier = Modifier,
) {
Column(
@@ -80,25 +80,25 @@ fun SettingsSidebarContent(
icon = Icons.Default.Settings,
category = SettingsCategory.GENERAL,
isSelected = selectedCategory == SettingsCategory.GENERAL,
- onClick = { onCategorySelected(SettingsCategory.GENERAL) },
+ onClick = { onCategorySelect(SettingsCategory.GENERAL) },
)
SettingsCategoryItem(
icon = Icons.AutoMirrored.Filled.Chat,
category = SettingsCategory.CHAT,
isSelected = selectedCategory == SettingsCategory.CHAT,
- onClick = { onCategorySelected(SettingsCategory.CHAT) },
+ onClick = { onCategorySelect(SettingsCategory.CHAT) },
)
SettingsCategoryItem(
icon = Icons.Default.AccountCircle,
category = SettingsCategory.ACCOUNT,
isSelected = selectedCategory == SettingsCategory.ACCOUNT,
- onClick = { onCategorySelected(SettingsCategory.ACCOUNT) },
+ onClick = { onCategorySelect(SettingsCategory.ACCOUNT) },
)
SettingsCategoryItem(
icon = Icons.Default.Storage,
category = SettingsCategory.DATA,
isSelected = selectedCategory == SettingsCategory.DATA,
- onClick = { onCategorySelected(SettingsCategory.DATA) },
+ onClick = { onCategorySelect(SettingsCategory.DATA) },
)
Spacer(modifier = Modifier.weight(1f))
diff --git a/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/SidebarScaffold.kt b/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/SidebarScaffold.kt
index c74edbd..25342fa 100644
--- a/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/SidebarScaffold.kt
+++ b/shared/src/commonMain/kotlin/com/garfiec/librechat/shared/navigation/SidebarScaffold.kt
@@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import org.koin.compose.viewmodel.koinViewModel
/**
* Sidebar scaffold that switches between Conversations and Settings modes.
@@ -15,14 +16,14 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
*/
@Composable
fun SidebarScaffold(
- viewModel: NavHostViewModel,
onNewChat: () -> Unit,
onConversationClick: (String) -> Unit,
onSettingsClick: () -> Unit,
- onSettingsCategorySelected: (SettingsCategory) -> Unit,
+ onSettingsCategorySelect: (SettingsCategory) -> Unit,
onAgentsClick: () -> Unit,
onFilesClick: () -> Unit,
modifier: Modifier = Modifier,
+ viewModel: NavHostViewModel = koinViewModel(),
) {
val sidebarMode by viewModel.sidebarMode.collectAsStateWithLifecycle()
val selectedCategory by viewModel.selectedSettingsCategory.collectAsStateWithLifecycle()
@@ -44,7 +45,6 @@ fun SidebarScaffold(
when (mode) {
is SidebarMode.Conversations -> {
DrawerContent(
- viewModel = viewModel,
onNewChat = onNewChat,
onConversationClick = onConversationClick,
onSettingsClick = onSettingsClick,
@@ -58,9 +58,9 @@ fun SidebarScaffold(
onBackToConversations = {
viewModel.setSidebarMode(SidebarMode.Conversations)
},
- onCategorySelected = { category ->
+ onCategorySelect = { category ->
viewModel.selectSettingsCategory(category)
- onSettingsCategorySelected(category)
+ onSettingsCategorySelect(category)
},
)
}
diff --git a/shared/src/iosMain/kotlin/com/garfiec/librechat/shared/IosCrashReporting.kt b/shared/src/iosMain/kotlin/com/garfiec/librechat/shared/IosCrashReporting.kt
index 049243d..3f3910a 100644
--- a/shared/src/iosMain/kotlin/com/garfiec/librechat/shared/IosCrashReporting.kt
+++ b/shared/src/iosMain/kotlin/com/garfiec/librechat/shared/IosCrashReporting.kt
@@ -1,9 +1,9 @@
package com.garfiec.librechat.shared
import co.touchlab.kermit.Logger
-import kotlin.experimental.ExperimentalNativeApi
import platform.Foundation.NSException
import platform.Foundation.NSLog
+import kotlin.experimental.ExperimentalNativeApi
private val log = Logger.withTag("CrashReporting")
diff --git a/shared/src/iosMain/kotlin/com/garfiec/librechat/shared/IosKoinAccessor.kt b/shared/src/iosMain/kotlin/com/garfiec/librechat/shared/IosKoinAccessor.kt
index ef14beb..4f6a807 100644
--- a/shared/src/iosMain/kotlin/com/garfiec/librechat/shared/IosKoinAccessor.kt
+++ b/shared/src/iosMain/kotlin/com/garfiec/librechat/shared/IosKoinAccessor.kt
@@ -3,8 +3,8 @@ package com.garfiec.librechat.shared
import com.garfiec.librechat.core.common.di.KoinQualifiers
import com.garfiec.librechat.core.data.datastore.ServerDataStore
import com.garfiec.librechat.core.data.repository.AuthRepository
-import com.garfiec.librechat.core.data.repository.FileRepository
import com.garfiec.librechat.core.data.repository.ConfigRepository
+import com.garfiec.librechat.core.data.repository.FileRepository
import io.ktor.client.HttpClient
import org.koin.core.Koin
diff --git a/shared/src/iosMain/kotlin/com/garfiec/librechat/shared/IosKoinHelper.kt b/shared/src/iosMain/kotlin/com/garfiec/librechat/shared/IosKoinHelper.kt
index d8e1983..fe6eb1f 100644
--- a/shared/src/iosMain/kotlin/com/garfiec/librechat/shared/IosKoinHelper.kt
+++ b/shared/src/iosMain/kotlin/com/garfiec/librechat/shared/IosKoinHelper.kt
@@ -1,8 +1,8 @@
package com.garfiec.librechat.shared
+import co.touchlab.kermit.LogWriter
import co.touchlab.kermit.Logger
import co.touchlab.kermit.Severity
-import co.touchlab.kermit.LogWriter
import com.garfiec.librechat.shared.navigation.sharedAppModule
import org.koin.core.context.startKoin
import platform.Foundation.NSLog
diff --git a/shared/src/iosMain/kotlin/com/garfiec/librechat/shared/IosSharedModule.kt b/shared/src/iosMain/kotlin/com/garfiec/librechat/shared/IosSharedModule.kt
index 7b566f5..398ce21 100644
--- a/shared/src/iosMain/kotlin/com/garfiec/librechat/shared/IosSharedModule.kt
+++ b/shared/src/iosMain/kotlin/com/garfiec/librechat/shared/IosSharedModule.kt
@@ -3,12 +3,6 @@ package com.garfiec.librechat.shared
import com.garfiec.librechat.core.common.di.KoinQualifiers
import com.garfiec.librechat.core.common.di.commonModule
import com.garfiec.librechat.core.data.di.dataModule
-import com.garfiec.librechat.feature.agents.di.agentsModule
-import com.garfiec.librechat.feature.files.di.filesModule
-import com.garfiec.librechat.feature.auth.di.authModule
-import com.garfiec.librechat.feature.chat.di.chatModule
-import com.garfiec.librechat.feature.conversations.di.conversationsModule
-import com.garfiec.librechat.feature.settings.di.settingsModule
import com.garfiec.librechat.core.network.api.AgentsApi
import com.garfiec.librechat.core.network.api.ApiKeysApi
import com.garfiec.librechat.core.network.api.AuthApi
@@ -35,6 +29,12 @@ import com.garfiec.librechat.core.network.client.LibreChatHttpClient
import com.garfiec.librechat.core.network.client.ServerUrlProvider
import com.garfiec.librechat.core.network.client.TokenManager
import com.garfiec.librechat.core.network.sse.SseClient
+import com.garfiec.librechat.feature.agents.di.agentsModule
+import com.garfiec.librechat.feature.auth.di.authModule
+import com.garfiec.librechat.feature.chat.di.chatModule
+import com.garfiec.librechat.feature.conversations.di.conversationsModule
+import com.garfiec.librechat.feature.files.di.filesModule
+import com.garfiec.librechat.feature.settings.di.settingsModule
import io.ktor.client.HttpClient
import io.ktor.client.engine.darwin.Darwin
import io.ktor.client.plugins.HttpTimeout