cleanup: burn down detekt baselines and rename Compose Resources package
This commit is contained in:
parent
f9148c32c4
commit
63d87c843b
265 changed files with 1207 additions and 1585 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
<SmellBaseline>
|
||||
<ManuallySuppressedIssues/>
|
||||
<CurrentIssues>
|
||||
<ID>LambdaParameterInRestartableEffect:LibreChatNavHost.kt$onDeepLinkConsumed</ID>
|
||||
<ID>MutableStateAutoboxing:MainActivity.kt$MainActivity$mutableStateOf(0)</ID>
|
||||
<ID>ParameterNaming:LibreChatNavHost.kt$onDeepLinkConsumed</ID>
|
||||
<ID>ViewModelForwarding:TabletLayout.kt$MainContent( navigator = navigator, navHostViewModel = navHostViewModel, isInAuthFlow = false, banners = banners, dismissedBannerIds = dismissedBannerIds, onToggleDrawer = { navHostViewModel.setTabletSidebarOpen(!isSidebarOpen) }, )</ID>
|
||||
<ID>ViewModelForwarding:TabletLayout.kt$MainContent( navigator = navigator, navHostViewModel = navHostViewModel, isInAuthFlow = true, banners = banners, dismissedBannerIds = dismissedBannerIds, onToggleDrawer = {}, modifier = Modifier.fillMaxSize(), )</ID>
|
||||
<ID>ViewModelForwarding:TabletLayout.kt$MainNavDisplay( navigator = navigator, navHostViewModel = navHostViewModel, onMenuClick = onToggleDrawer, modifier = Modifier.fillMaxSize(), )</ID>
|
||||
<ID>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(), )</ID>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
|
@ -20,7 +20,7 @@ class AuthFlowTest {
|
|||
composeTestRule.setContent {
|
||||
LibreChatTheme {
|
||||
ServerUrlScreen(
|
||||
onServerValidated = {},
|
||||
onServerValidate = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Banner>,
|
||||
dismissedBannerIds: Set<String>,
|
||||
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(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<Project> {
|
||||
override fun apply(target: Project) {
|
||||
|
|
@ -14,7 +16,10 @@ class DetektConventionPlugin : Plugin<Project> {
|
|||
buildUponDefaultConfig = true
|
||||
allRules = false
|
||||
parallel = true
|
||||
baseline = file("detekt-baseline.xml")
|
||||
}
|
||||
|
||||
tasks.withType<DetektCreateBaselineTask>().configureEach {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
|
|
|||
|
|
@ -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<Project> {
|
||||
|
|
@ -11,7 +12,16 @@ class KmpComposeConventionPlugin : Plugin<Project> {
|
|||
pluginManager.apply("org.jetbrains.compose")
|
||||
pluginManager.apply("org.jetbrains.kotlin.plugin.compose")
|
||||
|
||||
val compose = extensions.getByType<ComposeExtension>().dependencies
|
||||
val composeExtension = extensions.getByType<ComposeExtension>()
|
||||
val compose = composeExtension.dependencies
|
||||
|
||||
// Override Compose Resources' default package. ResourcesExtension is a
|
||||
// sub-extension of ComposeExtension — `extensions.configure<ResourcesExtension>`
|
||||
// at project level throws "extension does not exist".
|
||||
composeExtension.extensions.configure<ResourcesExtension> {
|
||||
val modulePath = project.path.removePrefix(":").replace(":", ".")
|
||||
packageOfResClass = "com.garfiec.librechat.$modulePath.resources"
|
||||
}
|
||||
|
||||
extensions.configure<KotlinMultiplatformExtension> {
|
||||
sourceSets.commonMain.dependencies {
|
||||
|
|
|
|||
|
|
@ -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/**"
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
<SmellBaseline>
|
||||
<ManuallySuppressedIssues/>
|
||||
<CurrentIssues>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>NoUnusedImports:CommonModule.kt$com.garfiec.librechat.core.common.di.CommonModule.kt</ID>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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 <T> Flow<T>.retryWithBackoff(
|
||||
maxRetries: Int = 3,
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
<SmellBaseline>
|
||||
<ManuallySuppressedIssues/>
|
||||
<CurrentIssues>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>NoUnusedImports:DataModule.kt$com.garfiec.librechat.core.data.di.DataModule.kt</ID>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<Preferences>,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
<SmellBaseline>
|
||||
<ManuallySuppressedIssues/>
|
||||
<CurrentIssues>
|
||||
<ID>NoUnusedImports:StartupConfig.kt$com.garfiec.librechat.core.model.config.StartupConfig.kt</ID>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
<SmellBaseline>
|
||||
<ManuallySuppressedIssues/>
|
||||
<CurrentIssues>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>MaxLineLength:FilesApi.kt$FilesApi$"uploadFile success: fileId=${response.fileId}, filepath=${response.filepath}, type=${response.type}, width=${response.width}, height=${response.height}"</ID>
|
||||
<ID>NoEmptyFirstLineInMethodBlock:LibreChatHttpClient.kt$LibreChatHttpClient$ </ID>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
<SmellBaseline>
|
||||
<ManuallySuppressedIssues/>
|
||||
<CurrentIssues>
|
||||
<ID>ComposableParamOrder:FilterChipBottomSheet.kt$FilterChipBottomSheet</ID>
|
||||
<ID>FunctionNaming:Drawable0.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainDrawable0Resources(map: MutableMap<String, DrawableResource>)</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>MaxLineLength:Res.kt$Res$public suspend</ID>
|
||||
<ID>MultiLineIfElse:DynamicSlider.kt$str + "0".repeat(decimals - existing)</ID>
|
||||
<ID>MultiLineIfElse:DynamicSlider.kt$str.substring(0, dot + decimals + 1)</ID>
|
||||
<ID>PackageName:Drawable0.commonMain.kt$package librechat_mobile.core.ui.generated.resources</ID>
|
||||
<ID>PackageName:ExpectResourceCollectors.kt$package librechat_mobile.core.ui.generated.resources</ID>
|
||||
<ID>PackageName:Res.kt$package librechat_mobile.core.ui.generated.resources</ID>
|
||||
<ID>PackageNaming:Drawable0.commonMain.kt$package librechat_mobile.core.ui.generated.resources</ID>
|
||||
<ID>PackageNaming:ExpectResourceCollectors.kt$package librechat_mobile.core.ui.generated.resources</ID>
|
||||
<ID>PackageNaming:Res.kt$package librechat_mobile.core.ui.generated.resources</ID>
|
||||
<ID>ParameterNaming:DynamicParameterPanel.kt$onValueChanged</ID>
|
||||
<ID>ParameterNaming:DynamicTagsInput.kt$onTagsChanged</ID>
|
||||
<ID>ParameterNaming:FilterChipBottomSheet.kt$onSelectionChanged</ID>
|
||||
<ID>ParameterNaming:ModelParameterSheet.kt$onParametersChanged</ID>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import org.jetbrains.compose.ui.tooling.preview.Preview
|
|||
fun DynamicParameterPanel(
|
||||
definitions: List<ParameterDefinition>,
|
||||
values: Map<String, String>,
|
||||
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 }
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import org.jetbrains.compose.ui.tooling.preview.Preview
|
|||
fun DynamicTagsInput(
|
||||
label: String,
|
||||
tags: List<String>,
|
||||
onTagsChanged: (List<String>) -> Unit,
|
||||
onTagsChange: (List<String>) -> 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,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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 <T : Any> FilterChipBottomSheet(
|
||||
items: List<T>,
|
||||
selectedItems: Set<T>,
|
||||
onSelectionChanged: (Set<T>) -> Unit,
|
||||
onSelectionChange: (Set<T>) -> 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 <T : Any> FilterChipBottomSheet(
|
|||
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = {
|
||||
onSelectionChanged(currentSelection)
|
||||
onSelectionChange(currentSelection)
|
||||
onDismiss()
|
||||
},
|
||||
modifier = modifier,
|
||||
|
|
|
|||
|
|
@ -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<ParameterDefinition>? = 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(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -1,72 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
<SmellBaseline>
|
||||
<ManuallySuppressedIssues/>
|
||||
<CurrentIssues>
|
||||
<ID>ComposableParamOrder:AgentDetailScreen.kt$AgentDetailScreen</ID>
|
||||
<ID>ComposableParamOrder:AgentEditorScreen.kt$AgentEditorScreen</ID>
|
||||
<ID>DeprecatedKoinApi:AgentsModule.kt$viewModel { params -> AgentDetailViewModel( savedStateHandle = get(), agentRepository = get(), serverDataStore = get(), initialAgentId = params.getOrNull(), ) }</ID>
|
||||
<ID>DeprecatedKoinApi:AgentsModule.kt$viewModel { params -> AgentEditorViewModel( savedStateHandle = get(), agentRepository = get(), configRepository = get(), mcpRepository = get(), contentReader = get(), initialAgentId = params.getOrNull(), ) }</ID>
|
||||
<ID>FunctionNaming:String0.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString0Resources(map: MutableMap<String, StringResource>)</ID>
|
||||
<ID>FunctionNaming:String1.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString1Resources(map: MutableMap<String, StringResource>)</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>LambdaParameterInRestartableEffect:AgentDetailScreen.kt$onBack</ID>
|
||||
<ID>LambdaParameterInRestartableEffect:AgentDetailScreen.kt$onDuplicated</ID>
|
||||
<ID>LambdaParameterInRestartableEffect:AgentEditorScreen.kt$onDeleted</ID>
|
||||
<ID>LambdaParameterInRestartableEffect:AgentEditorScreen.kt$onDuplicated</ID>
|
||||
<ID>LambdaParameterInRestartableEffect:AgentEditorScreen.kt$onSaved</ID>
|
||||
<ID>LoopWithTooManyJumpStatements:YamlParser.kt$YamlParser$while</ID>
|
||||
<ID>MaxLineLength:AgentEditorViewModel.kt$AgentEditorViewModel$"name=${agent.name}, description=${agent.description}, instructions=${agent.instructions}, model=${agent.model}, "</ID>
|
||||
<ID>MaxLineLength:AgentEditorViewModel.kt$AgentEditorViewModel$"name=${newState.name}, description=${newState.description}, instructions=${newState.instructions}, model=${newState.model}, "</ID>
|
||||
<ID>MaxLineLength:Res.kt$Res$public suspend</ID>
|
||||
<ID>NoConsecutiveBlankLines:AgentDetailScreen.kt$ </ID>
|
||||
<ID>NoConsecutiveBlankLines:AgentMarketplaceScreen.kt$ </ID>
|
||||
<ID>NoUnusedImports:OpenApiSpecParser.kt$com.garfiec.librechat.feature.agents.util.OpenApiSpecParser.kt</ID>
|
||||
<ID>PackageName:ExpectResourceCollectors.kt$package librechat_mobile.feature.agents.generated.resources</ID>
|
||||
<ID>PackageName:Res.kt$package librechat_mobile.feature.agents.generated.resources</ID>
|
||||
<ID>PackageName:String0.commonMain.kt$package librechat_mobile.feature.agents.generated.resources</ID>
|
||||
<ID>PackageName:String1.commonMain.kt$package librechat_mobile.feature.agents.generated.resources</ID>
|
||||
<ID>PackageNaming:ExpectResourceCollectors.kt$package librechat_mobile.feature.agents.generated.resources</ID>
|
||||
<ID>PackageNaming:Res.kt$package librechat_mobile.feature.agents.generated.resources</ID>
|
||||
<ID>PackageNaming:String0.commonMain.kt$package librechat_mobile.feature.agents.generated.resources</ID>
|
||||
<ID>PackageNaming:String1.commonMain.kt$package librechat_mobile.feature.agents.generated.resources</ID>
|
||||
<ID>ParameterNaming:AgentAdvancedPanel.kt$onSettingsChanged</ID>
|
||||
<ID>ParameterNaming:AgentAvatarPicker.kt$onImageSelected</ID>
|
||||
<ID>ParameterNaming:AgentCapabilitiesSection.kt$onCapabilitiesChanged</ID>
|
||||
<ID>ParameterNaming:AgentCategorySelector.kt$onCategorySelected</ID>
|
||||
<ID>ParameterNaming:AgentDetailScreen.kt$onDuplicated</ID>
|
||||
<ID>ParameterNaming:AgentEditorScreen.kt$onDeleted</ID>
|
||||
<ID>ParameterNaming:AgentEditorScreen.kt$onDuplicated</ID>
|
||||
<ID>ParameterNaming:AgentEditorScreen.kt$onSaved</ID>
|
||||
<ID>ParameterNaming:AgentMcpToolsSelector.kt$onToolToggled</ID>
|
||||
<ID>ParameterNaming:AgentModelPicker.kt$onModelSelected</ID>
|
||||
<ID>ParameterNaming:AgentSharingSection.kt$onSharingChanged</ID>
|
||||
<ID>ParameterNaming:AgentSupportContactSection.kt$onSupportContactChanged</ID>
|
||||
<ID>ParameterNaming:ToolSelectDialog.kt$onToolAdded</ID>
|
||||
<ID>ParameterNaming:ToolSelectDialog.kt$onToolRemoved</ID>
|
||||
<ID>SpacingBetweenDeclarationsWithAnnotations:AgentsNavigation.kt$AgentDetail : AgentsRoute</ID>
|
||||
<ID>SpacingBetweenDeclarationsWithAnnotations:AgentsNavigation.kt$AgentEditorCreate : AgentsRoute</ID>
|
||||
<ID>SpacingBetweenDeclarationsWithAnnotations:AgentsNavigation.kt$AgentEditorEdit : AgentsRoute</ID>
|
||||
<ID>UnusedPrivateProperty:AgentDetailViewModel.kt$AgentDetailViewModel$savedStateHandle: SavedStateHandle</ID>
|
||||
<ID>UnusedPrivateProperty:AgentEditorViewModel.kt$AgentEditorViewModel$savedStateHandle: SavedStateHandle</ID>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 = "<HIDDEN>"
|
||||
|
|
|
|||
|
|
@ -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()),
|
||||
)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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)),
|
||||
)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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<AgentCategory>,
|
||||
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
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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<McpTool>,
|
||||
selectedToolNames: Set<String>,
|
||||
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<McpTool>,
|
||||
selectedToolNames: Set<String>,
|
||||
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) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<ModelOption>,
|
||||
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 = ""
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<AgentToolDisplayData>,
|
||||
selectedToolIds: List<String>,
|
||||
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)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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<NavKey>.agentsEntries(
|
||||
|
|
@ -34,21 +37,21 @@ fun EntryProviderScope<NavKey>.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<AgentEditorCreate> {
|
||||
AgentEditorScreen(
|
||||
onBack = onBack,
|
||||
onSaved = { agentId -> onNavigate(AgentDetail(agentId = agentId)) },
|
||||
onSave = { agentId -> onNavigate(AgentDetail(agentId = agentId)) },
|
||||
agentId = null,
|
||||
)
|
||||
}
|
||||
entry<AgentEditorEdit> { key ->
|
||||
AgentEditorScreen(
|
||||
onBack = onBack,
|
||||
onSaved = { agentId -> onNavigate(AgentDetail(agentId = agentId)) },
|
||||
onSave = { agentId -> onNavigate(AgentDetail(agentId = agentId)) },
|
||||
agentId = key.agentId,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -54,19 +54,11 @@ private class YamlParser(input: String) {
|
|||
val entries = mutableMapOf<String, JsonElement>()
|
||||
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<JsonElement>()
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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}, " +
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -1,58 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
<SmellBaseline>
|
||||
<ManuallySuppressedIssues/>
|
||||
<CurrentIssues>
|
||||
<ID>ComposableParamOrder:ResetPasswordScreen.kt$ResetPasswordScreen</ID>
|
||||
<ID>ComposableParamOrder:TwoFactorScreen.kt$TwoFactorScreen</ID>
|
||||
<ID>ComposableParamOrder:VerifyEmailScreen.kt$VerifyEmailScreen</ID>
|
||||
<ID>DeprecatedKoinApi:AuthModule.kt$viewModel { params -> ResetPasswordViewModel( savedStateHandle = get(), authRepository = get(), initialUserId = params.getOrNull(), initialToken = params.getOrNull(), ) }</ID>
|
||||
<ID>DeprecatedKoinApi:AuthModule.kt$viewModel { params -> TwoFactorViewModel( savedStateHandle = get(), authRepository = get(), initialTempToken = params.getOrNull(), ) }</ID>
|
||||
<ID>DeprecatedKoinApi:AuthModule.kt$viewModel { params -> VerifyEmailViewModel( savedStateHandle = get(), userRepository = get(), initialEmail = params.getOrNull(), ) }</ID>
|
||||
<ID>FunctionNaming:String0.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString0Resources(map: MutableMap<String, StringResource>)</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>LambdaParameterInRestartableEffect:LoginScreen.kt$onLoginSuccess</ID>
|
||||
<ID>LambdaParameterInRestartableEffect:LoginScreen.kt$onNavigateToTwoFactor</ID>
|
||||
<ID>LambdaParameterInRestartableEffect:RegisterScreen.kt$onRegistered</ID>
|
||||
<ID>LambdaParameterInRestartableEffect:ServerUrlScreen.kt$onServerValidated</ID>
|
||||
<ID>LambdaParameterInRestartableEffect:TermsScreen.kt$onAccepted</ID>
|
||||
<ID>LambdaParameterInRestartableEffect:TwoFactorScreen.kt$onVerified</ID>
|
||||
<ID>LambdaParameterInRestartableEffect:VerifyEmailScreen.kt$onVerified</ID>
|
||||
<ID>MaxLineLength:Res.kt$Res$public suspend</ID>
|
||||
<ID>MaxLineLength:TwoFactorScreen.kt$if (uiState.isBackupMode) stringResource(Res.string.use_authenticator_code) else stringResource(Res.string.use_backup_code)</ID>
|
||||
<ID>ModifierNotUsedAtRoot:ForgotPasswordScreen.kt$modifier = modifier .fillMaxSize() .background(MaterialTheme.colorScheme.background) .padding(padding) .padding(24.dp)</ID>
|
||||
<ID>NoBlankLineBeforeRbrace:ServerUrlViewModel.kt$ServerUrlViewModel$ </ID>
|
||||
<ID>PackageName:ExpectResourceCollectors.kt$package librechat_mobile.feature.auth.generated.resources</ID>
|
||||
<ID>PackageName:Res.kt$package librechat_mobile.feature.auth.generated.resources</ID>
|
||||
<ID>PackageName:String0.commonMain.kt$package librechat_mobile.feature.auth.generated.resources</ID>
|
||||
<ID>PackageNaming:ExpectResourceCollectors.kt$package librechat_mobile.feature.auth.generated.resources</ID>
|
||||
<ID>PackageNaming:Res.kt$package librechat_mobile.feature.auth.generated.resources</ID>
|
||||
<ID>PackageNaming:String0.commonMain.kt$package librechat_mobile.feature.auth.generated.resources</ID>
|
||||
<ID>ParameterNaming:RegisterScreen.kt$onRegistered</ID>
|
||||
<ID>ParameterNaming:ServerUrlScreen.kt$onServerValidated</ID>
|
||||
<ID>ParameterNaming:TermsScreen.kt$onAccepted</ID>
|
||||
<ID>ParameterNaming:TwoFactorScreen.kt$onCodeChanged</ID>
|
||||
<ID>ParameterNaming:TwoFactorScreen.kt$onDigitChanged</ID>
|
||||
<ID>ParameterNaming:TwoFactorScreen.kt$onVerified</ID>
|
||||
<ID>ParameterNaming:VerifyEmailScreen.kt$onVerified</ID>
|
||||
<ID>SpacingBetweenDeclarationsWithAnnotations:AuthNavigation.kt$ForgotPassword : AuthRoute</ID>
|
||||
<ID>SpacingBetweenDeclarationsWithAnnotations:AuthNavigation.kt$Login : AuthRoute</ID>
|
||||
<ID>SpacingBetweenDeclarationsWithAnnotations:AuthNavigation.kt$Register : AuthRoute</ID>
|
||||
<ID>SpacingBetweenDeclarationsWithAnnotations:AuthNavigation.kt$ResetPassword : AuthRoute</ID>
|
||||
<ID>SpacingBetweenDeclarationsWithAnnotations:AuthNavigation.kt$Terms : AuthRoute</ID>
|
||||
<ID>SpacingBetweenDeclarationsWithAnnotations:AuthNavigation.kt$TwoFactor : AuthRoute</ID>
|
||||
<ID>SpacingBetweenDeclarationsWithAnnotations:AuthNavigation.kt$VerifyEmail : AuthRoute</ID>
|
||||
<ID>UnusedPrivateProperty:ResetPasswordViewModel.kt$ResetPasswordViewModel$savedStateHandle: SavedStateHandle</ID>
|
||||
<ID>UnusedPrivateProperty:TwoFactorViewModel.kt$TwoFactorViewModel$savedStateHandle: SavedStateHandle</ID>
|
||||
<ID>UnusedPrivateProperty:VerifyEmailViewModel.kt$VerifyEmailViewModel$savedStateHandle: SavedStateHandle</ID>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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<NavKey>.authEntries(
|
||||
|
|
@ -33,7 +40,7 @@ fun EntryProviderScope<NavKey>.authEntries(
|
|||
) {
|
||||
entry<ServerUrl> {
|
||||
ServerUrlScreen(
|
||||
onServerValidated = { onNavigate(Login) },
|
||||
onServerValidate = { onNavigate(Login) },
|
||||
)
|
||||
}
|
||||
entry<Login> {
|
||||
|
|
@ -48,7 +55,7 @@ fun EntryProviderScope<NavKey>.authEntries(
|
|||
}
|
||||
entry<Register> {
|
||||
RegisterScreen(
|
||||
onRegistered = onBack,
|
||||
onRegister = onBack,
|
||||
onNavigateToLogin = onBack,
|
||||
)
|
||||
}
|
||||
|
|
@ -59,21 +66,21 @@ fun EntryProviderScope<NavKey>.authEntries(
|
|||
}
|
||||
entry<TwoFactor> { key ->
|
||||
TwoFactorScreen(
|
||||
onVerified = onAuthComplete,
|
||||
onVerify = onAuthComplete,
|
||||
onBack = onBack,
|
||||
tempToken = key.tempToken,
|
||||
)
|
||||
}
|
||||
entry<VerifyEmail> { key ->
|
||||
VerifyEmailScreen(
|
||||
onVerified = onBack,
|
||||
onVerify = onBack,
|
||||
onBack = onBack,
|
||||
email = key.email,
|
||||
)
|
||||
}
|
||||
entry<Terms> {
|
||||
TermsScreen(
|
||||
onAccepted = onAuthComplete,
|
||||
onAccept = onAuthComplete,
|
||||
onBack = onBack,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<String>,
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -106,5 +106,4 @@ class ServerUrlViewModel(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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<NSHTTPCookie>
|
||||
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<NSHTTPCookie>
|
||||
cookieList.filter { it.name == "refreshToken" }.forEach {
|
||||
|
|
|
|||
|
|
@ -1,118 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
<SmellBaseline>
|
||||
<ManuallySuppressedIssues/>
|
||||
<CurrentIssues>
|
||||
<ID>ComposableParamOrder:CommonChatInputCore.kt$CommonChatInputCore</ID>
|
||||
<ID>DeprecatedKoinApi:ChatModule.kt$viewModel { params -> PromptEditorViewModel( promptRepository = get(), savedStateHandle = get(), initialGroupId = params.getOrNull(), ) }</ID>
|
||||
<ID>FunctionNaming:String0.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString0Resources(map: MutableMap<String, StringResource>)</ID>
|
||||
<ID>FunctionNaming:String1.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString1Resources(map: MutableMap<String, StringResource>)</ID>
|
||||
<ID>FunctionNaming:String2.commonMain.kt$@InternalResourceApi internal fun _collectCommonMainString2Resources(map: MutableMap<String, StringResource>)</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>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.*</ID>
|
||||
<ID>LambdaParameterInRestartableEffect:MessageList.kt$onSearchScrollHandled</ID>
|
||||
<ID>LambdaParameterInRestartableEffect:PromptEditorScreen.kt$onBack</ID>
|
||||
<ID>MaxLineLength:ChatViewModel.kt$ChatViewModel$Logger.d { "sendMessage: webSearch=$webSearchEnabled, endpoint=${_uiState.value.selectedEndpoint}, model=${_uiState.value.selectedModel}, files=${fileRefs.size}, ephemeralAgent=$ephemeralAgent" }</ID>
|
||||
<ID>MaxLineLength:ModelSelectorSheet.kt$contentDescription = stringResource(if (isExpanded) Res.string.cd_collapse_section else Res.string.cd_expand_section, displayLabel)</ID>
|
||||
<ID>MaxLineLength:Res.kt$Res$public suspend</ID>
|
||||
<ID>MaxLineLength:SharedContentParts.kt$Icon(Icons.Default.BrokenImage, stringResource(Res.string.cd_failed_to_load_image), Modifier.size(32.dp), tint = MaterialTheme.colorScheme.onSurfaceVariant)</ID>
|
||||
<ID>MaxLineLength:SharedContentParts.kt$Icon(Icons.Default.Build, stringResource(Res.string.cd_tool_call), Modifier.size(16.dp), tint = MaterialTheme.colorScheme.onSurfaceVariant)</ID>
|
||||
<ID>MaxLineLength:SharedContentParts.kt$Icon(Icons.Default.Psychology, stringResource(Res.string.cd_thinking_indicator), Modifier.size(18.dp), tint = MaterialTheme.colorScheme.primary)</ID>
|
||||
<ID>MaxLineLength:SharedContentParts.kt$Icon(Icons.Filled.Videocam, contentDescription = null, tint = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.size(18.dp))</ID>
|
||||
<ID>MaxLineLength:SharedContentParts.kt$MarkdownContent(segment.text, Modifier.fillMaxWidth(), fontSizeMultiplier, useKatex, searchQuery, searchFocusedOccurrence, onFocusedOccurrencePositioned)</ID>
|
||||
<ID>MaxLineLength:SharedContentParts.kt$MarkdownContent(thinkingText, fontSizeMultiplier = fontSizeMultiplier, useKatex = useKatex, searchQuery = searchQuery, searchFocusedOccurrence = searchFocusedOccurrence, onFocusedOccurrencePositioned = onFocusedOccurrencePositioned)</ID>
|
||||
<ID>MaxLineLength:SharedContentParts.kt$Text(stringResource(Res.string.label_input), style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.onSurfaceVariant)</ID>
|
||||
<ID>MaxLineLength:SharedContentParts.kt$Text(stringResource(Res.string.label_output), style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.onSurfaceVariant)</ID>
|
||||
<ID>MaxLineLength:SharedContentParts.kt$Text(stringResource(Res.string.label_thinking), style = MaterialTheme.typography.titleSmall, color = MaterialTheme.colorScheme.primary, modifier = Modifier.weight(1f))</ID>
|
||||
<ID>MaxLineLength:SharedContentParts.kt$Text(stringResource(Res.string.video_not_supported), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant)</ID>
|
||||
<ID>MaxLineLength:SharedContentParts.kt$Text(toolName, style = MaterialTheme.typography.titleSmall, color = MaterialTheme.colorScheme.onSurface, modifier = Modifier.weight(1f))</ID>
|
||||
<ID>ModifierMissing:CommonChatInputCore.kt$ChatInputPlaceholder</ID>
|
||||
<ID>ModifierWithoutDefault:SharedContentParts.kt$modifier</ID>
|
||||
<ID>NoConsecutiveBlankLines:MarkdownParsing.kt$ </ID>
|
||||
<ID>PackageName:ExpectResourceCollectors.kt$package librechat_mobile.feature.chat.generated.resources</ID>
|
||||
<ID>PackageName:Res.kt$package librechat_mobile.feature.chat.generated.resources</ID>
|
||||
<ID>PackageName:String0.commonMain.kt$package librechat_mobile.feature.chat.generated.resources</ID>
|
||||
<ID>PackageName:String1.commonMain.kt$package librechat_mobile.feature.chat.generated.resources</ID>
|
||||
<ID>PackageName:String2.commonMain.kt$package librechat_mobile.feature.chat.generated.resources</ID>
|
||||
<ID>PackageNaming:ExpectResourceCollectors.kt$package librechat_mobile.feature.chat.generated.resources</ID>
|
||||
<ID>PackageNaming:Res.kt$package librechat_mobile.feature.chat.generated.resources</ID>
|
||||
<ID>PackageNaming:String0.commonMain.kt$package librechat_mobile.feature.chat.generated.resources</ID>
|
||||
<ID>PackageNaming:String1.commonMain.kt$package librechat_mobile.feature.chat.generated.resources</ID>
|
||||
<ID>PackageNaming:String2.commonMain.kt$package librechat_mobile.feature.chat.generated.resources</ID>
|
||||
<ID>ParameterNaming:ComparisonTabBar.kt$onTabChanged</ID>
|
||||
<ID>ParameterNaming:InConvoSearchBar.kt$onQueryChanged</ID>
|
||||
<ID>ParameterNaming:InlineEditInput.kt$onTextChanged</ID>
|
||||
<ID>ParameterNaming:MessageContentAndActions.kt$onEditTextChanged</ID>
|
||||
<ID>ParameterNaming:MessageContentAndActions.kt$onFocusedOccurrencePositioned</ID>
|
||||
<ID>ParameterNaming:MessageList.kt$onEditTextChanged</ID>
|
||||
<ID>ParameterNaming:MessageList.kt$onSearchScrollHandled</ID>
|
||||
<ID>ParameterNaming:ModelSelectorSheet.kt$onModelSelected</ID>
|
||||
<ID>ParameterNaming:PlatformChatComponents.kt$onEditTextChanged</ID>
|
||||
<ID>ParameterNaming:PlatformChatComponents.kt$onFocusedOccurrencePositioned</ID>
|
||||
<ID>ParameterNaming:PlatformScreens.kt$onConversationStarted</ID>
|
||||
<ID>ParameterNaming:PresetPicker.kt$onPresetSelected</ID>
|
||||
<ID>ParameterNaming:PromptFilterSheet.kt$onCategorySelected</ID>
|
||||
<ID>ParameterNaming:PromptFilterSheet.kt$onSortOrderChanged</ID>
|
||||
<ID>ParameterNaming:PromptShareDialog.kt$onShareToggled</ID>
|
||||
<ID>ParameterNaming:PromptVariablesSection.kt$onVariableChanged</ID>
|
||||
<ID>ParameterNaming:SharedContentParts.kt$onFocusedOccurrencePositioned</ID>
|
||||
<ID>ParameterNaming:SlashCommandMenu.kt$onCommandSelected</ID>
|
||||
<ID>SpacingBetweenDeclarationsWithAnnotations:ChatNavigation.kt$Chat : ChatRoute</ID>
|
||||
<ID>SpacingBetweenDeclarationsWithAnnotations:ChatNavigation.kt$PromptEditor : ChatRoute</ID>
|
||||
<ID>SpacingBetweenDeclarationsWithAnnotations:ChatNavigation.kt$PromptsLibrary : ChatRoute</ID>
|
||||
<ID>UnusedPrivateProperty:ChatViewModel.kt$ChatViewModel$savedStateHandle: SavedStateHandle</ID>
|
||||
<ID>UnusedPrivateProperty:PromptEditorViewModel.kt$PromptEditorViewModel$savedStateHandle: SavedStateHandle</ID>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue