Welcome to mirror list, hosted at ThFree Co, Russian Federation.

FeedViewModel.kt « database « ocreader « schaal « email « java « main « src « app - github.com/schaal/ocreader.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 48a343b617bac9c027df7c33f02db8e744cbc979 (plain)
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
 * Copyright © 2019. Daniel Schaal <daniel@schaal.email>
 *
 * This file is part of ocreader.
 *
 * ocreader is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * ocreader is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 */
package email.schaal.ocreader.database

import android.content.Context
import android.content.SharedPreferences
import androidx.lifecycle.*
import androidx.preference.PreferenceManager
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkInfo
import androidx.work.WorkManager
import androidx.work.workDataOf
import email.schaal.ocreader.Preferences
import email.schaal.ocreader.database.model.*
import email.schaal.ocreader.database.model.TemporaryFeed.Companion.getListTemporaryFeed
import email.schaal.ocreader.putBreadCrumbs
import email.schaal.ocreader.service.SyncType
import email.schaal.ocreader.service.SyncWorker
import io.realm.Realm
import io.realm.kotlin.where
import kotlin.IllegalArgumentException

class FeedViewModel(context: Context) : RealmViewModel() {
    private val temporaryFeedLiveData: MutableLiveData<TemporaryFeed>
    private val itemsLiveData: MutableLiveData<List<Item>>
    private val foldersLiveData: MutableLiveData<List<Folder>>
    private val selectedTreeItemLiveData: MutableLiveData<TreeItem>
    private val userLiveData: MutableLiveData<User>

    val topFolders: Array<TreeItem>

    val temporaryFeed: LiveData<TemporaryFeed>
        get() = temporaryFeedLiveData

    val items: LiveData<List<Item>>
        get() = itemsLiveData

    val folders: LiveData<List<Folder>>
        get() = foldersLiveData

    val selectedTreeItem: LiveData<TreeItem>
        get() = selectedTreeItemLiveData

    val user: LiveData<User>
        get() = userLiveData

    fun sync(context: Context, syncType: SyncType): LiveData<WorkInfo> {
        val workManager = WorkManager.getInstance(context)
        val syncWork = OneTimeWorkRequestBuilder<SyncWorker>()
            .setInputData(workDataOf(SyncWorker.KEY_SYNC_TYPE to syncType.action))
            .build()
        workManager.enqueue(syncWork)
        return workManager.getWorkInfoByIdLiveData(syncWork.id)
    }

    fun updateFolders(onlyUnread: Boolean) {
        foldersLiveData.value = Folder.getAll(realm, onlyUnread)
    }

    fun updateSelectedTreeItem(context: Context, treeItem: TreeItem?) {
        val newTreeItem = treeItem ?: topFolders[0]
        selectedTreeItemLiveData.value = newTreeItem
        PreferenceManager.getDefaultSharedPreferences(context).edit().putBreadCrumbs(listOf(newTreeItem.treeItemId() to (newTreeItem is Feed))).apply()
    }

    fun updateTemporaryFeed(context: Context, preferences: SharedPreferences, updateTemporaryFeed: Boolean) {
        val temporaryFeed = temporaryFeedLiveData.value
        val selectedTreeItem = selectedTreeItemLiveData.value
        if (temporaryFeed == null || selectedTreeItem == null) return
        if (updateTemporaryFeed || temporaryFeed.treeItemId != selectedTreeItem.treeItemId()) {
            realm.executeTransaction { realm: Realm ->
                val tempItems = selectedTreeItem.getItems(realm, Preferences.SHOW_ONLY_UNREAD.getBoolean(preferences))
                temporaryFeed.treeItemId = selectedTreeItem.treeItemId()
                temporaryFeed.name = selectedTreeItem.treeItemName(context)
                temporaryFeed.items?.clear()
                temporaryFeed.items?.addAll(tempItems)
            }
        }
        itemsLiveData.value = temporaryFeed.items?.sort(Preferences.SORT_FIELD.getString(preferences), Preferences.ORDER.getOrder(preferences))
    }

    fun markTemporaryFeedAsRead() {
        realm.executeTransactionAsync(Realm.Transaction { realm1: Realm ->
            val unreadItems = getListTemporaryFeed(realm1)
                    ?.items
                    ?.where()
                    ?.equalTo(Item.UNREAD, true)
                    ?.findAll()
            if(unreadItems != null)
                for (item in unreadItems) {
                    item.unread = false
                }
        }, null, null)
    }

    fun markAboveAsRead(items: List<Item>?, lastItemId: Long) {
        if(items != null) {
            realm.executeTransaction {
                for (item in items) {
                    item.unread = false
                    if (item.id == lastItemId) {
                        break
                    }
                }
            }
        }
    }

    class FeedViewModelFactory(private val context: Context) : ViewModelProvider.Factory {
        override fun <T : ViewModel?> create(modelClass: Class<T>): T {
            @Suppress("UNCHECKED_CAST")
            return FeedViewModel(context) as? T
                    ?: throw IllegalArgumentException("Unknown ViewModel class")
        }
    }

    companion object {
        private fun getTreeItem(realm: Realm, breadcrumb: Pair<Long?, Boolean>, staticFolders: Array<TreeItem>): TreeItem {
            val (treeItemId, isFeed) = breadcrumb

            for(treeItem in staticFolders)
                if(treeItem.treeItemId() == treeItemId)
                    return treeItem

            return if(isFeed)
                realm.where<Feed>().equalTo(Feed::id.name, treeItemId).findFirst() ?: staticFolders[0]
            else
                realm.where<Folder>().equalTo(Folder::id.name, treeItemId).findFirst() ?: staticFolders[0]
        }
    }

    init {
        val preferences = PreferenceManager.getDefaultSharedPreferences(context)
        val temporaryFeed = getListTemporaryFeed(realm)!!
        temporaryFeedLiveData = LiveRealmObject(temporaryFeed)
        itemsLiveData = LiveRealmResults<Item>(temporaryFeed.items?.sort(Preferences.SORT_FIELD.getString(preferences) ?: Item::pubDate.name, Preferences.ORDER.getOrder(preferences))!!)
        foldersLiveData = LiveRealmResults(Folder.getAll(realm, Preferences.SHOW_ONLY_UNREAD.getBoolean(preferences)))
        topFolders = arrayOf(
                AllUnreadFolder(),
                StarredFolder(),
                FreshFolder()
        )
        selectedTreeItemLiveData = MutableLiveData(getTreeItem(realm, Preferences.BREADCRUMBS.getBreadCrumbs(preferences).last(), topFolders))
        userLiveData = LiveRealmObject(realm.where<User>().findFirst())
        updateTemporaryFeed(context, preferences, false)
    }
}