diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/data/WordRepository.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/data/WordRepository.kt index c657a77..58215c8 100644 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/data/WordRepository.kt +++ b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/data/WordRepository.kt @@ -63,4 +63,8 @@ class WordRepository( override fun checkIfWordIsSaved(word: String): Flow { return localDataSource.checkWordIsExist(word) } + + override fun getBookmarks(): Flow> { + return localDataSource.getAllWords() + } } diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/data/source/local/KosaKata.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/data/source/local/KosaKata.kt new file mode 100644 index 0000000..ef0c9ae --- /dev/null +++ b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/data/source/local/KosaKata.kt @@ -0,0 +1,3 @@ +package com.example.kbbikamusbesarbahasaindonesia.core.data.source.local + +class KosaKata : ArrayList() \ No newline at end of file diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/data/source/local/room/Converters.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/data/source/local/room/Converters.kt index 2740133..c36574c 100644 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/data/source/local/room/Converters.kt +++ b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/data/source/local/room/Converters.kt @@ -1,10 +1,9 @@ package com.example.kbbikamusbesarbahasaindonesia.core.data.source.local.room import androidx.room.TypeConverter +import com.example.kbbikamusbesarbahasaindonesia.core.data.source.local.entity.ListWordEntity import com.example.kbbikamusbesarbahasaindonesia.core.data.source.local.entity.MeaningEntity import com.example.kbbikamusbesarbahasaindonesia.core.data.source.local.entity.WordEntity -import com.example.kbbikamusbesarbahasaindonesia.model.Arti -import com.example.kbbikamusbesarbahasaindonesia.model.Data import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -14,10 +13,10 @@ class Converters { @JvmStatic @TypeConverter - fun toListData(string: String?): List? { - val listType = object : TypeToken>() {}.type + fun toWordList(string: String?): List? { + val listType = object : TypeToken>() {}.type return if (string != null) { - Gson().fromJson>(string, listType) + Gson().fromJson>(string, listType) } else { null } @@ -26,7 +25,7 @@ class Converters { @JvmStatic @TypeConverter fun toListWord(string: String?): List? { - val listType = object : TypeToken>() {}.type + val listType = object : TypeToken>() {}.type return if (string != null) { Gson().fromJson>(string, listType) } else { @@ -34,17 +33,6 @@ class Converters { } } - @JvmStatic - @TypeConverter - fun fromListData(list: List?): String? { - val type = object : TypeToken>() {}.type - return if (list != null) { - Gson().toJson(list, type) - } else { - null - } - } - @JvmStatic @TypeConverter fun fromListWord(list: List?): String? { @@ -58,10 +46,10 @@ class Converters { @JvmStatic @TypeConverter - fun toListArti(string: String?): List? { - val listType = object : TypeToken>() {}.type - return if (string != null) { - Gson().fromJson>(string, listType) + fun fromWordList(list: List?): String? { + val type = object : TypeToken>() {}.type + return if (list != null) { + Gson().toJson(list, type) } else { null } @@ -78,17 +66,6 @@ class Converters { } } - @JvmStatic - @TypeConverter - fun fromListArti(list: List?): String? { - val type = object : TypeToken>() {}.type - return if (list != null) { - Gson().toJson(list, type) - } else { - null - } - } - @JvmStatic @TypeConverter fun fromListMeanings(list: List?): String? { diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/data/source/remote/network/ApiService.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/data/source/remote/network/ApiService.kt index eddfe41..9717cfe 100644 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/data/source/remote/network/ApiService.kt +++ b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/data/source/remote/network/ApiService.kt @@ -1,18 +1,10 @@ package com.example.kbbikamusbesarbahasaindonesia.core.data.source.remote.network import com.example.kbbikamusbesarbahasaindonesia.core.data.source.remote.response.ListWordResponse -import com.example.kbbikamusbesarbahasaindonesia.model.Kata -import retrofit2.Call import retrofit2.http.GET import retrofit2.http.Path interface ApiService { - - @GET("/cari/{kata}") - fun getArtiKata( - @Path("kata") kata: String, - ): Call - @GET("/cari/{word}") suspend fun getMeaningWord(@Path("word") word: String): ListWordResponse } diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/di/CoreModule.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/di/CoreModule.kt index 62fa859..0d1bfd3 100644 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/di/CoreModule.kt +++ b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/di/CoreModule.kt @@ -8,7 +8,6 @@ import com.example.kbbikamusbesarbahasaindonesia.core.data.source.remote.RemoteD import com.example.kbbikamusbesarbahasaindonesia.core.data.source.remote.network.ApiService import com.example.kbbikamusbesarbahasaindonesia.core.domain.repository.IWordRepository import com.example.kbbikamusbesarbahasaindonesia.core.utils.AppExecutors -import com.example.kbbikamusbesarbahasaindonesia.repository.KataRepository import com.example.kbbikamusbesarbahasaindonesia.utils.Constant import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor @@ -53,7 +52,6 @@ val networkModule = module { } val repositoryModule = module { - single { KataRepository(get()) } single { RemoteDataSource(get()) } single { LocalDataSource(get()) } factory { AppExecutors() } diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/domain/repository/IWordRepository.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/domain/repository/IWordRepository.kt index 9c603e5..4d1f8ad 100644 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/domain/repository/IWordRepository.kt +++ b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/domain/repository/IWordRepository.kt @@ -2,6 +2,7 @@ package com.example.kbbikamusbesarbahasaindonesia.core.domain.repository import com.example.kbbikamusbesarbahasaindonesia.core.data.Resource import com.example.kbbikamusbesarbahasaindonesia.core.data.source.local.entity.HistoryEntity +import com.example.kbbikamusbesarbahasaindonesia.core.data.source.local.entity.ListWordEntity import com.example.kbbikamusbesarbahasaindonesia.core.domain.model.WordModel import kotlinx.coroutines.flow.Flow @@ -15,4 +16,5 @@ interface IWordRepository { fun getAllHistories(): Flow> suspend fun deleteWord(word: String) fun checkIfWordIsSaved(word: String): Flow + fun getBookmarks(): Flow> } diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/domain/usecase/WordInteractor.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/domain/usecase/WordInteractor.kt index 203c064..8873a83 100644 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/domain/usecase/WordInteractor.kt +++ b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/domain/usecase/WordInteractor.kt @@ -2,6 +2,7 @@ package com.example.kbbikamusbesarbahasaindonesia.core.domain.usecase import com.example.kbbikamusbesarbahasaindonesia.core.data.Resource import com.example.kbbikamusbesarbahasaindonesia.core.data.source.local.entity.HistoryEntity +import com.example.kbbikamusbesarbahasaindonesia.core.data.source.local.entity.ListWordEntity import com.example.kbbikamusbesarbahasaindonesia.core.domain.model.WordModel import com.example.kbbikamusbesarbahasaindonesia.core.domain.repository.IWordRepository import kotlinx.coroutines.flow.Flow @@ -34,4 +35,8 @@ class WordInteractor(private val wordRepository: IWordRepository) : WordUseCase override fun checkIfWordIsSaved(word: String): Flow { return wordRepository.checkIfWordIsSaved(word) } + + override fun getBookmarks(): Flow> { + return wordRepository.getBookmarks() + } } diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/domain/usecase/WordUseCase.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/domain/usecase/WordUseCase.kt index b5b1e81..a707553 100644 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/domain/usecase/WordUseCase.kt +++ b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/core/domain/usecase/WordUseCase.kt @@ -2,6 +2,7 @@ package com.example.kbbikamusbesarbahasaindonesia.core.domain.usecase import com.example.kbbikamusbesarbahasaindonesia.core.data.Resource import com.example.kbbikamusbesarbahasaindonesia.core.data.source.local.entity.HistoryEntity +import com.example.kbbikamusbesarbahasaindonesia.core.data.source.local.entity.ListWordEntity import com.example.kbbikamusbesarbahasaindonesia.core.domain.model.WordModel import kotlinx.coroutines.flow.Flow @@ -15,4 +16,5 @@ interface WordUseCase { fun getAllHistories(): Flow> suspend fun deleteWord(word: String) fun checkIfWordIsSaved(word: String): Flow + fun getBookmarks(): Flow> } diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/data/KosaKata.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/data/KosaKata.kt deleted file mode 100644 index f830256..0000000 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/data/KosaKata.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.example.kbbikamusbesarbahasaindonesia.data - -class KosaKata : ArrayList() \ No newline at end of file diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/database/KataDao.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/database/KataDao.kt deleted file mode 100644 index dbd5ae8..0000000 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/database/KataDao.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.example.kbbikamusbesarbahasaindonesia.database - -import androidx.room.* -import com.example.kbbikamusbesarbahasaindonesia.model.History -import com.example.kbbikamusbesarbahasaindonesia.model.Kata -import kotlinx.coroutines.flow.Flow - -@Dao -interface KataDao { - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insert(kata: Kata?) - - @Query("SELECT * FROM table_kata") - fun getAllKata(): Flow> - - @Delete - suspend fun delete(kata: Kata) - - @Query("SELECT EXISTS (SELECT * FROM table_kata WHERE id = :id)") - fun isExists(id: String): Boolean - - @Query("SELECT EXISTS (SELECT * FROM table_history WHERE kata = :kata)") - fun isHistoryExist(kata: String): Boolean - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertHistory(history: History) - - @Query("SELECT * FROM table_history ORDER BY id DESC") - fun getListHistory(): Flow> -} \ No newline at end of file diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/model/Arti.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/model/Arti.kt deleted file mode 100644 index ca9a752..0000000 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/model/Arti.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.example.kbbikamusbesarbahasaindonesia.model - -import android.os.Parcelable -import kotlinx.parcelize.Parcelize - - -@Parcelize -data class Arti( - val deskripsi: String, - val kelas_kata: String -) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/model/Data.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/model/Data.kt deleted file mode 100644 index 7cf3f6a..0000000 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/model/Data.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.example.kbbikamusbesarbahasaindonesia.model - -import android.os.Parcelable -import kotlinx.parcelize.Parcelize - -@Parcelize -data class Data( - val arti: List, - val lema: String -) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/model/History.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/model/History.kt deleted file mode 100644 index 360bb27..0000000 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/model/History.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.example.kbbikamusbesarbahasaindonesia.model - -import androidx.room.Entity -import androidx.room.PrimaryKey - -/** - * Created by Ar Razy Fathan Rabbani on 18/01/23. - */ - -@Entity(tableName = "table_history") -data class History( - @PrimaryKey(autoGenerate = true) - val id: Int = 0, - var kata: String = "" -) diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/model/Kata.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/model/Kata.kt deleted file mode 100644 index a87d7a9..0000000 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/model/Kata.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.example.kbbikamusbesarbahasaindonesia.model - -import android.os.Parcelable -import androidx.room.Entity -import androidx.room.PrimaryKey -import kotlinx.parcelize.Parcelize - - -@Entity(tableName = "table_kata") -@Parcelize -data class Kata( - val kata: String = "", - val data: List, - val message: String, - val status: Boolean, - var isSaved: Boolean = false -) : Parcelable { - @PrimaryKey(autoGenerate = false) - var id: String = kata -} \ No newline at end of file diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/repository/KataRepository.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/repository/KataRepository.kt deleted file mode 100644 index d377a56..0000000 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/repository/KataRepository.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.example.kbbikamusbesarbahasaindonesia.repository - -import androidx.annotation.WorkerThread -import com.example.kbbikamusbesarbahasaindonesia.database.KataDao -import com.example.kbbikamusbesarbahasaindonesia.model.History -import com.example.kbbikamusbesarbahasaindonesia.model.Kata -import kotlinx.coroutines.flow.Flow - -class KataRepository(private val kataDao: KataDao) { - - val allSavedKata: Flow> = kataDao.getAllKata() - val listHistory: Flow> = kataDao.getListHistory() - - @WorkerThread - fun kataIsExists(kata: String) = kataDao.isExists(kata) - - @WorkerThread - fun historyIsExist(kata: String) = kataDao.isHistoryExist(kata) - - @WorkerThread - suspend fun insert(kata: Kata?) { - kataDao.insert(kata) - } - - @WorkerThread - suspend fun insertHistory(history: History) { - kataDao.insertHistory(history) - } - - @WorkerThread - suspend fun delete(kata: Kata) { - kataDao.delete(kata) - } -} diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/adapter/ArtiAdapter.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/adapter/ArtiAdapter.kt deleted file mode 100644 index 5d1053c..0000000 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/adapter/ArtiAdapter.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.example.kbbikamusbesarbahasaindonesia.ui.adapter - -import android.graphics.Color -import android.graphics.Typeface -import android.text.Spannable -import android.text.TextUtils -import android.text.style.BackgroundColorSpan -import android.text.style.ForegroundColorSpan -import android.text.style.StyleSpan -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.core.text.toSpannable -import androidx.core.text.toSpanned -import androidx.recyclerview.widget.RecyclerView -import com.example.kbbikamusbesarbahasaindonesia.databinding.ItemListChildArtiBinding -import com.example.kbbikamusbesarbahasaindonesia.model.Arti - -class ArtiAdapter( - private val listArti: List -) : RecyclerView.Adapter() { - - inner class ViewHolder(val binding: ItemListChildArtiBinding) : - RecyclerView.ViewHolder(binding.root) - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - val view = - ItemListChildArtiBinding.inflate(LayoutInflater.from(parent.context), parent, false) - return ViewHolder(view) - } - - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val arti = listArti[position] - - val number = "${position + 1}. " - val regex = Regex("\\[(.*?)\\]") - val colorBoldString = ForegroundColorSpan(Color.parseColor("#2E494C")) - val boloString = StyleSpan(Typeface.BOLD) - val kelasKata =arti.kelas_kata.replace(regex, " ").toSpannable() - kelasKata.setSpan(colorBoldString, 0, kelasKata.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) - kelasKata.setSpan(boloString, 0, kelasKata.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) - val deskripsi = " ${arti.deskripsi.replace(Regex("\\?(.*)"), "")}" - - holder.binding.deskripsi.text = TextUtils.concat(number, kelasKata, deskripsi) - - } - - override fun getItemCount(): Int = listArti.size -} \ No newline at end of file diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/adapter/FavoriteAdapter.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/adapter/FavoriteAdapter.kt index a3ffd12..90b78ac 100644 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/adapter/FavoriteAdapter.kt +++ b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/adapter/FavoriteAdapter.kt @@ -2,17 +2,29 @@ package com.example.kbbikamusbesarbahasaindonesia.ui.adapter import android.view.LayoutInflater import android.view.ViewGroup +import androidx.recyclerview.widget.AsyncListDiffer +import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView +import com.example.kbbikamusbesarbahasaindonesia.core.data.source.local.entity.ListWordEntity import com.example.kbbikamusbesarbahasaindonesia.databinding.ItemListFavoriteBinding -import com.example.kbbikamusbesarbahasaindonesia.model.Kata class FavoriteAdapter( - private val listSavedKata: List, - private val clickListener: (Kata) -> Unit + private val listener: (ListWordEntity) -> Unit, ) : RecyclerView.Adapter() { inner class ViewHolder(val binding: ItemListFavoriteBinding) : - RecyclerView.ViewHolder(binding.root) + RecyclerView.ViewHolder(binding.root) { + fun bind(data: ListWordEntity) { + with(binding) { + kataSaved.text = data.word.replaceFirstChar { it.uppercase() } + lemmaSaved.text = data.listWords[0].entry + + root.setOnClickListener { + listener(data) + } + } + } + } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = @@ -21,19 +33,24 @@ class FavoriteAdapter( } override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val curretList = listSavedKata[position] + holder.bind(differ.currentList[position]) + } - holder.binding.kataSaved.text = curretList.kata.replaceFirstChar { it.uppercase() } - holder.binding.lemmaSaved.text = curretList.data[0].lema + val diffCallback = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: ListWordEntity, newItem: ListWordEntity): Boolean { + return oldItem.word == newItem.word + } - holder.itemView.setOnClickListener { - clickListener(curretList) + override fun areContentsTheSame(oldItem: ListWordEntity, newItem: ListWordEntity): Boolean { + return oldItem == newItem } } - fun isEmpty(): Boolean = listSavedKata.isEmpty() + val differ = AsyncListDiffer(this, diffCallback) + + fun isEmpty(): Boolean = differ.currentList.isEmpty() override fun getItemCount(): Int { - return listSavedKata.size + return differ.currentList.size } } diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/adapter/KataAdapter.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/adapter/KataAdapter.kt deleted file mode 100644 index 23fd101..0000000 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/adapter/KataAdapter.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.example.kbbikamusbesarbahasaindonesia.ui.adapter - -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context -import android.view.LayoutInflater -import android.view.ViewGroup -import android.widget.Toast -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import com.example.kbbikamusbesarbahasaindonesia.databinding.ItemListArtiBinding -import com.example.kbbikamusbesarbahasaindonesia.model.Data - -class KataAdapter( - private val listData: List -) : RecyclerView.Adapter() { - - inner class ArtiKataViewHolder(val binding: ItemListArtiBinding) : RecyclerView.ViewHolder(binding.root) - - override fun onCreateViewHolder( - parent: ViewGroup, - viewType: Int - ): ArtiKataViewHolder { - val binding = ItemListArtiBinding.inflate(LayoutInflater.from(parent.context), parent, false) - return ArtiKataViewHolder(binding) - } - - override fun onBindViewHolder(holder: ArtiKataViewHolder, position: Int) { - val data = listData[position] - - holder.binding.apply { - numberItem.text = (position.plus(1)).toString() - lemma.text = data.lema - } - - holder.binding.rvArtiKataChild.apply { - layoutManager = LinearLayoutManager(holder.binding.rvArtiKataChild.context) - adapter = ArtiAdapter(listData[position].arti) - recycledViewPool - } - - holder.binding.btnSalin.setOnClickListener { - val clipboarManager = holder.itemView.context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - var arti = "" - for((index, item) in data.arti.withIndex()) { - arti += """ - ${index + 1}. ${item.kelas_kata} - ${item.deskripsi} - - """.trimIndent() - } - val clip: ClipData = ClipData.newPlainText("arti", arti) - clipboarManager.setPrimaryClip(clip) - Toast.makeText(holder.itemView.context, "Berhasil menyalin teks.", Toast.LENGTH_SHORT).show() - } - } - - override fun getItemCount(): Int = listData.size - - -} \ No newline at end of file diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/adapter/KosaKataAdapter.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/adapter/KosaKataAdapter.kt index 37082f9..569ff9c 100644 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/adapter/KosaKataAdapter.kt +++ b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/adapter/KosaKataAdapter.kt @@ -6,7 +6,7 @@ import android.widget.Filter import android.widget.Filterable import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView -import com.example.kbbikamusbesarbahasaindonesia.data.KosaKata +import com.example.kbbikamusbesarbahasaindonesia.core.data.source.local.KosaKata import com.example.kbbikamusbesarbahasaindonesia.databinding.ItemListKosaKataBinding class KosaKataAdapter( diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/home/HomeFragment.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/home/HomeFragment.kt index 35bcc6a..6be79a7 100644 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/home/HomeFragment.kt @@ -3,6 +3,7 @@ package com.example.kbbikamusbesarbahasaindonesia.ui.home import android.content.Intent import android.os.Bundle import android.view.* +import android.view.inputmethod.EditorInfo import android.widget.Toast import androidx.fragment.app.Fragment import com.example.kbbikamusbesarbahasaindonesia.R @@ -13,12 +14,8 @@ import com.example.kbbikamusbesarbahasaindonesia.core.domain.model.WordModel import com.example.kbbikamusbesarbahasaindonesia.databinding.FragmentHomeBinding import com.example.kbbikamusbesarbahasaindonesia.ui.detail.DetailActivity import com.example.kbbikamusbesarbahasaindonesia.ui.home.adapter.HistoryAdapter -import com.example.kbbikamusbesarbahasaindonesia.utils.SwipeListener -import com.example.kbbikamusbesarbahasaindonesia.utils.gone -import com.example.kbbikamusbesarbahasaindonesia.utils.viewBinding -import com.example.kbbikamusbesarbahasaindonesia.utils.visible +import com.example.kbbikamusbesarbahasaindonesia.utils.* import com.google.android.material.bottomsheet.BottomSheetDialog -import com.google.gson.Gson import org.koin.androidx.viewmodel.ext.android.viewModel class HomeFragment : Fragment(R.layout.fragment_home) { @@ -42,9 +39,18 @@ class HomeFragment : Fragment(R.layout.fragment_home) { } } - private fun setupView() { - binding.homeButtonSearch.setOnClickListener { - getMeaningOfWord(binding.editTextSearch.text.toString()) + private fun setupView() = with(binding) { + homeButtonSearch.setOnClickListener { + getMeaningOfWord(editTextSearch.text.toString()) + hideKeyboard() + } + + editTextSearch.setOnEditorActionListener { _, actionId, _ -> + if (editTextSearch.text.isNotBlank()) { + if (actionId == EditorInfo.IME_ACTION_SEARCH) getMeaningOfWord(editTextSearch.text.toString()) + hideKeyboard() + } + true } view?.setOnTouchListener(object : SwipeListener(requireActivity()) { @@ -56,21 +62,21 @@ class HomeFragment : Fragment(R.layout.fragment_home) { adapter = HistoryAdapter { word -> getMeaningOfWord(word) } - binding.rvHistory.adapter = adapter + rvHistory.adapter = adapter } private fun getMeaningOfWord(word: String) { viewModel.getMeaningOfWord(word).observe(viewLifecycleOwner) { result -> if (result != null) { when (result) { - is Resource.Loading -> binding.loadingState.visibility = View.VISIBLE + is Resource.Loading -> showLoading(true) is Resource.Success -> { - binding.loadingState.visibility = View.GONE + showLoading(false) navigateToDetail(result, word) saveWordToHistory(word) } is Resource.Error -> { - binding.loadingState.visibility = View.GONE + showLoading(false) Toast.makeText( requireContext(), "${result.message}", @@ -82,6 +88,10 @@ class HomeFragment : Fragment(R.layout.fragment_home) { } } + fun showLoading(isLoading: Boolean) { + if (isLoading) binding.loadingState.visible() else binding.loadingState.gone() + } + private fun saveWordToHistory(word: String) { viewModel.addToHistory(HistoryEntity(word.lowercase())) } @@ -90,11 +100,13 @@ class HomeFragment : Fragment(R.layout.fragment_home) { val listWordModel = ListWordModel( word = word, listWords = result?.data!!, + ).toJson() + startActivity( + Intent(requireActivity(), DetailActivity::class.java).putExtra( + "data", + listWordModel, + ), ) - val dataJson = Gson().toJson(listWordModel) - val intent = Intent(requireActivity(), DetailActivity::class.java) - intent.putExtra("data", dataJson) - startActivity(intent) } private fun showBottomDialog() { diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/saved/SavedFragment.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/saved/SavedFragment.kt index 5006dc9..9b5fe6e 100644 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/saved/SavedFragment.kt +++ b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/saved/SavedFragment.kt @@ -7,42 +7,50 @@ import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.recyclerview.widget.GridLayoutManager import com.example.kbbikamusbesarbahasaindonesia.R -import com.example.kbbikamusbesarbahasaindonesia.ui.adapter.FavoriteAdapter +import com.example.kbbikamusbesarbahasaindonesia.core.domain.model.ListWordModel +import com.example.kbbikamusbesarbahasaindonesia.core.utils.DataMapper import com.example.kbbikamusbesarbahasaindonesia.databinding.FragmentSavedBinding +import com.example.kbbikamusbesarbahasaindonesia.ui.adapter.FavoriteAdapter import com.example.kbbikamusbesarbahasaindonesia.ui.detail.DetailActivity +import com.example.kbbikamusbesarbahasaindonesia.utils.toJson import com.example.kbbikamusbesarbahasaindonesia.utils.viewBinding import org.koin.androidx.viewmodel.ext.android.viewModel class SavedFragment : Fragment(R.layout.fragment_saved) { private val binding by viewBinding(FragmentSavedBinding::bind) - private lateinit var adapter: FavoriteAdapter - private val viewModel: SavedViewModel by viewModel() + private lateinit var adapter: FavoriteAdapter override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - + setupView() observe() } - private fun observe() { - viewModel.savedKata.observe(viewLifecycleOwner) { kata -> - adapter = FavoriteAdapter(kata) { - val intent = Intent(requireActivity(), DetailActivity::class.java) - intent.putExtra("word", it.kata) - intent.putExtra("kata", it) - startActivity(intent) - } - binding.rvFavoritKata.adapter = adapter - binding.rvFavoritKata.layoutManager = GridLayoutManager(requireActivity(), 2) + private fun setupView() = with(binding) { + adapter = FavoriteAdapter { items -> + val listWordModel = ListWordModel( + word = items.word, + listWords = DataMapper.mapEntitiesToDomain(items.listWords), + ).toJson() + val intent = Intent(requireActivity(), DetailActivity::class.java) + intent.putExtra("data", listWordModel) + startActivity(intent) + } + rvFavoritKata.adapter = adapter + rvFavoritKata.layoutManager = GridLayoutManager(requireActivity(), 2) + } + private fun observe() = with(binding) { + viewModel.getBookmarks().observe(viewLifecycleOwner) { + adapter.differ.submitList(it) if (adapter.isEmpty()) { - binding.emptyLayout.isVisible = true - binding.readingPeople.isVisible = false + emptyLayout.isVisible = true + readingPeople.isVisible = false } else { - binding.emptyLayout.isVisible = false - binding.readingPeople.isVisible = true + emptyLayout.isVisible = false + readingPeople.isVisible = true } } } diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/saved/SavedViewModel.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/saved/SavedViewModel.kt index 9d1a2d2..6110985 100644 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/saved/SavedViewModel.kt +++ b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/saved/SavedViewModel.kt @@ -2,27 +2,13 @@ package com.example.kbbikamusbesarbahasaindonesia.ui.saved import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.asLiveData -import com.example.kbbikamusbesarbahasaindonesia.model.Kata -import com.example.kbbikamusbesarbahasaindonesia.repository.KataRepository -import java.lang.IllegalArgumentException +import com.example.kbbikamusbesarbahasaindonesia.core.data.source.local.entity.ListWordEntity +import com.example.kbbikamusbesarbahasaindonesia.core.domain.usecase.WordUseCase class SavedViewModel( - repository: KataRepository + private val wordUseCase: WordUseCase, ) : ViewModel() { - val savedKata: LiveData> = repository.allSavedKata.asLiveData() - + fun getBookmarks(): LiveData> = wordUseCase.getBookmarks().asLiveData() } - - -class SavedViewModelFactory(private val repository: KataRepository) : ViewModelProvider.Factory { - override fun create(modelClass: Class): T { - if (modelClass.isAssignableFrom(SavedViewModel::class.java)) { - @Suppress("UNCHECKED_CAST") - return SavedViewModel(repository) as T - } - throw IllegalArgumentException("Unknown ViewModel class") - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/word/WordFragment.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/word/WordFragment.kt index e3eb318..3c127f0 100644 --- a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/word/WordFragment.kt +++ b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/ui/word/WordFragment.kt @@ -13,7 +13,7 @@ import com.example.kbbikamusbesarbahasaindonesia.R import com.example.kbbikamusbesarbahasaindonesia.core.data.Resource import com.example.kbbikamusbesarbahasaindonesia.core.domain.model.ListWordModel import com.example.kbbikamusbesarbahasaindonesia.core.domain.model.WordModel -import com.example.kbbikamusbesarbahasaindonesia.data.KosaKata +import com.example.kbbikamusbesarbahasaindonesia.core.data.source.local.KosaKata import com.example.kbbikamusbesarbahasaindonesia.databinding.FragmentWordBinding import com.example.kbbikamusbesarbahasaindonesia.ui.adapter.KosaKataAdapter import com.example.kbbikamusbesarbahasaindonesia.ui.detail.DetailActivity diff --git a/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/utils/Ext.kt b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/utils/Ext.kt new file mode 100644 index 0000000..aae9df3 --- /dev/null +++ b/app/src/main/java/com/example/kbbikamusbesarbahasaindonesia/utils/Ext.kt @@ -0,0 +1,83 @@ +package com.example.kbbikamusbesarbahasaindonesia.utils + +import android.app.Activity +import android.content.Context +import android.view.View +import android.view.inputmethod.InputMethodManager +import android.widget.EditText +import androidx.fragment.app.Fragment +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken + +/** + * Created by Ar Razy Fathan Rabbani on 19/03/23. + */ + +fun Fragment.hideKeyboard() { + view?.let { + activity?.hideKeyboard(it) + } +} + +fun Fragment.hideKeyboard(view: View) { + val inputMethodManager = + context?.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager + inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0) +} + +fun Activity.hideKeyboard() { + hideKeyboard(currentFocus ?: View(this)) +} + +fun Context.hideKeyboard(view: View) { + val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager + inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0) +} + +fun Fragment.focusAndShowKeyboard(view: View) { + if (view.isFocusable) { + view.requestFocus() + } + if (view is EditText) { + showKeyboard() + } +} + +fun Fragment.showKeyboard() { + val imm = activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_IMPLICIT_ONLY) +} + +fun Fragment.showKeyboard(editText: View) { + editText.requestFocus() + val imm = activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_IMPLICIT_ONLY) +} + +fun Activity.showKeyboard(editText: View) { + editText.requestFocus() + val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_IMPLICIT_ONLY) +} + +fun showKeyboard(context: Context, editText: View) { + editText.requestFocus() + editText.postDelayed({ + val keyboard = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + keyboard.showSoftInput(editText, 0) + }, 200) +} + +fun hideSoftKeyboard(context: Context, editText: View) { + val inputMethodManager = + context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + inputMethodManager.hideSoftInputFromWindow(editText.windowToken, 0) +} + +inline fun fromJson(json: String): T { + return Gson().fromJson(json, object : TypeToken() {}.type) +} + +fun Any.toJson(): String { + return Gson().toJson(this) +} diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 210c7dc..9c060e6 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -47,6 +47,7 @@ android:inputType="text" android:paddingStart="12dp" android:paddingEnd="12dp" + android:imeOptions="actionSearch" android:textCursorDrawable="@drawable/custom_cursor_color" android:textSize="14sp" app:layout_constraintEnd_toStartOf="@id/home_button_search" diff --git a/app/src/main/res/layout/fragment_saved.xml b/app/src/main/res/layout/fragment_saved.xml index e8cfc53..03cf3dc 100644 --- a/app/src/main/res/layout/fragment_saved.xml +++ b/app/src/main/res/layout/fragment_saved.xml @@ -22,8 +22,9 @@