Bimba.git

ref: e4d7079147c16b0d67cd39e35f5d943644d24c68

app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedsViewModel.kt


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
// SPDX-FileCopyrightText: Adam Evyčędo
//
// SPDX-License-Identifier: GPL-3.0-or-later

package xyz.apiote.bimba.czwek.settings.feeds

import android.content.Context
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import xyz.apiote.bimba.czwek.api.Error
import xyz.apiote.bimba.czwek.repo.FeedInfo
import xyz.apiote.bimba.czwek.repo.OfflineRepository
import xyz.apiote.bimba.czwek.repo.OnlineRepository
import xyz.apiote.bimba.czwek.repo.TrafficResponseException
import xyz.apiote.bimba.czwek.repo.join

class FeedsViewModel : ViewModel() {
	private val _settings = MutableLiveData<FeedsSettings>()
	val settings: LiveData<FeedsSettings> = _settings

	private val _feeds = MutableLiveData<Map<String, FeedInfo>>()
	val feeds: LiveData<Map<String, FeedInfo>> = _feeds

	private val _error = MutableLiveData<Error>()
	val error: LiveData<Error> = _error

	fun loadSettings(context: Context) {
		_settings.value = FeedsSettings.load(context)
	}

	fun setSettings(feedID: String, feedSettings: FeedSettings) {
		val feedsSettings = _settings.value ?: FeedsSettings(mutableMapOf())
		feedsSettings.settings[feedID] = feedSettings
		_settings.value = feedsSettings
	}

	fun setEnabled(feedID: String, enabled: Boolean) {
		val feedSettings = (_settings.value ?: FeedsSettings(mutableMapOf())).settings[feedID]
		setSettings(feedID, feedSettings?.copy(enabled = enabled) ?: FeedSettings(enabled, true))
	}

	fun loadFeeds(context: Context) {
		var offlineFeeds: Map<String, FeedInfo>? = null
		var onlineFeeds: Map<String, FeedInfo>? = null
		var error: Error? = null
		MainScope().launch {
			withContext(coroutineContext) {
				launch {
					val repository = OfflineRepository(context)
					offlineFeeds =
						repository.getFeeds(context)
					repository.close()
					if (!offlineFeeds.isNullOrEmpty()) {
						_feeds.value = offlineFeeds!!
					}
				}
				launch {
					try {
						val repository = OnlineRepository()
						onlineFeeds =
							repository.getFeeds(context)
					} catch (e: TrafficResponseException) {
						error = e.error
						Log.e("Feeds", "$e")
					}
				}
			}
			if (offlineFeeds.isNullOrEmpty() && error != null) {
				_error.value = error!!
			} else {
				joinFeeds(offlineFeeds, onlineFeeds).let { joinedFeeds ->
					_feeds.value = joinedFeeds
					val repository = OfflineRepository(context)
					repository.saveFeedCache(context, joinedFeeds)
					repository.close()
				}
			}
		}
	}

	private fun joinFeeds(
		feeds1: Map<String, FeedInfo>?,
		feeds2: Map<String, FeedInfo>?
	): Map<String, FeedInfo> {
		if (feeds1.isNullOrEmpty() && feeds2.isNullOrEmpty()) {
			return emptyMap()
		}

		if (feeds1.isNullOrEmpty()) {
			return feeds2!!
		}
		if (feeds2.isNullOrEmpty()) {
			return feeds1
		}

		return feeds1.keys.union(feeds2.keys).associateWith {
			feeds1[it].join(feeds2[it])
		}
	}
}