Let repository not expose API responses

Signed-off-by: Tim Krüger <t@timkrueger.me>
This commit is contained in:
Tim Krüger 2022-05-10 13:09:45 +02:00
parent bb4102612b
commit 577357011e
No known key found for this signature in database
GPG key ID: FECE3A7222C52A4E
3 changed files with 86 additions and 76 deletions

View file

@ -1,5 +1,6 @@
package com.nextcloud.talk.repositories
import android.util.Log
import autodagger.AutoInjector
import com.nextcloud.talk.R
import com.nextcloud.talk.api.NcApi
@ -7,8 +8,8 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.chat.ChatShareOverall
import com.nextcloud.talk.models.json.chat.ChatShareOverviewOverall
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.viewmodels.SharedItemsViewModel
import io.reactivex.Observable
import retrofit2.Response
import java.util.Locale
@ -26,11 +27,11 @@ class SharedItemsRepository {
sharedApplication!!.componentApplication.inject(this)
}
fun media(type: SharedItemType): Observable<Response<ChatShareOverall>>? {
fun media(type: SharedItemType): Observable<SharedMediaItems>? {
return media(type, null)
}
fun media(type: SharedItemType, lastKnownMessageId: Int?): Observable<Response<ChatShareOverall>>? {
fun media(type: SharedItemType, lastKnownMessageId: Int?): Observable<SharedMediaItems>? {
val credentials = ApiUtils.getCredentials(parameters!!.userName, parameters!!.userToken)
return ncApi.getSharedItems(
@ -39,24 +40,86 @@ class SharedItemsRepository {
type.toString().lowercase(Locale.ROOT),
lastKnownMessageId,
BATCH_SIZE
).map { map(it, type) }
}
private fun map(response: Response<ChatShareOverall>, type: SharedItemType): SharedMediaItems {
var chatLastGiven: Int? = null
val items = mutableMapOf<String, SharedItem>()
if (response.headers()["x-chat-last-given"] != null) {
chatLastGiven = response.headers()["x-chat-last-given"]!!.toInt()
}
val mediaItems = response.body()!!.ocs!!.data
if (mediaItems != null) {
for (it in mediaItems) {
if (it.value.messageParameters?.containsKey("file") == true) {
val fileParameters = it.value.messageParameters!!["file"]!!
val previewAvailable =
"yes".equals(fileParameters["preview-available"]!!, ignoreCase = true)
items[it.value.id] = SharedItem(
fileParameters["id"]!!,
fileParameters["name"]!!,
fileParameters["size"]!!.toLong(),
it.value.timestamp,
fileParameters["path"]!!,
fileParameters["link"]!!,
fileParameters["mimetype"]!!,
previewAvailable,
previewLink(fileParameters["id"]),
parameters!!.userEntity
)
} else {
Log.w(TAG, "location and deckcard are not yet supported")
}
}
}
val sortedMutableItems = items.toSortedMap().values.toList().reversed().toMutableList()
val moreItemsExisting = items.count() == SharedItemsViewModel.BATCH_SIZE
return SharedMediaItems(
type,
sortedMutableItems,
chatLastGiven,
moreItemsExisting,
authHeader()
)
}
fun availableTypes(): Observable<Response<ChatShareOverviewOverall>>? {
fun availableTypes(): Observable<Set<SharedItemType>> {
val credentials = ApiUtils.getCredentials(parameters!!.userName, parameters!!.userToken)
return ncApi.getSharedItemsOverview(
credentials,
ApiUtils.getUrlForChatSharedItemsOverview(1, parameters!!.baseUrl, parameters!!.roomToken),
1
)
).map {
val types = mutableSetOf<SharedItemType>()
val typeMap = it.body()!!.ocs!!.data!!
for (t in typeMap) {
if (t.value.isNotEmpty()) {
try {
types += SharedItemType.typeFor(t.key)
} catch (e: IllegalArgumentException) {
Log.w(TAG, "Server responds an unknown shared item type: ${t.key}")
}
}
}
types.toSet()
}
}
fun authHeader(): Map<String, String> {
return mapOf(Pair("Authorization", ApiUtils.getCredentials(parameters!!.userName, parameters!!.userToken)))
}
fun previewLink(fileId: String?): String {
private fun previewLink(fileId: String?): String {
return ApiUtils.getUrlForFilePreviewWithFileId(
parameters!!.baseUrl,
fileId,
@ -74,5 +137,6 @@ class SharedItemsRepository {
companion object {
const val BATCH_SIZE: Int = 28
private val TAG = SharedItemsRepository::class.simpleName
}
}

View file

@ -2,7 +2,7 @@ package com.nextcloud.talk.repositories
class SharedMediaItems(
val type: SharedItemType,
val items: MutableList<SharedItem>,
val items: List<SharedItem>,
var lastSeenId: Int?,
var moreItemsExisting: Boolean,
val authHeader: Map<String, String>

View file

@ -6,9 +6,6 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.chat.ChatShareOverall
import com.nextcloud.talk.models.json.chat.ChatShareOverviewOverall
import com.nextcloud.talk.repositories.SharedItem
import com.nextcloud.talk.repositories.SharedItemType
import com.nextcloud.talk.repositories.SharedItemsRepository
import com.nextcloud.talk.repositories.SharedMediaItems
@ -16,7 +13,6 @@ import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import retrofit2.Response
class SharedItemsViewModel(private val repository: SharedItemsRepository, private val initialType: SharedItemType) :
ViewModel() {
@ -55,46 +51,15 @@ class SharedItemsViewModel(private val repository: SharedItemsRepository, privat
?.subscribe(observer(type, true))
}
private fun observer(type: SharedItemType, initModel: Boolean): Observer<Response<ChatShareOverall>> {
return object : Observer<Response<ChatShareOverall>> {
private fun observer(type: SharedItemType, initModel: Boolean): Observer<SharedMediaItems> {
return object : Observer<SharedMediaItems> {
var chatLastGiven: Int? = null
val items = mutableMapOf<String, SharedItem>()
var newSharedItems: SharedMediaItems? = null
override fun onSubscribe(d: Disposable) = Unit
override fun onNext(response: Response<ChatShareOverall>) {
if (response.headers()["x-chat-last-given"] != null) {
chatLastGiven = response.headers()["x-chat-last-given"]!!.toInt()
}
val mediaItems = response.body()!!.ocs!!.data
if (mediaItems != null) {
for (it in mediaItems) {
if (it.value.messageParameters!!.containsKey("file")) {
val fileParameters = it.value.messageParameters!!["file"]!!
val previewAvailable =
"yes".equals(fileParameters["preview-available"], ignoreCase = true)
items[it.value.id] = SharedItem(
fileParameters["id"]!!,
fileParameters["name"]!!,
fileParameters["size"]?.toLong(),
it.value.timestamp,
fileParameters["path"]!!,
fileParameters["link"],
fileParameters["mimetype"],
previewAvailable,
repository.previewLink(fileParameters["id"]),
repository.parameters!!.userEntity
)
} else {
Log.w(TAG, "location and deckcard are not yet supported")
}
}
}
override fun onNext(response: SharedMediaItems) {
newSharedItems = response
}
override fun onError(e: Throwable) {
@ -102,27 +67,17 @@ class SharedItemsViewModel(private val repository: SharedItemsRepository, privat
}
override fun onComplete() {
val sortedMutableItems = items.toSortedMap().values.toList().reversed().toMutableList()
val moreItemsExisting = items.count() == BATCH_SIZE
if (initModel) {
this@SharedItemsViewModel._sharedItems.value =
SharedMediaItems(
type,
sortedMutableItems,
chatLastGiven,
moreItemsExisting,
repository.authHeader()
)
newSharedItems
} else {
val oldItems = this@SharedItemsViewModel._sharedItems.value!!.items
this@SharedItemsViewModel._sharedItems.value =
SharedMediaItems(
type,
(oldItems.toMutableList() + sortedMutableItems) as MutableList<SharedItem>,
chatLastGiven,
moreItemsExisting,
oldItems + newSharedItems!!.items,
newSharedItems!!.lastSeenId,
newSharedItems!!.moreItemsExisting,
repository.authHeader()
)
}
@ -131,25 +86,16 @@ class SharedItemsViewModel(private val repository: SharedItemsRepository, privat
}
private fun availableTypes() {
repository.availableTypes()?.subscribeOn(Schedulers.io())
repository.availableTypes().subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.subscribe(object : Observer<Response<ChatShareOverviewOverall>> {
?.subscribe(object : Observer<Set<SharedItemType>> {
val types = mutableSetOf<SharedItemType>()
var types: Set<SharedItemType>? = null
override fun onSubscribe(d: Disposable) = Unit
override fun onNext(response: Response<ChatShareOverviewOverall>) {
val typeMap = response.body()!!.ocs!!.data!!
for (it in typeMap) {
if (it.value.size > 0) {
try {
types += SharedItemType.typeFor(it.key)
} catch (e: IllegalArgumentException) {
Log.w(TAG, "Server responds an unknown shared item type: ${it.key}")
}
}
}
override fun onNext(types: Set<SharedItemType>) {
this.types = types
}
override fun onError(e: Throwable) {
@ -157,7 +103,7 @@ class SharedItemsViewModel(private val repository: SharedItemsRepository, privat
}
override fun onComplete() {
this@SharedItemsViewModel._sharedItemType.value = types
this@SharedItemsViewModel._sharedItemType.value = this.types
}
})
}