Format TimelineRepository.kt
This commit is contained in:
parent
7047eb67aa
commit
69f27b92e5
1 changed files with 242 additions and 222 deletions
|
@ -19,7 +19,6 @@ import io.reactivex.schedulers.Schedulers
|
|||
import java.io.IOException
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
data class Placeholder(val id: String)
|
||||
|
||||
|
@ -30,8 +29,10 @@ enum class TimelineRequestMode {
|
|||
}
|
||||
|
||||
interface TimelineRepository {
|
||||
fun getStatuses(maxId: String?, sinceId: String?, sincedIdMinusOne: String?, limit: Int,
|
||||
requestMode: TimelineRequestMode): Single<out List<TimelineStatus>>
|
||||
fun getStatuses(
|
||||
maxId: String?, sinceId: String?, sincedIdMinusOne: String?, limit: Int,
|
||||
requestMode: TimelineRequestMode
|
||||
): Single<out List<TimelineStatus>>
|
||||
|
||||
companion object {
|
||||
val CLEANUP_INTERVAL = TimeUnit.DAYS.toMillis(14)
|
||||
|
@ -49,20 +50,22 @@ class TimelineRepositoryImpl(
|
|||
this.cleanup()
|
||||
}
|
||||
|
||||
override fun getStatuses(maxId: String?, sinceId: String?, sincedIdMinusOne: String?,
|
||||
override fun getStatuses(
|
||||
maxId: String?, sinceId: String?, sincedIdMinusOne: String?,
|
||||
limit: Int, requestMode: TimelineRequestMode
|
||||
): Single<out List<TimelineStatus>> {
|
||||
val acc = accountManager.activeAccount ?: throw IllegalStateException()
|
||||
val accountId = acc.id
|
||||
|
||||
return if (requestMode == DISK) {
|
||||
return if(requestMode == DISK) {
|
||||
this.getStatusesFromDb(accountId, maxId, sinceId, limit)
|
||||
} else {
|
||||
getStatusesFromNetwork(maxId, sinceId, sincedIdMinusOne, limit, accountId, requestMode)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getStatusesFromNetwork(maxId: String?, sinceId: String?,
|
||||
private fun getStatusesFromNetwork(
|
||||
maxId: String?, sinceId: String?,
|
||||
sinceIdMinusOne: String?, limit: Int,
|
||||
accountId: Long, requestMode: TimelineRequestMode
|
||||
): Single<out List<TimelineStatus>> {
|
||||
|
@ -74,7 +77,7 @@ class TimelineRepositoryImpl(
|
|||
this.addFromDbIfNeeded(accountId, statuses, maxId, sinceId, limit, requestMode)
|
||||
}
|
||||
.onErrorResumeNext { error ->
|
||||
if (error is IOException && requestMode != NETWORK) {
|
||||
if(error is IOException && requestMode != NETWORK) {
|
||||
this.getStatusesFromDb(accountId, maxId, sinceId, limit)
|
||||
} else {
|
||||
Single.error(error)
|
||||
|
@ -82,12 +85,13 @@ class TimelineRepositoryImpl(
|
|||
}
|
||||
}
|
||||
|
||||
private fun addFromDbIfNeeded(accountId: Long, statuses: List<Either<Placeholder, Status>>,
|
||||
private fun addFromDbIfNeeded(
|
||||
accountId: Long, statuses: List<Either<Placeholder, Status>>,
|
||||
maxId: String?, sinceId: String?, limit: Int,
|
||||
requestMode: TimelineRequestMode
|
||||
): Single<List<TimelineStatus>>? {
|
||||
return if (requestMode != NETWORK && statuses.size < 2) {
|
||||
val newMaxID = if (statuses.isEmpty()) {
|
||||
return if(requestMode != NETWORK && statuses.size < 2) {
|
||||
val newMaxID = if(statuses.isEmpty()) {
|
||||
maxId
|
||||
} else {
|
||||
statuses.last { it.isRight() }.asRight().id
|
||||
|
@ -96,7 +100,7 @@ class TimelineRepositoryImpl(
|
|||
.map { fromDb ->
|
||||
// If it's just placeholders and less than limit (so we exhausted both
|
||||
// db and server at this point)
|
||||
if (fromDb.size < limit && fromDb.all { !it.isRight() }) {
|
||||
if(fromDb.size < limit && fromDb.all { !it.isRight() }) {
|
||||
statuses
|
||||
} else {
|
||||
statuses + fromDb
|
||||
|
@ -107,8 +111,10 @@ class TimelineRepositoryImpl(
|
|||
}
|
||||
}
|
||||
|
||||
private fun getStatusesFromDb(accountId: Long, maxId: String?, sinceId: String?,
|
||||
limit: Int): Single<out List<TimelineStatus>> {
|
||||
private fun getStatusesFromDb(
|
||||
accountId: Long, maxId: String?, sinceId: String?,
|
||||
limit: Int
|
||||
): Single<out List<TimelineStatus>> {
|
||||
return timelineDao.getStatusesForAccount(accountId, maxId, sinceId, limit)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.map { statuses ->
|
||||
|
@ -116,15 +122,16 @@ class TimelineRepositoryImpl(
|
|||
}
|
||||
}
|
||||
|
||||
private fun saveStatusesToDb(accountId: Long, statuses: List<Status>,
|
||||
private fun saveStatusesToDb(
|
||||
accountId: Long, statuses: List<Status>,
|
||||
maxId: String?, sinceId: String?
|
||||
): List<Either<Placeholder, Status>> {
|
||||
var placeholderToInsert: Placeholder? = null
|
||||
|
||||
// Look for overlap
|
||||
val resultStatuses = if (statuses.isNotEmpty() && sinceId != null) {
|
||||
val resultStatuses = if(statuses.isNotEmpty() && sinceId != null) {
|
||||
val indexOfSince = statuses.indexOfLast { it.id == sinceId }
|
||||
if (indexOfSince == -1) {
|
||||
if(indexOfSince == -1) {
|
||||
// We didn't find the status which must be there. Add a placeholder
|
||||
placeholderToInsert = Placeholder(sinceId.inc())
|
||||
statuses.mapTo(mutableListOf(), Status::lift)
|
||||
|
@ -149,7 +156,7 @@ class TimelineRepositoryImpl(
|
|||
timelineDao.deleteRange(accountId, statuses.last().id, statuses.first().id)
|
||||
}
|
||||
|
||||
for (status in statuses) {
|
||||
for(status in statuses) {
|
||||
timelineDao.insertInTransaction(
|
||||
status.toEntity(accountId, gson),
|
||||
status.account.toEntity(accountId, gson),
|
||||
|
@ -163,16 +170,19 @@ class TimelineRepositoryImpl(
|
|||
|
||||
// If we're loading in the bottom insert placeholder after every load
|
||||
// (for requests on next launches) but not return it.
|
||||
if (sinceId == null && statuses.isNotEmpty()) {
|
||||
if(sinceId == null && statuses.isNotEmpty()) {
|
||||
timelineDao.insertStatusIfNotThere(
|
||||
Placeholder(statuses.last().id.dec()).toEntity(accountId))
|
||||
Placeholder(statuses.last().id.dec()).toEntity(accountId)
|
||||
)
|
||||
}
|
||||
|
||||
// There may be placeholders which we thought could be from our TL but they are not
|
||||
if (statuses.size > 2) {
|
||||
timelineDao.removeAllPlaceholdersBetween(accountId, statuses.first().id,
|
||||
statuses.last().id)
|
||||
} else if (placeholderToInsert == null && maxId != null && sinceId != null) {
|
||||
if(statuses.size > 2) {
|
||||
timelineDao.removeAllPlaceholdersBetween(
|
||||
accountId, statuses.first().id,
|
||||
statuses.last().id
|
||||
)
|
||||
} else if(placeholderToInsert == null && maxId != null && sinceId != null) {
|
||||
timelineDao.removeAllPlaceholdersBetween(accountId, maxId, sinceId)
|
||||
}
|
||||
}
|
||||
|
@ -190,17 +200,23 @@ class TimelineRepositoryImpl(
|
|||
}
|
||||
|
||||
private fun TimelineStatusWithAccount.toStatus(): TimelineStatus {
|
||||
if (this.status.authorServerId == null) {
|
||||
if(this.status.authorServerId == null) {
|
||||
return Either.Left(Placeholder(this.status.serverId))
|
||||
}
|
||||
|
||||
val attachments: ArrayList<Attachment> = gson.fromJson(status.attachments,
|
||||
object : TypeToken<List<Attachment>>() {}.type) ?: ArrayList()
|
||||
val mentions: Array<Status.Mention> = gson.fromJson(status.mentions,
|
||||
Array<Status.Mention>::class.java) ?: arrayOf()
|
||||
val attachments: ArrayList<Attachment> = gson.fromJson(
|
||||
status.attachments,
|
||||
object : TypeToken<List<Attachment>>() {}.type
|
||||
) ?: ArrayList()
|
||||
val mentions: Array<Status.Mention> = gson.fromJson(
|
||||
status.mentions,
|
||||
Array<Status.Mention>::class.java
|
||||
) ?: arrayOf()
|
||||
val application = gson.fromJson(status.application, Status.Application::class.java)
|
||||
val emojis: List<Emoji> = gson.fromJson(status.emojis,
|
||||
object : TypeToken<List<Emoji>>() {}.type) ?: listOf()
|
||||
val emojis: List<Emoji> = gson.fromJson(
|
||||
status.emojis,
|
||||
object : TypeToken<List<Emoji>>() {}.type
|
||||
) ?: listOf()
|
||||
val poll: Poll? = gson.fromJson(status.poll, Poll::class.java)
|
||||
val pleroma = gson.fromJson(status.pleroma, Status.PleromaStatus::class.java)
|
||||
|
||||
|
@ -212,7 +228,8 @@ class TimelineRepositoryImpl(
|
|||
inReplyToId = status.inReplyToId,
|
||||
inReplyToAccountId = status.inReplyToAccountId,
|
||||
reblog = null,
|
||||
content = status.content?.parseAsHtml()?.trimTrailingWhitespace() ?: SpannedString(""),
|
||||
content = status.content?.parseAsHtml()?.trimTrailingWhitespace()
|
||||
?: SpannedString(""),
|
||||
createdAt = Date(status.createdAt),
|
||||
emojis = emojis,
|
||||
reblogsCount = status.reblogsCount,
|
||||
|
@ -232,7 +249,7 @@ class TimelineRepositoryImpl(
|
|||
pleroma = pleroma
|
||||
)
|
||||
}
|
||||
val status = if (reblog != null) {
|
||||
val status = if(reblog != null) {
|
||||
Status(
|
||||
id = status.serverId,
|
||||
url = null, // no url for reblogs
|
||||
|
@ -267,7 +284,8 @@ class TimelineRepositoryImpl(
|
|||
inReplyToId = status.inReplyToId,
|
||||
inReplyToAccountId = status.inReplyToAccountId,
|
||||
reblog = null,
|
||||
content = status.content?.parseAsHtml()?.trimTrailingWhitespace() ?: SpannedString(""),
|
||||
content = status.content?.parseAsHtml()?.trimTrailingWhitespace()
|
||||
?: SpannedString(""),
|
||||
createdAt = Date(status.createdAt),
|
||||
emojis = emojis,
|
||||
reblogsCount = status.reblogsCount,
|
||||
|
@ -359,8 +377,10 @@ fun Placeholder.toEntity(timelineUserId: Long): TimelineStatusEntity {
|
|||
)
|
||||
}
|
||||
|
||||
fun Status.toEntity(timelineUserId: Long,
|
||||
gson: Gson): TimelineStatusEntity {
|
||||
fun Status.toEntity(
|
||||
timelineUserId: Long,
|
||||
gson: Gson
|
||||
): TimelineStatusEntity {
|
||||
val actionable = actionableStatus
|
||||
return TimelineStatusEntity(
|
||||
serverId = this.id,
|
||||
|
|
Loading…
Reference in a new issue