Skip to content

Commit

Permalink
fixes #75 fixes #66
Browse files Browse the repository at this point in the history
  • Loading branch information
yamin8000 committed Feb 9, 2024
1 parent 768ca39 commit bcbce76
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ data class TermEntity(
val word: String,
@PrimaryKey(autoGenerate = true)
val id: Long = 0
)
)
18 changes: 10 additions & 8 deletions app/src/main/java/io/github/yamin8000/owl/ui/content/home/Home.kt
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ import io.github.yamin8000.owl.ui.composable.InternetAwareComposable
import io.github.yamin8000.owl.ui.composable.LockScreenOrientation
import io.github.yamin8000.owl.ui.composable.MySnackbar
import io.github.yamin8000.owl.ui.composable.PersianText
import io.github.yamin8000.owl.ui.content.MainBottomBar
import io.github.yamin8000.owl.ui.content.MainTopBar
import io.github.yamin8000.owl.ui.content.TopBarItem
import io.github.yamin8000.owl.util.AutoCompleteHelper
import io.github.yamin8000.owl.util.viewModelFactory
import kotlinx.collections.immutable.toPersistentList
Expand All @@ -76,7 +73,7 @@ internal fun HomeContent(
isStartingBlank: Boolean,
isVibrating: Boolean,
ttsLang: String,
onTopBarClick: (TopBarItem) -> Unit,
onTopBarClick: (HomeTopBarItem) -> Unit,
onAddToHistory: (String) -> Unit,
onAddToFavourite: (String) -> Unit
) {
Expand Down Expand Up @@ -115,7 +112,12 @@ internal fun HomeContent(
focusManager.clearFocus()
}

else -> {}
SearchState.Cached -> {
keyboardManager?.hide()
focusManager.clearFocus()
}

SearchState.Unknown -> {}
}
vm.resetSearchState()
}
Expand Down Expand Up @@ -158,15 +160,15 @@ internal fun HomeContent(
}
},
topBar = {
val onClick: (TopBarItem) -> Unit = remember {
val onClick: (HomeTopBarItem) -> Unit = remember {
{
when (it) {
TopBarItem.Random -> vm.ioScope.launch { vm.searchForRandomWord() }
HomeTopBarItem.Random -> vm.ioScope.launch { vm.searchForRandomWord() }
else -> onTopBarClick(it)
}
}
}
MainTopBar(onTopBarClick = onClick)
MainTopBar(onItemClick = onClick)
},
bottomBar = {
val search = vm.searchTerm.collectAsState()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* freeDictionaryApp/freeDictionaryApp.app.main
* MainBottomBar.kt Copyrighted by Yamin Siahmargooei at 2023/8/26
* MainBottomBar.kt Last modified at 2023/8/26
* HomeBottomBar.kt Copyrighted by Yamin Siahmargooei at 2023/8/26
* HomeBottomBar.kt Last modified at 2023/8/26
* This file is part of freeDictionaryApp/freeDictionaryApp.app.main.
* Copyright (C) 2023 Yamin Siahmargooei
*
Expand All @@ -19,7 +19,7 @@
* along with freeDictionaryApp. If not, see <https://www.gnu.org/licenses/>.
*/

package io.github.yamin8000.owl.ui.content
package io.github.yamin8000.owl.ui.content.home

import android.content.Context
import androidx.compose.animation.Crossfade
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/*
* freeDictionaryApp/freeDictionaryApp.app.main
* MainTopBar.kt Copyrighted by Yamin Siahmargooei at 2023/8/26
* MainTopBar.kt Last modified at 2023/8/26
* HomeTopBar.kt Copyrighted by Yamin Siahmargooei at 2024/2/9
* HomeTopBar.kt Last modified at 2024/2/8
* This file is part of freeDictionaryApp/freeDictionaryApp.app.main.
* Copyright (C) 2023 Yamin Siahmargooei
* Copyright (C) 2024 Yamin Siahmargooei
*
* freeDictionaryApp/freeDictionaryApp.app.main is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand All @@ -19,7 +19,7 @@
* along with freeDictionaryApp. If not, see <https://www.gnu.org/licenses/>.
*/

package io.github.yamin8000.owl.ui.content
package io.github.yamin8000.owl.ui.content.home

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.twotone.Casino
Expand All @@ -41,19 +41,19 @@ import io.github.yamin8000.owl.ui.composable.ClickableIcon
@OptIn(ExperimentalMaterial3Api::class)
@Composable
internal fun MainTopBar(
onTopBarClick: (TopBarItem) -> Unit
onItemClick: (HomeTopBarItem) -> Unit
) {
Surface(
shadowElevation = 8.dp,
content = {
TopAppBar(
title = { AppIcon() },
actions = {
val onHistoryClick = remember { { onTopBarClick(TopBarItem.History) } }
val onFavouriteClick = remember { { onTopBarClick(TopBarItem.Favourites) } }
val onRandomClick = remember { { onTopBarClick(TopBarItem.Random) } }
val onSettingsClick = remember { { onTopBarClick(TopBarItem.Settings) } }
val onInfoClick = remember { { onTopBarClick(TopBarItem.Info) } }
val onHistoryClick = remember { { onItemClick(HomeTopBarItem.History) } }
val onFavouriteClick = remember { { onItemClick(HomeTopBarItem.Favourites) } }
val onRandomClick = remember { { onItemClick(HomeTopBarItem.Random) } }
val onSettingsClick = remember { { onItemClick(HomeTopBarItem.Settings) } }
val onInfoClick = remember { { onItemClick(HomeTopBarItem.Info) } }
ClickableIcon(
imageVector = Icons.TwoTone.History,
contentDescription = stringResource(R.string.search_history),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* freeDictionaryApp/freeDictionaryApp.app.main
* TopBarItem.kt Copyrighted by Yamin Siahmargooei at 2024/2/2
* TopBarItem.kt Last modified at 2024/2/2
* HomeTopBarItem.kt Copyrighted by Yamin Siahmargooei at 2024/2/9
* HomeTopBarItem.kt Last modified at 2024/2/4
* This file is part of freeDictionaryApp/freeDictionaryApp.app.main.
* Copyright (C) 2024 Yamin Siahmargooei
*
Expand All @@ -19,16 +19,16 @@
* along with freeDictionaryApp. If not, see <https://www.gnu.org/licenses/>.
*/

package io.github.yamin8000.owl.ui.content
package io.github.yamin8000.owl.ui.content.home

import io.github.yamin8000.owl.ui.navigation.Nav

internal sealed class TopBarItem {
data object Info : TopBarItem()
data object Settings : TopBarItem()
data object Favourites : TopBarItem()
data object History : TopBarItem()
data object Random : TopBarItem()
internal sealed class HomeTopBarItem {
data object Info : HomeTopBarItem()
data object Settings : HomeTopBarItem()
data object Favourites : HomeTopBarItem()
data object History : HomeTopBarItem()
data object Random : HomeTopBarItem()

fun route() = when (this) {
Favourites -> Nav.Routes.Favourites.toString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ import io.github.yamin8000.owl.data.db.entity.EntryEntity
import io.github.yamin8000.owl.data.db.entity.MeaningEntity
import io.github.yamin8000.owl.data.db.entity.PhoneticEntity
import io.github.yamin8000.owl.data.db.entity.TermEntity
import io.github.yamin8000.owl.data.model.Definition
import io.github.yamin8000.owl.data.model.Entry
import io.github.yamin8000.owl.data.model.License
import io.github.yamin8000.owl.data.model.Meaning
import io.github.yamin8000.owl.data.model.Phonetic
import io.github.yamin8000.owl.data.network.APIs
import io.github.yamin8000.owl.data.network.Web
import io.github.yamin8000.owl.data.network.Web.getAPI
Expand Down Expand Up @@ -139,29 +142,75 @@ internal class HomeViewModel(
_isSearching.value = true
_searchTerm.value = searchTerm

return try {
val result = Web.retrofit.getAPI<APIs.FreeDictionaryAPI>().search(searchTerm.trim())
val entry = result.firstOrNull()
if (entry != null) {
addWordToDatabase(entry)
cacheEntryData(entry)
val cache = findCachedDefinitionOrNull(searchTerm)
if (cache == null) {
return try {
val result = Web.retrofit.getAPI<APIs.FreeDictionaryAPI>().search(searchTerm.trim())
val entry = result.firstOrNull()
if (entry != null) {
addWordToDatabase(entry)
cacheEntryData(entry)
}
_searchState.emit(SearchState.RequestSucceed)
result
} catch (e: HttpException) {
_searchState.emit(SearchState.RequestFailed(e.code()))
listOf()
} catch (e: CancellationException) {
_searchState.emit(SearchState.RequestFailed(SearchState.CANCEL))
listOf()
} catch (e: Exception) {
_searchState.emit(SearchState.RequestFailed(SearchState.UNKNOWN))
listOf()
} finally {
_isSearching.value = false
}
_searchState.emit(SearchState.RequestSucceed)
result
} catch (e: HttpException) {
_searchState.emit(SearchState.RequestFailed(e.code()))
listOf()
} catch (e: CancellationException) {
_searchState.emit(SearchState.RequestFailed(SearchState.CANCEL))
listOf()
} catch (e: Exception) {
_searchState.emit(SearchState.RequestFailed(SearchState.UNKNOWN))
listOf()
} finally {
} else {
_isSearching.value = false
_searchState.emit(SearchState.Cached)
return listOf(cache)
}
}

private suspend fun findCachedDefinitionOrNull(
searchTerm: String
): Entry? {
val entry = Constants.db.entryDao()
.where("word", searchTerm.trim().lowercase())
.firstOrNull()
return if (entry != null) retrieveCachedWordData(entry) else null
}

private suspend fun retrieveCachedWordData(
entry: EntryEntity
): Entry {
val phonetics = Constants.db.phoneticDao().where("entryId", entry.id)
val meanings = Constants.db.meaningDao().where("entryId", entry.id)
val definitions = Constants.db.definitionDao().all()

return Entry(
word = entry.word,
phonetics = phonetics.map { Phonetic(text = it.value) },
license = License("", ""),
sourceUrls = listOf(),
meanings = meanings.map { meaning ->
Meaning(
partOfSpeech = meaning.partOfSpeech,
antonyms = listOf(),
synonyms = listOf(),
definitions = definitions.filter { it.meaningId == meaning.id }.map {
Definition(
definition = it.definition,
example = it.example,
antonyms = listOf(),
synonyms = listOf()
)
}
)
}
)
}

private suspend fun addWordToDatabase(
entry: Entry
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ internal sealed class SearchState {
data class RequestFailed(val code: Int) : SearchState()
data class RequestFinished(val term: String) : SearchState()
data object Unknown : SearchState()
data object Cached : SearchState()

companion object {
const val CANCEL = 997
Expand Down

0 comments on commit bcbce76

Please sign in to comment.