Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
2d338d4
- Updated `TopicScreen` to use a `Scaffold` layout with a top app bar…
YugaJ7 May 28, 2025
c7b0c33
- Implement `CodeExampleBox` for displaying code snippets with copy f…
YugaJ7 May 29, 2025
9853a8d
- Removed unnecessary empty lines from `DetailScreen.kt` and `App.kt`.
YugaJ7 May 29, 2025
13f9ef3
- Updated Compose and Material dependencies.
YugaJ7 May 29, 2025
005c05f
Merge remote-tracking branch 'origin/master' into yuga/detail-topic-ui
YugaJ7 May 29, 2025
185e881
- Upgrade Material library to Material3.
YugaJ7 May 30, 2025
0471b58
Remove obsolete drawable resources
YugaJ7 May 30, 2025
21e0a29
- Updated app theming to Material 3.
YugaJ7 May 30, 2025
9e9265d
- Update `TopicScreen` and `DetailScreen` to use Material3 components…
YugaJ7 May 30, 2025
677fd94
Add string resources for UI elements.
YugaJ7 May 30, 2025
808d8fe
- Internationalized `TopicScreen` and `DetailScreen` using string res…
YugaJ7 May 30, 2025
d80dfe6
Merge remote-tracking branch 'origin/master' into yuga/detail-topic-ui
YugaJ7 May 30, 2025
404e829
Add new string resources for error handling.
YugaJ7 May 30, 2025
a1f5312
- Migrate `UiStateHandler` and `ShowAlertDialog` to Material 3 compon…
YugaJ7 May 30, 2025
54c2b40
Integrate `UiStateHandler` into `TopicScreen` and `DetailScreen` for …
YugaJ7 May 30, 2025
3ffb031
- Refined color scheme for both light and dark themes.
YugaJ7 May 31, 2025
851fae4
- Added previews for `CodeExampleBox`, `SearchField`, and `TopicCard`…
YugaJ7 May 31, 2025
3bdede0
- Update Android Previews to use `@PreviewLightDark` for concise ligh…
YugaJ7 Jun 1, 2025
608999d
Remove trailing newlines from preview files.
YugaJ7 Jun 1, 2025
54c0dc8
- Moved search query, filtered topics, and bookmarked states logic to…
yesshreyes Jun 1, 2025
4045399
Rename preview functions
YugaJ7 Jun 1, 2025
b5cb6ae
- Refactored `TopicScreen` and `DetailScreen` to separate layout from…
YugaJ7 Jun 1, 2025
509deea
- Add preview files for Detail and Topic screens.
YugaJ7 Jun 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,17 @@ kotlin {
val desktopMain by getting

androidMain.dependencies {
implementation(compose.preview)
implementation(libs.androidx.activity.compose)
implementation(libs.koin.android)
implementation(libs.koin.androidx.compose)
implementation(compose.components.uiToolingPreview)
}
commonMain.dependencies {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material)
implementation(compose.material3)
implementation(compose.ui)
implementation(compose.components.resources)
implementation(compose.materialIconsExtended)
implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.androidx.lifecycle.runtime.compose)
implementation(libs.androidx.navigation.compose)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.developersbreach.kotlindictionarymultiplatform.previews

import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import com.developersbreach.kotlindictionarymultiplatform.ui.screens.detail.CodeExampleBox
import com.developersbreach.kotlindictionarymultiplatform.ui.theme.KotlinDictionaryTheme

@PreviewLightDark
@Composable
fun CodeExampleBoxPreview() {
KotlinDictionaryTheme {
CodeExampleBox(
code = sampleCodeSnippet(),
modifier = Modifier.padding(16.dp),
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.developersbreach.kotlindictionarymultiplatform.previews

import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.PreviewLightDark
import com.developersbreach.kotlindictionarymultiplatform.ui.screens.detail.DetailScreenContent
import com.developersbreach.kotlindictionarymultiplatform.ui.theme.KotlinDictionaryTheme

@PreviewLightDark
@Composable
fun DetailScreenPreview() {
KotlinDictionaryTheme {
DetailScreenContent(topic = fakeTopicDetails())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.developersbreach.kotlindictionarymultiplatform.previews

import com.developersbreach.kotlindictionarymultiplatform.data.detail.model.CodeExample
import com.developersbreach.kotlindictionarymultiplatform.data.detail.model.KotlinTopicDetails
import com.developersbreach.kotlindictionarymultiplatform.data.detail.model.Section
import com.developersbreach.kotlindictionarymultiplatform.data.detail.model.Syntax
import com.developersbreach.kotlindictionarymultiplatform.data.topic.model.Topic

fun sampleCodeSnippet(): String = """
fun greet(name: String): String {
return "Hello, Sam!"
}
""".trimIndent()

fun topic() = "Smart Casts"

fun subtitle() = "Automatic casting of immutable values"

fun fakeTopicDetails() = KotlinTopicDetails(
topicId = "smart-cast",
topicName = "Smart Cast",
intro = "Smart casting allows the compiler to automatically cast types.",
syntax = Syntax(
signature = "if (x is String) println(x.length)",
notes = "Works only with immutable vars",
),
sections = listOf(
Section(
heading = "Why Use It?",
content = "Because it’s safer and reduces boilerplate.",
codeExamples = listOf(
CodeExample(
description = "Basic usage of smart cast",
code = """
fun printLength(obj: Any) {
if (obj is String) {
println(obj.length) // Smart cast
}
}
""".trimIndent(),
),
),
),
),
pitfalls = listOf("Doesn't work with mutable vars."),
relatedTopics = listOf("Type Checking", "Safe Casts"),
)

fun sampleTopicList(): List<Topic> = listOf(
Topic("Smart Casts"),
Topic("Null Safety"),
Topic("Coroutines"),
Topic("Lambdas"),
Topic("Sealed Classes"),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.developersbreach.kotlindictionarymultiplatform.previews

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.tooling.preview.PreviewLightDark
import com.developersbreach.kotlindictionarymultiplatform.ui.screens.topic.SearchField
import com.developersbreach.kotlindictionarymultiplatform.ui.theme.KotlinDictionaryTheme

@PreviewLightDark
@Composable
fun SearchFieldPreview() {
KotlinDictionaryTheme {
var searchQuery by remember { mutableStateOf("") }
SearchField(
searchQuery = searchQuery,
onQueryChange = { searchQuery = it },
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.developersbreach.kotlindictionarymultiplatform.previews

import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.PreviewLightDark
import com.developersbreach.kotlindictionarymultiplatform.ui.screens.topic.TopicCard
import com.developersbreach.kotlindictionarymultiplatform.ui.theme.KotlinDictionaryTheme

@PreviewLightDark
@Composable
fun TopicCardPreview() {
KotlinDictionaryTheme {
TopicCard(
topic = topic(),
subtitle = subtitle(),
isBookmarked = false,
onBookmarkClick = {},
onCardClick = {},
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.developersbreach.kotlindictionarymultiplatform.previews

import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.tooling.preview.PreviewLightDark
import com.developersbreach.kotlindictionarymultiplatform.data.topic.model.Topic
import com.developersbreach.kotlindictionarymultiplatform.ui.components.UiState
import com.developersbreach.kotlindictionarymultiplatform.ui.components.UiStateHandler
import com.developersbreach.kotlindictionarymultiplatform.ui.screens.topic.TopicScreenLayout
import com.developersbreach.kotlindictionarymultiplatform.ui.theme.KotlinDictionaryTheme
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

// Fake ViewModel for previews
class FakeTopicViewModel : TopicViewModelFakeBase() {
override val topics = MutableStateFlow<UiState<List<Topic>>>(UiState.Success(sampleTopicList()))
override val searchQuery = MutableStateFlow("")
override val filteredTopics = MutableStateFlow(sampleTopicList())
override val bookmarkedStates = MutableStateFlow(List(sampleTopicList().size) { true })

override fun updateSearchQuery(newQuery: String) {}

override fun toggleBookmark(index: Int) {}
}

// Base class to avoid needing Android ViewModel
abstract class TopicViewModelFakeBase {
abstract val topics: StateFlow<UiState<List<Topic>>>
abstract val searchQuery: StateFlow<String>
abstract val filteredTopics: StateFlow<List<Topic>>
abstract val bookmarkedStates: StateFlow<List<Boolean>>

abstract fun updateSearchQuery(newQuery: String)

abstract fun toggleBookmark(index: Int)
}

@Composable
fun TopicScreenContent(
viewModel: TopicViewModelFakeBase,
onTopicClick: (String) -> Unit = {},
) {
val topicState by viewModel.topics.collectAsState()
val filteredTopics by viewModel.filteredTopics.collectAsState()
val searchQuery by viewModel.searchQuery.collectAsState()
val bookmarkedStates by viewModel.bookmarkedStates.collectAsState()

UiStateHandler(uiState = topicState) {
TopicScreenLayout(
topics = filteredTopics,
bookmarkedStates = bookmarkedStates,
searchQuery = searchQuery,
onQueryChange = viewModel::updateSearchQuery,
onBookmarkClick = viewModel::toggleBookmark,
onTopicClick = onTopicClick,
)
}
}

@PreviewLightDark
@Composable
fun TopicScreenPreview() {
KotlinDictionaryTheme {
TopicScreenContent(viewModel = FakeTopicViewModel())
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
24 changes: 24 additions & 0 deletions composeApp/src/commonMain/composeResources/values/string.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,28 @@
<string name="error_occurred">Error occurred</string>
<string name="ok">OK</string>
<string name="error_info_unavailable">Error information not available</string>
<string name="table_of_contents">Table of Contents</string>
<string name="back">Back</string>
<string name="introduction_bullet">&#8226; Introduction</string>
<string name="syntax_bullet">&#8226; Syntax</string>
<string name="sections_bullet">&#8226; Sections</string>
<string name="pitfalls_bullet">&#8226; Pitfalls</string>
<string name="related_topics_bullet">&#8226; Related Topics</string>
<string name="introduction">Introduction</string>
<string name="syntax">Syntax</string>
<string name="sections">Sections</string>
<string name="pitfalls">Pitfalls</string>
<string name="related_topics">Related Topics</string>
<string name="notes_with_value">Notes: %1$s</string>
<string name="bullet_item">&#8226; %1$s</string>
<string name="kotlin">Kotlin</string>
<string name="copy">Copy</string>
<string name="copied">Copied</string>
<string name="topics">Topics</string>
<string name="description_subtitle">Description need to be added</string>
<string name="icon">Icon</string>
<string name="remove_bookmark">Remove bookmark</string>
<string name="add_bookmark">Add bookmark</string>
<string name="search_kotlin_terms">Search Kotlin terms...</string>
<string name="search">Search</string>
</resources>
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.developersbreach.kotlindictionarymultiplatform

import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import com.developersbreach.kotlindictionarymultiplatform.ui.navigation.AppNavigation
import com.developersbreach.kotlindictionarymultiplatform.ui.theme.KotlinDictionaryTheme

@Composable
fun App() {
MaterialTheme {
KotlinDictionaryTheme {
AppNavigation()
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.developersbreach.kotlindictionarymultiplatform.data.detail.model

import kotlinx.serialization.Serializable
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonElement

@Serializable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.developersbreach.kotlindictionarymultiplatform.ui.components

import androidx.compose.material.AlertDialog
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import kotlindictionarymultiplatform.composeapp.generated.resources.Res
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ package com.developersbreach.kotlindictionarymultiplatform.ui.components

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.mutableStateOf
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.runtime.saveable.rememberSaveable
import kotlindictionarymultiplatform.composeapp.generated.resources.Res
import kotlindictionarymultiplatform.composeapp.generated.resources.error_info_unavailable
import kotlindictionarymultiplatform.composeapp.generated.resources.error_occurred
Expand All @@ -32,7 +32,7 @@ fun <T> UiStateHandler(
is UiState.Loading -> {
CircularProgressIndicator(
modifier = Modifier.align(Alignment.Center),
color = MaterialTheme.colors.onBackground,
color = MaterialTheme.colorScheme.onBackground,
)
}

Expand All @@ -54,7 +54,7 @@ fun <T> UiStateHandler(
if (isLoading) {
CircularProgressIndicator(
modifier = Modifier.align(Alignment.Center),
color = MaterialTheme.colors.onBackground,
color = MaterialTheme.colorScheme.onBackground,
)
}
}
Expand Down
Loading
Loading