From 68febac2376f0f9e91f9869df8466d20c6f2a1c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Ch=C3=AD=20D=C5=A9ng?= Date: Sat, 31 Aug 2024 22:37:18 +0700 Subject: [PATCH] FavouriteScreen Complete --- .../weather/data/model/FavouriteLocation.kt | 11 +++- .../data/model/entity/WeatherEntity.kt | 1 - .../data/repository/WeatherRepository.kt | 23 ++----- .../data/repository/WeatherRepositoryImpl.kt | 18 +++++- .../repository/source/WeatherDataSource.kt | 9 +++ .../repository/source/local/AppDatabase.kt | 6 +- .../source/local/WeatherLocalDataSource.kt | 21 +++++++ .../source/local/dao/FavouriteDao.kt | 22 +++++++ .../source/remote/api/error/ErrorResponse.kt | 2 - .../main/java/com/sun/weather/di/AppModule.kt | 1 + .../com/sun/weather/di/ViewModelModule.kt | 4 +- .../java/com/sun/weather/ui/MainActivity.kt | 12 ++++ .../weather/ui/favourite/FavouriteAdapter.kt | 51 ++++++++++++++++ .../weather/ui/favourite/FavouriteFragment.kt | 60 +++++++++++++++++++ .../ui/favourite/FavouriteViewModel.kt | 41 +++++++++++++ .../com/sun/weather/ui/home/HomeFragment.kt | 7 ++- .../com/sun/weather/ui/home/HomeViewModel.kt | 44 ++++++++++++-- .../com/sun/weather/utils/ext/Extensions.kt | 1 - .../utils/listener/MyLocationListener.kt | 29 --------- .../weather/utils/listener/OnFetchListener.kt | 7 --- app/src/main/res/values-vi/strings.xml | 3 +- app/src/main/res/values/strings.xml | 3 +- 22 files changed, 299 insertions(+), 77 deletions(-) create mode 100644 app/src/main/java/com/sun/weather/data/repository/source/local/dao/FavouriteDao.kt create mode 100644 app/src/main/java/com/sun/weather/ui/favourite/FavouriteAdapter.kt create mode 100644 app/src/main/java/com/sun/weather/ui/favourite/FavouriteFragment.kt create mode 100644 app/src/main/java/com/sun/weather/ui/favourite/FavouriteViewModel.kt delete mode 100644 app/src/main/java/com/sun/weather/utils/listener/MyLocationListener.kt delete mode 100644 app/src/main/java/com/sun/weather/utils/listener/OnFetchListener.kt diff --git a/app/src/main/java/com/sun/weather/data/model/FavouriteLocation.kt b/app/src/main/java/com/sun/weather/data/model/FavouriteLocation.kt index 2f36b84..9c24055 100644 --- a/app/src/main/java/com/sun/weather/data/model/FavouriteLocation.kt +++ b/app/src/main/java/com/sun/weather/data/model/FavouriteLocation.kt @@ -1,7 +1,12 @@ package com.sun.weather.data.model +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "favourite_locations") data class FavouriteLocation( - val id: Long? = null, - val cityName: String, - val countryName: String, + @PrimaryKey(autoGenerate = true) val id: Long? = null, + @ColumnInfo(name = "city_name") val cityName: String, + @ColumnInfo(name = "country_name") val countryName: String, ) diff --git a/app/src/main/java/com/sun/weather/data/model/entity/WeatherEntity.kt b/app/src/main/java/com/sun/weather/data/model/entity/WeatherEntity.kt index df26f92..655f364 100644 --- a/app/src/main/java/com/sun/weather/data/model/entity/WeatherEntity.kt +++ b/app/src/main/java/com/sun/weather/data/model/entity/WeatherEntity.kt @@ -38,7 +38,6 @@ data class WeatherEntity( } object WeatherEntry { - // Local database entries const val TBL_WEATHER_NAME = "weather_forecasts" const val CURRENTLY_OBJECT = "currently" const val HOURLY_OBJECT = "hourly" diff --git a/app/src/main/java/com/sun/weather/data/repository/WeatherRepository.kt b/app/src/main/java/com/sun/weather/data/repository/WeatherRepository.kt index 424db18..c28e080 100644 --- a/app/src/main/java/com/sun/weather/data/repository/WeatherRepository.kt +++ b/app/src/main/java/com/sun/weather/data/repository/WeatherRepository.kt @@ -1,31 +1,16 @@ package com.sun.weather.data.repository - import com.sun.weather.data.model.FavouriteLocation -import com.sun.weather.data.model.Weather import com.sun.weather.data.model.entity.WeatherEntity import kotlinx.coroutines.flow.Flow interface WeatherRepository { - fun getSelectedLocation(key: String): String - - fun isFavoriteLocationExists( - cityName: String, - countryName: String, - ): Boolean - - fun saveCurrentWeather(currentWeather: WeatherEntity) - - fun saveWeeklyForecastLocal(weeklyForecast: WeatherEntity) - - fun getLocalWeather(id: String): Weather? - - fun saveHourlyForecastLocal(hourlyForecast: WeatherEntity) + suspend fun insertFavoriteWeather(favouriteLocation: FavouriteLocation) - fun insertFavoriteWeather(favouriteLocation: FavouriteLocation) + suspend fun getAllFavorite(): List - fun getAllFavorite(): List + suspend fun removeFavoriteItem(id: Long) - fun removeFavoriteItem(id: Long) + suspend fun isFavoriteLocationExists(cityName: String): Int fun getCurrentWeather( city: String, diff --git a/app/src/main/java/com/sun/weather/data/repository/WeatherRepositoryImpl.kt b/app/src/main/java/com/sun/weather/data/repository/WeatherRepositoryImpl.kt index 749ef2d..f5339ff 100644 --- a/app/src/main/java/com/sun/weather/data/repository/WeatherRepositoryImpl.kt +++ b/app/src/main/java/com/sun/weather/data/repository/WeatherRepositoryImpl.kt @@ -1,5 +1,5 @@ package com.sun.weather.data.repository - +import com.sun.weather.data.model.FavouriteLocation import com.sun.weather.data.model.entity.WeatherEntity import com.sun.weather.data.model.toWeatherEntity import com.sun.weather.data.repository.source.WeatherDataSource @@ -11,6 +11,22 @@ class WeatherRepositoryImpl( private val localDataSource: WeatherDataSource.Local, private val remoteDataSource: WeatherDataSource.Remote, ) : KoinComponent, WeatherRepository { + override suspend fun isFavoriteLocationExists(cityName: String): Int { + return localDataSource.isFavoriteLocationExists(cityName) + } + + override suspend fun insertFavoriteWeather(favouriteLocation: FavouriteLocation) { + localDataSource.insertFavourite(favouriteLocation) + } + + override suspend fun getAllFavorite(): List { + return localDataSource.getAllFavourite() + } + + override suspend fun removeFavoriteItem(id: Long) { + localDataSource.removeFavouriteItem(id) + } + override fun getCurrentWeather( city: String, language: String, diff --git a/app/src/main/java/com/sun/weather/data/repository/source/WeatherDataSource.kt b/app/src/main/java/com/sun/weather/data/repository/source/WeatherDataSource.kt index 4e4484a..7c78e7b 100644 --- a/app/src/main/java/com/sun/weather/data/repository/source/WeatherDataSource.kt +++ b/app/src/main/java/com/sun/weather/data/repository/source/WeatherDataSource.kt @@ -1,6 +1,7 @@ package com.sun.weather.data.repository.source import com.sun.weather.data.model.CurrentWeather +import com.sun.weather.data.model.FavouriteLocation import com.sun.weather.data.model.HourlyForecast import com.sun.weather.data.model.WeeklyForecast import com.sun.weather.data.model.entity.WeatherEntity @@ -20,6 +21,14 @@ interface WeatherDataSource { suspend fun getLocalWeather(id: String): WeatherEntity? suspend fun deleteWeather(id: String) + + suspend fun insertFavourite(favourite: FavouriteLocation) + + suspend fun getAllFavourite(): List + + suspend fun removeFavouriteItem(favouriteId: Long) + + suspend fun isFavoriteLocationExists(cityName: String): Int } interface Remote { diff --git a/app/src/main/java/com/sun/weather/data/repository/source/local/AppDatabase.kt b/app/src/main/java/com/sun/weather/data/repository/source/local/AppDatabase.kt index f34abf5..ff44668 100644 --- a/app/src/main/java/com/sun/weather/data/repository/source/local/AppDatabase.kt +++ b/app/src/main/java/com/sun/weather/data/repository/source/local/AppDatabase.kt @@ -1,20 +1,22 @@ package com.sun.weather.data.repository.source.local - import android.content.Context import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase import androidx.room.TypeConverters +import com.sun.weather.data.model.FavouriteLocation import com.sun.weather.data.model.entity.WeatherEntity import com.sun.weather.data.repository.source.local.converter.WeatherBasicConverter import com.sun.weather.data.repository.source.local.converter.WeatherBasicListConverter +import com.sun.weather.data.repository.source.local.dao.FavouriteDao import com.sun.weather.data.repository.source.local.dao.WeatherDao -@Database(entities = [WeatherEntity::class], version = 1, exportSchema = false) +@Database(entities = [WeatherEntity::class, FavouriteLocation::class], version = 2, exportSchema = false) @TypeConverters(WeatherBasicConverter::class, WeatherBasicListConverter::class) abstract class AppDatabase : RoomDatabase() { abstract fun weatherDao(): WeatherDao + abstract fun favouriteDao(): FavouriteDao companion object { private const val DB_NAME = "Weather.db" diff --git a/app/src/main/java/com/sun/weather/data/repository/source/local/WeatherLocalDataSource.kt b/app/src/main/java/com/sun/weather/data/repository/source/local/WeatherLocalDataSource.kt index 538c9b9..761ebd0 100644 --- a/app/src/main/java/com/sun/weather/data/repository/source/local/WeatherLocalDataSource.kt +++ b/app/src/main/java/com/sun/weather/data/repository/source/local/WeatherLocalDataSource.kt @@ -1,20 +1,25 @@ package com.sun.weather.data.repository.source.local +import com.sun.weather.data.model.FavouriteLocation import com.sun.weather.data.model.entity.WeatherEntity import com.sun.weather.data.repository.source.WeatherDataSource +import com.sun.weather.data.repository.source.local.dao.FavouriteDao import com.sun.weather.data.repository.source.local.dao.WeatherDao class WeatherLocalDataSource( private val weatherDao: WeatherDao, + private val favouriteDao: FavouriteDao, ) : WeatherDataSource.Local { override suspend fun insertCurrentWeather( current: WeatherEntity, hourly: WeatherEntity, daily: WeatherEntity, ) { + // Todo implement later } override suspend fun insertCurrentWeather(weather: WeatherEntity) { + // Todo implement later } override suspend fun getAllLocalWeathers(): List { @@ -28,4 +33,20 @@ class WeatherLocalDataSource( override suspend fun deleteWeather(id: String) { weatherDao.deleteWeather(id) } + + override suspend fun insertFavourite(favourite: FavouriteLocation) { + favouriteDao.insertFavourite(favourite) + } + + override suspend fun getAllFavourite(): List { + return favouriteDao.getAllFavourite() + } + + override suspend fun removeFavouriteItem(favouriteId: Long) { + favouriteDao.removeFavouriteItem(favouriteId) + } + + override suspend fun isFavoriteLocationExists(cityName: String): Int { + return favouriteDao.countCityByName(cityName) + } } diff --git a/app/src/main/java/com/sun/weather/data/repository/source/local/dao/FavouriteDao.kt b/app/src/main/java/com/sun/weather/data/repository/source/local/dao/FavouriteDao.kt new file mode 100644 index 0000000..f6bcd56 --- /dev/null +++ b/app/src/main/java/com/sun/weather/data/repository/source/local/dao/FavouriteDao.kt @@ -0,0 +1,22 @@ +package com.sun.weather.data.repository.source.local.dao + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import com.sun.weather.data.model.FavouriteLocation + +@Dao +interface FavouriteDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertFavourite(favourite: FavouriteLocation) + + @Query("SELECT * FROM favourite_locations") + suspend fun getAllFavourite(): List + + @Query("DELETE FROM favourite_locations WHERE id = :favouriteId") + suspend fun removeFavouriteItem(favouriteId: Long) + + @Query("SELECT COUNT(*) FROM favourite_locations WHERE city_name = :cityName") + suspend fun countCityByName(cityName: String): Int +} diff --git a/app/src/main/java/com/sun/weather/data/repository/source/remote/api/error/ErrorResponse.kt b/app/src/main/java/com/sun/weather/data/repository/source/remote/api/error/ErrorResponse.kt index 9557264..d502e36 100644 --- a/app/src/main/java/com/sun/weather/data/repository/source/remote/api/error/ErrorResponse.kt +++ b/app/src/main/java/com/sun/weather/data/repository/source/remote/api/error/ErrorResponse.kt @@ -61,8 +61,6 @@ data class ErrorResponse( return RetrofitException.toHttpError(response) } - - // We don't know what happened. We need to simply convert to an unknown error return RetrofitException.toUnexpectedError(throwable) } } diff --git a/app/src/main/java/com/sun/weather/di/AppModule.kt b/app/src/main/java/com/sun/weather/di/AppModule.kt index cdeeee9..4141d45 100644 --- a/app/src/main/java/com/sun/weather/di/AppModule.kt +++ b/app/src/main/java/com/sun/weather/di/AppModule.kt @@ -22,6 +22,7 @@ val AppModule = single { provideBaseDispatcherProvider() } single { provideAppDatabase(androidContext()) } factory { get().weatherDao() } + factory { get().favouriteDao() } single { provideGson() } } diff --git a/app/src/main/java/com/sun/weather/di/ViewModelModule.kt b/app/src/main/java/com/sun/weather/di/ViewModelModule.kt index 8b52012..e687ce7 100644 --- a/app/src/main/java/com/sun/weather/di/ViewModelModule.kt +++ b/app/src/main/java/com/sun/weather/di/ViewModelModule.kt @@ -3,6 +3,7 @@ package com.sun.weather.di import com.sun.weather.ui.MainViewModel import com.sun.weather.ui.SharedViewModel import com.sun.weather.ui.detail.DetailViewModel +import com.sun.weather.ui.favourite.FavouriteViewModel import com.sun.weather.ui.home.HomeViewModel import com.sun.weather.ui.search.SearchViewModel import org.koin.androidx.viewmodel.dsl.viewModel @@ -13,7 +14,8 @@ val ViewModelModule: Module = module { viewModel { MainViewModel(get()) } viewModel { SharedViewModel() } - viewModel { HomeViewModel(get()) } + viewModel { HomeViewModel(get(), get()) } viewModel { SearchViewModel(get()) } viewModel { DetailViewModel(get()) } + viewModel { FavouriteViewModel(get()) } } diff --git a/app/src/main/java/com/sun/weather/ui/MainActivity.kt b/app/src/main/java/com/sun/weather/ui/MainActivity.kt index 2232c39..c6d6715 100644 --- a/app/src/main/java/com/sun/weather/ui/MainActivity.kt +++ b/app/src/main/java/com/sun/weather/ui/MainActivity.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.Observer import com.sun.weather.R import com.sun.weather.base.BaseActivity import com.sun.weather.databinding.ActivityMainBinding +import com.sun.weather.ui.favourite.FavouriteFragment import com.sun.weather.ui.home.HomeFragment import org.koin.androidx.viewmodel.ext.android.viewModel @@ -23,6 +24,7 @@ class MainActivity : BaseActivity(ActivityMainBinding::infl }, ) viewModel.requestLocationAndFetchWeather(this) + setNavigation() } private fun setNextFragment(fragment: Fragment) { @@ -32,4 +34,14 @@ class MainActivity : BaseActivity(ActivityMainBinding::infl .replace(R.id.fragment_container, fragment) .commit() } + + private fun setNavigation() { + binding.bottomNavigation.setOnItemSelectedListener { + when (it.itemId) { + R.id.mi_home -> setNextFragment(HomeFragment.newInstance()) + R.id.mi_favorite -> setNextFragment(FavouriteFragment.newInstance()) + } + true + } + } } diff --git a/app/src/main/java/com/sun/weather/ui/favourite/FavouriteAdapter.kt b/app/src/main/java/com/sun/weather/ui/favourite/FavouriteAdapter.kt new file mode 100644 index 0000000..9653d24 --- /dev/null +++ b/app/src/main/java/com/sun/weather/ui/favourite/FavouriteAdapter.kt @@ -0,0 +1,51 @@ +package com.sun.weather.ui.favourite + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.sun.weather.data.model.FavouriteLocation +import com.sun.weather.databinding.ItemFavouriteBinding +import com.sun.weather.utils.listener.OnItemClickListener + +class FavouriteAdapter(private var listener: OnItemClickListener) : RecyclerView.Adapter() { + private val mListWeathers by lazy { mutableListOf() } + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int, + ): ViewHolder { + val inflater = LayoutInflater.from(parent.context) + return ViewHolder(ItemFavouriteBinding.inflate(inflater, parent, false)) + } + + override fun getItemCount(): Int { + return mListWeathers.size + } + + override fun onBindViewHolder( + holder: ViewHolder, + position: Int, + ) { + holder.bindData(mListWeathers[position]) + holder.buttonFavourite.setOnClickListener { + listener.onItemClickListener(holder.itemView, position) + } + } + + fun updateData(listData: List) { + mListWeathers.clear() + if (listData != null) { + mListWeathers.addAll(listData) + } + notifyDataSetChanged() + } + + inner class ViewHolder(private val binding: ItemFavouriteBinding) : RecyclerView.ViewHolder(binding.root) { + val buttonFavourite = binding.btnHeart + + fun bindData(newItem: FavouriteLocation) { + binding.tvCityName.text = newItem.cityName + binding.tvCountryName.text = newItem.countryName + } + } +} diff --git a/app/src/main/java/com/sun/weather/ui/favourite/FavouriteFragment.kt b/app/src/main/java/com/sun/weather/ui/favourite/FavouriteFragment.kt new file mode 100644 index 0000000..4385d15 --- /dev/null +++ b/app/src/main/java/com/sun/weather/ui/favourite/FavouriteFragment.kt @@ -0,0 +1,60 @@ +package com.sun.weather.ui.favourite + +import android.util.Log +import android.view.View +import android.widget.ImageButton +import androidx.recyclerview.widget.LinearLayoutManager +import com.sun.weather.R +import com.sun.weather.base.BaseFragment +import com.sun.weather.databinding.FragmentFavouriteBinding +import com.sun.weather.ui.SharedViewModel +import com.sun.weather.utils.ext.goBackFragment +import com.sun.weather.utils.listener.OnItemClickListener +import org.koin.androidx.viewmodel.ext.android.activityViewModel +import org.koin.androidx.viewmodel.ext.android.viewModel + +class FavouriteFragment() : BaseFragment(FragmentFavouriteBinding::inflate), OnItemClickListener { + override val viewModel: FavouriteViewModel by viewModel() + override lateinit var sharedViewModel: SharedViewModel + private lateinit var favoriteAdapter: FavouriteAdapter + + override fun initView() { + sharedViewModel = activityViewModel().value + favoriteAdapter = FavouriteAdapter(this) + binding.rvFavorite.apply { + layoutManager = LinearLayoutManager(requireContext()) + adapter = favoriteAdapter + } + + binding.toolBar.findViewById(R.id.btn_back).setOnClickListener { + goBackFragment() + } + } + + override fun initData() { + viewModel.getAllFavouriteLocations() + } + + override fun bindData() { + viewModel.favouriteLocations.observe(viewLifecycleOwner) { favouriteList -> + favouriteList?.let { + favoriteAdapter.updateData(it) + } + } + + viewModel.error.observe(viewLifecycleOwner) { errorMessage -> + Log.v("FavouriteFragment", "Error: $errorMessage") + } + } + + override fun onItemClickListener( + view: View, + position: Int, + ) { + val favouriteLocation = viewModel.favouriteLocations.value?.get(position) + favouriteLocation?.id?.let { viewModel.removeFavouriteItem(it) } + } + companion object { + fun newInstance() = FavouriteFragment() + } +} diff --git a/app/src/main/java/com/sun/weather/ui/favourite/FavouriteViewModel.kt b/app/src/main/java/com/sun/weather/ui/favourite/FavouriteViewModel.kt new file mode 100644 index 0000000..46dddbd --- /dev/null +++ b/app/src/main/java/com/sun/weather/ui/favourite/FavouriteViewModel.kt @@ -0,0 +1,41 @@ +package com.sun.weather.ui.favourite + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.sun.weather.data.model.FavouriteLocation +import com.sun.weather.data.repository.WeatherRepository +import kotlinx.coroutines.launch + +class FavouriteViewModel( + private val weatherRepository: WeatherRepository, +) : ViewModel() { + private val _favouriteLocations = MutableLiveData>() + val favouriteLocations: LiveData> = _favouriteLocations + + private val _error = MutableLiveData() + val error: LiveData = _error + + fun getAllFavouriteLocations() { + viewModelScope.launch { + try { + val locations = weatherRepository.getAllFavorite() + _favouriteLocations.value = locations + } catch (e: Exception) { + _error.value = e.message + } + } + } + + fun removeFavouriteItem(id: Long) { + viewModelScope.launch { + try { + weatherRepository.removeFavoriteItem(id) + getAllFavouriteLocations() + } catch (e: Exception) { + _error.value = e.message + } + } + } +} diff --git a/app/src/main/java/com/sun/weather/ui/home/HomeFragment.kt b/app/src/main/java/com/sun/weather/ui/home/HomeFragment.kt index 9d03174..132cfcb 100644 --- a/app/src/main/java/com/sun/weather/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/sun/weather/ui/home/HomeFragment.kt @@ -49,11 +49,12 @@ class HomeFragment : BaseFragment(FragmentHomeBinding::infl } binding.constraintLayout.setOnClickListener { cityName?.let { - replaceFragment(R.id.fragment_container, DetailFragment.newInstance(it), true) - } ?: run { - Toast.makeText(context, "City name is not available", Toast.LENGTH_SHORT).show() + replaceFragment(R.id.fragment_container, DetailFragment.newInstance(cityName!!), true) } } + binding.btnAddFavourite.setOnClickListener { + viewModel.addFavouriteLocation() + } } override fun initData() { diff --git a/app/src/main/java/com/sun/weather/ui/home/HomeViewModel.kt b/app/src/main/java/com/sun/weather/ui/home/HomeViewModel.kt index 67b7d4c..6004ef2 100644 --- a/app/src/main/java/com/sun/weather/ui/home/HomeViewModel.kt +++ b/app/src/main/java/com/sun/weather/ui/home/HomeViewModel.kt @@ -1,20 +1,27 @@ package com.sun.weather.ui.home -import androidx.lifecycle.ViewModel +import android.app.Application +import android.util.Log +import android.widget.Toast +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope +import com.sun.weather.R +import com.sun.weather.data.model.FavouriteLocation import com.sun.weather.data.model.entity.WeatherEntity import com.sun.weather.data.repository.WeatherRepository -import com.sun.weather.utils.livedata.SingleLiveData +import com.sun.weather.ui.detail.DetailFragment.Companion.MY_TAG import kotlinx.coroutines.async import kotlinx.coroutines.flow.singleOrNull import kotlinx.coroutines.launch class HomeViewModel( private val weatherRepository: WeatherRepository, -) : ViewModel() { - var currentWeather = SingleLiveData() - var isLoading = SingleLiveData() - var errorMessage = SingleLiveData() + application: Application, +) : AndroidViewModel(application) { + var currentWeather = MutableLiveData() + private var isLoading = MutableLiveData() + var errorMessage = MutableLiveData() fun fetchCurrentWeather( latitude: Double, @@ -52,4 +59,29 @@ class HomeViewModel( } } } + + fun addFavouriteLocation() { + val context = getApplication().applicationContext + currentWeather.value?.let { weather -> + val cityName = weather.city + val countryName = weather.country + + viewModelScope.launch { + val cnt = weatherRepository.isFavoriteLocationExists(cityName!!) + if (cnt > 0) { + Toast.makeText(context, context.getString(R.string.already_favorite, cityName), Toast.LENGTH_SHORT).show() + } else { + Toast.makeText( + context, + context.getString(R.string.add_favorite_success, cityName), + Toast.LENGTH_SHORT, + ).show() + val favouriteLocation = FavouriteLocation(cityName = cityName!!, countryName = countryName!!) + weatherRepository.insertFavoriteWeather(favouriteLocation) + } + } + } ?: run { + Log.v(MY_TAG, "Weather data is null, cannot add to favourites.") + } + } } diff --git a/app/src/main/java/com/sun/weather/utils/ext/Extensions.kt b/app/src/main/java/com/sun/weather/utils/ext/Extensions.kt index 4f304bd..6fb8bc3 100644 --- a/app/src/main/java/com/sun/weather/utils/ext/Extensions.kt +++ b/app/src/main/java/com/sun/weather/utils/ext/Extensions.kt @@ -1,5 +1,4 @@ package com.sun.weather.utils.ext - import android.os.Build import android.util.Log import androidx.annotation.RequiresApi diff --git a/app/src/main/java/com/sun/weather/utils/listener/MyLocationListener.kt b/app/src/main/java/com/sun/weather/utils/listener/MyLocationListener.kt deleted file mode 100644 index 414feb8..0000000 --- a/app/src/main/java/com/sun/weather/utils/listener/MyLocationListener.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.example.weather.utils.listener - -import android.location.Location -import android.location.LocationListener -import android.os.Bundle - -class MyLocationListener( - private val onFetchLocation: OnFetchListener, -) : LocationListener { - override fun onLocationChanged(location: Location) { - onFetchLocation.onDataLocation(location) - } - - override fun onStatusChanged( - provider: String?, - status: Int, - extras: Bundle?, - ) { - // TODO implement later - } - - override fun onProviderEnabled(provider: String) { - // TODO implement later - } - - override fun onProviderDisabled(provider: String) { - // TODO implement later - } -} diff --git a/app/src/main/java/com/sun/weather/utils/listener/OnFetchListener.kt b/app/src/main/java/com/sun/weather/utils/listener/OnFetchListener.kt deleted file mode 100644 index 96db1a5..0000000 --- a/app/src/main/java/com/sun/weather/utils/listener/OnFetchListener.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.example.weather.utils.listener - -import android.location.Location - -interface OnFetchListener { - fun onDataLocation(location: Location?) -} diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 85295ae..00d7e08 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -35,5 +35,6 @@ Dự báo tuần tới Thành phố yêu thích Chọn ngôn ngữ - Thành phố đã được thêm vào yêu thích,không thể thêm nữa + Thành phố %1$s đã được thêm vào yêu thích,không thể thêm nữa + Thêm thành phố %1$s vào danh sách yêu thích thành công! diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4260b4a..658b487 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -40,7 +40,8 @@ Favourite Cities heart icon Select Language - City has been added to favorites, cannot be added again + City %1$s has been added to favorites, cannot be added again + City %1$s added to favorites successfully! Tiếng Việt Tiếng Anh