update providers_config.json models and refactor IntroFlow.kt UI
This commit is contained in:
2
.idea/deploymentTargetSelector.xml
generated
2
.idea/deploymentTargetSelector.xml
generated
@@ -4,7 +4,7 @@
|
|||||||
<selectionStates>
|
<selectionStates>
|
||||||
<SelectionState runConfigName="app">
|
<SelectionState runConfigName="app">
|
||||||
<option name="selectionMode" value="DROPDOWN" />
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
<DropdownSelection timestamp="2026-02-15T16:58:18.944420200Z">
|
<DropdownSelection timestamp="2026-02-15T17:06:55.070074900Z">
|
||||||
<Target type="DEFAULT_BOOT">
|
<Target type="DEFAULT_BOOT">
|
||||||
<handle>
|
<handle>
|
||||||
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\jonas\.android\avd\Pixel_Tablet.avd" />
|
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\jonas\.android\avd\Pixel_Tablet.avd" />
|
||||||
|
|||||||
@@ -58,17 +58,17 @@
|
|||||||
"websiteUrl": "https://platform.openai.com/",
|
"websiteUrl": "https://platform.openai.com/",
|
||||||
"isCustom": false,
|
"isCustom": false,
|
||||||
"models": [
|
"models": [
|
||||||
|
{
|
||||||
|
"modelId": "gpt-5.2",
|
||||||
|
"displayName": "GPT-5.2",
|
||||||
|
"provider": "openai",
|
||||||
|
"description": "Balanced performance with enhanced reasoning and creativity."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"modelId": "gpt-5.1-instant",
|
"modelId": "gpt-5.1-instant",
|
||||||
"displayName": "GPT-5.1 Instant",
|
"displayName": "GPT-5.1 Instant",
|
||||||
"provider": "openai",
|
"provider": "openai",
|
||||||
"description": "The standard high-speed efficiency model replacing older 'Nano' tiers."
|
"description": "The standard high-speed efficiency model replacing older 'Nano' tiers."
|
||||||
},
|
|
||||||
{
|
|
||||||
"modelId": "gpt-5-nano",
|
|
||||||
"displayName": "GPT-5 Nano",
|
|
||||||
"provider": "openai",
|
|
||||||
"description": "Fast and cheap model sufficient for most tasks."
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -120,15 +120,15 @@
|
|||||||
"key": "gemini",
|
"key": "gemini",
|
||||||
"displayName": "Google Gemini",
|
"displayName": "Google Gemini",
|
||||||
"baseUrl": "https://generativelanguage.googleapis.com/",
|
"baseUrl": "https://generativelanguage.googleapis.com/",
|
||||||
"endpoint": "v1beta/models/gemini-3-flash-preview:generateContent",
|
"endpoint": "v1beta/models/gemini-2.5-pro:generateContent",
|
||||||
"websiteUrl": "https://ai.google/",
|
"websiteUrl": "https://ai.google/",
|
||||||
"isCustom": false,
|
"isCustom": false,
|
||||||
"models": [
|
"models": [
|
||||||
{
|
{
|
||||||
"modelId": "gemini-3-flash-preview",
|
"modelId": "gemini-2.5-pro",
|
||||||
"displayName": "Gemini 3 Flash",
|
"displayName": "Gemini 2.5 Pro",
|
||||||
"provider": "gemini",
|
"provider": "gemini",
|
||||||
"description": "Current default: Massive context, grounded, and extremely fast."
|
"description": "Stable release: State-of-the-art reasoning with 1M context."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"modelId": "gemini-3-pro-preview",
|
"modelId": "gemini-3-pro-preview",
|
||||||
@@ -155,12 +155,6 @@
|
|||||||
"websiteUrl": "https://groq.com/",
|
"websiteUrl": "https://groq.com/",
|
||||||
"isCustom": false,
|
"isCustom": false,
|
||||||
"models": [
|
"models": [
|
||||||
{
|
|
||||||
"modelId": "llama-4-scout-17b",
|
|
||||||
"displayName": "Llama 4 Scout",
|
|
||||||
"provider": "groq",
|
|
||||||
"description": "Powerful Llama 4 model running at extreme speed."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"modelId": "meta-llama/llama-4-maverick",
|
"modelId": "meta-llama/llama-4-maverick",
|
||||||
"displayName": "Llama 4 Maverick",
|
"displayName": "Llama 4 Maverick",
|
||||||
@@ -216,10 +210,10 @@
|
|||||||
"description": "World's fastest inference (2000+ tokens/sec) on Wafer-Scale Engines."
|
"description": "World's fastest inference (2000+ tokens/sec) on Wafer-Scale Engines."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"modelId": "llama3.1-8b",
|
"modelId": "llama-4-scout",
|
||||||
"displayName": "Llama 3.1 8B",
|
"displayName": "Llama 4 Scout",
|
||||||
"provider": "cerebras",
|
"provider": "cerebras",
|
||||||
"description": "Instant speed for simple tasks."
|
"description": "High-quality 17B active param model running at 2,600 tokens/sec."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -238,10 +232,10 @@
|
|||||||
"description": "Hosted via the Hugging Face serverless router (Free tier limits apply)."
|
"description": "Hosted via the Hugging Face serverless router (Free tier limits apply)."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"modelId": "microsoft/Phi-3.5-mini-instruct",
|
"modelId": "Qwen/Qwen2.5-72B-Instruct",
|
||||||
"displayName": "Phi 3.5 Mini",
|
"displayName": "Qwen 2.5 72B",
|
||||||
"provider": "huggingface",
|
"provider": "huggingface",
|
||||||
"description": "Highly capable small model from Microsoft."
|
"description": "High-quality open model with excellent reasoning and multilingual capabilities."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,9 @@ import androidx.compose.foundation.background
|
|||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
|
||||||
import androidx.compose.foundation.layout.FlowRow
|
import androidx.compose.foundation.layout.FlowRow
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
@@ -42,82 +40,89 @@ import eu.gaudian.translator.view.composable.AppIcons
|
|||||||
import eu.gaudian.translator.view.composable.PrimaryButton
|
import eu.gaudian.translator.view.composable.PrimaryButton
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@OptIn(ExperimentalLayoutApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
fun IntroNavHost(onIntroFinished: () -> Unit) {
|
fun IntroNavHost(onIntroFinished: () -> Unit) {
|
||||||
val pages = listOf(
|
val pages = listOf(
|
||||||
IntroPageData(
|
IntroPageData(
|
||||||
title = stringResource(R.string.intro_title_welcome),
|
title = stringResource(R.string.intro_title_welcome),
|
||||||
description = stringResource(R.string.intro_desc_welcome),
|
description = stringResource(R.string.intro_desc_welcome),
|
||||||
content = { IconContent(iconRes = R.drawable.ic_intro_welcome) }
|
content = { IconContent(iconRes = R.drawable.ic_intro_welcome) }
|
||||||
),
|
),
|
||||||
IntroPageData(
|
IntroPageData(
|
||||||
title = stringResource(R.string.intro_title_ai_assistant),
|
title = stringResource(R.string.intro_title_ai_assistant),
|
||||||
description = stringResource(R.string.intro_desc_ai_assistant),
|
description = stringResource(R.string.intro_desc_ai_assistant),
|
||||||
content = {
|
content = {
|
||||||
Column(horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(4.dp)) {
|
Column(
|
||||||
IconContent(iconRes = R.drawable.ic_intro_ai_agents)
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
FlowRow(horizontalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterHorizontally), verticalArrangement = Arrangement.spacedBy(2.dp), modifier = Modifier.fillMaxWidth()) {
|
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
SuggestionChip(onClick = { }, label = { Text(stringResource(R.string.text_mistral)) })
|
) {
|
||||||
SuggestionChip(onClick = { }, label = { Text(stringResource(R.string.text_your_own_ai)) })
|
IconContent(iconRes = R.drawable.ic_intro_ai_agents)
|
||||||
SuggestionChip(onClick = { }, label = { Text(stringResource(R.string.text_openai)) })
|
FlowRow(
|
||||||
SuggestionChip(onClick = { }, label = { Text(stringResource(R.string.text_claude)) })
|
horizontalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterHorizontally),
|
||||||
SuggestionChip(onClick = { }, label = { Text(stringResource(R.string.text_gemini)) })
|
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||||
SuggestionChip(onClick = { }, label = { Text(stringResource(R.string.text_deepseek)) })
|
modifier = Modifier.fillMaxWidth()
|
||||||
SuggestionChip(onClick = { }, label = { Text(stringResource(R.string.text_openrouter)) })
|
) {
|
||||||
SuggestionChip(onClick = { }, label = { Text(stringResource(R.string.text_and_many_more)) })
|
SuggestionChip(onClick = { }, label = { Text(stringResource(R.string.text_mistral)) })
|
||||||
|
SuggestionChip(onClick = { }, label = { Text(stringResource(R.string.text_your_own_ai)) })
|
||||||
|
SuggestionChip(onClick = { }, label = { Text(stringResource(R.string.text_openai)) })
|
||||||
|
SuggestionChip(onClick = { }, label = { Text(stringResource(R.string.text_claude)) })
|
||||||
|
SuggestionChip(onClick = { }, label = { Text(stringResource(R.string.text_gemini)) })
|
||||||
|
SuggestionChip(onClick = { }, label = { Text(stringResource(R.string.text_deepseek)) })
|
||||||
|
SuggestionChip(onClick = { }, label = { Text(stringResource(R.string.text_openrouter)) })
|
||||||
|
SuggestionChip(onClick = { }, label = { Text(stringResource(R.string.text_and_many_more)) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
IntroPageData(
|
IntroPageData(
|
||||||
title = stringResource(R.string.intro_title_dictionary_translator),
|
title = stringResource(R.string.intro_title_dictionary_translator),
|
||||||
description = stringResource(R.string.intro_desc_dictionary_translator),
|
description = stringResource(R.string.intro_desc_dictionary_translator),
|
||||||
content = { IconContent(iconRes = R.drawable.ic_intro_lookup) }
|
content = { IconContent(iconRes = R.drawable.ic_intro_lookup) }
|
||||||
|
|
||||||
),
|
),
|
||||||
IntroPageData(
|
IntroPageData(
|
||||||
title = stringResource(R.string.intro_title_flashcards),
|
title = stringResource(R.string.intro_title_flashcards),
|
||||||
description = stringResource(R.string.intro_desc_flashcards),
|
description = stringResource(R.string.intro_desc_flashcards),
|
||||||
content = { FlashcardTopicsPreview() }
|
content = { FlashcardTopicsPreview() }
|
||||||
),
|
),
|
||||||
IntroPageData(
|
IntroPageData(
|
||||||
title = stringResource(R.string.intro_title_practice),
|
title = stringResource(R.string.intro_title_practice),
|
||||||
description = stringResource(R.string.intro_desc_practice),
|
description = stringResource(R.string.intro_desc_practice),
|
||||||
content = { IconContent(iconRes = R.drawable.ic_inro_practice) }
|
content = { IconContent(iconRes = R.drawable.ic_inro_practice) }
|
||||||
),
|
),
|
||||||
IntroPageData(
|
IntroPageData(
|
||||||
title = stringResource(R.string.intro_title_learning_journey),
|
title = stringResource(R.string.intro_title_learning_journey),
|
||||||
description = stringResource(R.string.intro_desc_learning_journey),
|
description = stringResource(R.string.intro_desc_learning_journey),
|
||||||
content = { IconContent(iconRes = R.drawable.ic_intro_learning_journey)}
|
content = { IconContent(iconRes = R.drawable.ic_intro_learning_journey) }
|
||||||
),
|
),
|
||||||
IntroPageData(
|
IntroPageData(
|
||||||
title = stringResource(R.string.intro_title_categories),
|
title = stringResource(R.string.intro_title_categories),
|
||||||
description = stringResource(R.string.intro_desc_categories),
|
description = stringResource(R.string.intro_desc_categories),
|
||||||
content = { IconContent(iconRes = R.drawable.ic_intro_categories) }
|
content = { IconContent(iconRes = R.drawable.ic_intro_categories) }
|
||||||
),
|
),
|
||||||
IntroPageData(
|
IntroPageData(
|
||||||
title = stringResource(R.string.intro_title_progress),
|
title = stringResource(R.string.intro_title_progress),
|
||||||
description = stringResource(R.string.intro_desc_progress),
|
description = stringResource(R.string.intro_desc_progress),
|
||||||
content = { IconContent(iconRes = R.drawable.ic_intro_track_progress) }
|
content = { IconContent(iconRes = R.drawable.ic_intro_track_progress) }
|
||||||
),
|
),
|
||||||
IntroPageData(
|
IntroPageData(
|
||||||
title = stringResource(R.string.intro_need_help),
|
title = stringResource(R.string.intro_need_help),
|
||||||
description = stringResource(R.string.intro_if_you_need_help_you),
|
description = stringResource(R.string.intro_if_you_need_help_you),
|
||||||
content = { IconContent(iconRes = R.drawable.ic_intro_help) }
|
content = { IconContent(iconRes = R.drawable.ic_intro_help) }
|
||||||
),
|
),
|
||||||
IntroPageData(
|
IntroPageData(
|
||||||
title = stringResource(R.string.intro_title_beta),
|
title = stringResource(R.string.intro_title_beta),
|
||||||
description = stringResource(R.string.intro_desc_beta),
|
description = stringResource(R.string.intro_desc_beta),
|
||||||
content = { IconContent(iconRes = R.drawable.ic_icon_construction) }
|
content = { IconContent(iconRes = R.drawable.ic_icon_construction) }
|
||||||
),
|
),
|
||||||
IntroPageData(
|
IntroPageData(
|
||||||
title = stringResource(R.string.intro_title_all_set),
|
title = stringResource(R.string.intro_title_all_set),
|
||||||
description = stringResource(R.string.intro_desc_all_set),
|
description = stringResource(R.string.intro_desc_all_set),
|
||||||
content = { IconContent(iconRes = R.drawable.ic_intro_robot) }
|
content = { IconContent(iconRes = R.drawable.ic_intro_robot) }
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
val pagerState = rememberPagerState(pageCount = { pages.size })
|
val pagerState = rememberPagerState(pageCount = { pages.size })
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
@@ -128,7 +133,6 @@ fun IntroNavHost(onIntroFinished: () -> Unit) {
|
|||||||
.statusBarsPadding()
|
.statusBarsPadding()
|
||||||
.padding(horizontal = 16.dp, vertical = 8.dp)
|
.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||||
) {
|
) {
|
||||||
// Full-width Skip intro button aligned to end but sized like primary (fillMaxWidth)
|
|
||||||
eu.gaudian.translator.view.composable.SecondaryButton(
|
eu.gaudian.translator.view.composable.SecondaryButton(
|
||||||
onClick = { onIntroFinished() },
|
onClick = { onIntroFinished() },
|
||||||
text = stringResource(R.string.intro_skip),
|
text = stringResource(R.string.intro_skip),
|
||||||
@@ -145,7 +149,9 @@ fun IntroNavHost(onIntroFinished: () -> Unit) {
|
|||||||
) {
|
) {
|
||||||
HorizontalPager(
|
HorizontalPager(
|
||||||
state = pagerState,
|
state = pagerState,
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.weight(1f)
|
||||||
) { pageIndex ->
|
) { pageIndex ->
|
||||||
IntroPage(pageData = pages[pageIndex])
|
IntroPage(pageData = pages[pageIndex])
|
||||||
}
|
}
|
||||||
@@ -170,7 +176,7 @@ fun IntroNavHost(onIntroFinished: () -> Unit) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
text = if (pagerState.currentPage < pages.size - 1) stringResource(R.string.next) else stringResource(R.string.get_started),
|
text = if (pagerState.currentPage < pages.size - 1) stringResource(R.string.next) else stringResource(R.string.get_started),
|
||||||
icon = if (pagerState.currentPage < pages.size - 1)AppIcons.ArrowForwardNoChevron else null,
|
icon = if (pagerState.currentPage < pages.size - 1) AppIcons.ArrowForwardNoChevron else null,
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -189,9 +195,9 @@ private fun IntroPage(pageData: IntroPageData) {
|
|||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement.spacedBy(24.dp, Alignment.CenterVertically),
|
verticalArrangement = Arrangement.spacedBy(24.dp, Alignment.CenterVertically),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxHeight()
|
.fillMaxSize() // Fixed: This was previously fillMaxHeight()
|
||||||
.padding(horizontal = 16.dp)
|
.padding(horizontal = 16.dp)
|
||||||
.verticalScroll(rememberScrollState()) // Allow scrolling for larger hint content
|
.verticalScroll(rememberScrollState())
|
||||||
) {
|
) {
|
||||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
Text(
|
Text(
|
||||||
@@ -234,15 +240,14 @@ private fun PagerIndicator(pageCount: Int, currentPage: Int) {
|
|||||||
@Composable
|
@Composable
|
||||||
private fun IconContent(iconRes: Int) {
|
private fun IconContent(iconRes: Int) {
|
||||||
Box(modifier = Modifier.clip(RoundedCornerShape(16.dp))) {
|
Box(modifier = Modifier.clip(RoundedCornerShape(16.dp))) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(id = iconRes),
|
painter = painterResource(id = iconRes),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = Color.Unspecified,
|
tint = Color.Unspecified,
|
||||||
modifier = Modifier.size(250.dp)
|
modifier = Modifier.size(250.dp)
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun FlashcardTopicsPreview() {
|
private fun FlashcardTopicsPreview() {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import androidx.compose.foundation.BorderStroke
|
|||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
|
||||||
import androidx.compose.foundation.layout.FlowRow
|
import androidx.compose.foundation.layout.FlowRow
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
@@ -391,7 +390,6 @@ private fun ExerciseTypeSelector(
|
|||||||
onTypeSelected: (VocabularyExerciseType) -> Unit,
|
onTypeSelected: (VocabularyExerciseType) -> Unit,
|
||||||
) {
|
) {
|
||||||
// Using FlowRow for a more flexible layout that wraps to the next line if needed
|
// Using FlowRow for a more flexible layout that wraps to the next line if needed
|
||||||
@OptIn(ExperimentalLayoutApi::class)
|
|
||||||
FlowRow(
|
FlowRow(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterHorizontally),
|
horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterHorizontally),
|
||||||
|
|||||||
Reference in New Issue
Block a user