mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-01-18 12:56:45 -06:00
[UI] Refactor Messages fragment.
This commit is contained in:
parent
c0aeb0d2f3
commit
f98b174857
@ -816,7 +816,7 @@ fun View.findParentById(targetId: Int): View? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun CoroutineScope.startCoroutineTimer(delayMillis: Long = 0, repeatMillis: Long = 0, action: () -> Unit) = launch {
|
||||
fun CoroutineScope.startCoroutineTimer(delayMillis: Long = 0, repeatMillis: Long = 0, action: suspend CoroutineScope.() -> Unit) = launch {
|
||||
delay(delayMillis)
|
||||
if (repeatMillis > 0) {
|
||||
while (true) {
|
||||
|
@ -68,9 +68,9 @@ import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.login.LoginActivity
|
||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessageFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesComposeFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesListFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesListFragmentOld
|
||||
import pl.szczodrzynski.edziennik.ui.modules.messages.compose.MessagesComposeFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.notifications.NotificationsListFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.settings.ProfileManagerFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.settings.SettingsNewFragment
|
||||
@ -889,9 +889,9 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
}
|
||||
app.profileLoad(id) {
|
||||
MessagesFragment.pageSelection = -1
|
||||
MessagesListFragment.tapPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
||||
MessagesListFragment.topPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
||||
MessagesListFragment.bottomPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
||||
MessagesListFragmentOld.tapPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
||||
MessagesListFragmentOld.topPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
||||
MessagesListFragmentOld.bottomPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
||||
|
||||
setDrawerItems()
|
||||
// the drawer profile is updated automatically when the drawer item is clicked
|
||||
|
@ -13,8 +13,8 @@ import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOME
|
||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOMEWORK
|
||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
|
||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||
|
||||
internal const val FEATURE_TIMETABLE = 1
|
||||
internal const val FEATURE_AGENDA = 2
|
||||
|
@ -11,8 +11,8 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikApi
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.*
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_DELETED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_DELETED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.getBoolean
|
||||
import pl.szczodrzynski.edziennik.getString
|
||||
import pl.szczodrzynski.edziennik.utils.Utils.crc32
|
||||
@ -33,11 +33,11 @@ class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
||||
return@apiGet
|
||||
}
|
||||
|
||||
json.asJsonObjectList()?.forEach { jMessage ->
|
||||
val subject = jMessage.getString("tytul")
|
||||
if (subject?.contains("(") == true && subject.startsWith("iDziennik - "))
|
||||
json.asJsonObjectList().forEach { jMessage ->
|
||||
val subject = jMessage.getString("tytul") ?: ""
|
||||
if (subject.contains("(") && subject.startsWith("iDziennik - "))
|
||||
return@forEach
|
||||
if (subject?.startsWith("Uwaga dla ucznia (klasa:") == true)
|
||||
if (subject.startsWith("Uwaga dla ucznia (klasa:"))
|
||||
return@forEach
|
||||
|
||||
val messageIdStr = jMessage.getString("id")
|
||||
@ -64,13 +64,12 @@ class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
||||
rTeacher.setTeacherType(Teacher.TYPE_OTHER)
|
||||
|
||||
val message = Message(
|
||||
profileId,
|
||||
messageId,
|
||||
subject,
|
||||
body,
|
||||
if (jMessage.getBoolean("rekordUsuniety") == true) TYPE_DELETED else TYPE_RECEIVED,
|
||||
rTeacher.id,
|
||||
-1
|
||||
profileId = profileId,
|
||||
id = messageId,
|
||||
type = if (jMessage.getBoolean("rekordUsuniety") == true) TYPE_DELETED else TYPE_RECEIVED,
|
||||
subject = subject,
|
||||
body = body,
|
||||
senderId = rTeacher.id
|
||||
)
|
||||
|
||||
val messageRecipient = MessageRecipient(
|
||||
@ -81,7 +80,7 @@ class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
||||
/*messageId*/ messageId
|
||||
)
|
||||
|
||||
data.messageIgnoreList.add(message)
|
||||
data.messageList.add(message)
|
||||
data.messageRecipientList.add(messageRecipient)
|
||||
data.setSeenMetadataList.add(Metadata(
|
||||
profileId,
|
||||
|
@ -13,7 +13,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_API_MESSAGES_SENT
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikApi
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.utils.Utils.crc32
|
||||
@ -46,13 +46,12 @@ class IdziennikApiMessagesSent(override val data: DataIdziennik,
|
||||
val sentDate = Date.fromIso(jMessage.get("dataWyslania").asString)
|
||||
|
||||
val message = Message(
|
||||
profileId,
|
||||
messageId,
|
||||
subject,
|
||||
body,
|
||||
TYPE_SENT,
|
||||
-1,
|
||||
-1
|
||||
profileId = profileId,
|
||||
id = messageId,
|
||||
type = TYPE_SENT,
|
||||
subject = subject,
|
||||
body = body,
|
||||
senderId = null
|
||||
)
|
||||
|
||||
for (recipientEl in jMessage.getAsJsonArray("odbiorcy")) {
|
||||
@ -76,7 +75,7 @@ class IdziennikApiMessagesSent(override val data: DataIdziennik,
|
||||
data.messageRecipientIgnoreList.add(messageRecipient)
|
||||
}
|
||||
|
||||
data.messageIgnoreList.add(message)
|
||||
data.messageList.add(message)
|
||||
data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true, sentDate))
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,8 @@ import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_GET_MESSAGE
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||
import pl.szczodrzynski.edziennik.data.db.full.MessageRecipientFull
|
||||
@ -50,7 +50,11 @@ class IdziennikWebGetMessage(override val data: DataIdziennik,
|
||||
message.recipients?.clear()
|
||||
when (message.type) {
|
||||
TYPE_RECEIVED -> {
|
||||
val recipientObject = MessageRecipientFull(profileId, -1, message.id)
|
||||
val recipientObject = MessageRecipientFull(
|
||||
profileId = profileId,
|
||||
id = -1,
|
||||
messageId = message.id
|
||||
)
|
||||
|
||||
val readDateString = it.getString("DataOdczytania")
|
||||
recipientObject.readDate = if (readDateString.isNullOrBlank()) System.currentTimeMillis()
|
||||
@ -67,7 +71,11 @@ class IdziennikWebGetMessage(override val data: DataIdziennik,
|
||||
val recipientName = recipient.getString("NazwaOdbiorcy") ?: return@forEach
|
||||
val teacher = data.getTeacherByLastFirst(recipientName)
|
||||
|
||||
val recipientObject = MessageRecipientFull(profileId, teacher.id, message.id)
|
||||
val recipientObject = MessageRecipientFull(
|
||||
profileId = profileId,
|
||||
id = teacher.id,
|
||||
messageId = message.id
|
||||
)
|
||||
|
||||
recipientObject.readDate = recipient.getLong("Status") ?: return@forEach
|
||||
recipientObject.fullName = teacher.fullName
|
||||
@ -91,9 +99,10 @@ class IdziennikWebGetMessage(override val data: DataIdziennik,
|
||||
))
|
||||
}
|
||||
|
||||
EventBus.getDefault().postSticky(MessageGetEvent(message))
|
||||
|
||||
data.messageList.add(message)
|
||||
data.messageListReplace = true
|
||||
|
||||
EventBus.getDefault().postSticky(MessageGetEvent(message))
|
||||
onSuccess()
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ class IdziennikWebSendMessage(override val data: DataIdziennik,
|
||||
}
|
||||
|
||||
IdziennikApiMessagesSent(data, null) {
|
||||
val message = data.messageIgnoreList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
||||
val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
||||
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
|
||||
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate)
|
||||
|
||||
|
@ -12,7 +12,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_MESS
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_MESSAGES_SENT
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusMessages
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.*
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.fixName
|
||||
import pl.szczodrzynski.edziennik.singleOrNull
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
@ -78,7 +78,7 @@ class LibrusMessagesGetList(override val data: DataLibrus,
|
||||
|
||||
val senderId = when (type) {
|
||||
TYPE_RECEIVED -> recipientId
|
||||
else -> -1
|
||||
else -> null
|
||||
}
|
||||
|
||||
val receiverId = when (type) {
|
||||
@ -92,13 +92,12 @@ class LibrusMessagesGetList(override val data: DataLibrus,
|
||||
}
|
||||
|
||||
val messageObject = Message(
|
||||
profileId,
|
||||
id,
|
||||
subject,
|
||||
null,
|
||||
type,
|
||||
senderId,
|
||||
-1
|
||||
profileId = profileId,
|
||||
id = id,
|
||||
type = type,
|
||||
subject = subject,
|
||||
body = null,
|
||||
senderId = senderId
|
||||
)
|
||||
|
||||
val messageRecipientObject = MessageRecipient(
|
||||
@ -111,10 +110,10 @@ class LibrusMessagesGetList(override val data: DataLibrus,
|
||||
|
||||
element.select("isAnyFileAttached")?.text()?.let {
|
||||
if (it == "1")
|
||||
messageObject.overrideHasAttachments = true
|
||||
messageObject.hasAttachments = true
|
||||
}
|
||||
|
||||
data.messageIgnoreList.add(messageObject)
|
||||
data.messageList.add(messageObject)
|
||||
data.messageRecipientList.add(messageRecipientObject)
|
||||
data.setSeenMetadataList.add(Metadata(
|
||||
profileId,
|
||||
|
@ -9,8 +9,8 @@ import org.greenrobot.eventbus.EventBus
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusMessages
|
||||
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||
@ -102,11 +102,10 @@ class LibrusMessagesGetMessage(override val data: DataLibrus,
|
||||
}
|
||||
|
||||
val messageRecipientObject = MessageRecipientFull(
|
||||
profileId,
|
||||
-1,
|
||||
-1,
|
||||
readDate,
|
||||
messageObject.id
|
||||
profileId = profileId,
|
||||
id = -1,
|
||||
messageId = messageObject.id,
|
||||
readDate = readDate
|
||||
)
|
||||
|
||||
messageRecipientObject.fullName = profile.accountName ?: profile.studentNameLong ?: ""
|
||||
@ -132,11 +131,10 @@ class LibrusMessagesGetMessage(override val data: DataLibrus,
|
||||
}
|
||||
|
||||
val messageRecipientObject = MessageRecipientFull(
|
||||
profileId,
|
||||
receiverId,
|
||||
-1,
|
||||
readDate,
|
||||
messageObject.id
|
||||
profileId = profileId,
|
||||
id = receiverId,
|
||||
messageId = messageObject.id,
|
||||
readDate = readDate
|
||||
)
|
||||
|
||||
messageRecipientObject.fullName = "$receiverFirstName $receiverLastName"
|
||||
@ -159,7 +157,9 @@ class LibrusMessagesGetMessage(override val data: DataLibrus,
|
||||
|
||||
messageObject.recipients = messageRecipientList
|
||||
data.messageRecipientList.addAll(messageRecipientList)
|
||||
|
||||
data.messageList.add(messageObject)
|
||||
data.messageListReplace = true
|
||||
|
||||
EventBus.getDefault().postSticky(MessageGetEvent(messageObject))
|
||||
onSuccess()
|
||||
|
@ -48,7 +48,7 @@ class LibrusMessagesSendMessage(override val data: DataLibrus,
|
||||
}
|
||||
|
||||
LibrusMessagesGetList(data, type = Message.TYPE_SENT, lastSync = null) {
|
||||
val message = data.messageIgnoreList.firstOrNull { it.type == Message.TYPE_SENT && it.id == id }
|
||||
val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.id == id }
|
||||
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
|
||||
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate)
|
||||
|
||||
|
@ -11,7 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidzienn
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
|
||||
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||
import pl.szczodrzynski.edziennik.data.db.full.MessageRecipientFull
|
||||
@ -61,19 +61,17 @@ class MobidziennikWebGetMessage(override val data: DataMobidziennik,
|
||||
}
|
||||
|
||||
val recipient = MessageRecipientFull(
|
||||
profileId,
|
||||
-1,
|
||||
-1,
|
||||
readDate,
|
||||
message.id
|
||||
profileId = profileId,
|
||||
id = -1,
|
||||
messageId = message.id,
|
||||
readDate = readDate
|
||||
)
|
||||
|
||||
recipient.fullName = profile?.accountName ?: profile?.studentNameLong ?: ""
|
||||
|
||||
messageRecipientList.add(recipient)
|
||||
} else {
|
||||
message.senderId = -1
|
||||
message.senderReplyId = -1
|
||||
message.senderId = null
|
||||
|
||||
content.select("table.spis tr:has(td)")?.forEach { recipientEl ->
|
||||
val senderEl = recipientEl.select("td:eq(0)").first()
|
||||
@ -100,11 +98,10 @@ class MobidziennikWebGetMessage(override val data: DataMobidziennik,
|
||||
}
|
||||
|
||||
val recipient = MessageRecipientFull(
|
||||
profileId,
|
||||
receiverId,
|
||||
-1,
|
||||
readDate,
|
||||
message.id
|
||||
profileId = profileId,
|
||||
id = receiverId,
|
||||
messageId = message.id,
|
||||
readDate = readDate
|
||||
)
|
||||
|
||||
recipient.fullName = teacher?.fullName ?: "?"
|
||||
@ -149,7 +146,9 @@ class MobidziennikWebGetMessage(override val data: DataMobidziennik,
|
||||
|
||||
message.recipients = messageRecipientList
|
||||
data.messageRecipientList.addAll(messageRecipientList)
|
||||
|
||||
data.messageList.add(message)
|
||||
data.messageListReplace = true
|
||||
|
||||
EventBus.getDefault().postSticky(MessageGetEvent(message))
|
||||
onSuccess()
|
||||
|
@ -10,8 +10,8 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidzienn
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.ENDPOINT_MOBIDZIENNIK_WEB_MESSAGES_ALL
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.fixName
|
||||
@ -54,12 +54,12 @@ class MobidziennikWebMessagesAll(override val data: DataMobidziennik,
|
||||
type = TYPE_SENT
|
||||
|
||||
val senderEl = item.select("td:eq(3) div").first()
|
||||
var senderId: Long = -1
|
||||
var senderId: Long? = null
|
||||
|
||||
if (type == TYPE_RECEIVED) {
|
||||
// search sender teacher
|
||||
val senderName = senderEl.text().fixName()
|
||||
senderId = data.teacherList.singleOrNull { it.fullNameLastFirst == senderName }?.id ?: -1
|
||||
senderId = data.teacherList.singleOrNull { it.fullNameLastFirst == senderName }?.id
|
||||
data.messageRecipientList.add(MessageRecipient(profileId, -1, id))
|
||||
} else {
|
||||
// TYPE_SENT, so multiple recipients possible
|
||||
@ -72,16 +72,15 @@ class MobidziennikWebMessagesAll(override val data: DataMobidziennik,
|
||||
}
|
||||
|
||||
val message = Message(
|
||||
profileId,
|
||||
id,
|
||||
subject,
|
||||
null,
|
||||
type,
|
||||
senderId,
|
||||
-1
|
||||
profileId = profileId,
|
||||
id = id,
|
||||
type = type,
|
||||
subject = subject,
|
||||
body = null,
|
||||
senderId = senderId
|
||||
)
|
||||
|
||||
data.messageIgnoreList.add(message)
|
||||
data.messageList.add(message)
|
||||
data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true, addedDate))
|
||||
}
|
||||
|
||||
|
@ -52,25 +52,24 @@ class MobidziennikWebMessagesInbox(override val data: DataMobidziennik,
|
||||
|
||||
val senderEl = item.select("td:eq(2)").first()
|
||||
val senderName = senderEl.ownText().fixName()
|
||||
val senderId = data.teacherList.singleOrNull { it.fullNameLastFirst == senderName }?.id ?: -1
|
||||
val senderId = data.teacherList.singleOrNull { it.fullNameLastFirst == senderName }?.id
|
||||
data.messageRecipientIgnoreList.add(MessageRecipient(profileId, -1, id))
|
||||
|
||||
val isRead = item.select("td:eq(3) span").first().hasClass("wiadomosc_przeczytana")
|
||||
|
||||
val message = Message(
|
||||
profileId,
|
||||
id,
|
||||
subject,
|
||||
null,
|
||||
Message.TYPE_RECEIVED,
|
||||
senderId,
|
||||
-1
|
||||
profileId = profileId,
|
||||
id = id,
|
||||
type = Message.TYPE_RECEIVED,
|
||||
subject = subject,
|
||||
body = null,
|
||||
senderId = senderId
|
||||
)
|
||||
|
||||
if (hasAttachments)
|
||||
message.setHasAttachments()
|
||||
message.hasAttachments = true
|
||||
|
||||
data.messageIgnoreList.add(message)
|
||||
data.messageList.add(message)
|
||||
data.setSeenMetadataList.add(
|
||||
Metadata(
|
||||
profileId,
|
||||
|
@ -73,19 +73,18 @@ class MobidziennikWebMessagesSent(override val data: DataMobidziennik,
|
||||
val addedDate = Date.fromIsoHm(addedDateEl.text())
|
||||
|
||||
val message = Message(
|
||||
profileId,
|
||||
id,
|
||||
subject,
|
||||
null,
|
||||
Message.TYPE_SENT,
|
||||
-1,
|
||||
-1
|
||||
profileId = profileId,
|
||||
id = id,
|
||||
type = Message.TYPE_SENT,
|
||||
subject = subject,
|
||||
body = null,
|
||||
senderId = null
|
||||
)
|
||||
|
||||
if (hasAttachments)
|
||||
message.setHasAttachments()
|
||||
message.hasAttachments = true
|
||||
|
||||
data.messageIgnoreList.add(message)
|
||||
data.messageList.add(message)
|
||||
data.setSeenMetadataList.add(
|
||||
Metadata(
|
||||
profileId,
|
||||
|
@ -43,7 +43,7 @@ class MobidziennikWebSendMessage(override val data: DataMobidziennik,
|
||||
|
||||
// TODO create MobidziennikWebMessagesSent and replace this
|
||||
MobidziennikWebMessagesAll(data, null) {
|
||||
val message = data.messageIgnoreList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
||||
val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
||||
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
|
||||
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate)
|
||||
|
||||
|
@ -9,7 +9,7 @@ import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_MESSAGES_CHANGE_S
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
||||
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||
|
@ -10,7 +10,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_MESSAGES_INBOX
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.*
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
import kotlin.text.replace
|
||||
@ -44,8 +44,7 @@ class VulcanApiMessagesInbox(override val data: DataVulcan,
|
||||
val body = message.getString("Tresc") ?: ""
|
||||
|
||||
val senderLoginId = message.getString("NadawcaId") ?: return@forEach
|
||||
val senderId = data.teacherList
|
||||
.singleOrNull { it.loginId == senderLoginId }?.id ?: {
|
||||
val senderId = data.teacherList.singleOrNull { it.loginId == senderLoginId }?.id ?: {
|
||||
|
||||
val senderName = message.getString("Nadawca") ?: ""
|
||||
|
||||
@ -60,7 +59,7 @@ class VulcanApiMessagesInbox(override val data: DataVulcan,
|
||||
data.teacherList.put(teacherObject.id, teacherObject)
|
||||
teacherObject.id
|
||||
}
|
||||
}.invoke() ?: -1
|
||||
}.invoke()
|
||||
|
||||
val sentDate = message.getLong("DataWyslaniaUnixEpoch")?.let { it * 1000 }
|
||||
?: -1
|
||||
@ -68,13 +67,12 @@ class VulcanApiMessagesInbox(override val data: DataVulcan,
|
||||
?: -1
|
||||
|
||||
val messageObject = Message(
|
||||
profileId,
|
||||
id,
|
||||
subject,
|
||||
body.replace("\n", "<br>"),
|
||||
TYPE_RECEIVED,
|
||||
senderId,
|
||||
-1
|
||||
profileId = profileId,
|
||||
id = id,
|
||||
type = TYPE_RECEIVED,
|
||||
subject = subject,
|
||||
body = body.replace("\n", "<br>"),
|
||||
senderId = senderId
|
||||
)
|
||||
|
||||
val messageRecipientObject = MessageRecipient(
|
||||
@ -85,7 +83,7 @@ class VulcanApiMessagesInbox(override val data: DataVulcan,
|
||||
id
|
||||
)
|
||||
|
||||
data.messageIgnoreList.add(messageObject)
|
||||
data.messageList.add(messageObject)
|
||||
data.messageRecipientList.add(messageRecipientObject)
|
||||
data.setSeenMetadataList.add(Metadata(
|
||||
profileId,
|
||||
|
@ -11,7 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_MESSAGES_SENT
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||
@ -92,16 +92,15 @@ class VulcanApiMessagesSent(override val data: DataVulcan,
|
||||
}
|
||||
|
||||
val messageObject = Message(
|
||||
profileId,
|
||||
id,
|
||||
subject,
|
||||
body.replace("\n", "<br>"),
|
||||
TYPE_SENT,
|
||||
-1,
|
||||
-1
|
||||
profileId = profileId,
|
||||
id = id,
|
||||
type = TYPE_SENT,
|
||||
subject = subject,
|
||||
body = body.replace("\n", "<br>"),
|
||||
senderId = null
|
||||
)
|
||||
|
||||
data.messageIgnoreList.add(messageObject)
|
||||
data.messageList.add(messageObject)
|
||||
data.setSeenMetadataList.add(Metadata(
|
||||
profileId,
|
||||
Metadata.TYPE_MESSAGE,
|
||||
|
@ -52,7 +52,7 @@ class VulcanApiSendMessage(override val data: DataVulcan,
|
||||
}
|
||||
|
||||
VulcanApiMessagesSent(data, null) {
|
||||
val message = data.messageIgnoreList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
||||
val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
||||
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == messageId }
|
||||
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate)
|
||||
|
||||
|
@ -87,6 +87,7 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
|
||||
|
||||
var teacherOnConflictStrategy = OnConflictStrategy.IGNORE
|
||||
var eventListReplace = false
|
||||
var messageListReplace = false
|
||||
|
||||
val classrooms = LongSparseArray<Classroom>()
|
||||
val attendanceTypes = LongSparseArray<AttendanceType>()
|
||||
@ -126,7 +127,6 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
|
||||
val teacherAbsenceList = mutableListOf<TeacherAbsence>()
|
||||
|
||||
val messageList = mutableListOf<Message>()
|
||||
val messageIgnoreList = mutableListOf<Message>()
|
||||
val messageRecipientList = mutableListOf<MessageRecipient>()
|
||||
val messageRecipientIgnoreList = mutableListOf<MessageRecipient>()
|
||||
|
||||
@ -182,7 +182,6 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
|
||||
luckyNumberList.clear()
|
||||
teacherAbsenceList.clear()
|
||||
messageList.clear()
|
||||
messageIgnoreList.clear()
|
||||
messageRecipientList.clear()
|
||||
messageRecipientIgnoreList.clear()
|
||||
metadataList.clear()
|
||||
@ -305,10 +304,12 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
|
||||
if (teacherAbsenceList.isNotEmpty())
|
||||
db.teacherAbsenceDao().addAll(teacherAbsenceList)
|
||||
|
||||
if (messageList.isNotEmpty())
|
||||
db.messageDao().addAll(messageList)
|
||||
if (messageIgnoreList.isNotEmpty())
|
||||
db.messageDao().addAllIgnore(messageIgnoreList)
|
||||
if (messageList.isNotEmpty()) {
|
||||
if (messageListReplace)
|
||||
db.messageDao().replaceAll(messageList)
|
||||
else
|
||||
db.messageDao().upsertAll(messageList, removeNotKept = false) // TODO dataRemoveModel for messages
|
||||
}
|
||||
if (messageRecipientList.isNotEmpty())
|
||||
db.messageRecipientDao().addAll(messageRecipientList)
|
||||
if (messageRecipientIgnoreList.isNotEmpty())
|
||||
|
@ -227,10 +227,10 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
|
||||
}
|
||||
|
||||
private fun messageNotifications() {
|
||||
for (message in app.db.messageDao().receivedNotNotifiedNow) {
|
||||
for (message in app.db.messageDao().getNotNotifiedNow()) {
|
||||
val text = app.getString(
|
||||
R.string.notification_message_format,
|
||||
message.senderFullName,
|
||||
message.senderName,
|
||||
message.subject
|
||||
)
|
||||
notifications += Notification(
|
||||
|
@ -43,7 +43,7 @@ import pl.szczodrzynski.edziennik.data.db.migration.*
|
||||
LibrusLesson::class,
|
||||
TimetableManual::class,
|
||||
Metadata::class
|
||||
], version = 83)
|
||||
], version = 84)
|
||||
@TypeConverters(
|
||||
ConverterTime::class,
|
||||
ConverterDate::class,
|
||||
@ -168,7 +168,8 @@ abstract class AppDb : RoomDatabase() {
|
||||
Migration80(),
|
||||
Migration81(),
|
||||
Migration82(),
|
||||
Migration83()
|
||||
Migration83(),
|
||||
Migration84()
|
||||
).allowMainThreadQueries().build()
|
||||
}
|
||||
}
|
||||
|
@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.db.dao;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Insert;
|
||||
import androidx.room.OnConflictStrategy;
|
||||
import androidx.room.Query;
|
||||
import androidx.room.RawQuery;
|
||||
import androidx.sqlite.db.SimpleSQLiteQuery;
|
||||
import androidx.sqlite.db.SupportSQLiteQuery;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message;
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata;
|
||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull;
|
||||
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_DELETED;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_MESSAGE;
|
||||
|
||||
@Dao
|
||||
public abstract class MessageDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
public abstract long add(Message message);
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
public abstract void addAll(List<Message> messageList);
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||
public abstract void addAllIgnore(List<Message> messageList);
|
||||
|
||||
@Query("DELETE FROM messages WHERE profileId = :profileId")
|
||||
public abstract void clear(int profileId);
|
||||
|
||||
@RawQuery(observedEntities = {Message.class})
|
||||
abstract LiveData<List<MessageFull>> getAll(SupportSQLiteQuery query);
|
||||
@RawQuery(observedEntities = {Message.class, Metadata.class})
|
||||
abstract List<MessageFull> getNow(SupportSQLiteQuery query);
|
||||
@RawQuery(observedEntities = {Message.class, Metadata.class})
|
||||
abstract MessageFull getOneNow(SupportSQLiteQuery query);
|
||||
|
||||
public LiveData<List<MessageFull>> getWithMetadataAndSenderName(int profileId, int messageType, String filter) {
|
||||
return getAll(new SimpleSQLiteQuery("SELECT \n" +
|
||||
"*, \n" +
|
||||
"teachers.teacherName || ' ' || teachers.teacherSurname AS senderFullName\n" +
|
||||
"FROM messages \n" +
|
||||
"LEFT JOIN teachers ON teachers.profileId = "+profileId+" AND teacherId = senderId\n" +
|
||||
"LEFT JOIN metadata ON messageId = thingId AND thingType = "+TYPE_MESSAGE+" AND metadata.profileId = "+profileId+"\n" +
|
||||
"WHERE messages.profileId = "+profileId+" AND messageType = "+messageType+" AND "+filter+"\n" +
|
||||
"ORDER BY addedDate DESC"));
|
||||
}
|
||||
|
||||
public LiveData<List<MessageFull>> getWithMetadata(int profileId, int messageType, String filter) {
|
||||
return getAll(new SimpleSQLiteQuery("SELECT \n" +
|
||||
"* \n" +
|
||||
"FROM messages \n" +
|
||||
"LEFT JOIN metadata ON messageId = thingId AND thingType = "+TYPE_MESSAGE+" AND metadata.profileId = "+profileId+"\n" +
|
||||
"WHERE messages.profileId = "+profileId+" AND messageType = "+messageType+" AND "+filter+"\n" +
|
||||
"ORDER BY addedDate DESC"));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MessageFull getById(int profileId, long messageId) {
|
||||
return getOneNow(new SimpleSQLiteQuery("SELECT \n" +
|
||||
"*, \n" +
|
||||
"teachers.teacherName || ' ' || teachers.teacherSurname AS senderFullName\n" +
|
||||
"FROM messages \n" +
|
||||
"LEFT JOIN teachers ON teachers.profileId = "+profileId+" AND teacherId = senderId\n" +
|
||||
"LEFT JOIN metadata ON messageId = thingId AND thingType = "+TYPE_MESSAGE+" AND metadata.profileId = "+profileId+"\n" +
|
||||
"WHERE messages.profileId = "+profileId+" AND messageId = "+messageId+"\n" +
|
||||
"ORDER BY addedDate DESC"));
|
||||
}
|
||||
|
||||
public LiveData<List<MessageFull>> getReceived(int profileId) {
|
||||
return getWithMetadataAndSenderName(profileId, TYPE_RECEIVED, "1");
|
||||
}
|
||||
public LiveData<List<MessageFull>> getDeleted(int profileId) {
|
||||
return getWithMetadataAndSenderName(profileId, TYPE_DELETED, "1");
|
||||
}
|
||||
public LiveData<List<MessageFull>> getSent(int profileId) {
|
||||
return getWithMetadata(profileId, TYPE_SENT, "1");
|
||||
}
|
||||
|
||||
public List<MessageFull> getReceivedNow(int profileId, String filter) {
|
||||
return getNow(new SimpleSQLiteQuery("SELECT \n" +
|
||||
"*, \n" +
|
||||
"teachers.teacherName || ' ' || teachers.teacherSurname AS senderFullName\n" +
|
||||
"FROM messages \n" +
|
||||
"LEFT JOIN teachers ON teachers.profileId = "+profileId+" AND teacherId = senderId\n" +
|
||||
"LEFT JOIN metadata ON messageId = thingId AND thingType = "+TYPE_MESSAGE+" AND metadata.profileId = "+profileId+"\n" +
|
||||
"WHERE messages.profileId = "+profileId+" AND messageType = 0 AND "+filter+"\n" +
|
||||
"ORDER BY addedDate DESC"));
|
||||
}
|
||||
public List<MessageFull> getReceivedNotNotifiedNow(int profileId) {
|
||||
return getReceivedNow(profileId, "notified = 0");
|
||||
}
|
||||
|
||||
@Query("SELECT " +
|
||||
"*, " +
|
||||
"teachers.teacherName || ' ' || teachers.teacherSurname AS senderFullName " +
|
||||
"FROM messages " +
|
||||
"LEFT JOIN teachers ON teachers.profileId = messages.profileId AND teacherId = senderId " +
|
||||
"LEFT JOIN metadata ON messageId = thingId AND thingType = "+TYPE_MESSAGE+" AND metadata.profileId = messages.profileId " +
|
||||
"WHERE messageType = 0 AND notified = 0 " +
|
||||
"ORDER BY addedDate DESC")
|
||||
public abstract List<MessageFull> getReceivedNotNotifiedNow();
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
||||
*/
|
||||
package pl.szczodrzynski.edziennik.data.db.dao
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import androidx.room.RawQuery
|
||||
import androidx.sqlite.db.SupportSQLiteQuery
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.annotation.SelectiveDao
|
||||
import pl.szczodrzynski.edziennik.annotation.UpdateSelective
|
||||
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||
|
||||
@Dao
|
||||
@SelectiveDao(db = AppDb::class)
|
||||
abstract class MessageDao : BaseDao<Message, MessageFull> {
|
||||
companion object {
|
||||
private const val QUERY = """
|
||||
SELECT
|
||||
*,
|
||||
teachers.teacherName ||" "|| teachers.teacherSurname AS senderName
|
||||
FROM messages
|
||||
LEFT JOIN teachers ON teachers.profileId = messages.profileId AND teacherId = senderId
|
||||
LEFT JOIN metadata ON messageId = thingId AND thingType = ${Metadata.TYPE_MESSAGE} AND metadata.profileId = messages.profileId
|
||||
"""
|
||||
|
||||
private const val ORDER_BY = """ORDER BY messageIsPinned, addedDate DESC"""
|
||||
}
|
||||
|
||||
private val selective by lazy { MessageDaoSelective(App.db) }
|
||||
|
||||
@RawQuery(observedEntities = [Message::class])
|
||||
abstract override fun getRaw(query: SupportSQLiteQuery): LiveData<List<MessageFull>>
|
||||
|
||||
@UpdateSelective(primaryKeys = ["profileId", "messageId"], skippedColumns = ["messageType", "messageBody", "messageIsPinned", "attachmentIds", "attachmentNames", "attachmentSizes"])
|
||||
override fun update(item: Message) = selective.update(item)
|
||||
override fun updateAll(items: List<Message>) = selective.updateAll(items)
|
||||
|
||||
// CLEAR
|
||||
@Query("DELETE FROM messages WHERE profileId = :profileId")
|
||||
abstract override fun clear(profileId: Int)
|
||||
|
||||
// GET ALL - LIVE DATA
|
||||
fun getAll(profileId: Int) =
|
||||
getRaw("$QUERY WHERE messages.profileId = $profileId $ORDER_BY")
|
||||
fun getAllByType(profileId: Int, type: Int) =
|
||||
getRaw("$QUERY WHERE messages.profileId = $profileId AND messageType = $type $ORDER_BY")
|
||||
fun getReceived(profileId: Int) = getAllByType(profileId, Message.TYPE_RECEIVED)
|
||||
fun getSent(profileId: Int) = getAllByType(profileId, Message.TYPE_SENT)
|
||||
fun getDeleted(profileId: Int) = getAllByType(profileId, Message.TYPE_DELETED)
|
||||
fun getDraft(profileId: Int) = getAllByType(profileId, Message.TYPE_DRAFT)
|
||||
|
||||
// GET ALL - NOW
|
||||
fun getAllNow(profileId: Int) =
|
||||
getRawNow("$QUERY WHERE messages.profileId = $profileId $ORDER_BY")
|
||||
fun getNotNotifiedNow() =
|
||||
getRawNow("$QUERY WHERE notified = 0 AND messageType = ${Message.TYPE_RECEIVED} $ORDER_BY")
|
||||
|
||||
// GET ONE - NOW
|
||||
fun getByIdNow(profileId: Int, id: Long) =
|
||||
getOneNow("$QUERY WHERE messages.profileId = $profileId AND messageId = $id")
|
||||
}
|
@ -93,8 +93,8 @@ public abstract class MetadataDao {
|
||||
}
|
||||
}
|
||||
if (o instanceof Message) {
|
||||
if (add(new Metadata(profileId, TYPE_MESSAGE, ((Message) o).id, seen, false, 0)) == -1) {
|
||||
updateSeen(profileId, TYPE_MESSAGE, ((Message) o).id, seen);
|
||||
if (add(new Metadata(profileId, TYPE_MESSAGE, ((Message) o).getId(), seen, false, 0)) == -1) {
|
||||
updateSeen(profileId, TYPE_MESSAGE, ((Message) o).getId(), seen);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -132,8 +132,8 @@ public abstract class MetadataDao {
|
||||
}
|
||||
}
|
||||
if (o instanceof Message) {
|
||||
if (add(new Metadata(profileId, TYPE_MESSAGE, ((Message) o).id, false, notified, 0)) == -1) {
|
||||
updateNotified(profileId, TYPE_MESSAGE, ((Message) o).id, notified);
|
||||
if (add(new Metadata(profileId, TYPE_MESSAGE, ((Message) o).getId(), false, notified, 0)) == -1) {
|
||||
updateNotified(profileId, TYPE_MESSAGE, ((Message) o).getId(), notified);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.db.entity;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.Ignore;
|
||||
import androidx.room.Index;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Entity(tableName = "messages",
|
||||
primaryKeys = {"profileId", "messageId"},
|
||||
indices = {@Index(value = {"profileId"})})
|
||||
public class Message {
|
||||
public int profileId;
|
||||
|
||||
@ColumnInfo(name = "messageId")
|
||||
public long id;
|
||||
|
||||
@ColumnInfo(name = "messageSubject")
|
||||
public String subject;
|
||||
@Nullable
|
||||
@ColumnInfo(name = "messageBody")
|
||||
public String body = null;
|
||||
|
||||
public static final int TYPE_RECEIVED = 0;
|
||||
public static final int TYPE_SENT = 1;
|
||||
public static final int TYPE_DELETED = 2;
|
||||
public static final int TYPE_DRAFT = 3;
|
||||
@ColumnInfo(name = "messageType")
|
||||
public int type = TYPE_RECEIVED;
|
||||
|
||||
public long senderId = -1; // -1 for sent messages
|
||||
public long senderReplyId = -1;
|
||||
public boolean overrideHasAttachments = false; // if the attachments are not yet downloaded but we already know there are some
|
||||
public List<Long> attachmentIds = null;
|
||||
public List<String> attachmentNames = null;
|
||||
public List<Long> attachmentSizes = null;
|
||||
|
||||
@Ignore
|
||||
public Message() {}
|
||||
|
||||
public Message(int profileId, long id, String subject, @Nullable String body, int type, long senderId, long senderReplyId) {
|
||||
this.profileId = profileId;
|
||||
this.id = id;
|
||||
this.subject = subject;
|
||||
this.body = body;
|
||||
this.type = type;
|
||||
this.senderId = senderId;
|
||||
this.senderReplyId = senderReplyId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an attachment
|
||||
* @param id attachment ID
|
||||
* @param name file name incl. extension
|
||||
* @param size file size or -1 if unknown
|
||||
* @return a Message to which the attachment has been added
|
||||
*/
|
||||
public Message addAttachment(long id, String name, long size) {
|
||||
if (attachmentIds == null)
|
||||
attachmentIds = new ArrayList<>();
|
||||
if (attachmentNames == null)
|
||||
attachmentNames = new ArrayList<>();
|
||||
if (attachmentSizes == null)
|
||||
attachmentSizes = new ArrayList<>();
|
||||
attachmentIds.add(id);
|
||||
attachmentNames.add(name);
|
||||
attachmentSizes.add(size);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void clearAttachments() {
|
||||
attachmentIds = null;
|
||||
attachmentNames = null;
|
||||
attachmentSizes = null;
|
||||
}
|
||||
|
||||
public Message setHasAttachments() {
|
||||
overrideHasAttachments = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean hasAttachments() {
|
||||
return overrideHasAttachments || (attachmentIds != null && attachmentIds.size() > 0);
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
||||
*/
|
||||
package pl.szczodrzynski.edziennik.data.db.entity
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Ignore
|
||||
import androidx.room.Index
|
||||
import pl.szczodrzynski.edziennik.isNotNullNorEmpty
|
||||
|
||||
@Entity(tableName = "messages",
|
||||
primaryKeys = ["profileId", "messageId"],
|
||||
indices = [
|
||||
Index(value = ["profileId", "messageType"])
|
||||
])
|
||||
open class Message(
|
||||
val profileId: Int,
|
||||
@ColumnInfo(name = "messageId")
|
||||
val id: Long,
|
||||
@ColumnInfo(name = "messageType")
|
||||
var type: Int,
|
||||
|
||||
@ColumnInfo(name = "messageSubject")
|
||||
var subject: String,
|
||||
@ColumnInfo(name = "messageBody")
|
||||
var body: String?,
|
||||
|
||||
/**
|
||||
* Keep in mind that this being null does NOT
|
||||
* necessarily mean the message is sent.
|
||||
*/
|
||||
var senderId: Long?
|
||||
) : Keepable() {
|
||||
companion object {
|
||||
const val TYPE_RECEIVED = 0
|
||||
const val TYPE_SENT = 1
|
||||
const val TYPE_DELETED = 2
|
||||
const val TYPE_DRAFT = 3
|
||||
}
|
||||
|
||||
@ColumnInfo(name = "messageIsPinned")
|
||||
var isPinned: Boolean = false
|
||||
|
||||
var hasAttachments = false // if the attachments are not yet downloaded but we already know there are some
|
||||
get() = field || attachmentIds.isNotNullNorEmpty()
|
||||
var attachmentIds: MutableList<Long>? = null
|
||||
var attachmentNames: MutableList<String>? = null
|
||||
var attachmentSizes: MutableList<Long>? = null
|
||||
|
||||
@Ignore
|
||||
var showAsUnseen: Boolean? = null
|
||||
|
||||
/**
|
||||
* Add an attachment
|
||||
* @param id attachment ID
|
||||
* @param name file name incl. extension
|
||||
* @param size file size or -1 if unknown
|
||||
* @return a Message to which the attachment has been added
|
||||
*/
|
||||
fun addAttachment(id: Long, name: String, size: Long): Message {
|
||||
if (attachmentIds == null) attachmentIds = mutableListOf()
|
||||
if (attachmentNames == null) attachmentNames = mutableListOf()
|
||||
if (attachmentSizes == null) attachmentSizes = mutableListOf()
|
||||
attachmentIds?.add(id)
|
||||
attachmentNames?.add(name)
|
||||
attachmentSizes?.add(size)
|
||||
return this
|
||||
}
|
||||
|
||||
fun clearAttachments() {
|
||||
attachmentIds = null
|
||||
attachmentNames = null
|
||||
attachmentSizes = null
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.db.full;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.room.Ignore;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message;
|
||||
|
||||
public class MessageFull extends Message {
|
||||
public String senderFullName = null;
|
||||
@Ignore
|
||||
@Nullable
|
||||
public List<MessageRecipientFull> recipients = null;
|
||||
|
||||
public MessageFull addRecipient(MessageRecipientFull recipient) {
|
||||
if (recipients == null)
|
||||
recipients = new ArrayList<>();
|
||||
recipients.add(recipient);
|
||||
return this;
|
||||
}
|
||||
|
||||
// metadata
|
||||
public boolean seen;
|
||||
public boolean notified;
|
||||
public long addedDate;
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
||||
*/
|
||||
package pl.szczodrzynski.edziennik.data.db.full
|
||||
|
||||
import androidx.room.Relation
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
||||
|
||||
class MessageFull(
|
||||
profileId: Int, id: Long, type: Int,
|
||||
subject: String, body: String?, senderId: Long?
|
||||
) : Message(
|
||||
profileId, id, type,
|
||||
subject, body, senderId
|
||||
) {
|
||||
var senderName: String? = null
|
||||
@Relation(parentColumn = "messageId", entityColumn = "messageId", entity = MessageRecipient::class)
|
||||
var recipients: MutableList<MessageRecipientFull>? = null
|
||||
|
||||
fun addRecipient(recipient: MessageRecipientFull): MessageFull {
|
||||
if (recipients == null) recipients = mutableListOf()
|
||||
recipients?.add(recipient)
|
||||
return this
|
||||
}
|
||||
|
||||
// metadata
|
||||
var seen = false
|
||||
var notified = false
|
||||
var addedDate: Long = 0
|
||||
}
|
@ -2,17 +2,13 @@ package pl.szczodrzynski.edziennik.data.db.full
|
||||
|
||||
import androidx.room.Ignore
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
||||
import pl.szczodrzynski.edziennik.fixName
|
||||
|
||||
class MessageRecipientFull : MessageRecipient {
|
||||
var fullName: String? = ""
|
||||
get() {
|
||||
return field?.fixName() ?: ""
|
||||
}
|
||||
|
||||
class MessageRecipientFull(
|
||||
profileId: Int,
|
||||
id: Long,
|
||||
messageId: Long,
|
||||
readDate: Long = -1L
|
||||
) : MessageRecipient(profileId, id, -1, readDate, messageId) {
|
||||
@Ignore
|
||||
constructor(profileId: Int, id: Long, replyId: Long, readDate: Long, messageId: Long) : super(profileId, id, replyId, readDate, messageId) {}
|
||||
@Ignore
|
||||
constructor(profileId: Int, id: Long, messageId: Long) : super(profileId, id, messageId) {}
|
||||
constructor() : super() {}
|
||||
var fullName: String? = null
|
||||
}
|
||||
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-4-4.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.db.migration
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
class Migration84 : Migration(83, 84) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
// The Message Update
|
||||
database.execSQL("ALTER TABLE messages RENAME TO _messages;")
|
||||
database.execSQL("""CREATE TABLE messages (
|
||||
profileId INTEGER NOT NULL,
|
||||
messageId INTEGER NOT NULL,
|
||||
messageType INTEGER NOT NULL,
|
||||
messageSubject TEXT NOT NULL,
|
||||
messageBody TEXT,
|
||||
senderId INTEGER,
|
||||
messageIsPinned INTEGER NOT NULL DEFAULT 0,
|
||||
hasAttachments INTEGER NOT NULL DEFAULT 0,
|
||||
attachmentIds TEXT DEFAULT NULL,
|
||||
attachmentNames TEXT DEFAULT NULL,
|
||||
attachmentSizes TEXT DEFAULT NULL,
|
||||
keep INTEGER NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY(profileId, messageId)
|
||||
)""")
|
||||
database.execSQL("DROP INDEX IF EXISTS index_messages_profileId")
|
||||
database.execSQL("CREATE INDEX index_messages_profileId_messageType ON messages (profileId, messageType)")
|
||||
database.execSQL("""
|
||||
INSERT INTO messages (profileId, messageId, messageType, messageSubject, messageBody, senderId, hasAttachments, attachmentIds, attachmentNames, attachmentSizes)
|
||||
SELECT profileId, messageId, messageType, messageSubject, messageBody,
|
||||
CASE senderId WHEN -1 THEN NULL ELSE senderId END,
|
||||
overrideHasAttachments, attachmentIds, attachmentNames, attachmentSizes
|
||||
FROM _messages
|
||||
""")
|
||||
database.execSQL("DROP TABLE _messages")
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
|
||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_MOBIDZIENNIK
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||
import pl.szczodrzynski.edziennik.getLong
|
||||
import pl.szczodrzynski.edziennik.getString
|
||||
|
@ -71,7 +71,7 @@ class GradesListFragment : Fragment(), CoroutineScope {
|
||||
val adapter = GradesAdapter(activity)
|
||||
var firstRun = true
|
||||
|
||||
app.db.gradeDao().getAllOrderBy(App.profileId, app.gradesManager.getOrderByString()).observe(this, Observer { items -> launch {
|
||||
app.db.gradeDao().getAllOrderBy(App.profileId, app.gradesManager.getOrderByString()).observe(this@GradesListFragment, Observer { items -> launch {
|
||||
if (!isAdded) return@launch
|
||||
|
||||
// load & configure the adapter
|
||||
|
@ -94,7 +94,7 @@ class HomeworkListFragment : LazyFragment(), CoroutineScope {
|
||||
}
|
||||
}
|
||||
adapter.notifyDataSetChanged()
|
||||
setSwipeToRefresh(false) // TODO
|
||||
setSwipeToRefresh(items.isNullOrEmpty())
|
||||
|
||||
// show/hide relevant views
|
||||
b.progressBar.isVisible = false
|
||||
|
@ -37,8 +37,8 @@ import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent.Companion.T
|
||||
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore.Companion.LOGIN_TYPE_IDZIENNIK
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||
import pl.szczodrzynski.edziennik.databinding.MessageFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.utils.Anim
|
||||
@ -127,7 +127,7 @@ class MessageFragment : Fragment(), CoroutineScope {
|
||||
it.addedDate = arguments?.getLong("sentDate") ?: System.currentTimeMillis()
|
||||
}
|
||||
else
|
||||
app.db.messageDao().getById(App.profileId, messageId)
|
||||
app.db.messageDao().getByIdNow(App.profileId, messageId)
|
||||
|
||||
msg?.also {
|
||||
it.recipients = app.db.messageRecipientDao().getAllByMessageId(it.profileId, it.id)
|
||||
@ -290,10 +290,10 @@ class MessageFragment : Fragment(), CoroutineScope {
|
||||
|
||||
// CREATE VIEWS AND AN OBJECT FOR EVERY ATTACHMENT
|
||||
|
||||
message.attachmentNames.forEachIndexed { index, name ->
|
||||
message.attachmentNames?.forEachIndexed { index, name ->
|
||||
val messageId = message.id
|
||||
val id = message.attachmentIds[index]
|
||||
val size = message.attachmentSizes[index]
|
||||
val id = message.attachmentIds?.getOrNull(index) ?: return@forEachIndexed
|
||||
val size = message.attachmentSizes?.getOrNull(index) ?: return@forEachIndexed
|
||||
// create the parent
|
||||
val attachmentLayout = FrameLayout(b.root.context)
|
||||
attachmentLayout.setPadding(16.dp, 0, 16.dp, 0)
|
||||
|
@ -2,73 +2,88 @@ package pl.szczodrzynski.edziennik.ui.modules.messages
|
||||
|
||||
import android.graphics.Typeface
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView.OnItemClickListener
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.Adapter
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||
import pl.szczodrzynski.edziennik.databinding.MessagesItemBinding
|
||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesAdapter.ViewHolder
|
||||
import pl.szczodrzynski.edziennik.databinding.MessagesListItemBinding
|
||||
import pl.szczodrzynski.edziennik.onClick
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class MessagesAdapter(private val app: App, private val onItemClickListener: OnItemClickListener) : Adapter<ViewHolder>() {
|
||||
var messageList: List<MessageFull> = ArrayList()
|
||||
fun setData(messageList: List<MessageFull>) {
|
||||
this.messageList = messageList
|
||||
notifyDataSetChanged()
|
||||
class MessagesAdapter(
|
||||
val activity: AppCompatActivity,
|
||||
val teachers: List<Teacher>,
|
||||
val onItemClick: ((item: MessageFull) -> Unit)? = null
|
||||
) : RecyclerView.Adapter<MessagesAdapter.ViewHolder>(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "TemplateAdapter"
|
||||
}
|
||||
|
||||
private val app = activity.applicationContext as App
|
||||
// optional: place the manager here
|
||||
|
||||
private val job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
var items = listOf<MessageFull>()
|
||||
private val typefaceNormal by lazy { Typeface.create(Typeface.DEFAULT, Typeface.NORMAL) }
|
||||
private val typefaceBold by lazy { Typeface.create(Typeface.DEFAULT, Typeface.BOLD) }
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
return ViewHolder(DataBindingUtil.inflate(inflater, R.layout.messages_item, parent, false))
|
||||
val view = MessagesListItemBinding.inflate(inflater, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val item = items[position]
|
||||
val b = holder.b
|
||||
val message = messageList[position]
|
||||
b.root.setOnClickListener { v: View? -> onItemClickListener.onItemClick(null, v, position, position.toLong()) }
|
||||
|
||||
ViewCompat.setTransitionName(b.root, message.id.toString())
|
||||
|
||||
b.messageSubject.text = message.subject
|
||||
b.messageDate.text = Date.fromMillis(message.addedDate).formattedStringShort
|
||||
b.messageAttachmentImage.visibility = if (message.hasAttachments()) View.VISIBLE else View.GONE
|
||||
|
||||
val text = message.body?.substring(0, message.body!!.length.coerceAtMost(200)) ?: ""
|
||||
b.messageBody.text = MessagesUtils.htmlToSpannable(b.root.context, text)
|
||||
|
||||
if (message.type == Message.TYPE_SENT || message.type == Message.TYPE_DRAFT || message.seen) {
|
||||
b.messageSender.setTextAppearance(b.messageSender.context, R.style.NavView_TextView_Small)
|
||||
b.messageSender.typeface = Typeface.create(Typeface.DEFAULT, Typeface.NORMAL)
|
||||
b.messageSender.textSize = 16f
|
||||
b.messageSubject.setTextAppearance(b.messageSubject.context, R.style.NavView_TextView_Small)
|
||||
b.messageSubject.typeface = Typeface.create(Typeface.DEFAULT, Typeface.NORMAL)
|
||||
b.messageDate.setTextAppearance(b.messageDate.context, R.style.NavView_TextView_Small)
|
||||
b.messageDate.typeface = Typeface.create(Typeface.DEFAULT, Typeface.NORMAL)
|
||||
} else {
|
||||
b.messageSender.setTextAppearance(b.messageSender.context, R.style.NavView_TextView_Normal)
|
||||
b.messageSender.typeface = Typeface.create(Typeface.DEFAULT, Typeface.BOLD)
|
||||
b.messageSender.textSize = 16f
|
||||
b.messageSubject.setTextAppearance(b.messageSubject.context, R.style.NavView_TextView_Normal)
|
||||
b.messageSubject.typeface = Typeface.create(Typeface.DEFAULT, Typeface.BOLD)
|
||||
b.messageDate.setTextAppearance(b.messageDate.context, R.style.NavView_TextView_Normal)
|
||||
b.messageDate.typeface = Typeface.create(Typeface.DEFAULT, Typeface.BOLD)
|
||||
item.recipients?.forEach { recipient ->
|
||||
if (recipient.fullName == null) {
|
||||
recipient.fullName = teachers.firstOrNull { it.id == recipient.id }?.fullName ?: ""
|
||||
}
|
||||
}
|
||||
val messageInfo = MessagesUtils.getMessageInfo(app, message, 48, 24, 18, 12)
|
||||
|
||||
b.messageSubject.text = item.subject
|
||||
b.messageDate.text = Date.fromMillis(item.addedDate).formattedStringShort
|
||||
b.messageAttachmentImage.isVisible = item.hasAttachments
|
||||
|
||||
val text = item.body?.take(200) ?: ""
|
||||
b.messageBody.text = MessagesUtils.htmlToSpannable(activity, text)
|
||||
|
||||
val isRead = item.type == Message.TYPE_SENT || item.type == Message.TYPE_DRAFT || item.seen
|
||||
val typeface = if (isRead) typefaceNormal else typefaceBold
|
||||
val style = if (isRead) R.style.NavView_TextView_Small else R.style.NavView_TextView_Normal
|
||||
// set text styles
|
||||
b.messageSender.setTextAppearance(activity, style)
|
||||
b.messageSender.typeface = typeface
|
||||
b.messageSubject.setTextAppearance(activity, style)
|
||||
b.messageSubject.typeface = typeface
|
||||
b.messageDate.setTextAppearance(activity, style)
|
||||
b.messageDate.typeface = typeface
|
||||
|
||||
val messageInfo = MessagesUtils.getMessageInfo(app, item, 48, 24, 18, 12)
|
||||
b.messageProfileBackground.setImageBitmap(messageInfo.profileImage)
|
||||
b.messageSender.text = messageInfo.profileName
|
||||
|
||||
onItemClick?.let { listener ->
|
||||
b.root.onClick { listener(item) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return messageList.size
|
||||
}
|
||||
|
||||
inner class ViewHolder(var b: MessagesItemBinding) : RecyclerView.ViewHolder(b.root)
|
||||
override fun getItemCount() = items.size
|
||||
|
||||
class ViewHolder(val b: MessagesListItemBinding) : RecyclerView.ViewHolder(b.root)
|
||||
}
|
||||
|
@ -5,82 +5,79 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||
import pl.szczodrzynski.edziennik.databinding.FragmentMessagesBinding
|
||||
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyPagerAdapter
|
||||
import pl.szczodrzynski.edziennik.utils.Themes
|
||||
import pl.szczodrzynski.edziennik.databinding.MessagesFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.FragmentLazyPagerAdapter
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class MessagesFragment : Fragment() {
|
||||
class MessagesFragment : Fragment(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "MessagesFragment"
|
||||
var pageSelection = 0
|
||||
}
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: FragmentMessagesBinding
|
||||
private lateinit var b: MessagesFragmentBinding
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
// local/private variables go here
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as MainActivity?) ?: return null
|
||||
if (context == null)
|
||||
return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
context!!.theme.applyStyle(Themes.appTheme, true)
|
||||
if (app.profile == null)
|
||||
return inflater.inflate(R.layout.fragment_loading, container, false)
|
||||
// activity, context and profile is valid
|
||||
b = FragmentMessagesBinding.inflate(inflater)
|
||||
b = MessagesFragmentBinding.inflate(inflater)
|
||||
b.refreshLayout.setParent(activity.swipeRefreshLayout)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
// TODO check if app, activity, b can be null
|
||||
if (app.profile == null || !isAdded)
|
||||
return
|
||||
if (!isAdded) return
|
||||
|
||||
val messageId = arguments?.getLong("messageId", -1L) ?: -1L
|
||||
if (messageId != -1L) {
|
||||
val args = Bundle()
|
||||
args.putLong("messageId", messageId)
|
||||
arguments!!.remove("messageId")
|
||||
arguments?.remove("messageId")
|
||||
activity.loadTarget(MainActivity.TARGET_MESSAGES_DETAILS, args)
|
||||
return
|
||||
}
|
||||
|
||||
b.viewPager.adapter = Adapter(childFragmentManager, b.refreshLayout).also { adapter ->
|
||||
val pagerAdapter = FragmentLazyPagerAdapter(
|
||||
fragmentManager ?: return,
|
||||
b.refreshLayout,
|
||||
listOf(
|
||||
MessagesListFragment().apply {
|
||||
arguments = Bundle("messageType" to Message.TYPE_RECEIVED)
|
||||
} to getString(R.string.messages_tab_received),
|
||||
|
||||
adapter.addFragment(MessagesListFragment().also { fragment ->
|
||||
fragment.arguments = Bundle().also { args ->
|
||||
args.putInt("messageType", Message.TYPE_RECEIVED)
|
||||
}
|
||||
}, getString(R.string.menu_messages_inbox))
|
||||
MessagesListFragment().apply {
|
||||
arguments = Bundle("messageType" to Message.TYPE_SENT)
|
||||
} to getString(R.string.messages_tab_sent),
|
||||
|
||||
adapter.addFragment(MessagesListFragment().also { fragment ->
|
||||
fragment.arguments = Bundle().also { args ->
|
||||
args.putInt("messageType", Message.TYPE_SENT)
|
||||
}
|
||||
}, getString(R.string.menu_messages_sent))
|
||||
|
||||
}
|
||||
|
||||
b.viewPager.currentItem = pageSelection
|
||||
b.viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
|
||||
override fun onPageScrollStateChanged(state: Int) {}
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
|
||||
override fun onPageSelected(position: Int) {
|
||||
pageSelection = position
|
||||
MessagesListFragment().apply {
|
||||
arguments = Bundle("messageType" to Message.TYPE_DELETED)
|
||||
} to getString(R.string.messages_tab_deleted)
|
||||
)
|
||||
)
|
||||
b.viewPager.apply {
|
||||
offscreenPageLimit = 1
|
||||
adapter = pagerAdapter
|
||||
currentItem = pageSelection
|
||||
addOnPageSelectedListener {
|
||||
pageSelection = it
|
||||
}
|
||||
})
|
||||
|
||||
b.tabLayout.setupWithViewPager(b.viewPager)
|
||||
b.tabLayout.setupWithViewPager(this)
|
||||
}
|
||||
|
||||
activity.navView.apply {
|
||||
bottomBar.apply {
|
||||
@ -95,52 +92,5 @@ class MessagesFragment : Fragment() {
|
||||
}
|
||||
|
||||
activity.gainAttentionFAB()
|
||||
|
||||
/*if (app.profile.loginStoreType == LOGIN_TYPE_LIBRUS && app.profile.getStudentData("accountPassword", null) == null) {
|
||||
MaterialDialog.Builder(activity)
|
||||
.title("Wiadomości w systemie Synergia")
|
||||
.content("Moduł Wiadomości w aplikacji Szkolny.eu jest przeglądarką zasobów szkolnego konta Synergia. Z tego powodu, musisz wpisać swoje hasło do tego konta, aby móc korzystać z tej funkcji.")
|
||||
.positiveText(R.string.ok)
|
||||
.onPositive { dialog, which ->
|
||||
MaterialDialog.Builder(activity)
|
||||
.title("Zaloguj się")
|
||||
.content(Html.fromHtml("Podaj hasło do konta Synergia z loginem <b>" + app.profile.getStudentData("accountLogin", "???") + "</b>"))
|
||||
.inputType(InputType.TYPE_TEXT_VARIATION_PASSWORD)
|
||||
.input(null, null) { dialog1, input ->
|
||||
app.profile.putStudentData("accountPassword", input.toString())
|
||||
app.profileSaveFullAsync(app.profile)
|
||||
EdziennikTask.syncProfile(App.profileId, listOf(
|
||||
DRAWER_ITEM_MESSAGES to Message.TYPE_RECEIVED,
|
||||
DRAWER_ITEM_MESSAGES to Message.TYPE_SENT
|
||||
)).enqueue(context!!)
|
||||
}
|
||||
.positiveText(R.string.ok)
|
||||
.negativeText(R.string.cancel)
|
||||
.show()
|
||||
}
|
||||
.show()
|
||||
}*/
|
||||
}
|
||||
|
||||
internal class Adapter(manager: FragmentManager, swipeRefreshLayout: SwipeRefreshLayout) : LazyPagerAdapter(manager, swipeRefreshLayout) {
|
||||
private val mFragmentList = mutableListOf<LazyFragment>()
|
||||
private val mFragmentTitleList = mutableListOf<String>()
|
||||
|
||||
override fun getPage(position: Int): LazyFragment {
|
||||
return mFragmentList[position]
|
||||
}
|
||||
|
||||
override fun getCount(): Int {
|
||||
return mFragmentList.size
|
||||
}
|
||||
|
||||
fun addFragment(fragment: LazyFragment, title: String) {
|
||||
mFragmentList.add(fragment)
|
||||
mFragmentTitleList.add(title)
|
||||
}
|
||||
|
||||
override fun getPageTitle(position: Int): CharSequence {
|
||||
return mFragmentTitleList[position]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-4-4.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.messages
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.withContext
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||
import pl.szczodrzynski.edziennik.databinding.MessagesListFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyFragment
|
||||
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class MessagesListFragment : LazyFragment(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "MessagesListFragment"
|
||||
}
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: MessagesListFragmentBinding
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
// local/private variables go here
|
||||
var teachers = listOf<Teacher>()
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as MainActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = MessagesListFragmentBinding.inflate(inflater)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onPageCreated(): Boolean { startCoroutineTimer(100L) {
|
||||
val messageType = arguments.getInt("messageType", Message.TYPE_RECEIVED)
|
||||
|
||||
teachers = withContext(Dispatchers.Default) {
|
||||
app.db.teacherDao().getAllNow(App.profileId)
|
||||
}
|
||||
|
||||
val adapter = MessagesAdapter(activity, teachers) {
|
||||
|
||||
}
|
||||
|
||||
app.db.messageDao().getAllByType(App.profileId, messageType).observe(this@MessagesListFragment, Observer { items ->
|
||||
if (!isAdded) return@Observer
|
||||
|
||||
items.forEach { message ->
|
||||
message.recipients?.removeAll { it.profileId != message.profileId }
|
||||
}
|
||||
|
||||
// load & configure the adapter
|
||||
adapter.items = items
|
||||
if (items.isNotNullNorEmpty() && b.list.adapter == null) {
|
||||
b.list.adapter = adapter
|
||||
b.list.apply {
|
||||
setHasFixedSize(true)
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
addItemDecoration(SimpleDividerItemDecoration(context))
|
||||
if (messageType in Message.TYPE_RECEIVED..Message.TYPE_SENT)
|
||||
addOnScrollListener(onScrollListener)
|
||||
}
|
||||
}
|
||||
adapter.notifyDataSetChanged()
|
||||
setSwipeToRefresh(messageType in Message.TYPE_RECEIVED..Message.TYPE_SENT && items.isNullOrEmpty())
|
||||
|
||||
// show/hide relevant views
|
||||
b.progressBar.isVisible = false
|
||||
if (items.isNullOrEmpty()) {
|
||||
b.list.isVisible = false
|
||||
b.noData.isVisible = true
|
||||
} else {
|
||||
b.list.isVisible = true
|
||||
b.noData.isVisible = false
|
||||
}
|
||||
})
|
||||
}; return true }
|
||||
}
|
@ -33,7 +33,7 @@ import static androidx.recyclerview.widget.RecyclerView.NO_POSITION;
|
||||
import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
|
||||
import static pl.szczodrzynski.edziennik.utils.Utils.d;
|
||||
|
||||
public class MessagesListFragment extends LazyFragment {
|
||||
public class MessagesListFragmentOld extends LazyFragment {
|
||||
|
||||
private App app = null;
|
||||
private MainActivity activity = null;
|
||||
@ -90,19 +90,19 @@ public class MessagesListFragment extends LazyFragment {
|
||||
activity.syncCurrentFeature(messageType, b.refreshLayout);
|
||||
});*/
|
||||
|
||||
messagesAdapter = new MessagesAdapter(app, ((parent, view1, position, id) -> {
|
||||
/*messagesAdapter = new MessagesAdapter(app, ((parent, view1, position, id) -> {
|
||||
// TODO ANIMATION
|
||||
tapPositions[messageType] = position;
|
||||
topPositions[messageType] = ((LinearLayoutManager) b.emailList.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
|
||||
bottomPositions[messageType] = ((LinearLayoutManager) b.emailList.getLayoutManager()).findLastCompletelyVisibleItemPosition();
|
||||
|
||||
/*view1.getGlobalVisibleRect(viewRect);
|
||||
*//*view1.getGlobalVisibleRect(viewRect);
|
||||
((Transition) MessagesListFragment.this.getExitTransition()).setEpicenterCallback(new Transition.EpicenterCallback() {
|
||||
@Override
|
||||
public Rect onGetEpicenter(@NonNull Transition transition) {
|
||||
return viewRect;
|
||||
}
|
||||
});*/
|
||||
});*//*
|
||||
|
||||
Bundle args = new Bundle();
|
||||
args.putLong("messageId", messagesAdapter.getMessageList().get(position).id);
|
||||
@ -110,7 +110,7 @@ public class MessagesListFragment extends LazyFragment {
|
||||
|
||||
// KOD W WERSJI 2.7
|
||||
// TODO ANIMATION
|
||||
/*TransitionSet sharedElementTransition = new TransitionSet()
|
||||
*//*TransitionSet sharedElementTransition = new TransitionSet()
|
||||
.addTransition(new Fade())
|
||||
.addTransition(new ChangeBounds())
|
||||
.addTransition(new ChangeTransform())
|
||||
@ -123,10 +123,10 @@ public class MessagesListFragment extends LazyFragment {
|
||||
args.putLong("messageId", messagesAdapter.messageList.get(position).id);
|
||||
fragment.setArguments(args);
|
||||
fragment.setSharedElementEnterTransition(sharedElementTransition);
|
||||
fragment.setSharedElementReturnTransition(sharedElementTransition);*/
|
||||
fragment.setSharedElementReturnTransition(sharedElementTransition);*//*
|
||||
|
||||
// JAKIS STARSZY KOD
|
||||
/*Intent intent = new Intent(activity, MessagesDetailsActivity.class);
|
||||
*//*Intent intent = new Intent(activity, MessagesDetailsActivity.class);
|
||||
intent.putExtra("item_id", 1);
|
||||
intent.putExtra("transition_name", ViewCompat.getTransitionName(view1));
|
||||
|
||||
@ -143,17 +143,17 @@ public class MessagesListFragment extends LazyFragment {
|
||||
setExitTransition(sharedElementTransition);
|
||||
setSharedElementEnterTransition(sharedElementTransition);
|
||||
setSharedElementReturnTransition(sharedElementTransition);
|
||||
startActivity(intent, options.toBundle());*/
|
||||
startActivity(intent, options.toBundle());*//*
|
||||
|
||||
/*activity.getSupportFragmentManager()
|
||||
*//*activity.getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.setReorderingAllowed(true)
|
||||
.replace(R.id.fragment_container, fragment)
|
||||
.addToBackStack(null)
|
||||
.addSharedElement(view1, getString(R.string.transition_name))
|
||||
.commit();*/
|
||||
.commit();*//*
|
||||
|
||||
}));
|
||||
}));*/
|
||||
|
||||
|
||||
//tapPosition = savedInstanceState != null ? savedInstanceState.getInt(TAP_POSITION, tapPosition) : tapPosition;
|
||||
@ -195,7 +195,7 @@ public class MessagesListFragment extends LazyFragment {
|
||||
List<MessageRecipientFull> messageRecipients = App.db.messageRecipientDao().getAll(App.Companion.getProfileId());
|
||||
List<Long> messageIds = new ArrayList<>();
|
||||
for (MessageFull messageFull: messageFulls) {
|
||||
messageIds.add(messageFull.id);
|
||||
messageIds.add(messageFull.getId());
|
||||
}
|
||||
for (MessageRecipientFull messageRecipientFull: messageRecipients) {
|
||||
if (messageRecipientFull.id == -1)
|
||||
@ -233,7 +233,7 @@ public class MessagesListFragment extends LazyFragment {
|
||||
private void createMessageList(List<MessageFull> messageFulls) {
|
||||
b.progressBar.setVisibility(View.GONE);
|
||||
b.emailList.setVisibility(View.VISIBLE);
|
||||
messagesAdapter.setData(messageFulls);
|
||||
//messagesAdapter.setData(messageFulls);
|
||||
|
||||
LinearLayoutManager layoutManager = (LinearLayoutManager) b.emailList.getLayoutManager();
|
||||
if (tapPositions[messageType] != NO_POSITION && layoutManager != null) {
|
@ -124,7 +124,7 @@ object MessagesUtils {
|
||||
var profileImage: Bitmap? = null
|
||||
var profileName: String? = null
|
||||
if (message.type == Message.TYPE_RECEIVED || message.type == Message.TYPE_DELETED) {
|
||||
profileName = message.senderFullName?.fixName()
|
||||
profileName = message.senderName?.fixName()
|
||||
profileImage = getProfileImage(diameterDp, textSizeBigDp, textSizeMediumDp, textSizeSmallDp, 1, profileName)
|
||||
} else if (message.type == Message.TYPE_SENT || message.type == Message.TYPE_DRAFT && message.recipients != null) {
|
||||
when (val count = message.recipients?.size ?: 0) {
|
||||
|
@ -1,75 +0,0 @@
|
||||
package pl.szczodrzynski.edziennik.ui.modules.messages;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.graphics.Rect;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.transition.TransitionValues;
|
||||
import androidx.transition.Visibility;
|
||||
|
||||
public class SlideExplode extends Visibility {
|
||||
private static final String KEY_SCREEN_BOUNDS = "screenBounds";
|
||||
|
||||
private int[] mTempLoc = new int[2];
|
||||
|
||||
private void captureValues(TransitionValues transitionValues) {
|
||||
View view = transitionValues.view;
|
||||
view.getLocationOnScreen(mTempLoc);
|
||||
int left = mTempLoc[0];
|
||||
int top = mTempLoc[1];
|
||||
int right = left + view.getWidth();
|
||||
int bottom = top + view.getHeight();
|
||||
transitionValues.values.put(KEY_SCREEN_BOUNDS, new Rect(left, top, right, bottom));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void captureStartValues(@NonNull TransitionValues transitionValues) {
|
||||
super.captureStartValues(transitionValues);
|
||||
captureValues(transitionValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void captureEndValues(@NonNull TransitionValues transitionValues) {
|
||||
super.captureEndValues(transitionValues);
|
||||
captureValues(transitionValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues, TransitionValues endValues) {
|
||||
if (endValues == null)
|
||||
return null;
|
||||
|
||||
Rect bounds = (Rect) endValues.values.get(KEY_SCREEN_BOUNDS);
|
||||
float endY = view.getTranslationY();
|
||||
float startY = endY + calculateDistance(sceneRoot, bounds);
|
||||
return ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, startY, endY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues, TransitionValues endValues) {
|
||||
if (startValues == null)
|
||||
return null;
|
||||
|
||||
Rect bounds = (Rect) startValues.values.get(KEY_SCREEN_BOUNDS);
|
||||
float startY = view.getTranslationY();
|
||||
float endY = startY + calculateDistance(sceneRoot, bounds);
|
||||
return ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, startY, endY);
|
||||
}
|
||||
|
||||
private int calculateDistance(View sceneRoot, Rect viewBounds) {
|
||||
sceneRoot.getLocationOnScreen(mTempLoc);
|
||||
int sceneRootY = mTempLoc[1];
|
||||
if (getEpicenter() == null) {
|
||||
return -sceneRoot.getHeight();
|
||||
}
|
||||
else if (viewBounds.top <= getEpicenter().top) {
|
||||
return sceneRootY - getEpicenter().top;
|
||||
}
|
||||
else {
|
||||
return sceneRootY + sceneRoot.getHeight() - getEpicenter().bottom;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package pl.szczodrzynski.edziennik.ui.modules.messages;
|
||||
|
||||
import android.animation.TimeInterpolator;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.transition.TransitionSet;
|
||||
|
||||
public class Transitions extends TransitionSet {
|
||||
@NonNull
|
||||
@Override
|
||||
public TransitionSet setInterpolator(@Nullable TimeInterpolator interpolator) {
|
||||
for (int i = 0; i < getTransitionCount(); i++) {
|
||||
getTransitionAt(i).setInterpolator(interpolator);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-12-22.
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-4-4.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.messages
|
||||
package pl.szczodrzynski.edziennik.ui.modules.messages.compose
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Typeface
|
||||
@ -43,6 +43,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||
import pl.szczodrzynski.edziennik.databinding.MessagesComposeFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesUtils
|
||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesUtils.getProfileImage
|
||||
import pl.szczodrzynski.edziennik.utils.Colors
|
||||
import pl.szczodrzynski.edziennik.utils.Themes
|
||||
@ -361,7 +362,7 @@ class MessagesComposeFragment : Fragment(), CoroutineScope {
|
||||
span.appendText("W dniu ")
|
||||
span.appendSpan(dateString, StyleSpan(Typeface.ITALIC), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
span.appendText(", ")
|
||||
span.appendSpan(msg.senderFullName.fixName(), StyleSpan(Typeface.ITALIC), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
span.appendSpan(msg.senderName.fixName(), StyleSpan(Typeface.ITALIC), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
span.appendText(" napisał(a):")
|
||||
span.setSpan(StyleSpan(Typeface.BOLD), 0, span.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
span.appendText("\n\n")
|
||||
@ -380,7 +381,8 @@ class MessagesComposeFragment : Fragment(), CoroutineScope {
|
||||
span.replace(0, 0, "\n\n")
|
||||
subject = "Fwd: ${msg.subject}"
|
||||
}
|
||||
body = MessagesUtils.htmlToSpannable(activity,msg.body ?: "Nie udało się wczytać oryginalnej wiadomości.")//Html.fromHtml(msg.body?.replace("<br\\s?/?>".toRegex(), "\n") ?: "Nie udało się wczytać oryginalnej wiadomości.")
|
||||
body = MessagesUtils.htmlToSpannable(activity, msg.body
|
||||
?: "Nie udało się wczytać oryginalnej wiadomości.")//Html.fromHtml(msg.body?.replace("<br\\s?/?>".toRegex(), "\n") ?: "Nie udało się wczytać oryginalnej wiadomości.")
|
||||
}
|
||||
|
||||
b.recipients.addTextWithChips(chipList)
|
@ -1,4 +1,8 @@
|
||||
package pl.szczodrzynski.edziennik.ui.modules.messages
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-4-4.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.messages.compose
|
||||
|
||||
class MessagesComposeInfo(
|
||||
/**
|
@ -1,4 +1,4 @@
|
||||
package pl.szczodrzynski.edziennik.ui.modules.messages
|
||||
package pl.szczodrzynski.edziennik.ui.modules.messages.compose
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Typeface.BOLD
|
@ -72,7 +72,7 @@ class NotificationsListFragment : Fragment(), CoroutineScope {
|
||||
app.sendBroadcast(intent)
|
||||
}
|
||||
|
||||
app.db.notificationDao().getAll().observe(this, Observer { items ->
|
||||
app.db.notificationDao().getAll().observe(this@NotificationsListFragment, Observer { items ->
|
||||
if (!isAdded) return@Observer
|
||||
|
||||
// load & configure the adapter
|
||||
|
@ -12,12 +12,11 @@ import androidx.fragment.app.Fragment
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.addOnPageSelectedListener
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.databinding.TemplateFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.FragmentLazyPagerAdapter
|
||||
import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkDate
|
||||
import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkListFragment
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class TemplateFragment : Fragment(), CoroutineScope {
|
||||
@ -52,6 +51,14 @@ class TemplateFragment : Fragment(), CoroutineScope {
|
||||
fragmentManager ?: return,
|
||||
b.refreshLayout,
|
||||
listOf(
|
||||
HomeworkListFragment().apply {
|
||||
arguments = Bundle("homeworkDate" to HomeworkDate.CURRENT)
|
||||
} to getString(R.string.homework_tab_current),
|
||||
|
||||
HomeworkListFragment().apply {
|
||||
arguments = Bundle("homeworkDate" to HomeworkDate.PAST)
|
||||
} to getString(R.string.homework_tab_past),
|
||||
|
||||
TemplatePageFragment() to "Pager 0",
|
||||
TemplatePageFragment() to "Pager 1",
|
||||
TemplatePageFragment() to "Pager 2",
|
||||
@ -67,7 +74,7 @@ class TemplateFragment : Fragment(), CoroutineScope {
|
||||
adapter = pagerAdapter
|
||||
currentItem = pageSelection
|
||||
addOnPageSelectedListener {
|
||||
HomeworkFragment.pageSelection = it
|
||||
pageSelection = it
|
||||
}
|
||||
b.tabLayout.setupWithViewPager(this)
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ class TemplateListFragment : Fragment(), CoroutineScope {
|
||||
|
||||
val adapter = TemplateAdapter(activity)
|
||||
|
||||
app.db.notificationDao().getAll().observe(this, Observer { items ->
|
||||
app.db.notificationDao().getAll().observe(this@TemplateListFragment, Observer { items ->
|
||||
if (!isAdded) return@Observer
|
||||
|
||||
// load & configure the adapter
|
||||
|
@ -49,7 +49,7 @@ class TemplateListPageFragment : LazyFragment(), CoroutineScope {
|
||||
override fun onPageCreated(): Boolean { startCoroutineTimer(100L) {
|
||||
val adapter = TemplateAdapter(activity)
|
||||
|
||||
app.db.notificationDao().getAll().observe(this, Observer { items ->
|
||||
app.db.notificationDao().getAll().observe(this@TemplateListPageFragment, Observer { items ->
|
||||
if (!isAdded) return@Observer
|
||||
|
||||
// load & configure the adapter
|
||||
@ -64,7 +64,7 @@ class TemplateListPageFragment : LazyFragment(), CoroutineScope {
|
||||
}
|
||||
}
|
||||
adapter.notifyDataSetChanged()
|
||||
setSwipeToRefresh(false) // TODO
|
||||
setSwipeToRefresh(items.isNullOrEmpty())
|
||||
|
||||
// show/hide relevant views
|
||||
b.progressBar.isVisible = false
|
||||
|
10
app/src/main/res/drawable/ic_no_messages.xml
Normal file
10
app/src/main/res/drawable/ic_no_messages.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2020-4-4.
|
||||
-->
|
||||
|
||||
<vector android:height="128dp" android:viewportHeight="512"
|
||||
android:viewportWidth="512" android:width="128dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#f4a402" android:pathData="m440,416h-368c-22.1,0 -40,-17.9 -40,-40v-240c0,-22.1 17.9,-40 40,-40h368c22.1,0 40,17.9 40,40v240c0,22.1 -17.9,40 -40,40z"/>
|
||||
<path android:fillColor="#feb600" android:pathData="m256,200 l-223,183c3.21,18.9 19.5,33.3 39.3,33.3h368c19.8,0 36.1,-14.4 39.3,-33.3l-223,-183"/>
|
||||
<path android:fillColor="#ffc71c" android:pathData="m32.7,129 l206,169c10.1,8.24 24.6,8.24 34.6,0l206,-169c-3.21,-18.9 -19.5,-33.3 -39.3,-33.3h-368c-19.8,0 -36.1,14.4 -39.3,33.3z"/>
|
||||
</vector>
|
36
app/src/main/res/layout/messages_fragment.xml
Normal file
36
app/src/main/res/layout/messages_fragment.xml
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2020-4-4.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator
|
||||
android:id="@+id/refreshLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tabLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/colorSurface_6dp"
|
||||
app:tabIndicatorColor="?colorPrimary"
|
||||
app:tabMode="auto"
|
||||
app:tabSelectedTextColor="?colorPrimary"
|
||||
app:tabTextColor="?android:textColorPrimary" />
|
||||
|
||||
<pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyViewPager
|
||||
android:id="@+id/viewPager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||
</LinearLayout>
|
||||
</pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator>
|
||||
</layout>
|
42
app/src/main/res/layout/messages_list_fragment.xml
Normal file
42
app/src/main/res/layout/messages_list_fragment.xml
Normal file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2020-4-4.
|
||||
-->
|
||||
|
||||
<layout 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">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/noData"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:drawablePadding="16dp"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:text="@string/messages_no_data"
|
||||
android:textSize="24sp"
|
||||
android:visibility="gone"
|
||||
app:drawableTopCompat="@drawable/ic_no_messages"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"
|
||||
tools:listitem="@layout/messages_list_item"
|
||||
tools:visibility="visible" />
|
||||
</FrameLayout>
|
||||
</layout>
|
||||
|
118
app/src/main/res/layout/messages_list_item.xml
Normal file
118
app/src/main/res/layout/messages_list_item.xml
Normal file
@ -0,0 +1,118 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2020-4-4.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackground">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/messageProfileBackground"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:padding="12dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/bg_circle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messageProfileName"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:gravity="center"
|
||||
android:padding="12dp"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="24sp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="JP"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messageSubject"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:singleLine="true"
|
||||
android:textStyle="normal"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/messageProfileBackground"
|
||||
app:layout_constraintTop_toBottomOf="@+id/messageSender"
|
||||
tools:text="Nowe oferty w Twoich obserwowanych wyszukiwaniach" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messageSender"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toStartOf="@+id/messageAttachmentImage"
|
||||
app:layout_constraintStart_toEndOf="@+id/messageProfileBackground"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Allegro" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messageBody"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/messageProfileBackground"
|
||||
app:layout_constraintTop_toBottomOf="@+id/messageSubject"
|
||||
tools:text="Znajdź produkty, których szukasz. Witaj Kuba Szczodrzyński (Client" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messageDate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="09:41" />
|
||||
|
||||
<com.mikepenz.iconics.view.IconicsImageView
|
||||
android:id="@+id/messageAttachmentImage"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:paddingTop="2dp"
|
||||
android:paddingBottom="2dp"
|
||||
android:scaleType="fitCenter"
|
||||
app:iiv_color="?android:textColorSecondary"
|
||||
app:iiv_icon="cmd-attachment"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/messageDate"
|
||||
app:layout_constraintEnd_toStartOf="@+id/messageDate"
|
||||
app:layout_constraintTop_toTopOf="@+id/messageDate"
|
||||
tools:srcCompat="@tools:sample/avatars[4]" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
@ -414,8 +414,8 @@
|
||||
<string name="menu_manage_profiles">Manage profiles</string>
|
||||
<string name="menu_mark_as_read">Mark as read</string>
|
||||
<string name="menu_messages">Messages</string>
|
||||
<string name="menu_messages_inbox">Inbox</string>
|
||||
<string name="menu_messages_sent">Sent</string>
|
||||
<string name="messages_tab_received">Inbox</string>
|
||||
<string name="messages_tab_sent">Sent</string>
|
||||
<string name="menu_notices">Behaviour</string>
|
||||
<string name="menu_notifications">Notifications</string>
|
||||
<string name="menu_settings">Settings</string>
|
||||
|
@ -458,8 +458,8 @@
|
||||
<string name="menu_mark_as_read">Oznacz jako przeczytane</string>
|
||||
<string name="menu_mark_everything_as_read">Oznacz wszystko jako przeczytane</string>
|
||||
<string name="menu_messages">Wiadomości</string>
|
||||
<string name="menu_messages_inbox">Odebrane</string>
|
||||
<string name="menu_messages_sent">Wysłane</string>
|
||||
<string name="messages_tab_received">Odebrane</string>
|
||||
<string name="messages_tab_sent">Wysłane</string>
|
||||
<string name="menu_notices">Zachowanie</string>
|
||||
<string name="menu_notifications">Powiadomienia</string>
|
||||
<string name="menu_set_student_number">Ustaw numer w dzienniku</string>
|
||||
@ -1287,4 +1287,6 @@
|
||||
<string name="dialog_event_details_attachments">Załączniki</string>
|
||||
<string name="hint_download_again">Pobierz ponownie</string>
|
||||
<string name="menu_lab">Laboratorium</string>
|
||||
<string name="messages_no_data">Nie masz żadnych wiadomości.</string>
|
||||
<string name="messages_tab_deleted">Usunięte</string>
|
||||
</resources>
|
||||
|
@ -158,9 +158,12 @@ class FileGenerator : AbstractProcessor() {
|
||||
|
||||
allFields.removeAll { skippedColumns.contains(it.name()) }
|
||||
allFields.removeAll { it.getAnnotation(Ignore::class.java) != null }
|
||||
allFields.removeAll { field -> field.modifiers.any { it == Modifier.STATIC || it == Modifier.FINAL } }
|
||||
allFields.removeAll { field -> field.modifiers.any { it == Modifier.STATIC } }
|
||||
val allFieldsDistinct = allFields.distinct()
|
||||
|
||||
// dump fields
|
||||
//processingEnv.messager.printMessage(Diagnostic.Kind.ERROR, allFieldsDistinct.joinToString())
|
||||
|
||||
val fields = allFieldsDistinct.filterNot { primaryKeys.contains(it.name()) }
|
||||
val primaryFields = allFieldsDistinct.filter { primaryKeys.contains(it.name()) }
|
||||
val fieldNames = fields.map { it.name() }
|
||||
|
Loading…
x
Reference in New Issue
Block a user