Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
## Download the APK
Access the latest APK for Kotlin Dictionary from the link below.

[![Get APK](https://img.shields.io/badge/Get%20APK-maroon?style=for-the-badge&logo=android&logoColor=white)](https://github.com/DevelopersBreach/kotlin-dictionary-multiplatform/releases/download/v0.1.0/app-release-v0.1.0.apk)
[![Get APK](https://img.shields.io/badge/Get%20APK-%23B125EA?style=for-the-badge&logo=android&logoColor=white)](https://github.com/DevelopersBreach/kotlin-dictionary-multiplatform/releases/download/v0.1.0/app-release-v0.1.0.apk)

---

Expand All @@ -29,13 +29,13 @@ Access the latest APK for Kotlin Dictionary from the link below.

### Roadmap v0.2.0

- [ ] Assign unique IDs to objects and enforce consistent ordering logic
- [x] Assign unique IDs to objects and enforce consistent ordering logic
- [ ] Correct usage of visibility modifiers across the codebase
- [ ] Introduce common `@Preview` annotations for reusable Composable previews
- [x] Add code block for syntax display on the `Detail Screen`
- [ ] Implement caching on the `Detail Screen` to store previously viewed topic data
- [ ] Implement dynamic topic loading in `TopicRepository` to support scalability
- [ ] Integrate Room database to persist bookmark states
- [x] Implement dynamic topic loading in `TopicRepository` to support scalability
- [ ] Add bookmark feature for topic cards to allow users to save and revisit important topics
- [ ] Add a `Home Page` for navigation
- [ ] Add a `Quiz Page` to host topic-based quizzes
- [ ] Add a button in `DetailScreen` to attempt a quiz for that topic
Expand Down
1 change: 1 addition & 0 deletions composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ kotlin {
implementation(libs.koin.androidx.compose)
implementation(libs.generativeai)
implementation(compose.uiTooling)
implementation(libs.ktor.client.okhttp)
}
commonMain.dependencies {
implementation(compose.runtime)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,35 @@ internal fun fakeTopicDetails(): KotlinTopicDetails {

private fun sampleTopicList(): List<Topic> {
return listOf(
Topic("Smart Casts"),
Topic("Null Safety"),
Topic("Coroutines"),
Topic("Lambdas"),
Topic("Sealed Classes"),
Topic(
name = "Smart Casts",
description = "Automatic casting by the compiler after type checks.",
),
Topic(
name = "Null Safety",
description = "Kotlin's system to eliminate null pointer exceptions at compile time.",
),
Topic(
name = "Coroutines",
description = "Lightweight threads for asynchronous and non-blocking programming.",
),
Topic(
name = "Lambdas",
description = "Anonymous functions used to pass behavior as data.",
),
Topic(
name = "Sealed Classes",
description = "Classes used to represent restricted class hierarchies for type safety.",
),
)
}

internal fun sampleTopicUiList(): List<ItemTopic> {
return sampleTopicList().map { topic ->
ItemTopic(
name = topic.name,
initial = topic.name.firstOrNull()?.uppercase() ?: "",
isBookmarked = true,
name = topic.name ?: "",
initial = topic.name?.firstOrNull()?.uppercase() ?: "",
description = topic.description ?: "",
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ private fun TopicScreenPreview() {
KotlinDictionaryTheme {
TopicScreenUI(
topics = sampleTopicUiList(),
bookmarkedStates = listOf(),
searchQuery = "Search",
onQueryChange = { },
onBookmarkClick = { },
onTopicClick = { },
)
}
Expand Down
2 changes: 0 additions & 2 deletions composeApp/src/commonMain/composeResources/values/string.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
<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,8 +1,8 @@
package com.developersbreach.kotlindictionarymultiplatform.core.network.api
package com.developersbreach.kotlindictionarymultiplatform.core.network.detailsGenerator.api

import com.developersbreach.kotlindictionarymultiplatform.Log
import com.developersbreach.kotlindictionarymultiplatform.core.network.parser.GeminiJsonParser
import com.developersbreach.kotlindictionarymultiplatform.core.network.request.GeminiPromptBuilder
import com.developersbreach.kotlindictionarymultiplatform.core.network.detailsGenerator.parser.GeminiJsonParser
import com.developersbreach.kotlindictionarymultiplatform.core.network.detailsGenerator.request.GeminiPromptBuilder
import com.developersbreach.kotlindictionarymultiplatform.data.detail.model.KotlinTopicDetails
import io.ktor.client.HttpClient
import io.ktor.client.request.post
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.developersbreach.kotlindictionarymultiplatform.core.network.parser
package com.developersbreach.kotlindictionarymultiplatform.core.network.detailsGenerator.parser

import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.developersbreach.kotlindictionarymultiplatform.core.network.request
package com.developersbreach.kotlindictionarymultiplatform.core.network.detailsGenerator.request

import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.buildJsonObject
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.developersbreach.kotlindictionarymultiplatform.core.network.topicSource

object FirestoreConstants {
private const val ROOT_URL = "https://firestore.googleapis.com/v1/projects/kotlin-dictionary/databases/(default)/documents"
const val TOPICS_URL = "$ROOT_URL/topics"
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.developersbreach.kotlindictionarymultiplatform.data.detail.repository

import arrow.core.Either
import com.developersbreach.kotlindictionarymultiplatform.core.network.api.GeminiApiService
import com.developersbreach.kotlindictionarymultiplatform.core.network.detailsGenerator.api.GeminiApiService
import com.developersbreach.kotlindictionarymultiplatform.data.detail.model.KotlinTopicDetails
import com.developersbreach.kotlindictionarymultiplatform.getOpenApiKey

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.developersbreach.kotlindictionarymultiplatform.data.topic.model

import kotlinx.serialization.Serializable

@Serializable
data class Topic(
val name: String,
val name: String?,
val description: String?,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.developersbreach.kotlindictionarymultiplatform.data.topic.model

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class TopicResponse(
@SerialName("documents") val topics: List<RawTopic>,
)

@Serializable
data class RawTopic(
@SerialName("fields") val fields: TopicFields,
)

@Serializable
data class TopicFields(
@SerialName("name") val name: RawField,
@SerialName("description") val description: RawField,
)

@Serializable
data class RawField(
@SerialName("stringValue") val value: String,
)

fun RawTopic.toTopic(): Topic {
return Topic(
name = fields.name.value,
description = fields.description.value,
)
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
package com.developersbreach.kotlindictionarymultiplatform.data.topic.repository

import arrow.core.Either
import com.developersbreach.kotlindictionarymultiplatform.data.topic.model.TopicResponse
import com.developersbreach.kotlindictionarymultiplatform.data.topic.model.Topic
import com.developersbreach.kotlindictionarymultiplatform.data.topic.model.toTopic
import com.developersbreach.kotlindictionarymultiplatform.core.network.topicSource.FirestoreConstants
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.request.get

object TopicRepository {
fun getTopics(): Either<Throwable, List<Topic>> {
class TopicRepository(
private val httpClient: HttpClient,
) {
suspend fun getTopics(): Either<Throwable, List<Topic>> {
return Either.catch {
listOf(
Topic("Variables"),
Topic("Strings"),
Topic("Functions"),
Topic("Coroutines"),
Topic("Classes"),
Topic("Interfaces"),
Topic("Objects"),
Topic("Collections"),
Topic("Null Safety"),
Topic("Lambdas"),
Topic("Higher-Order Functions"),
Topic("Delegation"),
Topic("Sealed Classes"),
Topic("Generics"),
Topic("Annotations"),
)
val topicResponse: TopicResponse = httpClient.get(FirestoreConstants.TOPICS_URL).body()
topicResponse.topics.map { it.toTopic() }
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.developersbreach.kotlindictionarymultiplatform.di

import com.developersbreach.kotlindictionarymultiplatform.core.network.api.GeminiApiService
import com.developersbreach.kotlindictionarymultiplatform.core.network.detailsGenerator.api.GeminiApiService
import org.koin.dsl.module

internal val apiModule = module {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ internal val repositoryModule = module {
DetailRepository(get())
}
single {
TopicRepository
TopicRepository(get())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,21 @@ 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.Bookmark
import androidx.compose.material.icons.outlined.BookmarkBorder
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.developersbreach.designsystem.components.KdIconButton
import com.developersbreach.designsystem.components.KdSurface
import com.developersbreach.designsystem.components.KdText
import kotlindictionarymultiplatform.composeapp.generated.resources.Res
import kotlindictionarymultiplatform.composeapp.generated.resources.add_bookmark
import kotlindictionarymultiplatform.composeapp.generated.resources.remove_bookmark
import org.jetbrains.compose.resources.stringResource

@Composable
fun TopicCard(
itemTopic: ItemTopic,
topic: String,
subtitle: String,
isBookmarked: Boolean,
onBookmarkClick: () -> Unit,
description: String,
onCardClick: () -> Unit,
) {
KdSurface(
Expand Down Expand Up @@ -91,31 +81,14 @@ fun TopicCard(
Spacer(modifier = Modifier.height(6.dp))
KdText(
modifier = Modifier,
text = subtitle,
text = description,
style = MaterialTheme.typography.labelMedium.copy(
color = MaterialTheme.colorScheme.onBackground,
),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}

KdIconButton(
modifier = Modifier,
iconModifier = Modifier,
onClick = onBookmarkClick,
imageVector = if (isBookmarked) {
Icons.Outlined.BookmarkBorder
} else {
Icons.Filled.Bookmark
},
contentDescription = if (isBookmarked) {
stringResource(Res.string.remove_bookmark)
} else {
stringResource(Res.string.add_bookmark)
},
tint = MaterialTheme.colorScheme.primary,
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,25 @@ package com.developersbreach.kotlindictionarymultiplatform.ui.screens.topic
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import kotlindictionarymultiplatform.composeapp.generated.resources.Res
import kotlindictionarymultiplatform.composeapp.generated.resources.description_subtitle
import org.jetbrains.compose.resources.stringResource

@Composable
fun TopicList(
topics: List<ItemTopic>,
bookmarkedStates: List<Boolean>,
onBookmarkClick: (Int) -> Unit,
onTopicClick: (String) -> Unit,
) {
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = PaddingValues(bottom = 40.dp),
) {
itemsIndexed(topics) { index, topic ->
val isBookmarked = bookmarkedStates.getOrNull(index) ?: true
items(topics) { topic ->
TopicCard(
topic = topic.name,
itemTopic = topic,
subtitle = stringResource(Res.string.description_subtitle),
isBookmarked = isBookmarked,
onBookmarkClick = { onBookmarkClick(index) },
description = topic.description,
onCardClick = { onTopicClick(topic.name) },
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ fun TopicScreen(
) { data ->
TopicScreenUI(
topics = data.filteredTopics,
bookmarkedStates = data.bookmarkedStates,
searchQuery = data.searchQuery,
onQueryChange = viewModel::updateSearchQuery,
onBookmarkClick = viewModel::toggleBookmark,
onTopicClick = onTopicClick,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ import com.developersbreach.designsystem.components.KdScaffold
@Composable
fun TopicScreenUI(
topics: List<ItemTopic>,
bookmarkedStates: List<Boolean>,
searchQuery: String,
onQueryChange: (String) -> Unit,
onBookmarkClick: (Int) -> Unit,
onTopicClick: (String) -> Unit,
) {
KdScaffold(
Expand All @@ -34,8 +32,6 @@ fun TopicScreenUI(
Spacer(modifier = Modifier.height(8.dp))
TopicList(
topics = topics,
bookmarkedStates = bookmarkedStates,
onBookmarkClick = onBookmarkClick,
onTopicClick = onTopicClick,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ data class TopicUi(
val isLoading: Boolean = false,
val topics: List<Topic> = emptyList(),
val searchQuery: String = "",
val bookmarkedStates: List<Boolean> = emptyList(),
val filteredTopics: List<ItemTopic> = emptyList(),
)

data class ItemTopic(
val name: String,
val initial: String,
val isBookmarked: Boolean,
val description: String,
)
Loading
Loading