mirror of
https://github.com/wulkanowy/wulkanowy.git
synced 2025-01-18 17:46:44 -06:00
Add message attachments (#734)
This commit is contained in:
parent
da357775ff
commit
502a98b70a
@ -128,7 +128,7 @@ configurations.all {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "io.github.wulkanowy:sdk:4ea879b"
|
||||
implementation "io.github.wulkanowy:sdk:44725a9"
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
implementation "androidx.core:core-ktx:1.2.0"
|
||||
|
1732
app/schemas/io.github.wulkanowy.data.db.AppDatabase/24.json
Normal file
1732
app/schemas/io.github.wulkanowy.data.db.AppDatabase/24.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -97,6 +97,10 @@ internal class RepositoryModule {
|
||||
@Provides
|
||||
fun provideMessagesDao(database: AppDatabase) = database.messagesDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideMessageAttachmentsDao(database: AppDatabase) = database.messageAttachmentDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideExamDao(database: AppDatabase) = database.examsDao
|
||||
|
@ -17,6 +17,7 @@ import io.github.wulkanowy.data.db.dao.GradeStatisticsDao
|
||||
import io.github.wulkanowy.data.db.dao.GradeSummaryDao
|
||||
import io.github.wulkanowy.data.db.dao.HomeworkDao
|
||||
import io.github.wulkanowy.data.db.dao.LuckyNumberDao
|
||||
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
|
||||
import io.github.wulkanowy.data.db.dao.MessagesDao
|
||||
import io.github.wulkanowy.data.db.dao.MobileDeviceDao
|
||||
import io.github.wulkanowy.data.db.dao.NoteDao
|
||||
@ -39,6 +40,7 @@ import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||
import io.github.wulkanowy.data.db.entities.Homework
|
||||
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.MessageAttachment
|
||||
import io.github.wulkanowy.data.db.entities.MobileDevice
|
||||
import io.github.wulkanowy.data.db.entities.Note
|
||||
import io.github.wulkanowy.data.db.entities.Recipient
|
||||
@ -64,6 +66,7 @@ import io.github.wulkanowy.data.db.migrations.Migration20
|
||||
import io.github.wulkanowy.data.db.migrations.Migration21
|
||||
import io.github.wulkanowy.data.db.migrations.Migration22
|
||||
import io.github.wulkanowy.data.db.migrations.Migration23
|
||||
import io.github.wulkanowy.data.db.migrations.Migration24
|
||||
import io.github.wulkanowy.data.db.migrations.Migration3
|
||||
import io.github.wulkanowy.data.db.migrations.Migration4
|
||||
import io.github.wulkanowy.data.db.migrations.Migration5
|
||||
@ -87,6 +90,7 @@ import javax.inject.Singleton
|
||||
GradeStatistics::class,
|
||||
GradePointsStatistics::class,
|
||||
Message::class,
|
||||
MessageAttachment::class,
|
||||
Note::class,
|
||||
Homework::class,
|
||||
Subject::class,
|
||||
@ -105,7 +109,7 @@ import javax.inject.Singleton
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
companion object {
|
||||
const val VERSION_SCHEMA = 23
|
||||
const val VERSION_SCHEMA = 24
|
||||
|
||||
fun getMigrations(sharedPrefProvider: SharedPrefProvider): Array<Migration> {
|
||||
return arrayOf(
|
||||
@ -130,7 +134,8 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
Migration20(),
|
||||
Migration21(),
|
||||
Migration22(),
|
||||
Migration23()
|
||||
Migration23(),
|
||||
Migration24()
|
||||
)
|
||||
}
|
||||
|
||||
@ -166,6 +171,8 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
abstract val messagesDao: MessagesDao
|
||||
|
||||
abstract val messageAttachmentDao: MessageAttachmentDao
|
||||
|
||||
abstract val noteDao: NoteDao
|
||||
|
||||
abstract val homeworkDao: HomeworkDao
|
||||
|
@ -0,0 +1,13 @@
|
||||
package io.github.wulkanowy.data.db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import io.github.wulkanowy.data.db.entities.MessageAttachment
|
||||
|
||||
@Dao
|
||||
interface MessageAttachmentDao : BaseDao<MessageAttachment> {
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insertAttachments(items: List<MessageAttachment>): List<Long>
|
||||
}
|
@ -2,19 +2,22 @@ package io.github.wulkanowy.data.db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
|
||||
import io.reactivex.Maybe
|
||||
import io.reactivex.Single
|
||||
|
||||
@Dao
|
||||
interface MessagesDao : BaseDao<Message> {
|
||||
|
||||
@Transaction
|
||||
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND message_id = :messageId")
|
||||
fun loadMessageWithAttachment(studentId: Int, messageId: Int): Single<MessageWithAttachment>
|
||||
|
||||
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND folder_id = :folder AND removed = 0 ORDER BY date DESC")
|
||||
fun loadAll(studentId: Int, folder: Int): Maybe<List<Message>>
|
||||
|
||||
@Query("SELECT * FROM Messages WHERE id = :id")
|
||||
fun load(id: Long): Single<Message>
|
||||
|
||||
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND removed = 1 ORDER BY date DESC")
|
||||
fun loadDeleted(studentId: Int): Maybe<List<Message>>
|
||||
}
|
||||
|
@ -44,7 +44,10 @@ data class Message(
|
||||
@ColumnInfo(name = "read_by")
|
||||
val readBy: Int,
|
||||
|
||||
val removed: Boolean
|
||||
val removed: Boolean,
|
||||
|
||||
@ColumnInfo(name = "has_attachments")
|
||||
val hasAttachments: Boolean
|
||||
) : Serializable {
|
||||
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
|
@ -0,0 +1,26 @@
|
||||
package io.github.wulkanowy.data.db.entities
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import java.io.Serializable
|
||||
|
||||
@Entity(tableName = "MessageAttachments")
|
||||
data class MessageAttachment(
|
||||
|
||||
@PrimaryKey
|
||||
@ColumnInfo(name = "real_id")
|
||||
val realId: Int,
|
||||
|
||||
@ColumnInfo(name = "message_id")
|
||||
val messageId: Int,
|
||||
|
||||
@ColumnInfo(name = "one_drive_id")
|
||||
val oneDriveId: String,
|
||||
|
||||
@ColumnInfo(name = "url")
|
||||
val url: String,
|
||||
|
||||
@ColumnInfo(name = "filename")
|
||||
val filename: String
|
||||
) : Serializable
|
@ -0,0 +1,12 @@
|
||||
package io.github.wulkanowy.data.db.entities
|
||||
|
||||
import androidx.room.Embedded
|
||||
import androidx.room.Relation
|
||||
|
||||
data class MessageWithAttachment(
|
||||
@Embedded
|
||||
val message: Message,
|
||||
|
||||
@Relation(parentColumn = "message_id", entityColumn = "message_id")
|
||||
val attachments: List<MessageAttachment>
|
||||
)
|
@ -0,0 +1,21 @@
|
||||
package io.github.wulkanowy.data.db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
class Migration24 : Migration(23, 24) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE Messages ADD COLUMN has_attachments INTEGER NOT NULL DEFAULT 0")
|
||||
database.execSQL("""
|
||||
CREATE TABLE IF NOT EXISTS MessageAttachments (
|
||||
real_id INTEGER NOT NULL,
|
||||
message_id INTEGER NOT NULL,
|
||||
one_drive_id TEXT NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
filename TEXT NOT NULL,
|
||||
PRIMARY KEY(real_id)
|
||||
)
|
||||
""")
|
||||
}
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
package io.github.wulkanowy.data.repositories.message
|
||||
|
||||
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
|
||||
import io.github.wulkanowy.data.db.dao.MessagesDao
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.MessageAttachment
|
||||
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.repositories.message.MessageFolder.TRASHED
|
||||
import io.reactivex.Maybe
|
||||
@ -10,7 +13,10 @@ import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class MessageLocal @Inject constructor(private val messagesDb: MessagesDao) {
|
||||
class MessageLocal @Inject constructor(
|
||||
private val messagesDb: MessagesDao,
|
||||
private val messageAttachmentDao: MessageAttachmentDao
|
||||
) {
|
||||
|
||||
fun saveMessages(messages: List<Message>) {
|
||||
messagesDb.insertAll(messages)
|
||||
@ -24,8 +30,12 @@ class MessageLocal @Inject constructor(private val messagesDb: MessagesDao) {
|
||||
messagesDb.deleteAll(messages)
|
||||
}
|
||||
|
||||
fun getMessage(id: Long): Single<Message> {
|
||||
return messagesDb.load(id)
|
||||
fun getMessageWithAttachment(student: Student, message: Message): Single<MessageWithAttachment> {
|
||||
return messagesDb.loadMessageWithAttachment(student.id.toInt(), message.messageId)
|
||||
}
|
||||
|
||||
fun saveMessageAttachments(attachments: List<MessageAttachment>) {
|
||||
messageAttachmentDao.insertAttachments(attachments)
|
||||
}
|
||||
|
||||
fun getMessages(student: Student, folder: MessageFolder): Maybe<List<Message>> {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package io.github.wulkanowy.data.repositories.message
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.MessageAttachment
|
||||
import io.github.wulkanowy.data.db.entities.Recipient
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
@ -33,14 +34,25 @@ class MessageRemote @Inject constructor(private val sdk: Sdk) {
|
||||
unread = it.unread ?: false,
|
||||
unreadBy = it.unreadBy ?: 0,
|
||||
readBy = it.readBy ?: 0,
|
||||
removed = it.removed
|
||||
removed = it.removed,
|
||||
hasAttachments = it.hasAttachments
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getMessagesContent(message: Message, markAsRead: Boolean = false): Single<String> {
|
||||
return sdk.getMessageContent(message.messageId, message.folderId, markAsRead, message.realId)
|
||||
fun getMessagesContentDetails(message: Message, markAsRead: Boolean = false): Single<Pair<String, List<MessageAttachment>>> {
|
||||
return sdk.getMessageDetails(message.messageId, message.folderId, markAsRead, message.realId).map { details ->
|
||||
details.content to details.attachments.map {
|
||||
MessageAttachment(
|
||||
realId = it.id,
|
||||
messageId = it.messageId,
|
||||
oneDriveId = it.oneDriveId,
|
||||
url = it.url,
|
||||
filename = it.filename
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun sendMessage(subject: String, content: String, recipients: List<Recipient>): Single<SentMessage> {
|
||||
|
@ -4,6 +4,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||
import io.github.wulkanowy.data.SdkHelper
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
|
||||
import io.github.wulkanowy.data.db.entities.Recipient
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
@ -11,7 +12,6 @@ import io.github.wulkanowy.data.repositories.message.MessageFolder.RECEIVED
|
||||
import io.github.wulkanowy.sdk.pojo.SentMessage
|
||||
import io.github.wulkanowy.utils.uniqueSubtract
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Maybe
|
||||
import io.reactivex.Single
|
||||
import timber.log.Timber
|
||||
import java.net.UnknownHostException
|
||||
@ -48,30 +48,31 @@ class MessageRepository @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun getMessage(student: Student, messageDbId: Long, markAsRead: Boolean = false): Single<Message> {
|
||||
fun getMessage(student: Student, message: Message, markAsRead: Boolean = false): Single<MessageWithAttachment> {
|
||||
return Single.just(sdkHelper.init(student))
|
||||
.flatMap { _ ->
|
||||
local.getMessage(messageDbId)
|
||||
local.getMessageWithAttachment(student, message)
|
||||
.filter {
|
||||
it.content.isNotEmpty().also { status ->
|
||||
it.message.content.isNotEmpty().also { status ->
|
||||
Timber.d("Message content in db empty: ${!status}")
|
||||
} && !it.unread
|
||||
} && !it.message.unread
|
||||
}
|
||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||
.flatMap {
|
||||
if (it) local.getMessage(messageDbId)
|
||||
if (it) local.getMessageWithAttachment(student, message)
|
||||
else Single.error(UnknownHostException())
|
||||
}
|
||||
.flatMap { dbMessage ->
|
||||
remote.getMessagesContent(dbMessage, markAsRead).doOnSuccess {
|
||||
local.updateMessages(listOf(dbMessage.copy(unread = !markAsRead).apply {
|
||||
id = dbMessage.id
|
||||
content = content.ifBlank { it }
|
||||
remote.getMessagesContentDetails(dbMessage.message, markAsRead).doOnSuccess { (downloadedMessage, attachments) ->
|
||||
local.updateMessages(listOf(dbMessage.message.copy(unread = !markAsRead).apply {
|
||||
id = dbMessage.message.id
|
||||
content = content.ifBlank { downloadedMessage }
|
||||
}))
|
||||
Timber.d("Message $messageDbId with blank content: ${dbMessage.content.isBlank()}, marked as read")
|
||||
local.saveMessageAttachments(attachments)
|
||||
Timber.d("Message ${message.messageId} with blank content: ${dbMessage.message.content.isBlank()}, marked as read")
|
||||
}
|
||||
}.flatMap {
|
||||
local.getMessage(messageDbId)
|
||||
local.getMessageWithAttachment(student, message)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -39,6 +39,9 @@ class MessageItem(val message: Message, private val noSubjectString: String) :
|
||||
text = message.date.toFormattedString()
|
||||
setTypeface(null, style)
|
||||
}
|
||||
with(messageItemAttachmentIcon) {
|
||||
visibility = if (message.hasAttachments) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +59,8 @@ class MessageItem(val message: Message, private val noSubjectString: String) :
|
||||
return message.hashCode()
|
||||
}
|
||||
|
||||
class ViewHolder(val view: View, adapter: FlexibleAdapter<*>) : FlexibleViewHolder(view, adapter), LayoutContainer {
|
||||
class ViewHolder(val view: View, adapter: FlexibleAdapter<*>) :
|
||||
FlexibleViewHolder(view, adapter), LayoutContainer {
|
||||
override val containerView: View
|
||||
get() = contentView
|
||||
}
|
||||
|
@ -0,0 +1,88 @@
|
||||
package io.github.wulkanowy.ui.modules.message.preview
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.MessageAttachment
|
||||
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
|
||||
import io.github.wulkanowy.data.repositories.message.MessageFolder
|
||||
import io.github.wulkanowy.utils.openInternetBrowser
|
||||
import io.github.wulkanowy.utils.toFormattedString
|
||||
import kotlinx.android.synthetic.main.item_message_attachment.view.*
|
||||
import kotlinx.android.synthetic.main.item_message_preview.view.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class MessagePreviewAdapter @Inject constructor() :
|
||||
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
enum class ViewType(val id: Int) {
|
||||
MESSAGE(1),
|
||||
DIVIDER(2),
|
||||
ATTACHMENT(3)
|
||||
}
|
||||
|
||||
var messageWithAttachment: MessageWithAttachment? = null
|
||||
set(value) {
|
||||
field = value
|
||||
attachments = value?.attachments.orEmpty()
|
||||
}
|
||||
|
||||
private var attachments: List<MessageAttachment> = emptyList()
|
||||
|
||||
override fun getItemCount() = if (messageWithAttachment == null) 0 else attachments.size + 1 + if (attachments.isNotEmpty()) 1 else 0
|
||||
|
||||
override fun getItemViewType(position: Int) = when (position) {
|
||||
0 -> ViewType.MESSAGE.id
|
||||
1 -> ViewType.DIVIDER.id
|
||||
else -> ViewType.ATTACHMENT.id
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
|
||||
return when (viewType) {
|
||||
ViewType.MESSAGE.id -> MessageViewHolder(inflater.inflate(R.layout.item_message_preview, parent, false))
|
||||
ViewType.DIVIDER.id -> DividerViewHolder(inflater.inflate(R.layout.item_message_divider, parent, false))
|
||||
ViewType.ATTACHMENT.id -> AttachmentViewHolder(inflater.inflate(R.layout.item_message_attachment, parent, false))
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
when (holder) {
|
||||
is MessageViewHolder -> bindMessage(holder.view, requireNotNull(messageWithAttachment).message)
|
||||
is AttachmentViewHolder -> bindAttachment(holder.view, requireNotNull(messageWithAttachment).attachments[position - 2])
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun bindMessage(view: View, message: Message) {
|
||||
with(view) {
|
||||
messagePreviewSubject.text = if (message.subject.isNotBlank()) message.subject else context.getString(R.string.message_no_subject)
|
||||
messagePreviewDate.text = context.getString(R.string.message_date, message.date.toFormattedString("yyyy-MM-dd HH:mm:ss"))
|
||||
messagePreviewContent.text = message.content
|
||||
messagePreviewAuthor.text = if (message.folderId == MessageFolder.SENT.id) "${context.getString(R.string.message_to)} ${message.recipient}"
|
||||
else "${context.getString(R.string.message_from)} ${message.sender}"
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindAttachment(view: View, attachment: MessageAttachment) {
|
||||
with(view) {
|
||||
messagePreviewAttachment.visibility = View.VISIBLE
|
||||
messagePreviewAttachment.text = attachment.filename
|
||||
setOnClickListener {
|
||||
context.openInternetBrowser(attachment.url) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MessageViewHolder(val view: View) : RecyclerView.ViewHolder(view)
|
||||
|
||||
class DividerViewHolder(val view: View) : RecyclerView.ViewHolder(view)
|
||||
|
||||
class AttachmentViewHolder(val view: View) : RecyclerView.ViewHolder(view)
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package io.github.wulkanowy.ui.modules.message.preview
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
@ -10,8 +9,10 @@ import android.view.View
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
|
||||
import io.github.wulkanowy.ui.base.BaseFragment
|
||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||
import io.github.wulkanowy.ui.modules.main.MainView
|
||||
@ -25,6 +26,9 @@ class MessagePreviewFragment : BaseFragment(), MessagePreviewView, MainView.Titl
|
||||
@Inject
|
||||
lateinit var presenter: MessagePreviewPresenter
|
||||
|
||||
@Inject
|
||||
lateinit var previewAdapter: MessagePreviewAdapter
|
||||
|
||||
private var menuReplyButton: MenuItem? = null
|
||||
|
||||
private var menuForwardButton: MenuItem? = null
|
||||
@ -34,18 +38,15 @@ class MessagePreviewFragment : BaseFragment(), MessagePreviewView, MainView.Titl
|
||||
override val titleStringId: Int
|
||||
get() = R.string.message_title
|
||||
|
||||
override val noSubjectString: String
|
||||
get() = getString(R.string.message_no_subject)
|
||||
|
||||
override val deleteMessageSuccessString: String
|
||||
get() = getString(R.string.message_delete_success)
|
||||
|
||||
companion object {
|
||||
const val MESSAGE_ID_KEY = "message_id"
|
||||
|
||||
fun newInstance(messageId: Long): MessagePreviewFragment {
|
||||
fun newInstance(message: Message): MessagePreviewFragment {
|
||||
return MessagePreviewFragment().apply {
|
||||
arguments = Bundle().apply { putLong(MESSAGE_ID_KEY, messageId) }
|
||||
arguments = Bundle().apply { putSerializable(MESSAGE_ID_KEY, message) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -62,11 +63,16 @@ class MessagePreviewFragment : BaseFragment(), MessagePreviewView, MainView.Titl
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
messageContainer = messagePreviewContainer
|
||||
presenter.onAttachView(this, (savedInstanceState ?: arguments)?.getLong(MESSAGE_ID_KEY) ?: 0L)
|
||||
presenter.onAttachView(this, (savedInstanceState ?: arguments)?.getSerializable(MESSAGE_ID_KEY) as Message)
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
messagePreviewErrorDetails.setOnClickListener { presenter.onDetailsClick() }
|
||||
|
||||
with(messagePreviewRecycler) {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
adapter = previewAdapter
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
@ -86,26 +92,11 @@ class MessagePreviewFragment : BaseFragment(), MessagePreviewView, MainView.Titl
|
||||
}
|
||||
}
|
||||
|
||||
override fun setSubject(subject: String) {
|
||||
messagePreviewSubject.text = subject
|
||||
override fun setMessageWithAttachment(item: MessageWithAttachment) {
|
||||
with(previewAdapter) {
|
||||
messageWithAttachment = item
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun setRecipient(recipient: String) {
|
||||
messagePreviewAuthor.text = "${getString(R.string.message_to)} $recipient"
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun setSender(sender: String) {
|
||||
messagePreviewAuthor.text = "${getString(R.string.message_from)} $sender"
|
||||
}
|
||||
|
||||
override fun setDate(date: String) {
|
||||
messagePreviewDate.text = getString(R.string.message_date, date)
|
||||
}
|
||||
|
||||
override fun setContent(content: String) {
|
||||
messagePreviewContent.text = content
|
||||
}
|
||||
|
||||
override fun showProgress(show: Boolean) {
|
||||
@ -113,7 +104,7 @@ class MessagePreviewFragment : BaseFragment(), MessagePreviewView, MainView.Titl
|
||||
}
|
||||
|
||||
override fun showContent(show: Boolean) {
|
||||
messagePreviewContentContainer.visibility = if (show) VISIBLE else GONE
|
||||
messagePreviewRecycler.visibility = if (show) VISIBLE else GONE
|
||||
}
|
||||
|
||||
override fun showOptions(show: Boolean) {
|
||||
@ -160,7 +151,7 @@ class MessagePreviewFragment : BaseFragment(), MessagePreviewView, MainView.Titl
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putLong(MESSAGE_ID_KEY, presenter.messageId)
|
||||
outState.putSerializable(MESSAGE_ID_KEY, presenter.message)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
|
@ -1,14 +1,12 @@
|
||||
package io.github.wulkanowy.ui.modules.message.preview
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.repositories.message.MessageFolder
|
||||
import io.github.wulkanowy.data.repositories.message.MessageRepository
|
||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||
import io.github.wulkanowy.utils.SchedulersProvider
|
||||
import io.github.wulkanowy.utils.toFormattedString
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -20,61 +18,51 @@ class MessagePreviewPresenter @Inject constructor(
|
||||
private val analytics: FirebaseAnalyticsHelper
|
||||
) : BasePresenter<MessagePreviewView>(errorHandler, studentRepository, schedulers) {
|
||||
|
||||
var messageId = 0L
|
||||
|
||||
private var message: Message? = null
|
||||
var message: Message? = null
|
||||
|
||||
private lateinit var lastError: Throwable
|
||||
|
||||
private var retryCallback: () -> Unit = {}
|
||||
|
||||
fun onAttachView(view: MessagePreviewView, id: Long) {
|
||||
fun onAttachView(view: MessagePreviewView, message: Message) {
|
||||
super.onAttachView(view)
|
||||
view.initView()
|
||||
errorHandler.showErrorMessage = ::showErrorViewOnError
|
||||
loadData(id)
|
||||
loadData(message)
|
||||
}
|
||||
|
||||
private fun onMessageLoadRetry() {
|
||||
private fun onMessageLoadRetry(message: Message) {
|
||||
view?.run {
|
||||
showErrorView(false)
|
||||
showProgress(true)
|
||||
}
|
||||
loadData(messageId)
|
||||
loadData(message)
|
||||
}
|
||||
|
||||
fun onDetailsClick() {
|
||||
view?.showErrorDetailsDialog(lastError)
|
||||
}
|
||||
|
||||
private fun loadData(id: Long) {
|
||||
Timber.i("Loading message $id preview started")
|
||||
messageId = id
|
||||
private fun loadData(message: Message) {
|
||||
Timber.i("Loading message ${message.messageId} preview started")
|
||||
disposable.apply {
|
||||
clear()
|
||||
add(studentRepository.getCurrentStudent()
|
||||
.flatMap { messageRepository.getMessage(it, messageId, true) }
|
||||
.flatMap { messageRepository.getMessage(it, message, true) }
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
.observeOn(schedulers.mainThread)
|
||||
.doFinally { view?.showProgress(false) }
|
||||
.subscribe({ message ->
|
||||
Timber.i("Loading message $id preview result: Success ")
|
||||
this@MessagePreviewPresenter.message = message
|
||||
view?.run {
|
||||
message.let {
|
||||
setSubject(if (it.subject.isNotBlank()) it.subject else noSubjectString)
|
||||
setDate(it.date.toFormattedString("yyyy-MM-dd HH:mm:ss"))
|
||||
setContent(it.content)
|
||||
Timber.i("Loading message ${message.message.messageId} preview result: Success ")
|
||||
this@MessagePreviewPresenter.message = message.message
|
||||
view?.apply {
|
||||
setMessageWithAttachment(message)
|
||||
initOptions()
|
||||
|
||||
if (it.folderId == MessageFolder.SENT.id) setRecipient(it.recipient)
|
||||
else setSender(it.sender)
|
||||
}
|
||||
}
|
||||
analytics.logEvent("load_message_preview", "length" to message.content.length)
|
||||
analytics.logEvent("load_message_preview", "length" to message.message.content.length)
|
||||
}) {
|
||||
Timber.i("Loading message $id preview result: An exception occurred ")
|
||||
retryCallback = { onMessageLoadRetry() }
|
||||
Timber.i("Loading message ${message.messageId} preview result: An exception occurred ")
|
||||
retryCallback = { onMessageLoadRetry(message) }
|
||||
errorHandler.dispatch(it)
|
||||
})
|
||||
}
|
||||
|
@ -1,25 +1,16 @@
|
||||
package io.github.wulkanowy.ui.modules.message.preview
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface MessagePreviewView : BaseView {
|
||||
|
||||
val noSubjectString: String
|
||||
|
||||
val deleteMessageSuccessString: String
|
||||
|
||||
fun initView()
|
||||
|
||||
fun setSubject(subject: String)
|
||||
|
||||
fun setRecipient(recipient: String)
|
||||
|
||||
fun setSender(sender: String)
|
||||
|
||||
fun setDate(date: String)
|
||||
|
||||
fun setContent(content: String)
|
||||
fun setMessageWithAttachment(item: MessageWithAttachment)
|
||||
|
||||
fun showProgress(show: Boolean)
|
||||
|
||||
|
@ -12,6 +12,7 @@ import eu.davidea.flexibleadapter.common.FlexibleItemDecoration
|
||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.repositories.message.MessageFolder
|
||||
import io.github.wulkanowy.ui.base.BaseFragment
|
||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||
@ -116,8 +117,8 @@ class MessageTabFragment : BaseFragment(), MessageTabView {
|
||||
messageTabSwipe.isRefreshing = show
|
||||
}
|
||||
|
||||
override fun openMessage(messageId: Long) {
|
||||
(activity as? MainActivity)?.pushView(MessagePreviewFragment.newInstance(messageId))
|
||||
override fun openMessage(message: Message) {
|
||||
(activity as? MainActivity)?.pushView(MessagePreviewFragment.newInstance(message))
|
||||
}
|
||||
|
||||
override fun notifyParentDataLoaded() {
|
||||
|
@ -62,7 +62,7 @@ class MessageTabPresenter @Inject constructor(
|
||||
if (item is MessageItem) {
|
||||
Timber.i("Select message ${item.message.id} item")
|
||||
view?.run {
|
||||
openMessage(item.message.id)
|
||||
openMessage(item.message)
|
||||
if (item.message.unread) {
|
||||
item.message.unread = false
|
||||
updateItem(item)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package io.github.wulkanowy.ui.modules.message.tab
|
||||
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
import io.github.wulkanowy.ui.modules.message.MessageItem
|
||||
|
||||
@ -32,7 +33,7 @@ interface MessageTabView : BaseView {
|
||||
|
||||
fun showRefresh(show: Boolean)
|
||||
|
||||
fun openMessage(messageId: Long)
|
||||
fun openMessage(message: Message)
|
||||
|
||||
fun notifyParentDataLoaded()
|
||||
}
|
||||
|
9
app/src/main/res/drawable/ic_attachment.xml
Normal file
9
app/src/main/res/drawable/ic_attachment.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M2,12.5C2,9.46 4.46,7 7.5,7H18c2.21,0 4,1.79 4,4s-1.79,4 -4,4H9.5C8.12,15 7,13.88 7,12.5S8.12,10 9.5,10H17v2H9.41c-0.55,0 -0.55,1 0,1H18c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2H7.5C5.57,9 4,10.57 4,12.5S5.57,16 7.5,16H17v2H7.5C4.46,18 2,15.54 2,12.5z"/>
|
||||
</vector>
|
@ -5,55 +5,12 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/messagePreviewRecycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/messagePreviewContentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messagePreviewSubject"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:lineSpacingMultiplier="1.2"
|
||||
android:textSize="22sp"
|
||||
tools:text="@tools:sample/lorem" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messagePreviewAuthor"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="15sp"
|
||||
tools:text="@tools:sample/full_names" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messagePreviewDate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="15sp"
|
||||
tools:text="@tools:sample/date/ddmmyy" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messagePreviewContent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autoLink="web"
|
||||
android:lineSpacingMultiplier="1.2"
|
||||
android:textIsSelectable="true"
|
||||
tools:text="@tools:sample/lorem" />
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
android:layout_height="match_parent"
|
||||
tools:itemCount="1"
|
||||
tools:listitem="@layout/item_message_preview" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/messagePreviewError"
|
||||
@ -95,7 +52,6 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:text="@string/all_details" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
|
@ -1,5 +1,7 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/relativeLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackground"
|
||||
@ -11,41 +13,53 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messageItemAuthor"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginEnd="40dp"
|
||||
android:layout_marginRight="40dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:textSize="15sp"
|
||||
tools:text="@tools:sample/full_names" />
|
||||
app:layout_constraintEnd_toStartOf="@+id/messageItemDate"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messageItemDate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_toEndOf="@id/messageItemAuthor"
|
||||
android:layout_toRightOf="@id/messageItemAuthor"
|
||||
android:gravity="end"
|
||||
android:textSize="13sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="@tools:sample/date/ddmmyy" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messageItemSubject"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/messageItemAuthor"
|
||||
android:layout_alignStart="@id/messageItemAuthor"
|
||||
android:layout_alignLeft="@id/messageItemAuthor"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintEnd_toStartOf="@id/messageItemAttachmentIcon"
|
||||
app:layout_constraintStart_toStartOf="@id/messageItemAuthor"
|
||||
app:layout_constraintTop_toBottomOf="@+id/messageItemAuthor"
|
||||
app:layout_goneMarginEnd="0dp"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
</RelativeLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/messageItemAttachmentIcon"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/messageItemSubject"
|
||||
app:layout_constraintEnd_toEndOf="@id/messageItemDate"
|
||||
app:srcCompat="@drawable/ic_attachment"
|
||||
app:tint="?colorOnBackground"
|
||||
tools:ignore="ContentDescription"
|
||||
tools:visibility="visible" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
22
app/src/main/res/layout/item_message_attachment.xml
Normal file
22
app/src/main/res/layout/item_message_attachment.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackground"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingBottom="10dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/messagePreviewAttachment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="10dp"
|
||||
android:visibility="gone"
|
||||
app:drawableStartCompat="@drawable/ic_attachment"
|
||||
app:drawableTint="?colorOnBackground"
|
||||
tools:text="@tools:sample/lorem"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
6
app/src/main/res/layout/item_message_divider.xml
Normal file
6
app/src/main/res/layout/item_message_divider.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="?android:attr/listDivider" />
|
45
app/src/main/res/layout/item_message_preview.xml
Normal file
45
app/src/main/res/layout/item_message_preview.xml
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/messagePreviewContentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messagePreviewSubject"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:lineSpacingMultiplier="1.2"
|
||||
android:textSize="22sp"
|
||||
tools:text="@tools:sample/lorem" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messagePreviewAuthor"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="15sp"
|
||||
tools:text="@tools:sample/full_names" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messagePreviewDate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="15sp"
|
||||
tools:text="@tools:sample/date/ddmmyy" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messagePreviewContent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autoLink="web"
|
||||
android:lineSpacingMultiplier="1.2"
|
||||
android:textIsSelectable="true"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
</LinearLayout>
|
@ -4,6 +4,7 @@ import androidx.room.EmptyResultSetException
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||
import io.github.wulkanowy.data.SdkHelper
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.repositories.UnitTestInternetObservingStrategy
|
||||
import io.reactivex.Single
|
||||
@ -47,63 +48,70 @@ class MessageRepositoryTest {
|
||||
|
||||
@Test
|
||||
fun `throw error when message is not in the db`() {
|
||||
`when`(local.getMessage(123)).thenReturn(Single.error(EmptyResultSetException("No message in database")))
|
||||
val testMessage = Message(1, 1, 1, "", 1, "", "", "", now(), 1, false, 1, 1, false, false)
|
||||
`when`(local.getMessageWithAttachment(student, testMessage)).thenReturn(Single.error(EmptyResultSetException("No message in database")))
|
||||
|
||||
val message = repo.getMessage(student, 123)
|
||||
val messageObserver = TestObserver<Message>()
|
||||
val message = repo.getMessage(student, testMessage)
|
||||
val messageObserver = TestObserver<MessageWithAttachment>()
|
||||
message.subscribe(messageObserver)
|
||||
messageObserver.assertError(EmptyResultSetException::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get message when content already in db`() {
|
||||
`when`(local.getMessage(123)).thenReturn(Single.just(
|
||||
Message(1, 1, 123, "", 1, "", "", "Test", now(), 1, false, 1, 1, false)
|
||||
))
|
||||
val testMessage = Message(1, 1, 123, "", 1, "", "", "Test", now(), 1, false, 1, 1, false, false)
|
||||
val messageWithAttachment = MessageWithAttachment(testMessage, emptyList())
|
||||
|
||||
val message = repo.getMessage(student, 123).blockingGet()
|
||||
`when`(local.getMessageWithAttachment(student, testMessage)).thenReturn(Single.just(messageWithAttachment))
|
||||
|
||||
assertEquals("Test", message.content)
|
||||
val message = repo.getMessage(student, testMessage).blockingGet()
|
||||
|
||||
assertEquals("Test", message.message.content)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get message when content in db is empty`() {
|
||||
val testMessage = Message(1, 1, 123, "", 1, "", "", "", now(), 1, true, 1, 1, false)
|
||||
val testMessage = Message(1, 1, 123, "", 1, "", "", "", now(), 1, true, 1, 1, false, false)
|
||||
val testMessageWithContent = testMessage.copy(content = "Test")
|
||||
|
||||
`when`(local.getMessage(123))
|
||||
.thenReturn(Single.just(testMessage))
|
||||
.thenReturn(Single.just(testMessageWithContent))
|
||||
`when`(remote.getMessagesContent(testMessageWithContent)).thenReturn(Single.just("Test"))
|
||||
val mWa = MessageWithAttachment(testMessage, emptyList())
|
||||
val mWaWithContent = MessageWithAttachment(testMessageWithContent, emptyList())
|
||||
|
||||
val message = repo.getMessage(student, 123).blockingGet()
|
||||
`when`(local.getMessageWithAttachment(student, testMessage))
|
||||
.thenReturn(Single.just(mWa))
|
||||
.thenReturn(Single.just(mWaWithContent))
|
||||
`when`(remote.getMessagesContentDetails(testMessageWithContent)).thenReturn(Single.just("Test" to emptyList()))
|
||||
|
||||
assertEquals("Test", message.content)
|
||||
val message = repo.getMessage(student, testMessage).blockingGet()
|
||||
|
||||
assertEquals("Test", message.message.content)
|
||||
verify(local).updateMessages(listOf(testMessageWithContent))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get message when content in db is empty and there is no internet connection`() {
|
||||
val testMessage = Message(1, 1, 123, "", 1, "", "", "", now(), 1, false, 1, 1, false)
|
||||
val testMessage = Message(1, 1, 123, "", 1, "", "", "", now(), 1, false, 1, 1, false, false)
|
||||
val messageWithAttachment = MessageWithAttachment(testMessage, emptyList())
|
||||
|
||||
testObservingStrategy.isInternetConnection = false
|
||||
`when`(local.getMessage(123)).thenReturn(Single.just(testMessage))
|
||||
`when`(local.getMessageWithAttachment(student, testMessage)).thenReturn(Single.just(messageWithAttachment))
|
||||
|
||||
val message = repo.getMessage(student, 123)
|
||||
val messageObserver = TestObserver<Message>()
|
||||
val message = repo.getMessage(student, testMessage)
|
||||
val messageObserver = TestObserver<MessageWithAttachment>()
|
||||
message.subscribe(messageObserver)
|
||||
messageObserver.assertError(UnknownHostException::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get message when content in db is empty, unread and there is no internet connection`() {
|
||||
val testMessage = Message(1, 1, 123, "", 1, "", "", "", now(), 1, true, 1, 1, false)
|
||||
val testMessage = Message(1, 1, 123, "", 1, "", "", "", now(), 1, true, 1, 1, false, false)
|
||||
val messageWithAttachment = MessageWithAttachment(testMessage, emptyList())
|
||||
|
||||
testObservingStrategy.isInternetConnection = false
|
||||
`when`(local.getMessage(123)).thenReturn(Single.just(testMessage))
|
||||
`when`(local.getMessageWithAttachment(student, testMessage)).thenReturn(Single.just(messageWithAttachment))
|
||||
|
||||
val message = repo.getMessage(student, 123)
|
||||
val messageObserver = TestObserver<Message>()
|
||||
val message = repo.getMessage(student, testMessage)
|
||||
val messageObserver = TestObserver<MessageWithAttachment>()
|
||||
message.subscribe(messageObserver)
|
||||
messageObserver.assertError(UnknownHostException::class.java)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user