forked from github/wulkanowy-mirror
Add support for messages plus API (#1945)
This commit is contained in:
parent
08a3bd77bd
commit
9d47127921
@ -186,7 +186,7 @@ ext {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "io.github.wulkanowy:sdk:9032e33686"
|
||||
implementation "io.github.wulkanowy:sdk:dbe87aac"
|
||||
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||
|
||||
|
2409
app/schemas/io.github.wulkanowy.data.db.AppDatabase/51.json
Normal file
2409
app/schemas/io.github.wulkanowy.data.db.AppDatabase/51.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,6 @@ import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
@ -110,7 +109,6 @@ internal class DataModule {
|
||||
fun provideSharedPref(@ApplicationContext context: Context): SharedPreferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(context)
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideFlowSharedPref(sharedPreferences: SharedPreferences) =
|
||||
@ -197,7 +195,7 @@ internal class DataModule {
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideReportingUnitDao(database: AppDatabase) = database.reportingUnitDao
|
||||
fun provideMailboxesDao(database: AppDatabase) = database.mailboxDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
|
@ -30,7 +30,7 @@ import javax.inject.Singleton
|
||||
Subject::class,
|
||||
LuckyNumber::class,
|
||||
CompletedLesson::class,
|
||||
ReportingUnit::class,
|
||||
Mailbox::class,
|
||||
Recipient::class,
|
||||
MobileDevice::class,
|
||||
Teacher::class,
|
||||
@ -55,7 +55,7 @@ import javax.inject.Singleton
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
companion object {
|
||||
const val VERSION_SCHEMA = 50
|
||||
const val VERSION_SCHEMA = 51
|
||||
|
||||
fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf(
|
||||
Migration2(),
|
||||
@ -103,7 +103,8 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
Migration44(),
|
||||
Migration46(),
|
||||
Migration49(),
|
||||
Migration50()
|
||||
Migration50(),
|
||||
Migration51(),
|
||||
)
|
||||
|
||||
fun newInstance(
|
||||
@ -154,7 +155,7 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
abstract val completedLessonsDao: CompletedLessonsDao
|
||||
|
||||
abstract val reportingUnitDao: ReportingUnitDao
|
||||
abstract val mailboxDao: MailboxDao
|
||||
|
||||
abstract val recipientDao: RecipientDao
|
||||
|
||||
|
@ -0,0 +1,17 @@
|
||||
package io.github.wulkanowy.data.db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import io.github.wulkanowy.data.db.entities.Mailbox
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
@Dao
|
||||
interface MailboxDao : BaseDao<Mailbox> {
|
||||
|
||||
@Query("SELECT * FROM Mailboxes WHERE userLoginId = :userLoginId ")
|
||||
suspend fun loadAll(userLoginId: Int): List<Mailbox>
|
||||
|
||||
@Query("SELECT * FROM Mailboxes WHERE userLoginId = :userLoginId AND studentName = :studentName ")
|
||||
suspend fun load(userLoginId: Int, studentName: String): Mailbox?
|
||||
}
|
@ -11,9 +11,9 @@ import kotlinx.coroutines.flow.Flow
|
||||
interface MessagesDao : BaseDao<Message> {
|
||||
|
||||
@Transaction
|
||||
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND message_id = :messageId")
|
||||
fun loadMessageWithAttachment(studentId: Int, messageId: Int): Flow<MessageWithAttachment?>
|
||||
@Query("SELECT * FROM Messages WHERE message_global_key = :messageGlobalKey")
|
||||
fun loadMessageWithAttachment(messageGlobalKey: String): Flow<MessageWithAttachment?>
|
||||
|
||||
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND folder_id = :folder ORDER BY date DESC")
|
||||
fun loadAll(studentId: Int, folder: Int): Flow<List<Message>>
|
||||
@Query("SELECT * FROM Messages WHERE mailbox_key = :mailboxKey AND folder_id = :folder ORDER BY date DESC")
|
||||
fun loadAll(mailboxKey: String, folder: Int): Flow<List<Message>>
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package io.github.wulkanowy.data.db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import io.github.wulkanowy.data.db.entities.MailboxType
|
||||
import io.github.wulkanowy.data.db.entities.Recipient
|
||||
import javax.inject.Singleton
|
||||
|
||||
@ -9,6 +10,6 @@ import javax.inject.Singleton
|
||||
@Dao
|
||||
interface RecipientDao : BaseDao<Recipient> {
|
||||
|
||||
@Query("SELECT * FROM Recipients WHERE student_id = :studentId AND unit_id = :unitId AND role = :role")
|
||||
suspend fun loadAll(studentId: Int, unitId: Int, role: Int): List<Recipient>
|
||||
@Query("SELECT * FROM Recipients WHERE type = :type AND studentMailboxGlobalKey = :studentMailboxGlobalKey")
|
||||
suspend fun loadAll(type: MailboxType, studentMailboxGlobalKey: String): List<Recipient>
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
package io.github.wulkanowy.data.db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import io.github.wulkanowy.data.db.entities.ReportingUnit
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
@Dao
|
||||
interface ReportingUnitDao : BaseDao<ReportingUnit> {
|
||||
|
||||
@Query("SELECT * FROM ReportingUnits WHERE student_id = :studentId")
|
||||
suspend fun load(studentId: Int): List<ReportingUnit>
|
||||
|
||||
@Query("SELECT * FROM ReportingUnits WHERE student_id = :studentId AND real_id = :unitId")
|
||||
suspend fun loadOne(studentId: Int, unitId: Int): ReportingUnit?
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package io.github.wulkanowy.data.db.entities
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "Mailboxes")
|
||||
data class Mailbox(
|
||||
|
||||
@PrimaryKey
|
||||
val globalKey: String,
|
||||
val fullName: String,
|
||||
val userName: String,
|
||||
val userLoginId: Int,
|
||||
val studentName: String,
|
||||
val schoolNameShort: String,
|
||||
val type: MailboxType,
|
||||
)
|
||||
|
||||
enum class MailboxType {
|
||||
STUDENT,
|
||||
PARENT,
|
||||
GUARDIAN,
|
||||
EMPLOYEE,
|
||||
UNKNOWN,
|
||||
}
|
@ -9,23 +9,16 @@ import java.time.Instant
|
||||
@Entity(tableName = "Messages")
|
||||
data class Message(
|
||||
|
||||
@ColumnInfo(name = "student_id")
|
||||
val studentId: Long,
|
||||
@ColumnInfo(name = "message_global_key")
|
||||
val messageGlobalKey: String,
|
||||
|
||||
@ColumnInfo(name = "real_id")
|
||||
val realId: Int,
|
||||
@ColumnInfo(name = "mailbox_key")
|
||||
val mailboxKey: String,
|
||||
|
||||
@ColumnInfo(name = "message_id")
|
||||
val messageId: Int,
|
||||
|
||||
@ColumnInfo(name = "sender_name")
|
||||
val sender: String,
|
||||
|
||||
@ColumnInfo(name = "sender_id")
|
||||
val senderId: Int,
|
||||
|
||||
@ColumnInfo(name = "recipient_name")
|
||||
val recipient: String,
|
||||
val correspondents: String,
|
||||
|
||||
val subject: String,
|
||||
|
||||
@ -36,8 +29,6 @@ data class Message(
|
||||
|
||||
var unread: Boolean,
|
||||
|
||||
val removed: Boolean,
|
||||
|
||||
@ColumnInfo(name = "has_attachments")
|
||||
val hasAttachments: Boolean
|
||||
) : Serializable {
|
||||
@ -48,11 +39,7 @@ data class Message(
|
||||
@ColumnInfo(name = "is_notified")
|
||||
var isNotified: Boolean = true
|
||||
|
||||
@ColumnInfo(name = "unread_by")
|
||||
var unreadBy: Int = 0
|
||||
|
||||
@ColumnInfo(name = "read_by")
|
||||
var readBy: Int = 0
|
||||
|
||||
var content: String = ""
|
||||
var sender: String? = null
|
||||
var recipients: String? = null
|
||||
}
|
||||
|
@ -12,11 +12,8 @@ data class MessageAttachment(
|
||||
@ColumnInfo(name = "real_id")
|
||||
val realId: Int,
|
||||
|
||||
@ColumnInfo(name = "message_id")
|
||||
val messageId: Int,
|
||||
|
||||
@ColumnInfo(name = "one_drive_id")
|
||||
val oneDriveId: String,
|
||||
@ColumnInfo(name = "message_global_key")
|
||||
val messageGlobalKey: String,
|
||||
|
||||
@ColumnInfo(name = "url")
|
||||
val url: String,
|
||||
|
@ -7,6 +7,6 @@ data class MessageWithAttachment(
|
||||
@Embedded
|
||||
val message: Message,
|
||||
|
||||
@Relation(parentColumn = "message_id", entityColumn = "message_id")
|
||||
@Relation(parentColumn = "message_global_key", entityColumn = "message_global_key")
|
||||
val attachments: List<MessageAttachment>
|
||||
)
|
||||
|
@ -1,6 +1,5 @@
|
||||
package io.github.wulkanowy.data.db.entities
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import java.io.Serializable
|
||||
@ -8,32 +7,16 @@ import java.io.Serializable
|
||||
@kotlinx.serialization.Serializable
|
||||
@Entity(tableName = "Recipients")
|
||||
data class Recipient(
|
||||
|
||||
@ColumnInfo(name = "student_id")
|
||||
val studentId: Int,
|
||||
|
||||
@ColumnInfo(name = "real_id")
|
||||
val realId: String,
|
||||
|
||||
val name: String,
|
||||
|
||||
@ColumnInfo(name = "real_name")
|
||||
val realName: String,
|
||||
|
||||
@ColumnInfo(name = "login_id")
|
||||
val loginId: Int,
|
||||
|
||||
@ColumnInfo(name = "unit_id")
|
||||
val unitId: Int,
|
||||
|
||||
val role: Int,
|
||||
|
||||
val hash: String
|
||||
|
||||
val mailboxGlobalKey: String,
|
||||
val studentMailboxGlobalKey: String,
|
||||
val fullName: String,
|
||||
val userName: String,
|
||||
val schoolShortName: String,
|
||||
val type: MailboxType,
|
||||
) : Serializable {
|
||||
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long = 0
|
||||
|
||||
override fun toString() = name
|
||||
override fun toString() = userName
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
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 = "ReportingUnits")
|
||||
data class ReportingUnit(
|
||||
|
||||
@ColumnInfo(name = "student_id")
|
||||
val studentId: Int,
|
||||
|
||||
@ColumnInfo(name = "real_id")
|
||||
val unitId: Int,
|
||||
|
||||
@ColumnInfo(name = "short")
|
||||
val shortName: String,
|
||||
|
||||
@ColumnInfo(name = "sender_id")
|
||||
val senderId: Int,
|
||||
|
||||
@ColumnInfo(name = "sender_name")
|
||||
val senderName: String,
|
||||
|
||||
val roles: List<Int>
|
||||
|
||||
) : Serializable {
|
||||
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long = 0
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package io.github.wulkanowy.data.db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
class Migration51 : Migration(50, 51) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
createMailboxTable(database)
|
||||
recreateMessagesTable(database)
|
||||
recreateMessageAttachmentsTable(database)
|
||||
recreateRecipientsTable(database)
|
||||
deleteReportingUnitTable(database)
|
||||
}
|
||||
|
||||
private fun createMailboxTable(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE IF EXISTS Mailboxes")
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `Mailboxes` (
|
||||
`globalKey` TEXT NOT NULL,
|
||||
`fullName` TEXT NOT NULL,
|
||||
`userName` TEXT NOT NULL,
|
||||
`userLoginId` INTEGER NOT NULL,
|
||||
`studentName` TEXT NOT NULL,
|
||||
`schoolNameShort` TEXT NOT NULL,
|
||||
`type` TEXT NOT NULL,
|
||||
PRIMARY KEY(`globalKey`)
|
||||
)""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
private fun recreateMessagesTable(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE IF EXISTS Messages")
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `Messages` (
|
||||
`message_global_key` TEXT NOT NULL,
|
||||
`mailbox_key` TEXT NOT NULL,
|
||||
`message_id` INTEGER NOT NULL,
|
||||
`correspondents` TEXT NOT NULL,
|
||||
`subject` TEXT NOT NULL,
|
||||
`date` INTEGER NOT NULL,
|
||||
`folder_id` INTEGER NOT NULL,
|
||||
`unread` INTEGER NOT NULL,
|
||||
`has_attachments` INTEGER NOT NULL,
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
`is_notified` INTEGER NOT NULL,
|
||||
`content` TEXT NOT NULL,
|
||||
`sender` TEXT, `recipients` TEXT
|
||||
)""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
private fun recreateMessageAttachmentsTable(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE IF EXISTS MessageAttachments")
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `MessageAttachments` (
|
||||
`real_id` INTEGER NOT NULL,
|
||||
`message_global_key` TEXT NOT NULL,
|
||||
`url` TEXT NOT NULL,
|
||||
`filename` TEXT NOT NULL,
|
||||
PRIMARY KEY(`real_id`)
|
||||
)""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
private fun recreateRecipientsTable(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE IF EXISTS Recipients")
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `Recipients` (
|
||||
`mailboxGlobalKey` TEXT NOT NULL,
|
||||
`studentMailboxGlobalKey` TEXT NOT NULL,
|
||||
`fullName` TEXT NOT NULL,
|
||||
`userName` TEXT NOT NULL,
|
||||
`schoolShortName` TEXT NOT NULL,
|
||||
`type` TEXT NOT NULL,
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL
|
||||
)""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
private fun deleteReportingUnitTable(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE IF EXISTS ReportingUnits")
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package io.github.wulkanowy.data.mappers
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Mailbox
|
||||
import io.github.wulkanowy.data.db.entities.MailboxType
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.sdk.pojo.Mailbox as SdkMailbox
|
||||
|
||||
fun List<SdkMailbox>.mapToEntities(student: Student) = map {
|
||||
Mailbox(
|
||||
globalKey = it.globalKey,
|
||||
fullName = it.fullName,
|
||||
userName = it.userName,
|
||||
userLoginId = student.userLoginId,
|
||||
studentName = it.studentName,
|
||||
schoolNameShort = it.schoolNameShort,
|
||||
type = MailboxType.valueOf(it.type.name),
|
||||
)
|
||||
}
|
@ -1,40 +1,31 @@
|
||||
package io.github.wulkanowy.data.mappers
|
||||
|
||||
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.Student
|
||||
import java.time.Instant
|
||||
import io.github.wulkanowy.data.db.entities.*
|
||||
import io.github.wulkanowy.sdk.pojo.MailboxType
|
||||
import io.github.wulkanowy.sdk.pojo.Message as SdkMessage
|
||||
import io.github.wulkanowy.sdk.pojo.MessageAttachment as SdkMessageAttachment
|
||||
import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient
|
||||
|
||||
fun List<SdkMessage>.mapToEntities(student: Student) = map {
|
||||
fun List<SdkMessage>.mapToEntities(mailbox: Mailbox) = map {
|
||||
Message(
|
||||
studentId = student.id,
|
||||
realId = it.id ?: 0,
|
||||
messageId = it.messageId ?: 0,
|
||||
sender = it.sender?.name.orEmpty(),
|
||||
senderId = it.sender?.loginId ?: 0,
|
||||
recipient = it.recipients.singleOrNull()?.name ?: "Wielu adresatów",
|
||||
messageGlobalKey = it.globalKey,
|
||||
mailboxKey = mailbox.globalKey,
|
||||
messageId = it.id,
|
||||
correspondents = it.correspondents,
|
||||
subject = it.subject.trim(),
|
||||
date = it.dateZoned?.toInstant() ?: Instant.now(),
|
||||
date = it.dateZoned.toInstant(),
|
||||
folderId = it.folderId,
|
||||
unread = it.unread ?: false,
|
||||
removed = it.removed,
|
||||
unread = it.unread,
|
||||
hasAttachments = it.hasAttachments
|
||||
).apply {
|
||||
content = it.content.orEmpty()
|
||||
unreadBy = it.unreadBy ?: 0
|
||||
readBy = it.readBy ?: 0
|
||||
}
|
||||
}
|
||||
|
||||
fun List<SdkMessageAttachment>.mapToEntities() = map {
|
||||
fun List<SdkMessageAttachment>.mapToEntities(messageGlobalKey: String) = map {
|
||||
MessageAttachment(
|
||||
realId = it.id,
|
||||
messageId = it.messageId,
|
||||
oneDriveId = it.oneDriveId,
|
||||
messageGlobalKey = messageGlobalKey,
|
||||
realId = it.url.hashCode(),
|
||||
url = it.url,
|
||||
filename = it.filename
|
||||
)
|
||||
@ -42,12 +33,11 @@ fun List<SdkMessageAttachment>.mapToEntities() = map {
|
||||
|
||||
fun List<Recipient>.mapFromEntities() = map {
|
||||
SdkRecipient(
|
||||
id = it.realId,
|
||||
name = it.realName,
|
||||
loginId = it.loginId,
|
||||
reportingUnitId = it.unitId,
|
||||
role = it.role,
|
||||
hash = it.hash,
|
||||
shortName = it.name
|
||||
fullName = it.fullName,
|
||||
userName = it.userName,
|
||||
studentName = it.userName,
|
||||
mailboxGlobalKey = it.mailboxGlobalKey,
|
||||
schoolNameShort = it.schoolShortName,
|
||||
type = MailboxType.valueOf(it.type.name),
|
||||
)
|
||||
}
|
||||
|
@ -1,17 +1,16 @@
|
||||
package io.github.wulkanowy.data.mappers
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.MailboxType
|
||||
import io.github.wulkanowy.data.db.entities.Recipient
|
||||
import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient
|
||||
|
||||
fun List<SdkRecipient>.mapToEntities(userLoginId: Int) = map {
|
||||
fun List<SdkRecipient>.mapToEntities(studentMailboxGlobalKey: String) = map {
|
||||
Recipient(
|
||||
studentId = userLoginId,
|
||||
realId = it.id,
|
||||
realName = it.name,
|
||||
name = it.shortName,
|
||||
hash = it.hash,
|
||||
loginId = it.loginId,
|
||||
role = it.role,
|
||||
unitId = it.reportingUnitId ?: 0
|
||||
mailboxGlobalKey = it.mailboxGlobalKey,
|
||||
fullName = it.fullName,
|
||||
userName = it.userName,
|
||||
studentMailboxGlobalKey = studentMailboxGlobalKey,
|
||||
schoolShortName = it.schoolNameShort,
|
||||
type = MailboxType.valueOf(it.type.name),
|
||||
)
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
package io.github.wulkanowy.data.mappers
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.ReportingUnit
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.sdk.pojo.ReportingUnit as SdkReportingUnit
|
||||
|
||||
fun List<SdkReportingUnit>.mapToEntities(student: Student) = map {
|
||||
ReportingUnit(
|
||||
studentId = student.id.toInt(),
|
||||
unitId = it.id,
|
||||
roles = it.roles,
|
||||
senderId = it.senderId,
|
||||
senderName = it.senderName,
|
||||
shortName = it.short
|
||||
)
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import io.github.wulkanowy.data.db.dao.MailboxDao
|
||||
import io.github.wulkanowy.data.db.entities.Mailbox
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.github.wulkanowy.utils.getRefreshKey
|
||||
import io.github.wulkanowy.utils.init
|
||||
import io.github.wulkanowy.utils.uniqueSubtract
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class MailboxRepository @Inject constructor(
|
||||
private val mailboxDao: MailboxDao,
|
||||
private val sdk: Sdk,
|
||||
private val refreshHelper: AutoRefreshHelper,
|
||||
) {
|
||||
private val cacheKey = "mailboxes"
|
||||
|
||||
suspend fun refreshMailboxes(student: Student) {
|
||||
val new = sdk.init(student).getMailboxes().mapToEntities(student)
|
||||
val old = mailboxDao.loadAll(student.userLoginId)
|
||||
|
||||
mailboxDao.deleteAll(old uniqueSubtract new)
|
||||
mailboxDao.insertAll(new uniqueSubtract old)
|
||||
|
||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student))
|
||||
}
|
||||
|
||||
suspend fun getMailbox(student: Student): Mailbox {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student))
|
||||
val mailbox = mailboxDao.load(student.userLoginId, student.studentName)
|
||||
|
||||
return if (isExpired || mailbox == null) {
|
||||
refreshMailboxes(student)
|
||||
val newMailbox = mailboxDao.load(student.userLoginId, student.studentName)
|
||||
|
||||
requireNotNull(newMailbox) {
|
||||
"Mailbox for ${student.userName} - ${student.studentName} not found!"
|
||||
}
|
||||
|
||||
newMailbox
|
||||
} else mailbox
|
||||
}
|
||||
}
|
@ -10,24 +10,24 @@ import io.github.wulkanowy.data.db.dao.MessagesDao
|
||||
import io.github.wulkanowy.data.db.entities.*
|
||||
import io.github.wulkanowy.data.enums.MessageFolder
|
||||
import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED
|
||||
import io.github.wulkanowy.data.enums.MessageFolder.TRASHED
|
||||
import io.github.wulkanowy.data.mappers.mapFromEntities
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
import io.github.wulkanowy.data.pojos.MessageDraft
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.pojo.Folder
|
||||
import io.github.wulkanowy.sdk.pojo.SentMessage
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.github.wulkanowy.utils.getRefreshKey
|
||||
import io.github.wulkanowy.utils.init
|
||||
import io.github.wulkanowy.utils.uniqueSubtract
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import timber.log.Timber
|
||||
import java.time.LocalDateTime.now
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@ -49,7 +49,7 @@ class MessageRepository @Inject constructor(
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
fun getMessages(
|
||||
student: Student,
|
||||
semester: Semester,
|
||||
mailbox: Mailbox,
|
||||
folder: MessageFolder,
|
||||
forceRefresh: Boolean,
|
||||
notify: Boolean = false,
|
||||
@ -62,42 +62,20 @@ class MessageRepository @Inject constructor(
|
||||
)
|
||||
it.isEmpty() || forceRefresh || isExpired
|
||||
},
|
||||
query = { messagesDb.loadAll(student.id.toInt(), folder.id) },
|
||||
query = { messagesDb.loadAll(mailbox.globalKey, folder.id) },
|
||||
fetch = {
|
||||
sdk.init(student).getMessages(Folder.valueOf(folder.name), now().minusMonths(3), now())
|
||||
.mapToEntities(student)
|
||||
sdk.init(student).getMessages(Folder.valueOf(folder.name)).mapToEntities(mailbox)
|
||||
},
|
||||
saveFetchResult = { old, new ->
|
||||
messagesDb.deleteAll(old uniqueSubtract new)
|
||||
messagesDb.insertAll((new uniqueSubtract old).onEach {
|
||||
it.isNotified = !notify
|
||||
})
|
||||
messagesDb.updateAll(getMessagesWithReadByChange(old, new, !notify))
|
||||
|
||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student, folder))
|
||||
}
|
||||
)
|
||||
|
||||
private fun getMessagesWithReadByChange(
|
||||
old: List<Message>,
|
||||
new: List<Message>,
|
||||
setNotified: Boolean
|
||||
): List<Message> {
|
||||
val oldMeta = old.map { Triple(it, it.readBy, it.unreadBy) }
|
||||
val newMeta = new.map { Triple(it, it.readBy, it.unreadBy) }
|
||||
|
||||
val updatedItems = newMeta uniqueSubtract oldMeta
|
||||
|
||||
return updatedItems.map {
|
||||
val oldItem = old.find { item -> item.messageId == it.first.messageId }
|
||||
it.first.apply {
|
||||
id = oldItem?.id ?: 0
|
||||
isNotified = oldItem?.isNotified ?: setNotified
|
||||
content = oldItem?.content.orEmpty()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getMessage(
|
||||
student: Student,
|
||||
message: Message,
|
||||
@ -106,34 +84,34 @@ class MessageRepository @Inject constructor(
|
||||
isResultEmpty = { it?.message?.content.isNullOrBlank() },
|
||||
shouldFetch = {
|
||||
checkNotNull(it) { "This message no longer exist!" }
|
||||
Timber.d("Message content in db empty: ${it.message.content.isEmpty()}")
|
||||
it.message.unread || it.message.content.isEmpty()
|
||||
Timber.d("Message content in db empty: ${it.message.content.isBlank()}")
|
||||
it.message.unread || it.message.content.isBlank()
|
||||
},
|
||||
query = { messagesDb.loadMessageWithAttachment(student.id.toInt(), message.messageId) },
|
||||
query = { messagesDb.loadMessageWithAttachment(message.messageGlobalKey) },
|
||||
fetch = {
|
||||
sdk.init(student).getMessageDetails(
|
||||
messageId = it!!.message.messageId,
|
||||
folderId = message.folderId,
|
||||
read = markAsRead,
|
||||
id = message.realId
|
||||
).let { details ->
|
||||
details.content to details.attachments.mapToEntities()
|
||||
}
|
||||
sdk.init(student).getMessageDetails(it!!.message.messageGlobalKey)
|
||||
},
|
||||
saveFetchResult = { old, (downloadedMessage, attachments) ->
|
||||
saveFetchResult = { old, new ->
|
||||
checkNotNull(old) { "Fetched message no longer exist!" }
|
||||
messagesDb.updateAll(listOf(old.message.apply {
|
||||
id = old.message.id
|
||||
unread = !markAsRead
|
||||
content = content.ifBlank { downloadedMessage }
|
||||
}))
|
||||
messageAttachmentDao.insertAttachments(attachments)
|
||||
messagesDb.updateAll(
|
||||
listOf(old.message.apply {
|
||||
id = message.id
|
||||
unread = !markAsRead
|
||||
sender = new.sender
|
||||
recipients = new.recipients.firstOrNull() ?: "Wielu adresoatów"
|
||||
content = content.ifBlank { new.content }
|
||||
})
|
||||
)
|
||||
messageAttachmentDao.insertAttachments(
|
||||
items = new.attachments.mapToEntities(message.messageGlobalKey),
|
||||
)
|
||||
|
||||
Timber.d("Message ${message.messageId} with blank content: ${old.message.content.isBlank()}, marked as read")
|
||||
}
|
||||
)
|
||||
|
||||
fun getMessagesFromDatabase(student: Student): Flow<List<Message>> {
|
||||
return messagesDb.loadAll(student.id.toInt(), RECEIVED.id)
|
||||
fun getMessagesFromDatabase(mailbox: Mailbox): Flow<List<Message>> {
|
||||
return messagesDb.loadAll(mailbox.globalKey, RECEIVED.id)
|
||||
}
|
||||
|
||||
suspend fun updateMessages(messages: List<Message>) {
|
||||
@ -145,32 +123,48 @@ class MessageRepository @Inject constructor(
|
||||
subject: String,
|
||||
content: String,
|
||||
recipients: List<Recipient>,
|
||||
): SentMessage = sdk.init(student).sendMessage(
|
||||
subject = subject,
|
||||
content = content,
|
||||
recipients = recipients.mapFromEntities()
|
||||
)
|
||||
mailboxId: String,
|
||||
) {
|
||||
sdk.init(student).sendMessage(
|
||||
subject = subject,
|
||||
content = content,
|
||||
recipients = recipients.mapFromEntities(),
|
||||
mailboxId = mailboxId,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun deleteMessages(student: Student, messages: List<Message>) {
|
||||
val folderId = messages.first().folderId
|
||||
val isDeleted = sdk.init(student)
|
||||
.deleteMessages(messages = messages.map { it.messageId }, folderId = folderId)
|
||||
suspend fun deleteMessages(student: Student, mailbox: Mailbox, messages: List<Message>) {
|
||||
val firstMessage = messages.first()
|
||||
sdk.init(student).deleteMessages(
|
||||
messages = messages.map { it.messageGlobalKey },
|
||||
removeForever = firstMessage.folderId == TRASHED.id,
|
||||
)
|
||||
|
||||
if (folderId != MessageFolder.TRASHED.id && isDeleted) {
|
||||
if (firstMessage.folderId != TRASHED.id) {
|
||||
val deletedMessages = messages.map {
|
||||
it.copy(folderId = MessageFolder.TRASHED.id)
|
||||
it.copy(folderId = TRASHED.id)
|
||||
.apply {
|
||||
id = it.id
|
||||
content = it.content
|
||||
sender = it.sender
|
||||
recipients = it.recipients
|
||||
}
|
||||
}
|
||||
|
||||
messagesDb.updateAll(deletedMessages)
|
||||
} else messagesDb.deleteAll(messages)
|
||||
|
||||
getMessages(
|
||||
student = student,
|
||||
mailbox = mailbox,
|
||||
folder = TRASHED,
|
||||
forceRefresh = true,
|
||||
).first()
|
||||
}
|
||||
|
||||
suspend fun deleteMessage(student: Student, message: Message) =
|
||||
deleteMessages(student, listOf(message))
|
||||
suspend fun deleteMessage(student: Student, mailbox: Mailbox, message: Message) {
|
||||
deleteMessages(student, mailbox, listOf(message))
|
||||
}
|
||||
|
||||
var draftMessage: MessageDraft?
|
||||
get() = sharedPrefProvider.getString(context.getString(R.string.pref_key_message_send_draft))
|
||||
|
@ -1,10 +1,7 @@
|
||||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import io.github.wulkanowy.data.db.dao.RecipientDao
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.Recipient
|
||||
import io.github.wulkanowy.data.db.entities.ReportingUnit
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.db.entities.*
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
@ -23,9 +20,10 @@ class RecipientRepository @Inject constructor(
|
||||
|
||||
private val cacheKey = "recipient"
|
||||
|
||||
suspend fun refreshRecipients(student: Student, unit: ReportingUnit, role: Int) {
|
||||
val new = sdk.init(student).getRecipients(unit.unitId, role).mapToEntities(unit.studentId)
|
||||
val old = recipientDb.loadAll(unit.studentId, unit.unitId, role)
|
||||
suspend fun refreshRecipients(student: Student, mailbox: Mailbox, type: MailboxType) {
|
||||
val new = sdk.init(student).getRecipients(mailbox.globalKey)
|
||||
.mapToEntities(mailbox.globalKey)
|
||||
val old = recipientDb.loadAll(type, mailbox.globalKey)
|
||||
|
||||
recipientDb.deleteAll(old uniqueSubtract new)
|
||||
recipientDb.insertAll(new uniqueSubtract old)
|
||||
@ -33,18 +31,27 @@ class RecipientRepository @Inject constructor(
|
||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student))
|
||||
}
|
||||
|
||||
suspend fun getRecipients(student: Student, unit: ReportingUnit, role: Int): List<Recipient> {
|
||||
val cached = recipientDb.loadAll(unit.studentId, unit.unitId, role)
|
||||
suspend fun getRecipients(
|
||||
student: Student,
|
||||
mailbox: Mailbox,
|
||||
type: MailboxType
|
||||
): List<Recipient> {
|
||||
val cached = recipientDb.loadAll(type, mailbox.globalKey)
|
||||
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student))
|
||||
return if (cached.isEmpty() || isExpired) {
|
||||
refreshRecipients(student, unit, role)
|
||||
recipientDb.loadAll(unit.studentId, unit.unitId, role)
|
||||
refreshRecipients(student, mailbox, type)
|
||||
recipientDb.loadAll(type, mailbox.globalKey)
|
||||
} else cached
|
||||
}
|
||||
|
||||
suspend fun getMessageRecipients(student: Student, message: Message): List<Recipient> {
|
||||
return sdk.init(student).getMessageRecipients(message.messageId, message.senderId)
|
||||
.mapToEntities(student.studentId)
|
||||
}
|
||||
suspend fun getMessageSender(
|
||||
student: Student,
|
||||
mailbox: Mailbox,
|
||||
message: Message
|
||||
): List<Recipient> = sdk.init(student)
|
||||
.getMessageReplayDetails(message.messageGlobalKey)
|
||||
.sender
|
||||
.let(::listOf)
|
||||
.mapToEntities(mailbox.globalKey)
|
||||
}
|
||||
|
@ -1,53 +0,0 @@
|
||||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import io.github.wulkanowy.data.db.dao.ReportingUnitDao
|
||||
import io.github.wulkanowy.data.db.entities.ReportingUnit
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.github.wulkanowy.utils.getRefreshKey
|
||||
import io.github.wulkanowy.utils.init
|
||||
import io.github.wulkanowy.utils.uniqueSubtract
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class ReportingUnitRepository @Inject constructor(
|
||||
private val reportingUnitDb: ReportingUnitDao,
|
||||
private val sdk: Sdk,
|
||||
private val refreshHelper: AutoRefreshHelper,
|
||||
) {
|
||||
|
||||
private val cacheKey = "reporting_unit"
|
||||
|
||||
suspend fun refreshReportingUnits(student: Student) {
|
||||
val new = sdk.init(student).getReportingUnits().mapToEntities(student)
|
||||
val old = reportingUnitDb.load(student.id.toInt())
|
||||
|
||||
reportingUnitDb.deleteAll(old.uniqueSubtract(new))
|
||||
reportingUnitDb.insertAll(new.uniqueSubtract(old))
|
||||
|
||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student))
|
||||
}
|
||||
|
||||
suspend fun getReportingUnits(student: Student): List<ReportingUnit> {
|
||||
val cached = reportingUnitDb.load(student.id.toInt())
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student))
|
||||
|
||||
return if (cached.isEmpty() || isExpired) {
|
||||
refreshReportingUnits(student)
|
||||
reportingUnitDb.load(student.id.toInt())
|
||||
} else cached
|
||||
}
|
||||
|
||||
suspend fun getReportingUnit(student: Student, unitId: Int): ReportingUnit? {
|
||||
val cached = reportingUnitDb.loadOne(student.id.toInt(), unitId)
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student))
|
||||
|
||||
return if (cached == null || isExpired) {
|
||||
refreshReportingUnits(student)
|
||||
reportingUnitDb.loadOne(student.id.toInt(), unitId)
|
||||
} else cached
|
||||
}
|
||||
}
|
@ -21,7 +21,7 @@ class NewMessageNotification @Inject constructor(
|
||||
val notificationDataList = items.map {
|
||||
NotificationData(
|
||||
title = context.getPlural(R.plurals.message_new_items, 1),
|
||||
content = "${it.sender}: ${it.subject}",
|
||||
content = "${it.correspondents}: ${it.subject}",
|
||||
destination = Destination.Message,
|
||||
)
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.services.sync.works
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED
|
||||
import io.github.wulkanowy.data.repositories.MailboxRepository
|
||||
import io.github.wulkanowy.data.repositories.MessageRepository
|
||||
import io.github.wulkanowy.data.waitForResult
|
||||
import io.github.wulkanowy.services.sync.notifications.NewMessageNotification
|
||||
@ -11,19 +12,21 @@ import javax.inject.Inject
|
||||
|
||||
class MessageWork @Inject constructor(
|
||||
private val messageRepository: MessageRepository,
|
||||
private val mailboxRepository: MailboxRepository,
|
||||
private val newMessageNotification: NewMessageNotification,
|
||||
) : Work {
|
||||
|
||||
override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) {
|
||||
val mailbox = mailboxRepository.getMailbox(student)
|
||||
messageRepository.getMessages(
|
||||
student = student,
|
||||
semester = semester,
|
||||
mailbox = mailbox,
|
||||
folder = RECEIVED,
|
||||
forceRefresh = true,
|
||||
notify = notify
|
||||
).waitForResult()
|
||||
|
||||
messageRepository.getMessagesFromDatabase(student).first()
|
||||
messageRepository.getMessagesFromDatabase(mailbox).first()
|
||||
.filter { !it.isNotified && it.unread }.let {
|
||||
if (it.isNotEmpty()) newMessageNotification.notify(it, student)
|
||||
messageRepository.updateMessages(it.onEach { message -> message.isNotified = true })
|
||||
|
@ -1,23 +1,22 @@
|
||||
package io.github.wulkanowy.services.sync.works
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.MailboxType
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.repositories.MailboxRepository
|
||||
import io.github.wulkanowy.data.repositories.RecipientRepository
|
||||
import io.github.wulkanowy.data.repositories.ReportingUnitRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
class RecipientWork @Inject constructor(
|
||||
private val reportingUnitRepository: ReportingUnitRepository,
|
||||
private val mailboxRepository: MailboxRepository,
|
||||
private val recipientRepository: RecipientRepository
|
||||
) : Work {
|
||||
|
||||
override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) {
|
||||
reportingUnitRepository.refreshReportingUnits(student)
|
||||
mailboxRepository.refreshMailboxes(student)
|
||||
|
||||
reportingUnitRepository.getReportingUnits(student).let { units ->
|
||||
units.map {
|
||||
recipientRepository.refreshRecipients(student, it, 2)
|
||||
}
|
||||
}
|
||||
val mailbox = mailboxRepository.getMailbox(student)
|
||||
|
||||
recipientRepository.refreshRecipients(student, mailbox, MailboxType.EMPLOYEE)
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ class DashboardPresenter @Inject constructor(
|
||||
private val gradeRepository: GradeRepository,
|
||||
private val semesterRepository: SemesterRepository,
|
||||
private val messageRepository: MessageRepository,
|
||||
private val mailboxRepository: MailboxRepository,
|
||||
private val attendanceSummaryRepository: AttendanceSummaryRepository,
|
||||
private val timetableRepository: TimetableRepository,
|
||||
private val homeworkRepository: HomeworkRepository,
|
||||
@ -227,6 +228,7 @@ class DashboardPresenter @Inject constructor(
|
||||
private fun loadHorizontalGroup(student: Student, forceRefresh: Boolean) {
|
||||
flow {
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
val mailbox = mailboxRepository.getMailbox(student)
|
||||
val selectedTiles = preferencesRepository.selectedDashboardTiles
|
||||
|
||||
val flowSuccess = flowOf(Resource.Success(null))
|
||||
@ -238,7 +240,7 @@ class DashboardPresenter @Inject constructor(
|
||||
|
||||
val messageFLow = messageRepository.getMessages(
|
||||
student = student,
|
||||
semester = semester,
|
||||
mailbox = mailbox,
|
||||
folder = MessageFolder.RECEIVED,
|
||||
forceRefresh = forceRefresh
|
||||
).takeIf { DashboardItem.Tile.MESSAGES in selectedTiles } ?: flowSuccess
|
||||
|
@ -17,16 +17,13 @@ val debugMessageItems = listOf(
|
||||
)
|
||||
|
||||
private fun generateMessage(sender: String, subject: String) = Message(
|
||||
sender = sender,
|
||||
subject = subject,
|
||||
studentId = 0,
|
||||
realId = 0,
|
||||
messageId = 0,
|
||||
senderId = 0,
|
||||
recipient = "",
|
||||
messageId = 123,
|
||||
date = Instant.now(),
|
||||
folderId = 0,
|
||||
unread = true,
|
||||
removed = false,
|
||||
hasAttachments = false
|
||||
hasAttachments = false,
|
||||
messageGlobalKey = "",
|
||||
correspondents = sender,
|
||||
mailboxKey = "",
|
||||
)
|
||||
|
@ -4,6 +4,8 @@ import android.annotation.SuppressLint
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT
|
||||
import androidx.core.text.parseAsHtml
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
@ -75,29 +77,25 @@ class MessagePreviewAdapter @Inject constructor() :
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun bindMessage(holder: MessageViewHolder, message: Message) {
|
||||
val context = holder.binding.root.context
|
||||
val recipientCount = message.unreadBy + message.readBy
|
||||
|
||||
val readText = when {
|
||||
recipientCount > 1 -> {
|
||||
context.getString(R.string.message_read_by, message.readBy, recipientCount)
|
||||
}
|
||||
message.readBy == 1 -> {
|
||||
context.getString(R.string.message_read, context.getString(R.string.all_yes))
|
||||
}
|
||||
else -> context.getString(R.string.message_read, context.getString(R.string.all_no))
|
||||
val readTextValue = when {
|
||||
!message.unread -> R.string.all_yes
|
||||
else -> R.string.all_no
|
||||
}
|
||||
val readText = context.getString(R.string.message_read, context.getString(readTextValue))
|
||||
|
||||
with(holder.binding) {
|
||||
messagePreviewSubject.text =
|
||||
message.subject.ifBlank { root.context.getString(R.string.message_no_subject) }
|
||||
messagePreviewDate.text = root.context.getString(
|
||||
messagePreviewSubject.text = message.subject.ifBlank {
|
||||
context.getString(R.string.message_no_subject)
|
||||
}
|
||||
messagePreviewDate.text = context.getString(
|
||||
R.string.message_date,
|
||||
message.date.toFormattedString("yyyy-MM-dd HH:mm:ss")
|
||||
)
|
||||
messagePreviewRead.text = readText
|
||||
messagePreviewContent.text = message.content
|
||||
messagePreviewContent.text = message.content.parseAsHtml(FROM_HTML_MODE_COMPACT)
|
||||
messagePreviewFromSender.text = message.sender
|
||||
messagePreviewToRecipient.text = message.recipient
|
||||
messagePreviewToRecipient.text = message.recipients
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,8 +135,8 @@ class MessagePreviewFragment :
|
||||
binding.messagePreviewRecycler.visibility = if (show) VISIBLE else GONE
|
||||
}
|
||||
|
||||
override fun showOptions(show: Boolean) {
|
||||
menuReplyButton?.isVisible = show
|
||||
override fun showOptions(show: Boolean, isReplayable: Boolean) {
|
||||
menuReplyButton?.isVisible = isReplayable
|
||||
menuForwardButton?.isVisible = show
|
||||
menuDeleteButton?.isVisible = show
|
||||
menuShareButton?.isVisible = show
|
||||
|
@ -1,10 +1,12 @@
|
||||
package io.github.wulkanowy.ui.modules.message.preview
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.core.text.parseAsHtml
|
||||
import io.github.wulkanowy.data.*
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.MessageAttachment
|
||||
import io.github.wulkanowy.data.enums.MessageFolder
|
||||
import io.github.wulkanowy.data.repositories.MailboxRepository
|
||||
import io.github.wulkanowy.data.repositories.MessageRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
@ -19,6 +21,7 @@ class MessagePreviewPresenter @Inject constructor(
|
||||
errorHandler: ErrorHandler,
|
||||
studentRepository: StudentRepository,
|
||||
private val messageRepository: MessageRepository,
|
||||
private val mailboxRepository: MailboxRepository,
|
||||
private val analytics: AnalyticsHelper
|
||||
) : BasePresenter<MessagePreviewView>(errorHandler, studentRepository) {
|
||||
|
||||
@ -52,7 +55,7 @@ class MessagePreviewPresenter @Inject constructor(
|
||||
|
||||
private fun loadData(messageToLoad: Message) {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getStudentById(messageToLoad.studentId)
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
messageRepository.getMessage(student, messageToLoad, true)
|
||||
}
|
||||
.logResourceStatus("message ${messageToLoad.messageId} preview")
|
||||
@ -104,62 +107,69 @@ class MessagePreviewPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
fun onShare(): Boolean {
|
||||
message?.let {
|
||||
var text =
|
||||
"Temat: ${it.subject.ifBlank { view?.messageNoSubjectString.orEmpty() }}\n" + when (it.sender.isNotEmpty()) {
|
||||
true -> "Od: ${it.sender}\n"
|
||||
false -> "Do: ${it.recipient}\n"
|
||||
} + "Data: ${it.date.toFormattedString("yyyy-MM-dd HH:mm:ss")}\n\n${it.content}"
|
||||
val message = message ?: return false
|
||||
val subject = message.subject.ifBlank { view?.messageNoSubjectString.orEmpty() }
|
||||
|
||||
attachments?.let { attachments ->
|
||||
if (attachments.isNotEmpty()) {
|
||||
text += "\n\nZałączniki:"
|
||||
val text = buildString {
|
||||
appendLine("Temat: $subject")
|
||||
appendLine("Od: ${message.sender}")
|
||||
appendLine("Do: ${message.recipients}")
|
||||
appendLine("Data: ${message.date.toFormattedString("yyyy-MM-dd HH:mm:ss")}")
|
||||
|
||||
attachments.forEach { attachment ->
|
||||
text += "\n${attachment.filename}: ${attachment.url}"
|
||||
}
|
||||
}
|
||||
appendLine()
|
||||
|
||||
appendLine(message.content.parseAsHtml())
|
||||
|
||||
if (!attachments.isNullOrEmpty()) {
|
||||
appendLine()
|
||||
appendLine("Załączniki:")
|
||||
|
||||
append(attachments.orEmpty().joinToString(separator = "\n") { attachment ->
|
||||
"${attachment.filename}: ${attachment.url}"
|
||||
})
|
||||
}
|
||||
|
||||
view?.shareText(
|
||||
text,
|
||||
"FW: ${it.subject.ifBlank { view?.messageNoSubjectString.orEmpty() }}"
|
||||
)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
view?.shareText(
|
||||
subject = "FW: $subject",
|
||||
text = text,
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
fun onPrint(): Boolean {
|
||||
message?.let {
|
||||
val dateString = it.date.toFormattedString("yyyy-MM-dd HH:mm:ss")
|
||||
val infoContent = "<div><h4>Data wysłania</h4>$dateString</div>" + when {
|
||||
it.sender.isNotEmpty() -> "<div><h4>Od</h4>${it.sender}</div>"
|
||||
else -> "<div><h4>Do</h4>${it.recipient}</div>"
|
||||
}
|
||||
val message = message ?: return false
|
||||
val subject = message.subject.ifBlank { view?.messageNoSubjectString.orEmpty() }
|
||||
|
||||
val messageContent = "<p>${it.content}</p>"
|
||||
.replace(Regex("[\\n\\r]{2,}"), "</p><p>")
|
||||
.replace(Regex("[\\n\\r]"), "<br>")
|
||||
val dateString = message.date.toFormattedString("yyyy-MM-dd HH:mm:ss")
|
||||
|
||||
val jobName = "Wiadomość " + when {
|
||||
it.sender.isNotEmpty() -> "od ${it.sender}"
|
||||
else -> "do ${it.recipient}"
|
||||
} + " $dateString: ${it.subject.ifBlank { view?.messageNoSubjectString.orEmpty() }} | Wulkanowy"
|
||||
val infoContent = buildString {
|
||||
append("<div><h4>Data wysłania</h4>$dateString</div>")
|
||||
|
||||
view?.apply {
|
||||
val html = printHTML
|
||||
.replace(
|
||||
"%SUBJECT%",
|
||||
it.subject.ifBlank { view?.messageNoSubjectString.orEmpty() })
|
||||
.replace("%CONTENT%", messageContent)
|
||||
.replace("%INFO%", infoContent)
|
||||
printDocument(html, jobName)
|
||||
}
|
||||
return true
|
||||
append("<div><h4>Od</h4>${message.sender}</div>")
|
||||
append("<div><h4>DO</h4>${message.recipients}</div>")
|
||||
}
|
||||
return false
|
||||
val messageContent = "<p>${message.content}</p>"
|
||||
.replace(Regex("[\\n\\r]{2,}"), "</p><p>")
|
||||
.replace(Regex("[\\n\\r]"), "<br>")
|
||||
|
||||
val jobName = buildString {
|
||||
append("Wiadomość ")
|
||||
append("od ${message.correspondents}")
|
||||
append("do ${message.correspondents}")
|
||||
append(" $dateString: $subject | Wulkanowy")
|
||||
}
|
||||
|
||||
view?.apply {
|
||||
val html = printHTML
|
||||
.replace("%SUBJECT%", subject)
|
||||
.replace("%CONTENT%", messageContent)
|
||||
.replace("%INFO%", infoContent)
|
||||
printDocument(html, jobName)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun deleteMessage() {
|
||||
@ -168,16 +178,17 @@ class MessagePreviewPresenter @Inject constructor(
|
||||
view?.run {
|
||||
showContent(false)
|
||||
showProgress(true)
|
||||
showOptions(false)
|
||||
showOptions(show = false, isReplayable = false)
|
||||
showErrorView(false)
|
||||
}
|
||||
|
||||
Timber.i("Delete message ${message?.id}")
|
||||
Timber.i("Delete message ${message?.messageGlobalKey}")
|
||||
|
||||
presenterScope.launch {
|
||||
runCatching {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
messageRepository.deleteMessage(student, message!!)
|
||||
val student = studentRepository.getCurrentStudent(decryptPass = true)
|
||||
val mailbox = mailboxRepository.getMailbox(student)
|
||||
messageRepository.deleteMessage(student, mailbox, message!!)
|
||||
}
|
||||
.onFailure {
|
||||
retryCallback = { onMessageDelete() }
|
||||
@ -211,7 +222,10 @@ class MessagePreviewPresenter @Inject constructor(
|
||||
|
||||
private fun initOptions() {
|
||||
view?.apply {
|
||||
showOptions(message != null)
|
||||
showOptions(
|
||||
show = message != null,
|
||||
isReplayable = message?.folderId != MessageFolder.SENT.id,
|
||||
)
|
||||
message?.let {
|
||||
when (it.folderId == MessageFolder.TRASHED.id) {
|
||||
true -> setDeletedOptionsLabels()
|
||||
|
@ -28,7 +28,7 @@ interface MessagePreviewView : BaseView {
|
||||
|
||||
fun setErrorRetryCallback(callback: () -> Unit)
|
||||
|
||||
fun showOptions(show: Boolean)
|
||||
fun showOptions(show: Boolean, isReplayable: Boolean)
|
||||
|
||||
fun setDeletedOptionsLabels()
|
||||
|
||||
|
@ -6,6 +6,7 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.text.Spanned
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.TouchDelegate
|
||||
@ -13,11 +14,12 @@ import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.widget.Toast
|
||||
import android.widget.Toast.LENGTH_LONG
|
||||
import androidx.core.text.parseAsHtml
|
||||
import androidx.core.text.toHtml
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.ReportingUnit
|
||||
import io.github.wulkanowy.databinding.ActivitySendMessageBinding
|
||||
import io.github.wulkanowy.ui.base.BaseActivity
|
||||
import io.github.wulkanowy.utils.dpToPx
|
||||
@ -72,17 +74,32 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter, ActivitySendMessa
|
||||
override val messageSuccess: String
|
||||
get() = getString(R.string.message_send_successful)
|
||||
|
||||
override val mailboxStudent: String
|
||||
get() = getString(R.string.message_mailbox_type_student)
|
||||
|
||||
override val mailboxParent: String
|
||||
get() = getString(R.string.message_mailbox_type_parent)
|
||||
|
||||
override val mailboxGuardian: String
|
||||
get() = getString(R.string.message_mailbox_type_guardian)
|
||||
|
||||
override val mailboxEmployee: String
|
||||
get() = getString(R.string.message_mailbox_type_employee)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(ActivitySendMessageBinding.inflate(layoutInflater).apply { binding = this }.root)
|
||||
setContentView(
|
||||
ActivitySendMessageBinding.inflate(layoutInflater).apply { binding = this }.root
|
||||
)
|
||||
setSupportActionBar(binding.sendMessageToolbar)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
messageContainer = binding.sendMessageContainer
|
||||
|
||||
formRecipientsData = binding.sendMessageTo.addedChipItems as List<RecipientChipItem>
|
||||
formSubjectValue = binding.sendMessageSubject.text.toString()
|
||||
formContentValue = binding.sendMessageMessageContent.text.toString()
|
||||
formContentValue =
|
||||
binding.sendMessageMessageContent.text.toString().parseAsHtml().toString()
|
||||
|
||||
presenter.onAttachView(
|
||||
view = this,
|
||||
@ -110,7 +127,7 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter, ActivitySendMessa
|
||||
}
|
||||
|
||||
private fun onMessageContentChange(text: CharSequence?) {
|
||||
formContentValue = text.toString()
|
||||
formContentValue = (text as Spanned).toHtml()
|
||||
presenter.onMessageContentChange()
|
||||
}
|
||||
|
||||
@ -132,8 +149,8 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter, ActivitySendMessa
|
||||
return presenter.onUpNavigate()
|
||||
}
|
||||
|
||||
override fun setReportingUnit(unit: ReportingUnit) {
|
||||
binding.sendMessageFrom.text = unit.senderName
|
||||
override fun setMailbox(mailbox: String) {
|
||||
binding.sendMessageFrom.text = mailbox
|
||||
}
|
||||
|
||||
override fun setRecipients(recipients: List<RecipientChipItem>) {
|
||||
@ -165,7 +182,7 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter, ActivitySendMessa
|
||||
}
|
||||
|
||||
override fun setContent(content: String) {
|
||||
binding.sendMessageMessageContent.setText(content)
|
||||
binding.sendMessageMessageContent.setText(content.parseAsHtml())
|
||||
}
|
||||
|
||||
override fun showMessage(text: String) {
|
||||
|
@ -1,6 +1,8 @@
|
||||
package io.github.wulkanowy.ui.modules.message.send
|
||||
|
||||
import io.github.wulkanowy.data.Resource
|
||||
import io.github.wulkanowy.data.db.entities.Mailbox
|
||||
import io.github.wulkanowy.data.db.entities.MailboxType
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.Recipient
|
||||
import io.github.wulkanowy.data.logResourceStatus
|
||||
@ -25,9 +27,8 @@ import javax.inject.Inject
|
||||
class SendMessagePresenter @Inject constructor(
|
||||
errorHandler: ErrorHandler,
|
||||
studentRepository: StudentRepository,
|
||||
private val semesterRepository: SemesterRepository,
|
||||
private val messageRepository: MessageRepository,
|
||||
private val reportingUnitRepository: ReportingUnitRepository,
|
||||
private val mailboxRepository: MailboxRepository,
|
||||
private val recipientRepository: RecipientRepository,
|
||||
private val preferencesRepository: PreferencesRepository,
|
||||
private val analytics: AnalyticsHelper
|
||||
@ -52,20 +53,21 @@ class SendMessagePresenter @Inject constructor(
|
||||
message?.let {
|
||||
setSubject(
|
||||
when (reply) {
|
||||
true -> "Re: "
|
||||
true -> "RE: "
|
||||
else -> "FW: "
|
||||
} + message.subject
|
||||
)
|
||||
if (preferencesRepository.fillMessageContent || reply != true) {
|
||||
setContent(
|
||||
when (reply) {
|
||||
true -> "\n\n"
|
||||
else -> ""
|
||||
} + when (message.sender.isNotEmpty()) {
|
||||
true -> "Od: ${message.sender}\n"
|
||||
false -> "Do: ${message.recipient}\n"
|
||||
} + "Data: ${message.date.toFormattedString("yyyy-MM-dd HH:mm:ss")}\n\n${message.content}"
|
||||
)
|
||||
setContent(buildString {
|
||||
if (reply == true) {
|
||||
append("<br><br>")
|
||||
}
|
||||
|
||||
append("Od: ${message.sender}<br>")
|
||||
append("Do: ${message.recipients}<br>")
|
||||
append("Data: ${message.date.toFormattedString("yyyy-MM-dd HH:mm:ss")}<br><br>")
|
||||
append(message.content)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -111,21 +113,24 @@ class SendMessagePresenter @Inject constructor(
|
||||
private fun loadData(message: Message?, reply: Boolean?) {
|
||||
resourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
val unit = reportingUnitRepository.getReportingUnit(student, semester.unitId)
|
||||
val mailbox = mailboxRepository.getMailbox(student)
|
||||
|
||||
Timber.i("Loading recipients started")
|
||||
val recipients = when {
|
||||
unit != null -> recipientRepository.getRecipients(student, unit, 2)
|
||||
else -> listOf()
|
||||
}.let { createChips(it) }
|
||||
val recipients = createChips(
|
||||
recipients = recipientRepository.getRecipients(
|
||||
student = student,
|
||||
mailbox = mailbox,
|
||||
type = MailboxType.EMPLOYEE,
|
||||
)
|
||||
)
|
||||
Timber.i("Loading recipients result: Success, fetched %d recipients", recipients.size)
|
||||
|
||||
Timber.i("Loading message recipients started")
|
||||
val messageRecipients = when {
|
||||
message != null && reply == true -> recipientRepository.getMessageRecipients(
|
||||
student,
|
||||
message
|
||||
message != null && reply == true -> recipientRepository.getMessageSender(
|
||||
student = student,
|
||||
message = message,
|
||||
mailbox = mailbox,
|
||||
)
|
||||
else -> emptyList()
|
||||
}.let { createChips(it) }
|
||||
@ -134,7 +139,7 @@ class SendMessagePresenter @Inject constructor(
|
||||
messageRecipients.size
|
||||
)
|
||||
|
||||
Triple(unit, recipients, messageRecipients)
|
||||
Triple(mailbox, recipients, messageRecipients)
|
||||
}
|
||||
.logResourceStatus("load recipients")
|
||||
.onEach {
|
||||
@ -143,19 +148,14 @@ class SendMessagePresenter @Inject constructor(
|
||||
showProgress(true)
|
||||
showContent(false)
|
||||
}
|
||||
is Resource.Success -> it.data.let { (reportingUnit, recipientChips, selectedRecipientChips) ->
|
||||
is Resource.Success -> it.data.let { (mailbox, recipientChips, selectedRecipientChips) ->
|
||||
view?.run {
|
||||
if (reportingUnit != null) {
|
||||
setReportingUnit(reportingUnit)
|
||||
setRecipients(recipientChips)
|
||||
if (selectedRecipientChips.isNotEmpty()) setSelectedRecipients(
|
||||
selectedRecipientChips
|
||||
)
|
||||
showContent(true)
|
||||
} else {
|
||||
Timber.i("Loading recipients result: Can't find the reporting unit")
|
||||
view?.showEmpty(true)
|
||||
}
|
||||
setMailbox(getMailboxName(mailbox))
|
||||
setRecipients(recipientChips)
|
||||
if (selectedRecipientChips.isNotEmpty()) setSelectedRecipients(
|
||||
selectedRecipientChips
|
||||
)
|
||||
showContent(true)
|
||||
}
|
||||
}
|
||||
is Resource.Error -> {
|
||||
@ -171,7 +171,14 @@ class SendMessagePresenter @Inject constructor(
|
||||
private fun sendMessage(subject: String, content: String, recipients: List<Recipient>) {
|
||||
resourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
messageRepository.sendMessage(student, subject, content, recipients)
|
||||
val mailbox = mailboxRepository.getMailbox(student)
|
||||
messageRepository.sendMessage(
|
||||
student = student,
|
||||
subject = subject,
|
||||
content = content,
|
||||
recipients = recipients,
|
||||
mailboxId = mailbox.globalKey,
|
||||
)
|
||||
}.logResourceStatus("sending message").onEach {
|
||||
when (it) {
|
||||
is Resource.Loading -> view?.run {
|
||||
@ -201,31 +208,44 @@ class SendMessagePresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun createChips(recipients: List<Recipient>): List<RecipientChipItem> {
|
||||
fun generateCorrectSummary(recipientRealName: String): String {
|
||||
val substring = recipientRealName.substringBeforeLast("-")
|
||||
return when {
|
||||
substring == recipientRealName -> recipientRealName
|
||||
substring.indexOf("(") != -1 -> {
|
||||
recipientRealName.indexOf("(")
|
||||
.let { recipientRealName.substring(if (it != -1) it else 0) }
|
||||
}
|
||||
substring.indexOf("[") != -1 -> {
|
||||
recipientRealName.indexOf("[")
|
||||
.let { recipientRealName.substring(if (it != -1) it else 0) }
|
||||
}
|
||||
else -> recipientRealName.substringAfter("-")
|
||||
}.trim()
|
||||
}
|
||||
|
||||
return recipients.map {
|
||||
RecipientChipItem(
|
||||
title = it.name,
|
||||
summary = generateCorrectSummary(it.realName),
|
||||
title = it.userName,
|
||||
summary = buildString {
|
||||
getMailboxType(it.type)?.let(::append)
|
||||
if (isNotBlank()) append(" ")
|
||||
|
||||
append("(${it.schoolShortName})")
|
||||
},
|
||||
recipient = it
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMailboxName(mailbox: Mailbox): String {
|
||||
return buildString {
|
||||
append(mailbox.userName)
|
||||
append(" - ")
|
||||
append(getMailboxType(mailbox.type))
|
||||
|
||||
if (mailbox.type == MailboxType.PARENT) {
|
||||
append(" - ")
|
||||
append(mailbox.studentName)
|
||||
}
|
||||
|
||||
append(" - ")
|
||||
append("(${mailbox.schoolNameShort})")
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMailboxType(type: MailboxType): String? = when (type) {
|
||||
MailboxType.STUDENT -> view?.mailboxStudent
|
||||
MailboxType.PARENT -> view?.mailboxParent
|
||||
MailboxType.GUARDIAN -> view?.mailboxGuardian
|
||||
MailboxType.EMPLOYEE -> view?.mailboxEmployee
|
||||
MailboxType.UNKNOWN -> null
|
||||
}
|
||||
|
||||
fun onMessageContentChange() {
|
||||
presenterScope.launch {
|
||||
messageUpdateChannel.send(Unit)
|
||||
@ -263,7 +283,7 @@ class SendMessagePresenter @Inject constructor(
|
||||
|
||||
fun getRecipientsNames(): String {
|
||||
return messageRepository.draftMessage?.recipients.orEmpty()
|
||||
.joinToString { it.recipient.name }
|
||||
.joinToString { it.recipient.userName }
|
||||
}
|
||||
|
||||
fun clearDraft() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.github.wulkanowy.ui.modules.message.send
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.ReportingUnit
|
||||
import io.github.wulkanowy.data.db.entities.Mailbox
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface SendMessageView : BaseView {
|
||||
@ -18,9 +18,17 @@ interface SendMessageView : BaseView {
|
||||
|
||||
val messageSuccess: String
|
||||
|
||||
val mailboxStudent: String
|
||||
|
||||
val mailboxParent: String
|
||||
|
||||
val mailboxGuardian: String
|
||||
|
||||
val mailboxEmployee: String
|
||||
|
||||
fun initView()
|
||||
|
||||
fun setReportingUnit(unit: ReportingUnit)
|
||||
fun setMailbox(mailbox: String)
|
||||
|
||||
fun setRecipients(recipients: List<RecipientChipItem>)
|
||||
|
||||
|
@ -8,7 +8,6 @@ import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.enums.MessageFolder
|
||||
import io.github.wulkanowy.databinding.ItemMessageBinding
|
||||
import io.github.wulkanowy.databinding.ItemMessageChipsBinding
|
||||
import io.github.wulkanowy.utils.toFormattedString
|
||||
@ -88,12 +87,8 @@ class MessageTabAdapter @Inject constructor() :
|
||||
with(holder.binding) {
|
||||
val style = if (message.unread) Typeface.BOLD else Typeface.NORMAL
|
||||
|
||||
messageItemAuthor.run {
|
||||
text = if (message.folderId == MessageFolder.SENT.id) {
|
||||
message.recipient
|
||||
} else {
|
||||
message.sender
|
||||
}
|
||||
with(messageItemAuthor) {
|
||||
text = message.correspondents
|
||||
setTypeface(null, style)
|
||||
}
|
||||
messageItemSubject.run {
|
||||
@ -145,7 +140,7 @@ class MessageTabAdapter @Inject constructor() :
|
||||
val newItem = new[newItemPosition]
|
||||
|
||||
return if (oldItem is MessageTabDataItem.MessageItem && newItem is MessageTabDataItem.MessageItem) {
|
||||
oldItem.message.id == newItem.message.id
|
||||
oldItem.message.messageGlobalKey == newItem.message.messageGlobalKey
|
||||
} else {
|
||||
oldItem.viewType == newItem.viewType
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ package io.github.wulkanowy.ui.modules.message.tab
|
||||
import io.github.wulkanowy.data.*
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.enums.MessageFolder
|
||||
import io.github.wulkanowy.data.repositories.MailboxRepository
|
||||
import io.github.wulkanowy.data.repositories.MessageRepository
|
||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
@ -26,7 +26,7 @@ class MessageTabPresenter @Inject constructor(
|
||||
errorHandler: ErrorHandler,
|
||||
studentRepository: StudentRepository,
|
||||
private val messageRepository: MessageRepository,
|
||||
private val semesterRepository: SemesterRepository,
|
||||
private val mailboxRepository: MailboxRepository,
|
||||
private val analytics: AnalyticsHelper
|
||||
) : BasePresenter<MessageTabView>(errorHandler, studentRepository) {
|
||||
|
||||
@ -122,7 +122,8 @@ class MessageTabPresenter @Inject constructor(
|
||||
|
||||
runCatching {
|
||||
val student = studentRepository.getCurrentStudent(true)
|
||||
messageRepository.deleteMessages(student, messageList)
|
||||
val mailbox = mailboxRepository.getMailbox(student)
|
||||
messageRepository.deleteMessages(student, mailbox, messageList)
|
||||
}
|
||||
.onFailure(errorHandler::dispatch)
|
||||
.onSuccess { view?.showMessagesDeleted() }
|
||||
@ -159,7 +160,7 @@ class MessageTabPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
fun onMessageItemSelected(messageItem: MessageTabDataItem.MessageItem, position: Int) {
|
||||
Timber.i("Select message ${messageItem.message.id} item (position: $position)")
|
||||
Timber.i("Select message ${messageItem.message.messageGlobalKey} item (position: $position)")
|
||||
|
||||
if (!isActionMode) {
|
||||
view?.run {
|
||||
@ -206,8 +207,8 @@ class MessageTabPresenter @Inject constructor(
|
||||
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
messageRepository.getMessages(student, semester, folder, forceRefresh)
|
||||
val mailbox = mailboxRepository.getMailbox(student)
|
||||
messageRepository.getMessages(student, mailbox, folder, forceRefresh)
|
||||
}
|
||||
.logResourceStatus("load $folder message")
|
||||
.onResourceData {
|
||||
@ -333,7 +334,7 @@ class MessageTabPresenter @Inject constructor(
|
||||
addAll(data.map { message ->
|
||||
MessageTabDataItem.MessageItem(
|
||||
message = message,
|
||||
isSelected = messagesToDelete.any { it.id == message.id },
|
||||
isSelected = messagesToDelete.any { it.messageGlobalKey == message.messageGlobalKey },
|
||||
isActionMode = isActionMode
|
||||
)
|
||||
})
|
||||
@ -345,10 +346,9 @@ class MessageTabPresenter @Inject constructor(
|
||||
private fun calculateMatchRatio(message: Message, query: String): Int {
|
||||
val subjectRatio = FuzzySearch.tokenSortPartialRatio(query.lowercase(), message.subject)
|
||||
|
||||
val senderOrRecipientRatio = FuzzySearch.tokenSortPartialRatio(
|
||||
val correspondentsRatio = FuzzySearch.tokenSortPartialRatio(
|
||||
query.lowercase(),
|
||||
if (message.sender.isNotEmpty()) message.sender.lowercase()
|
||||
else message.recipient.lowercase()
|
||||
message.correspondents
|
||||
)
|
||||
|
||||
val dateRatio = listOf(
|
||||
@ -364,7 +364,7 @@ class MessageTabPresenter @Inject constructor(
|
||||
|
||||
|
||||
return (subjectRatio.toDouble().pow(2)
|
||||
+ senderOrRecipientRatio.toDouble().pow(2)
|
||||
+ correspondentsRatio.toDouble().pow(2)
|
||||
+ dateRatio.toDouble().pow(2) * 2
|
||||
).toInt()
|
||||
}
|
||||
|
@ -16,8 +16,7 @@
|
||||
app:layout_constraintBottom_toTopOf="@id/sendMessageScroll"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:targetApi="lollipop" />
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<io.github.wulkanowy.materialchipsinput.ConsumedNestedScrollView
|
||||
android:id="@+id/sendMessageScroll"
|
||||
|
@ -289,6 +289,10 @@
|
||||
<string name="message_move_to_trash">Move to trash</string>
|
||||
<string name="message_delete_forever">Delete permanently</string>
|
||||
<string name="message_delete_success">Message deleted successfully</string>
|
||||
<string name="message_mailbox_type_student">student</string>
|
||||
<string name="message_mailbox_type_parent">parent</string>
|
||||
<string name="message_mailbox_type_guardian">guardian</string>
|
||||
<string name="message_mailbox_type_employee">employee</string>
|
||||
<string name="message_share">Share</string>
|
||||
<string name="message_print">Print</string>
|
||||
<string name="message_subject">Subject</string>
|
||||
@ -300,7 +304,6 @@
|
||||
<string name="message_chip_only_unread">Only unread</string>
|
||||
<string name="message_chip_only_with_attachments">Only with attachments</string>
|
||||
<string name="message_read">Read: %s</string>
|
||||
<string name="message_read_by">Read by: %1$d of %2$d people</string>
|
||||
<plurals name="message_number_item">
|
||||
<item quantity="one">%1$d message</item>
|
||||
<item quantity="other">%1$d messages</item>
|
||||
|
@ -1,5 +1,7 @@
|
||||
package io.github.wulkanowy
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Mailbox
|
||||
import io.github.wulkanowy.data.db.entities.MailboxType
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
@ -21,6 +23,16 @@ fun getSemesterEntity(diaryId: Int = 1, semesterId: Int = 1, start: LocalDate =
|
||||
end = end
|
||||
)
|
||||
|
||||
fun getMailboxEntity() = Mailbox(
|
||||
globalKey = "v4",
|
||||
fullName = "",
|
||||
userName = "",
|
||||
userLoginId = 0,
|
||||
studentName = "",
|
||||
schoolNameShort = "",
|
||||
type = MailboxType.UNKNOWN,
|
||||
)
|
||||
|
||||
fun getSemesterPojo(diaryId: Int, semesterId: Int, start: LocalDate, end: LocalDate, semesterName: Int = 1) = SdkSemester(
|
||||
diaryId = diaryId,
|
||||
kindergartenDiaryId = 0,
|
||||
|
@ -10,12 +10,10 @@ import io.github.wulkanowy.data.db.entities.MessageWithAttachment
|
||||
import io.github.wulkanowy.data.enums.MessageFolder
|
||||
import io.github.wulkanowy.data.errorOrNull
|
||||
import io.github.wulkanowy.data.toFirstResult
|
||||
import io.github.wulkanowy.getSemesterEntity
|
||||
import io.github.wulkanowy.getMailboxEntity
|
||||
import io.github.wulkanowy.getStudentEntity
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.pojo.Folder
|
||||
import io.github.wulkanowy.sdk.pojo.MessageDetails
|
||||
import io.github.wulkanowy.sdk.pojo.Sender
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.github.wulkanowy.utils.Status
|
||||
import io.github.wulkanowy.utils.status
|
||||
@ -23,7 +21,6 @@ import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.impl.annotations.SpyK
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.runBlocking
|
||||
@ -60,7 +57,7 @@ class MessageRepositoryTest {
|
||||
|
||||
private val student = getStudentEntity()
|
||||
|
||||
private val semester = getSemesterEntity()
|
||||
private val mailbox = getMailboxEntity()
|
||||
|
||||
private lateinit var repository: MessageRepository
|
||||
|
||||
@ -80,59 +77,18 @@ class MessageRepositoryTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get messages when read by values was changed on already read message`() = runTest {
|
||||
every { messageDb.loadAll(any(), any()) } returns flow {
|
||||
val dbMessage = getMessageEntity(3, "", false).apply {
|
||||
unreadBy = 10
|
||||
readBy = 5
|
||||
isNotified = true
|
||||
}
|
||||
emit(listOf(dbMessage))
|
||||
}
|
||||
coEvery { sdk.getMessages(Folder.RECEIVED, any(), any()) } returns listOf(
|
||||
getMessageDto(messageId = 3, content = "", unread = false).copy(
|
||||
unreadBy = 5,
|
||||
readBy = 10,
|
||||
)
|
||||
)
|
||||
coEvery { messageDb.deleteAll(any()) } just Runs
|
||||
coEvery { messageDb.insertAll(any()) } returns listOf()
|
||||
|
||||
repository.getMessages(
|
||||
student = student,
|
||||
semester = semester,
|
||||
folder = MessageFolder.RECEIVED,
|
||||
forceRefresh = true,
|
||||
notify = true, // all new messages will be marked as not notified
|
||||
).toFirstResult().dataOrNull.orEmpty()
|
||||
|
||||
coVerify(exactly = 1) { messageDb.deleteAll(emptyList()) }
|
||||
coVerify(exactly = 1) { messageDb.insertAll(emptyList()) }
|
||||
coVerify(exactly = 1) {
|
||||
messageDb.updateAll(withArg {
|
||||
assertEquals(1, it.size)
|
||||
assertEquals(5, it.single().unreadBy)
|
||||
assertEquals(10, it.single().readBy)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get messages when fetched completely new message without notify`() = runBlocking {
|
||||
every { messageDb.loadAll(any(), any()) } returns flowOf(emptyList())
|
||||
coEvery { sdk.getMessages(Folder.RECEIVED, any(), any()) } returns listOf(
|
||||
getMessageDto(messageId = 4, content = "Test", unread = true).copy(
|
||||
unreadBy = 5,
|
||||
readBy = 10,
|
||||
)
|
||||
coEvery { sdk.getMessages(Folder.RECEIVED, any()) } returns listOf(
|
||||
getMessageDto()
|
||||
)
|
||||
coEvery { messageDb.deleteAll(any()) } just Runs
|
||||
coEvery { messageDb.insertAll(any()) } returns listOf()
|
||||
|
||||
repository.getMessages(
|
||||
student = student,
|
||||
semester = semester,
|
||||
mailbox = mailbox,
|
||||
folder = MessageFolder.RECEIVED,
|
||||
forceRefresh = true,
|
||||
notify = false,
|
||||
@ -151,7 +107,7 @@ class MessageRepositoryTest {
|
||||
fun `throw error when message is not in the db`() {
|
||||
val testMessage = getMessageEntity(1, "", false)
|
||||
coEvery {
|
||||
messageDb.loadMessageWithAttachment(1, 1)
|
||||
messageDb.loadMessageWithAttachment("v4")
|
||||
} throws NoSuchElementException("No message in database")
|
||||
|
||||
runBlocking { repository.getMessage(student, testMessage).toFirstResult() }
|
||||
@ -162,7 +118,7 @@ class MessageRepositoryTest {
|
||||
val testMessage = getMessageEntity(123, "Test", false)
|
||||
val messageWithAttachment = MessageWithAttachment(testMessage, emptyList())
|
||||
|
||||
coEvery { messageDb.loadMessageWithAttachment(1, testMessage.messageId) } returns flowOf(
|
||||
coEvery { messageDb.loadMessageWithAttachment("v4") } returns flowOf(
|
||||
messageWithAttachment
|
||||
)
|
||||
|
||||
@ -174,7 +130,7 @@ class MessageRepositoryTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get message when content in db is empty`() {
|
||||
fun `get message when content in db is empty`() = runTest {
|
||||
val testMessage = getMessageEntity(123, "", true)
|
||||
val testMessageWithContent = testMessage.copy().apply { content = "Test" }
|
||||
|
||||
@ -182,23 +138,19 @@ class MessageRepositoryTest {
|
||||
val mWaWithContent = MessageWithAttachment(testMessageWithContent, emptyList())
|
||||
|
||||
coEvery {
|
||||
messageDb.loadMessageWithAttachment(
|
||||
1,
|
||||
testMessage.messageId
|
||||
)
|
||||
messageDb.loadMessageWithAttachment("v4")
|
||||
} returnsMany listOf(flowOf(mWa), flowOf(mWaWithContent))
|
||||
coEvery {
|
||||
sdk.getMessageDetails(
|
||||
messageId = testMessage.messageId,
|
||||
folderId = 1,
|
||||
read = false,
|
||||
id = testMessage.realId
|
||||
)
|
||||
} returns MessageDetails("Test", emptyList())
|
||||
sdk.getMessageDetails("v4")
|
||||
} returns mockk {
|
||||
every { sender } returns ""
|
||||
every { recipients } returns listOf("")
|
||||
every { attachments } returns listOf()
|
||||
}
|
||||
coEvery { messageDb.updateAll(any()) } just Runs
|
||||
coEvery { messageAttachmentDao.insertAttachments(any()) } returns listOf(1)
|
||||
|
||||
val res = runBlocking { repository.getMessage(student, testMessage).toFirstResult() }
|
||||
val res = repository.getMessage(student, testMessage).toFirstResult()
|
||||
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(Status.SUCCESS, res.status)
|
||||
@ -211,7 +163,7 @@ class MessageRepositoryTest {
|
||||
val testMessage = getMessageEntity(123, "", false)
|
||||
|
||||
coEvery {
|
||||
messageDb.loadMessageWithAttachment(1, testMessage.messageId)
|
||||
messageDb.loadMessageWithAttachment("v4")
|
||||
} throws UnknownHostException()
|
||||
|
||||
runBlocking { repository.getMessage(student, testMessage).toFirstResult() }
|
||||
@ -222,7 +174,7 @@ class MessageRepositoryTest {
|
||||
val testMessage = getMessageEntity(123, "", true)
|
||||
|
||||
coEvery {
|
||||
messageDb.loadMessageWithAttachment(1, testMessage.messageId)
|
||||
messageDb.loadMessageWithAttachment("v4")
|
||||
} throws UnknownHostException()
|
||||
|
||||
runBlocking { repository.getMessage(student, testMessage).toList()[1] }
|
||||
@ -233,42 +185,30 @@ class MessageRepositoryTest {
|
||||
content: String,
|
||||
unread: Boolean
|
||||
) = Message(
|
||||
studentId = 1,
|
||||
realId = 1,
|
||||
messageGlobalKey = "v4",
|
||||
mailboxKey = "",
|
||||
correspondents = "",
|
||||
messageId = messageId,
|
||||
sender = "",
|
||||
senderId = 0,
|
||||
recipient = "Wielu adresatów",
|
||||
subject = "",
|
||||
date = Instant.EPOCH,
|
||||
folderId = 1,
|
||||
unread = unread,
|
||||
removed = false,
|
||||
hasAttachments = false
|
||||
).apply {
|
||||
this.content = content
|
||||
unreadBy = 1
|
||||
readBy = 1
|
||||
}
|
||||
|
||||
private fun getMessageDto(
|
||||
messageId: Int,
|
||||
content: String,
|
||||
unread: Boolean,
|
||||
) = io.github.wulkanowy.sdk.pojo.Message(
|
||||
id = 1,
|
||||
messageId = messageId,
|
||||
sender = Sender("", "", 0, 0, 0, ""),
|
||||
private fun getMessageDto() = io.github.wulkanowy.sdk.pojo.Message(
|
||||
globalKey = "v4",
|
||||
mailbox = "",
|
||||
correspondents = "",
|
||||
id = 4,
|
||||
recipients = listOf(),
|
||||
subject = "",
|
||||
content = content,
|
||||
date = Instant.EPOCH.atZone(ZoneOffset.UTC).toLocalDateTime(),
|
||||
content = "Test",
|
||||
dateZoned = Instant.EPOCH.atZone(ZoneOffset.UTC),
|
||||
folderId = 1,
|
||||
unread = unread,
|
||||
unreadBy = 0,
|
||||
readBy = 0,
|
||||
removed = false,
|
||||
unread = true,
|
||||
hasAttachments = false,
|
||||
)
|
||||
}
|
||||
|
@ -1,19 +1,15 @@
|
||||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import io.github.wulkanowy.data.db.dao.RecipientDao
|
||||
import io.github.wulkanowy.data.db.entities.ReportingUnit
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.getMailboxEntity
|
||||
import io.github.wulkanowy.getStudentEntity
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.pojo.MailboxType
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.Runs
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.impl.annotations.SpyK
|
||||
import io.mockk.just
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
@ -36,9 +32,30 @@ class RecipientLocalTest {
|
||||
private lateinit var recipientRepository: RecipientRepository
|
||||
|
||||
private val remoteList = listOf(
|
||||
SdkRecipient("2rPracownik", "Kowalski Jan", 3, 4, 2, "hash", "Kowalski Jan [KJ] - Pracownik (Fake123456)"),
|
||||
SdkRecipient("3rPracownik", "Kowalska Karolina", 4, 4, 2, "hash", "Kowalska Karolina [KK] - Pracownik (Fake123456)"),
|
||||
SdkRecipient("4rPracownik", "Krupa Stanisław", 5, 4, 1, "hash", "Krupa Stanisław [KS] - Uczeń (Fake123456)")
|
||||
SdkRecipient(
|
||||
mailboxGlobalKey = "2rPracownik",
|
||||
userName = "Kowalski Jan",
|
||||
fullName = "Kowalski Jan [KJ] - Pracownik (Fake123456)",
|
||||
studentName = "",
|
||||
schoolNameShort = "",
|
||||
type = MailboxType.UNKNOWN,
|
||||
),
|
||||
SdkRecipient(
|
||||
mailboxGlobalKey = "3rPracownik",
|
||||
userName = "Kowalska Karolina",
|
||||
fullName = "Kowalska Karolina [KK] - Pracownik (Fake123456)",
|
||||
studentName = "",
|
||||
schoolNameShort = "",
|
||||
type = MailboxType.UNKNOWN,
|
||||
),
|
||||
SdkRecipient(
|
||||
mailboxGlobalKey = "4rPracownik",
|
||||
userName = "Krupa Stanisław",
|
||||
fullName = "Krupa Stanisław [KS] - Uczeń (Fake123456)",
|
||||
studentName = "",
|
||||
schoolNameShort = "",
|
||||
type = MailboxType.UNKNOWN,
|
||||
)
|
||||
)
|
||||
|
||||
@Before
|
||||
@ -52,39 +69,61 @@ class RecipientLocalTest {
|
||||
@Test
|
||||
fun `load recipients when items already in database`() {
|
||||
// prepare
|
||||
coEvery { recipientDb.loadAll(4, 123, 7) } returnsMany listOf(
|
||||
remoteList.mapToEntities(4),
|
||||
remoteList.mapToEntities(4)
|
||||
coEvery { recipientDb.loadAll(io.github.wulkanowy.data.db.entities.MailboxType.UNKNOWN, "v4") } returnsMany listOf(
|
||||
remoteList.mapToEntities("v4"),
|
||||
remoteList.mapToEntities("v4")
|
||||
)
|
||||
coEvery { recipientDb.insertAll(any()) } returns listOf(1, 2, 3)
|
||||
coEvery { recipientDb.deleteAll(any()) } just Runs
|
||||
|
||||
// execute
|
||||
val res = runBlocking { recipientRepository.getRecipients(student, ReportingUnit(4, 123, "", 4, "", listOf()), 7) }
|
||||
val res = runBlocking {
|
||||
recipientRepository.getRecipients(
|
||||
student = student,
|
||||
mailbox = getMailboxEntity(),
|
||||
type = io.github.wulkanowy.data.db.entities.MailboxType.UNKNOWN,
|
||||
)
|
||||
}
|
||||
|
||||
// verify
|
||||
assertEquals(3, res.size)
|
||||
coVerify { recipientDb.loadAll(4, 123, 7) }
|
||||
coVerify {
|
||||
recipientDb.loadAll(
|
||||
type = io.github.wulkanowy.data.db.entities.MailboxType.UNKNOWN,
|
||||
studentMailboxGlobalKey = "v4"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `load recipients when database is empty`() {
|
||||
// prepare
|
||||
coEvery { sdk.getRecipients(123, 7) } returns remoteList
|
||||
coEvery { recipientDb.loadAll(4, 123, 7) } returnsMany listOf(
|
||||
coEvery { sdk.getRecipients("v4") } returns remoteList
|
||||
coEvery {
|
||||
recipientDb.loadAll(
|
||||
io.github.wulkanowy.data.db.entities.MailboxType.UNKNOWN,
|
||||
"v4"
|
||||
)
|
||||
} returnsMany listOf(
|
||||
emptyList(),
|
||||
remoteList.mapToEntities(4)
|
||||
remoteList.mapToEntities("v4")
|
||||
)
|
||||
coEvery { recipientDb.insertAll(any()) } returns listOf(1, 2, 3)
|
||||
coEvery { recipientDb.deleteAll(any()) } just Runs
|
||||
|
||||
// execute
|
||||
val res = runBlocking { recipientRepository.getRecipients(student, ReportingUnit(4, 123, "", 4, "", listOf()), 7) }
|
||||
val res = runBlocking {
|
||||
recipientRepository.getRecipients(
|
||||
student = student,
|
||||
mailbox = getMailboxEntity(),
|
||||
type = io.github.wulkanowy.data.db.entities.MailboxType.UNKNOWN,
|
||||
)
|
||||
}
|
||||
|
||||
// verify
|
||||
assertEquals(3, res.size)
|
||||
coVerify { sdk.getRecipients(123, 7) }
|
||||
coVerify { recipientDb.loadAll(4, 123, 7) }
|
||||
coVerify { sdk.getRecipients("v4") }
|
||||
coVerify { recipientDb.loadAll(io.github.wulkanowy.data.db.entities.MailboxType.UNKNOWN, "v4") }
|
||||
coVerify { recipientDb.insertAll(match { it.isEmpty() }) }
|
||||
coVerify { recipientDb.deleteAll(match { it.isEmpty() }) }
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user