From 002c9a9e2db284873790c21980c38641e919311f Mon Sep 17 00:00:00 2001 From: JUNGGWAN KIM Date: Wed, 2 Oct 2024 17:43:18 +0900 Subject: [PATCH] today's dress by the hour --- .../rasel/lunar/launcher/LauncherActivity.kt | 2 +- .../rasel/lunar/launcher/home/LauncherHome.kt | 75 +++++++++++++++++- .../launcher/home/adapters/WeatherAdapter.kt | 76 ++++++++++++------- .../lunar/launcher/model/WeatherForcast.kt | 3 + .../rasel/lunar/launcher/workers/WorkersDb.kt | 5 -- app/src/main/res/layout/launcher_home.xml | 8 +- .../res/layout/recommended_hourly_dress.xml | 18 ++--- 7 files changed, 137 insertions(+), 50 deletions(-) diff --git a/app/src/main/kotlin/rasel/lunar/launcher/LauncherActivity.kt b/app/src/main/kotlin/rasel/lunar/launcher/LauncherActivity.kt index 9b2c172f..0529595f 100644 --- a/app/src/main/kotlin/rasel/lunar/launcher/LauncherActivity.kt +++ b/app/src/main/kotlin/rasel/lunar/launcher/LauncherActivity.kt @@ -304,7 +304,7 @@ internal class LauncherActivity : AppCompatActivity() { mWorkManager?.cancelAllWorkByTag(LocationGetter.TAG) mWorkManager?.enqueueUniquePeriodicWork( LocationGetter.TAG, ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE, - PeriodicWorkRequestBuilder(midTimePeriod, TimeUnit.MINUTES) + PeriodicWorkRequestBuilder(midTimePeriod, TimeUnit.MINUTES) .addTag(LocationGetter.TAG) .build()) }, weatherDelay, TimeUnit.SECONDS) diff --git a/app/src/main/kotlin/rasel/lunar/launcher/home/LauncherHome.kt b/app/src/main/kotlin/rasel/lunar/launcher/home/LauncherHome.kt index d2620d5d..fcc04202 100644 --- a/app/src/main/kotlin/rasel/lunar/launcher/home/LauncherHome.kt +++ b/app/src/main/kotlin/rasel/lunar/launcher/home/LauncherHome.kt @@ -53,9 +53,13 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.work.OneTimeWorkRequest import androidx.work.WorkManager +import io.realm.kotlin.ext.asFlow import io.realm.kotlin.ext.query +import io.realm.kotlin.notifications.InitialObject import io.realm.kotlin.notifications.InitialResults +import io.realm.kotlin.notifications.ObjectChange import io.realm.kotlin.notifications.ResultsChange +import io.realm.kotlin.notifications.UpdatedObject import io.realm.kotlin.notifications.UpdatedResults import io.realm.kotlin.query.RealmResults import io.realm.kotlin.query.Sort @@ -86,11 +90,13 @@ import rasel.lunar.launcher.home.adapters.NotificationItemAdapter import rasel.lunar.launcher.home.adapters.RecentCallsAdapter import rasel.lunar.launcher.home.adapters.RssItemAdapter import rasel.lunar.launcher.home.adapters.SmsLogsAdapter +import rasel.lunar.launcher.home.adapters.WeatherAdapter import rasel.lunar.launcher.model.CurrentPlayItem import rasel.lunar.launcher.model.NotificationItem import rasel.lunar.launcher.model.RssData import rasel.lunar.launcher.model.RssDataInterface import rasel.lunar.launcher.model.RssDataType +import rasel.lunar.launcher.model.WeatherForcast import rasel.lunar.launcher.qaccess.QuickAccess import rasel.lunar.launcher.settings.SettingsActivity import rasel.lunar.launcher.utils.BLog @@ -166,6 +172,7 @@ internal class LauncherHome : Fragment() { home = this BLog.LOGE("${this} ::::: onCreate >>>> ") } + var mWeatherResult : RealmResults? = null override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { BLog.LOGE("${this} ::::: onCreateView >>>> ") binding = LauncherHomeBinding.inflate(inflater, container, false) @@ -176,6 +183,11 @@ internal class LauncherHome : Fragment() { mSmsLogsAdapter = SmsLogsAdapter(arrayListOf(), requireContext()) mNotiAdapter = NotificationItemAdapter(requireContext()) mRssAdapter = RssItemAdapter(requireContext()) + mWeatherAdapter = WeatherAdapter(arrayListOf()) +// WorkersDb.getRealm().query().first().find()?.forecast?.let { +// mWeatherAdapter?.update(it.forecastday) +// BLog.LOGE("saved weatherForcast >>> ${it.forecastday}") +// } val decoration = DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL) @@ -189,12 +201,13 @@ internal class LauncherHome : Fragment() { binding.mainList.layoutManager = GridLayoutManager(requireContext(),2) binding.smsList.layoutManager = GridLayoutManager(requireContext(),2) binding.infoList.layoutManager = LinearLayoutManager(requireContext()) + binding.noticeSummary.weatherRecycller.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false) binding.mainList.adapter = mRecentCallsAdapter binding.smsList.adapter = mSmsLogsAdapter binding.infoList.adapter = mRssAdapter binding.notiList.adapter = mNotiAdapter - + binding.noticeSummary.weatherRecycller.adapter = mWeatherAdapter binding.favAppsGroup.setOnClickListener { searchData() } try{binding.mainList.removeOnScrollListener(onScrChanged)}catch (e : Exception){e.printStackTrace()} @@ -272,12 +285,45 @@ internal class LauncherHome : Fragment() { mAudioManager.dispatchMediaKeyEvent(upEvent) } - queryInfos() queryNotice() + queryWeather() + return binding.root } + @SuppressLint("NotifyDataSetChanged") + private fun queryWeather() { + mWeatherResult = WorkersDb.getRealm().query().find() + val weatherJob = CoroutineScope(Dispatchers.Default).launch { + mWeatherResult?.asFlow()?.collect { changes -> + BLog.LOGE("saved weatherForcast >>> asFlow ${changes.list}") + if (changes.list.size > 0) { + changes.list.first().forecast?.forecastdayRealm?.let { li -> + BLog.LOGE("LauncherHome Saved Forecastdays >>> ${li.size}") + Handler(Looper.getMainLooper()).post { + mWeatherAdapter?.let{ + it.update( + it.filter( + li.first() + .hourRealm + .also { hli -> + BLog.LOGE("LauncherHome Saved hli >>> ${hli.size}") + } + ).also { fli -> + BLog.LOGE("LauncherHome Saved fli >>> ${fli.size}") + } + ) + it.notifyDataSetChanged() + } + } + } + } + } + } + weatherJob.start() + } + val hideListViewTime = 1000L * 60L * 15L val hideListView = { @@ -451,6 +497,30 @@ internal class LauncherHome : Fragment() { } is UpdatedResults -> { // lasted = changes.list +// commandHandler.postDelayed(infoUpdate, UPDATE_DELAY * 3) + } + else -> { + } + } + } + } + infosJob?.start() + + mRssDataResult = rQ.sort("pubDate ", Sort.DESCENDING).find() + infosJob = CoroutineScope(Dispatchers.Default).launch { + mRssDataResult?.asFlow()?.collect { changes: ResultsChange -> + commandHandler.removeCallbacks(hideListView) + commandHandler.removeCallbacks(infoUpdate) + when (changes) { + is InitialResults -> { + WorkersDb.getRealm().apply { + lasted = copyFromRealm(changes.list) + } + + commandHandler.postDelayed(infoUpdate, UPDATE_DELAY) + } + is UpdatedResults -> { +// lasted = changes.list // commandHandler.postDelayed(infoUpdate, UPDATE_DELAY * 3) } else -> { @@ -468,6 +538,7 @@ internal class LauncherHome : Fragment() { lateinit var mSmsLogsAdapter : SmsLogsAdapter lateinit var mRssAdapter : RssItemAdapter lateinit var mNotiAdapter : NotificationItemAdapter + var mWeatherAdapter: WeatherAdapter? =null var mRssDataResult : RealmResults? = null var mNotificationResult : RealmResults? = null diff --git a/app/src/main/kotlin/rasel/lunar/launcher/home/adapters/WeatherAdapter.kt b/app/src/main/kotlin/rasel/lunar/launcher/home/adapters/WeatherAdapter.kt index e03a037c..a8059164 100644 --- a/app/src/main/kotlin/rasel/lunar/launcher/home/adapters/WeatherAdapter.kt +++ b/app/src/main/kotlin/rasel/lunar/launcher/home/adapters/WeatherAdapter.kt @@ -1,19 +1,23 @@ package rasel.lunar.launcher.home.adapters +import android.annotation.SuppressLint import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.RecyclerView +import io.realm.kotlin.ext.toRealmList import rasel.lunar.launcher.R import rasel.lunar.launcher.home.adapters.WeatherAdapter.ViewHolder +import rasel.lunar.launcher.model.Forecastday import rasel.lunar.launcher.model.Hour import rasel.lunar.launcher.model.WeatherForcast +import rasel.lunar.launcher.utils.BLog import java.time.Instant import java.time.ZoneId -class WeatherAdapter(private val dataSet: Array): RecyclerView.Adapter(){ +class WeatherAdapter(private val dataSet: ArrayList): RecyclerView.Adapter(){ var isShowAmOrPm: Boolean = true class ViewHolder(view: View): RecyclerView.ViewHolder(view) { @@ -24,42 +28,58 @@ class WeatherAdapter(private val dataSet: Array): RecyclerView.Adapter) { + li.toList() + this.dataSet.clear() + this.dataSet.addAll(li) +// notifyDataSetChanged() + } + + fun filter(arr: Collection) = mutableListOf() + .apply { + arr.forEach { + if (it.time_epoch >= (System.currentTimeMillis() / 1000)) { + this.add(it) + } + } + } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context) - .inflate(R.layout.recommended_hourly_dress, parent, false) + .inflate(R.layout.item_rec_hourly_dress, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val data = dataSet[position] as? Hour + BLog.LOGE("saved weatherForcast >>> asFlow ${dataSet.size}") data?.let { - if (it.time_epoch >= (System.currentTimeMillis() / 1000)) { - holder.viewItem.findViewById(R.id.amOrPm) - .run { - this.text = Instant.ofEpochSecond(it.time_epoch.toLong()) - .atZone(ZoneId.systemDefault()) - .hour - .run { - if (this < 12) "오전" else "오후" - } - } - holder.viewItem.findViewById(R.id.hour) - .run { - val hour = Instant.ofEpochSecond(it.time_epoch.toLong()) - .atZone(ZoneId.systemDefault()) - .hour - .toString() - this.text = "${hour}시" - } - holder.viewItem.findViewById(R.id.imgDress) - .run { this.setImageResource(R.drawable.ico_time) } - holder.viewItem.findViewById(R.id.temperature) - .run { - this.text = "${it.temp_c}도" - } + holder.viewItem.findViewById(R.id.amOrPm) + .run { + this.text = Instant.ofEpochSecond(it.time_epoch.toLong()) + .atZone(ZoneId.systemDefault()) + .hour + .run { + if (this < 12) "오전" else "오후" + } + } + holder.viewItem.findViewById(R.id.hour) + .run { + val hour = Instant.ofEpochSecond(it.time_epoch.toLong()) + .atZone(ZoneId.systemDefault()) + .hour + .toString() + this.text = "${hour}시" + } + holder.viewItem.findViewById(R.id.imgDress) + .run { this.setImageResource(R.drawable.ico_time) } + holder.viewItem.findViewById(R.id.temperature) + .run { + this.text = "${it.temp_c}도" + } } - } } - override fun getItemCount(): Int = 3 + override fun getItemCount(): Int = dataSet.size } \ No newline at end of file diff --git a/app/src/main/kotlin/rasel/lunar/launcher/model/WeatherForcast.kt b/app/src/main/kotlin/rasel/lunar/launcher/model/WeatherForcast.kt index 6a477824..a427619d 100644 --- a/app/src/main/kotlin/rasel/lunar/launcher/model/WeatherForcast.kt +++ b/app/src/main/kotlin/rasel/lunar/launcher/model/WeatherForcast.kt @@ -4,6 +4,7 @@ import io.realm.kotlin.ext.realmListOf import io.realm.kotlin.types.RealmList import io.realm.kotlin.types.RealmObject import io.realm.kotlin.types.annotations.Ignore +import io.realm.kotlin.types.annotations.PrimaryKey class WeatherForcast: RealmObject { @@ -82,6 +83,7 @@ class Condition: RealmObject { // Forecast class Forecastday: RealmObject { var date: String? = null + @PrimaryKey var date_epoch = 0 var day: Day? = null var astro: Astro? = null @@ -131,6 +133,7 @@ class Astro: RealmObject { } class Hour: RealmObject { + @PrimaryKey var time_epoch = 0 var time: String? = null var temp_c = 0.0 diff --git a/app/src/main/kotlin/rasel/lunar/launcher/workers/WorkersDb.kt b/app/src/main/kotlin/rasel/lunar/launcher/workers/WorkersDb.kt index 889d4a04..089ee45b 100644 --- a/app/src/main/kotlin/rasel/lunar/launcher/workers/WorkersDb.kt +++ b/app/src/main/kotlin/rasel/lunar/launcher/workers/WorkersDb.kt @@ -15,7 +15,6 @@ import rasel.lunar.launcher.apps.SimpleContact import rasel.lunar.launcher.model.AppInfo import rasel.lunar.launcher.model.Astro import rasel.lunar.launcher.model.BotCommandEentitie -import rasel.lunar.launcher.model.Clouds import rasel.lunar.launcher.model.Condition import rasel.lunar.launcher.model.Current import rasel.lunar.launcher.model.CurrentPlayItem @@ -24,19 +23,15 @@ import rasel.lunar.launcher.model.Forecast import rasel.lunar.launcher.model.Forecastday import rasel.lunar.launcher.model.Hour import rasel.lunar.launcher.model.Location -import rasel.lunar.launcher.model.Main import rasel.lunar.launcher.model.NotificationItem import rasel.lunar.launcher.model.RssData import rasel.lunar.launcher.model.RssDataInterface -import rasel.lunar.launcher.model.Sys import rasel.lunar.launcher.model.TelegramBotUpdate import rasel.lunar.launcher.model.TelegramChat import rasel.lunar.launcher.model.TelegramData import rasel.lunar.launcher.model.TelegramFrom import rasel.lunar.launcher.model.TelegramMessage -import rasel.lunar.launcher.model.Weather import rasel.lunar.launcher.model.WeatherForcast -import rasel.lunar.launcher.model.Wind import kotlin.reflect.KClass object WorkersDb { diff --git a/app/src/main/res/layout/launcher_home.xml b/app/src/main/res/layout/launcher_home.xml index b27a45c2..92d142d3 100644 --- a/app/src/main/res/layout/launcher_home.xml +++ b/app/src/main/res/layout/launcher_home.xml @@ -128,15 +128,15 @@ - - + android:layout_width="match_parent" + android:layout_height="wrap_content"/> - - - - + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toRightOf="parent" + android:id="@+id/weather_recycller" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + \ No newline at end of file