mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-01-31 05:48:19 +01:00
[Messages] Implement APIv2 in MessageFragment.
This commit is contained in:
parent
c6e2519dcc
commit
c83abe57d5
@ -40,3 +40,12 @@
|
|||||||
-keep class okhttp3.** { *; }
|
-keep class okhttp3.** { *; }
|
||||||
|
|
||||||
-keep class com.google.android.material.tabs.** {*;}
|
-keep class com.google.android.material.tabs.** {*;}
|
||||||
|
|
||||||
|
# ServiceLoader support
|
||||||
|
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
|
||||||
|
-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}
|
||||||
|
|
||||||
|
# Most of volatile fields are updated with AFU and should not be mangled
|
||||||
|
-keepclassmembernames class kotlinx.** {
|
||||||
|
volatile <fields>;
|
||||||
|
}
|
@ -11,6 +11,7 @@ import android.text.style.ForegroundColorSpan
|
|||||||
import android.text.style.StrikethroughSpan
|
import android.text.style.StrikethroughSpan
|
||||||
import android.util.LongSparseArray
|
import android.util.LongSparseArray
|
||||||
import android.util.SparseArray
|
import android.util.SparseArray
|
||||||
|
import android.view.View
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
@ -409,3 +410,10 @@ fun JsonObject(vararg properties: Pair<String, Any>): JsonObject {
|
|||||||
|
|
||||||
fun JsonArray?.isNullOrEmpty(): Boolean = (this?.size() ?: 0) == 0
|
fun JsonArray?.isNullOrEmpty(): Boolean = (this?.size() ?: 0) == 0
|
||||||
fun JsonArray.isEmpty(): Boolean = this.size() == 0
|
fun JsonArray.isEmpty(): Boolean = this.size() == 0
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
inline fun <T : View> T.onClick(crossinline onClickListener: (v: T) -> Unit) {
|
||||||
|
setOnClickListener { v: View ->
|
||||||
|
onClickListener(v as T)
|
||||||
|
}
|
||||||
|
}
|
@ -57,7 +57,7 @@ import pl.szczodrzynski.edziennik.ui.modules.grades.editor.GradesEditorFragment
|
|||||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment
|
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkFragment
|
import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.login.LoginActivity
|
import pl.szczodrzynski.edziennik.ui.modules.login.LoginActivity
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesDetailsFragment
|
import pl.szczodrzynski.edziennik.ui.modules.messages.MessageFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesFragment
|
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.notifications.NotificationsFragment
|
import pl.szczodrzynski.edziennik.ui.modules.notifications.NotificationsFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.settings.ProfileManagerFragment
|
import pl.szczodrzynski.edziennik.ui.modules.settings.ProfileManagerFragment
|
||||||
@ -203,7 +203,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
list += NavTarget(TARGET_GRADES_EDITOR, R.string.menu_grades_editor, GradesEditorFragment::class)
|
list += NavTarget(TARGET_GRADES_EDITOR, R.string.menu_grades_editor, GradesEditorFragment::class)
|
||||||
list += NavTarget(TARGET_HELP, R.string.menu_help, HelpFragment::class)
|
list += NavTarget(TARGET_HELP, R.string.menu_help, HelpFragment::class)
|
||||||
list += NavTarget(TARGET_FEEDBACK, R.string.menu_feedback, FeedbackFragment::class)
|
list += NavTarget(TARGET_FEEDBACK, R.string.menu_feedback, FeedbackFragment::class)
|
||||||
list += NavTarget(TARGET_MESSAGES_DETAILS, R.string.menu_message, MessagesDetailsFragment::class)
|
list += NavTarget(TARGET_MESSAGES_DETAILS, R.string.menu_message, MessageFragment::class)
|
||||||
list += NavTarget(DRAWER_ITEM_DEBUG, R.string.menu_debug, DebugFragment::class)
|
list += NavTarget(DRAWER_ITEM_DEBUG, R.string.menu_debug, DebugFragment::class)
|
||||||
|
|
||||||
list
|
list
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2019-11-12.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.api.v2.events
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageFull
|
||||||
|
|
||||||
|
data class MessageGetEvent(val message: MessageFull)
|
@ -12,6 +12,7 @@ import pl.szczodrzynski.edziennik.api.v2.mobidziennik.Mobidziennik
|
|||||||
import pl.szczodrzynski.edziennik.api.v2.template.Template
|
import pl.szczodrzynski.edziennik.api.v2.template.Template
|
||||||
import pl.szczodrzynski.edziennik.api.v2.vulcan.Vulcan
|
import pl.szczodrzynski.edziennik.api.v2.vulcan.Vulcan
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageFull
|
||||||
|
|
||||||
open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) {
|
open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) {
|
||||||
companion object {
|
companion object {
|
||||||
@ -21,7 +22,7 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
fun sync() = EdziennikTask(-1, SyncRequest())
|
fun sync() = EdziennikTask(-1, SyncRequest())
|
||||||
fun syncProfile(profileId: Int, viewIds: List<Pair<Int, Int>>? = null, arguments: JsonObject? = null) = EdziennikTask(profileId, SyncProfileRequest(viewIds, arguments))
|
fun syncProfile(profileId: Int, viewIds: List<Pair<Int, Int>>? = null, arguments: JsonObject? = null) = EdziennikTask(profileId, SyncProfileRequest(viewIds, arguments))
|
||||||
fun syncProfileList(profileList: List<Int>) = EdziennikTask(-1, SyncProfileListRequest(profileList))
|
fun syncProfileList(profileList: List<Int>) = EdziennikTask(-1, SyncProfileListRequest(profileList))
|
||||||
fun messageGet(profileId: Int, messageId: Long) = EdziennikTask(profileId, MessageGetRequest(messageId))
|
fun messageGet(profileId: Int, message: MessageFull) = EdziennikTask(profileId, MessageGetRequest(message))
|
||||||
fun announcementsRead(profileId: Int) = EdziennikTask(profileId, AnnouncementsReadRequest())
|
fun announcementsRead(profileId: Int) = EdziennikTask(profileId, AnnouncementsReadRequest())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +40,7 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
// get the requested profile and login store
|
// get the requested profile and login store
|
||||||
val profile = app.db.profileDao().getByIdNow(profileId)
|
val profile = app.db.profileDao().getByIdNow(profileId)
|
||||||
this.profile = profile
|
this.profile = profile
|
||||||
if (profile == null || !profile.syncEnabled) {
|
if (profile == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val loginStore = app.db.loginStoreDao().getByIdNow(profile.loginStoreId) ?: return
|
val loginStore = app.db.loginStoreDao().getByIdNow(profile.loginStoreId) ?: return
|
||||||
@ -69,7 +70,7 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
featureIds = request.viewIds?.flatMap { Features.getIdsByView(it.first, it.second) } ?: Features.getAllIds(),
|
featureIds = request.viewIds?.flatMap { Features.getIdsByView(it.first, it.second) } ?: Features.getAllIds(),
|
||||||
viewId = request.viewIds?.get(0)?.first,
|
viewId = request.viewIds?.get(0)?.first,
|
||||||
arguments = request.arguments)
|
arguments = request.arguments)
|
||||||
is MessageGetRequest -> edziennikInterface?.getMessage(request.messageId)
|
is MessageGetRequest -> edziennikInterface?.getMessage(request.message)
|
||||||
is FirstLoginRequest -> edziennikInterface?.firstLogin()
|
is FirstLoginRequest -> edziennikInterface?.firstLogin()
|
||||||
is AnnouncementsReadRequest -> edziennikInterface?.markAllAnnouncementsAsRead()
|
is AnnouncementsReadRequest -> edziennikInterface?.markAllAnnouncementsAsRead()
|
||||||
}
|
}
|
||||||
@ -87,6 +88,6 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
class SyncRequest
|
class SyncRequest
|
||||||
data class SyncProfileRequest(val viewIds: List<Pair<Int, Int>>? = null, val arguments: JsonObject? = null)
|
data class SyncProfileRequest(val viewIds: List<Pair<Int, Int>>? = null, val arguments: JsonObject? = null)
|
||||||
data class SyncProfileListRequest(val profileList: List<Int>)
|
data class SyncProfileListRequest(val profileList: List<Int>)
|
||||||
data class MessageGetRequest(val messageId: Long)
|
data class MessageGetRequest(val message: MessageFull)
|
||||||
class AnnouncementsReadRequest
|
class AnnouncementsReadRequest
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikInterface
|
|||||||
import pl.szczodrzynski.edziennik.api.v2.models.ApiError
|
import pl.szczodrzynski.edziennik.api.v2.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.api.v2.prepare
|
import pl.szczodrzynski.edziennik.api.v2.prepare
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMessage(messageId: Long) {
|
override fun getMessage(message: MessageFull) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
|||||||
/*messageId*/ messageId
|
/*messageId*/ messageId
|
||||||
)
|
)
|
||||||
|
|
||||||
data.messageList.add(message)
|
data.messageIgnoreList.add(message)
|
||||||
data.messageRecipientList.add(messageRecipient)
|
data.messageRecipientList.add(messageRecipient)
|
||||||
data.messageMetadataList.add(Metadata(
|
data.messageMetadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
|
@ -74,7 +74,7 @@ class IdziennikApiMessagesSent(override val data: DataIdziennik,
|
|||||||
data.messageRecipientIgnoreList.add(messageRecipient)
|
data.messageRecipientIgnoreList.add(messageRecipient)
|
||||||
}
|
}
|
||||||
|
|
||||||
data.messageList.add(message)
|
data.messageIgnoreList.add(message)
|
||||||
data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true, sentDate))
|
data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true, sentDate))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,10 +5,11 @@
|
|||||||
package pl.szczodrzynski.edziennik.api.v2.interfaces
|
package pl.szczodrzynski.edziennik.api.v2.interfaces
|
||||||
|
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageFull
|
||||||
|
|
||||||
interface EdziennikInterface {
|
interface EdziennikInterface {
|
||||||
fun sync(featureIds: List<Int>, viewId: Int? = null, arguments: JsonObject? = null)
|
fun sync(featureIds: List<Int>, viewId: Int? = null, arguments: JsonObject? = null)
|
||||||
fun getMessage(messageId: Long)
|
fun getMessage(message: MessageFull)
|
||||||
fun markAllAnnouncementsAsRead()
|
fun markAllAnnouncementsAsRead()
|
||||||
fun firstLogin()
|
fun firstLogin()
|
||||||
fun cancel()
|
fun cancel()
|
||||||
|
@ -19,6 +19,7 @@ import pl.szczodrzynski.edziennik.api.v2.librus.login.LibrusLoginMessages
|
|||||||
import pl.szczodrzynski.edziennik.api.v2.librus.login.LibrusLoginSynergia
|
import pl.szczodrzynski.edziennik.api.v2.librus.login.LibrusLoginSynergia
|
||||||
import pl.szczodrzynski.edziennik.api.v2.models.ApiError
|
import pl.szczodrzynski.edziennik.api.v2.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
@ -80,15 +81,17 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMessage(messageId: Long) {
|
override fun getMessage(message: MessageFull) {
|
||||||
LibrusLoginApi(data) {
|
LibrusLoginApi(data) {
|
||||||
|
LibrusLoginSynergia(data) {
|
||||||
LibrusLoginMessages(data) {
|
LibrusLoginMessages(data) {
|
||||||
LibrusMessagesGetMessage(data, messageId) {
|
LibrusMessagesGetMessage(data, message) {
|
||||||
completed()
|
completed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun markAllAnnouncementsAsRead() {
|
override fun markAllAnnouncementsAsRead() {
|
||||||
LibrusLoginApi(data) {
|
LibrusLoginApi(data) {
|
||||||
|
@ -22,8 +22,8 @@ class LibrusApiUsers(override val data: DataLibrus,
|
|||||||
|
|
||||||
users?.forEach { user ->
|
users?.forEach { user ->
|
||||||
val id = user.getLong("Id") ?: return@forEach
|
val id = user.getLong("Id") ?: return@forEach
|
||||||
val firstName = user.getString("FirstName")?.fixWhiteSpaces() ?: ""
|
val firstName = user.getString("FirstName")?.fixName() ?: ""
|
||||||
val lastName = user.getString("LastName")?.fixWhiteSpaces() ?: ""
|
val lastName = user.getString("LastName")?.fixName() ?: ""
|
||||||
|
|
||||||
data.teacherList.put(id, Teacher(profileId, id, firstName, lastName))
|
data.teacherList.put(id, Teacher(profileId, id, firstName, lastName))
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ class LibrusMessagesGetList(override val data: DataLibrus, private val type: Int
|
|||||||
id
|
id
|
||||||
)
|
)
|
||||||
|
|
||||||
data.messageList.add(messageObject)
|
data.messageIgnoreList.add(messageObject)
|
||||||
data.messageRecipientList.add(messageRecipientObject)
|
data.messageRecipientList.add(messageRecipientObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
|
@ -5,34 +5,43 @@
|
|||||||
package pl.szczodrzynski.edziennik.api.v2.librus.data.messages
|
package pl.szczodrzynski.edziennik.api.v2.librus.data.messages
|
||||||
|
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import pl.szczodrzynski.edziennik.api.v2.events.MessageGetEvent
|
||||||
import pl.szczodrzynski.edziennik.api.v2.librus.DataLibrus
|
import pl.szczodrzynski.edziennik.api.v2.librus.DataLibrus
|
||||||
import pl.szczodrzynski.edziennik.api.v2.librus.data.LibrusMessages
|
import pl.szczodrzynski.edziennik.api.v2.librus.data.LibrusMessages
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message.TYPE_RECEIVED
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message.TYPE_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message.TYPE_SENT
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message.TYPE_SENT
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageRecipient
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageRecipientFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.fixName
|
||||||
|
import pl.szczodrzynski.edziennik.singleOrNull
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
import java.nio.charset.Charset
|
||||||
|
|
||||||
class LibrusMessagesGetMessage(override val data: DataLibrus, val messageId: Long, val onSuccess: () -> Unit) : LibrusMessages(data) {
|
class LibrusMessagesGetMessage(
|
||||||
|
override val data: DataLibrus,
|
||||||
|
private val messageObject: MessageFull,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : LibrusMessages(data) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LibrusMessagesGetMessage"
|
const val TAG = "LibrusMessagesGetMessage"
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init { data.profile?.also { profile ->
|
||||||
messagesGet(TAG, "GetMessage", parameters = mapOf(
|
messagesGet(TAG, "GetMessage", parameters = mapOf(
|
||||||
"messageId" to messageId,
|
"messageId" to messageObject.id,
|
||||||
"archive" to 0
|
"archive" to 0
|
||||||
)) { doc ->
|
)) { doc ->
|
||||||
val message = doc.select("response GetMessage data").first()
|
val message = doc.select("response GetMessage data").first()
|
||||||
|
|
||||||
val body = Base64.decode(message.select("Message").text(), Base64.DEFAULT)
|
val body = Base64.decode(message.select("Message").text(), Base64.DEFAULT)
|
||||||
.toString().apply {
|
.toString(Charset.defaultCharset())
|
||||||
replace("\n", "")
|
.replace("\n", "<br>")
|
||||||
replace("<!\\[CDATA\\[", "")
|
.replace("<!\\[CDATA\\[", "")
|
||||||
replace("]]>", "")
|
.replace("]]>", "")
|
||||||
}
|
|
||||||
|
|
||||||
val messageObject = data.db.messageDao().getById(profileId, messageId).apply {
|
messageObject.apply {
|
||||||
this.body = body
|
this.body = body
|
||||||
|
|
||||||
clearAttachments()
|
clearAttachments()
|
||||||
@ -43,16 +52,20 @@ class LibrusMessagesGetMessage(override val data: DataLibrus, val messageId: Lon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val messageRecipientList = mutableListOf<MessageRecipientFull>()
|
||||||
|
|
||||||
when (messageObject.type) {
|
when (messageObject.type) {
|
||||||
TYPE_RECEIVED -> {
|
TYPE_RECEIVED -> {
|
||||||
val senderLoginId = message.select("senderId").text()
|
val senderLoginId = message.select("senderId").text()
|
||||||
|
data.teacherList.singleOrNull { it.id == messageObject.senderId }?.loginId = senderLoginId
|
||||||
|
|
||||||
val readDateText = message.select("readDate").text()
|
val readDateText = message.select("readDate").text()
|
||||||
val readDate = when (readDateText.isNotEmpty()) {
|
val readDate = when (readDateText.isNotEmpty()) {
|
||||||
true -> Date.fromIso(readDateText)
|
true -> Date.fromIso(readDateText)
|
||||||
else -> 0
|
else -> 0
|
||||||
}
|
}
|
||||||
|
|
||||||
val messageRecipientObject = MessageRecipient(
|
val messageRecipientObject = MessageRecipientFull(
|
||||||
profileId,
|
profileId,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
@ -60,21 +73,21 @@ class LibrusMessagesGetMessage(override val data: DataLibrus, val messageId: Lon
|
|||||||
messageObject.id
|
messageObject.id
|
||||||
)
|
)
|
||||||
|
|
||||||
data.messageRecipientList.add(messageRecipientObject)
|
messageRecipientObject.fullName = profile.accountNameLong ?: profile.studentNameLong
|
||||||
data.db.teacherDao().updateLoginId(profileId, messageObject.senderId, senderLoginId)
|
|
||||||
|
messageRecipientList.add(messageRecipientObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE_SENT -> {
|
TYPE_SENT -> {
|
||||||
val teachers = data.db.teacherDao().getAllNow(profileId)
|
|
||||||
|
|
||||||
message.select("receivers ArrayItem").forEach { receiver ->
|
message.select("receivers ArrayItem").forEach { receiver ->
|
||||||
val receiverFirstName = receiver.select("firstName").text()
|
val receiverFirstName = receiver.select("firstName").text().fixName()
|
||||||
val receiverLastName = receiver.select("lastName").text()
|
val receiverLastName = receiver.select("lastName").text().fixName()
|
||||||
val receiverLoginId = receiver.select("receiverId").text()
|
val receiverLoginId = receiver.select("receiverId").text()
|
||||||
|
|
||||||
val receiverId = teachers.singleOrNull {
|
val teacher = data.teacherList.singleOrNull { it.name == receiverFirstName && it.surname == receiverLastName }
|
||||||
it.name.equals(receiverFirstName, true) && it.surname.equals(receiverLastName, true)
|
val receiverId = teacher?.id ?: -1
|
||||||
}?.id ?: -1
|
teacher?.loginId = receiverLoginId
|
||||||
|
|
||||||
val readDateText = message.select("readed").text()
|
val readDateText = message.select("readed").text()
|
||||||
val readDate = when (readDateText.isNotEmpty()) {
|
val readDate = when (readDateText.isNotEmpty()) {
|
||||||
@ -82,24 +95,38 @@ class LibrusMessagesGetMessage(override val data: DataLibrus, val messageId: Lon
|
|||||||
else -> 0
|
else -> 0
|
||||||
}
|
}
|
||||||
|
|
||||||
val messageRecipientObject = MessageRecipient(
|
val messageRecipientObject = MessageRecipientFull(
|
||||||
profileId,
|
profileId,
|
||||||
-1,
|
receiverId,
|
||||||
-1,
|
-1,
|
||||||
readDate,
|
readDate,
|
||||||
messageObject.id
|
messageObject.id
|
||||||
)
|
)
|
||||||
|
|
||||||
data.messageRecipientList.add(messageRecipientObject)
|
messageRecipientObject.fullName = "$receiverFirstName $receiverLastName"
|
||||||
data.db.teacherDao().updateLoginId(profileId, receiverId, receiverLoginId)
|
|
||||||
|
messageRecipientList.add(messageRecipientObject)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!messageObject.seen) data.db.metadataDao().setSeen(profileId, messageObject, true)
|
if (!messageObject.seen) {
|
||||||
|
data.messageMetadataList.add(Metadata(
|
||||||
|
messageObject.profileId,
|
||||||
|
Metadata.TYPE_MESSAGE,
|
||||||
|
messageObject.id,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
messageObject.addedDate
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
data.messageList.add(messageObject as Message)
|
messageObject.recipients = messageRecipientList
|
||||||
|
data.messageRecipientList.addAll(messageRecipientList)
|
||||||
|
data.messageList.add(messageObject)
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(MessageGetEvent(messageObject))
|
||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
}
|
} ?: onSuccess()}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import pl.szczodrzynski.edziennik.api.v2.mobidziennikLoginMethods
|
|||||||
import pl.szczodrzynski.edziennik.api.v2.models.ApiError
|
import pl.szczodrzynski.edziennik.api.v2.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.api.v2.prepare
|
import pl.szczodrzynski.edziennik.api.v2.prepare
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMessage(messageId: Long) {
|
override fun getMessage(message: MessageFull) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,7 @@ import org.jsoup.Jsoup
|
|||||||
import pl.szczodrzynski.edziennik.DAY
|
import pl.szczodrzynski.edziennik.DAY
|
||||||
import pl.szczodrzynski.edziennik.api.v2.mobidziennik.DataMobidziennik
|
import pl.szczodrzynski.edziennik.api.v2.mobidziennik.DataMobidziennik
|
||||||
import pl.szczodrzynski.edziennik.api.v2.mobidziennik.ENDPOINT_MOBIDZIENNIK_WEB_MESSAGES_ALL
|
import pl.szczodrzynski.edziennik.api.v2.mobidziennik.ENDPOINT_MOBIDZIENNIK_WEB_MESSAGES_ALL
|
||||||
import pl.szczodrzynski.edziennik.api.v2.mobidziennik.ENDPOINT_MOBIDZIENNIK_WEB_MESSAGES_INBOX
|
|
||||||
import pl.szczodrzynski.edziennik.api.v2.mobidziennik.data.MobidziennikWeb
|
import pl.szczodrzynski.edziennik.api.v2.mobidziennik.data.MobidziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message.TYPE_RECEIVED
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message.TYPE_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message.TYPE_SENT
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message.TYPE_SENT
|
||||||
@ -79,7 +77,7 @@ class MobidziennikWebMessagesAll(override val data: DataMobidziennik,
|
|||||||
-1
|
-1
|
||||||
)
|
)
|
||||||
|
|
||||||
data.messageList.add(message)
|
data.messageIgnoreList.add(message)
|
||||||
data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true, addedDate))
|
data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true, addedDate))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ class MobidziennikWebMessagesInbox(override val data: DataMobidziennik,
|
|||||||
if (hasAttachments)
|
if (hasAttachments)
|
||||||
message.setHasAttachments()
|
message.setHasAttachments()
|
||||||
|
|
||||||
data.messageList.add(message)
|
data.messageIgnoreList.add(message)
|
||||||
data.messageMetadataList.add(
|
data.messageMetadataList.add(
|
||||||
Metadata(
|
Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
|
@ -156,6 +156,7 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore)
|
|||||||
val teacherAbsenceList = mutableListOf<TeacherAbsence>()
|
val teacherAbsenceList = mutableListOf<TeacherAbsence>()
|
||||||
|
|
||||||
val messageList = mutableListOf<Message>()
|
val messageList = mutableListOf<Message>()
|
||||||
|
val messageIgnoreList = mutableListOf<Message>()
|
||||||
val messageRecipientList = mutableListOf<MessageRecipient>()
|
val messageRecipientList = mutableListOf<MessageRecipient>()
|
||||||
val messageRecipientIgnoreList = mutableListOf<MessageRecipient>()
|
val messageRecipientIgnoreList = mutableListOf<MessageRecipient>()
|
||||||
|
|
||||||
@ -205,7 +206,7 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore)
|
|||||||
announcementList.clear()
|
announcementList.clear()
|
||||||
luckyNumberList.clear()
|
luckyNumberList.clear()
|
||||||
teacherAbsenceList.clear()
|
teacherAbsenceList.clear()
|
||||||
messageList.clear()
|
messageIgnoreList.clear()
|
||||||
messageRecipientList.clear()
|
messageRecipientList.clear()
|
||||||
messageRecipientIgnoreList.clear()
|
messageRecipientIgnoreList.clear()
|
||||||
metadataList.clear()
|
metadataList.clear()
|
||||||
@ -285,6 +286,11 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (metadataList.isNotEmpty())
|
||||||
|
db.metadataDao().addAllIgnore(metadataList)
|
||||||
|
if (messageMetadataList.isNotEmpty())
|
||||||
|
db.metadataDao().setSeen(messageMetadataList)
|
||||||
|
|
||||||
// not extracted from DB - always new data
|
// not extracted from DB - always new data
|
||||||
if (lessonList.isNotEmpty()) {
|
if (lessonList.isNotEmpty()) {
|
||||||
db.lessonDao().clear(profile.id)
|
db.lessonDao().clear(profile.id)
|
||||||
@ -316,15 +322,13 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore)
|
|||||||
db.teacherAbsenceDao().addAll(teacherAbsenceList)
|
db.teacherAbsenceDao().addAll(teacherAbsenceList)
|
||||||
|
|
||||||
if (messageList.isNotEmpty())
|
if (messageList.isNotEmpty())
|
||||||
db.messageDao().addAllIgnore(messageList)
|
db.messageDao().addAll(messageList)
|
||||||
|
if (messageIgnoreList.isNotEmpty())
|
||||||
|
db.messageDao().addAllIgnore(messageIgnoreList)
|
||||||
if (messageRecipientList.isNotEmpty())
|
if (messageRecipientList.isNotEmpty())
|
||||||
db.messageRecipientDao().addAll(messageRecipientList)
|
db.messageRecipientDao().addAll(messageRecipientList)
|
||||||
if (messageRecipientIgnoreList.isNotEmpty())
|
if (messageRecipientIgnoreList.isNotEmpty())
|
||||||
db.messageRecipientDao().addAllIgnore(messageRecipientIgnoreList)
|
db.messageRecipientDao().addAllIgnore(messageRecipientIgnoreList)
|
||||||
if (metadataList.isNotEmpty())
|
|
||||||
db.metadataDao().addAllIgnore(metadataList)
|
|
||||||
if (messageMetadataList.isNotEmpty())
|
|
||||||
db.metadataDao().setSeen(messageMetadataList)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun notifyAndSyncEvents(onSuccess: () -> Unit) {
|
fun notifyAndSyncEvents(onSuccess: () -> Unit) {
|
||||||
|
@ -16,6 +16,7 @@ import pl.szczodrzynski.edziennik.api.v2.template.firstlogin.TemplateFirstLogin
|
|||||||
import pl.szczodrzynski.edziennik.api.v2.template.login.TemplateLogin
|
import pl.szczodrzynski.edziennik.api.v2.template.login.TemplateLogin
|
||||||
import pl.szczodrzynski.edziennik.api.v2.templateLoginMethods
|
import pl.szczodrzynski.edziennik.api.v2.templateLoginMethods
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ class Template(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMessage(messageId: Long) {
|
override fun getMessage(message: MessageFull) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ import pl.szczodrzynski.edziennik.api.v2.vulcan.firstlogin.VulcanFirstLogin
|
|||||||
import pl.szczodrzynski.edziennik.api.v2.vulcan.login.VulcanLogin
|
import pl.szczodrzynski.edziennik.api.v2.vulcan.login.VulcanLogin
|
||||||
import pl.szczodrzynski.edziennik.api.v2.vulcanLoginMethods
|
import pl.szczodrzynski.edziennik.api.v2.vulcanLoginMethods
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMessage(messageId: Long) {
|
override fun getMessage(message: MessageFull) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ class VulcanApiMessagesInbox(override val data: DataVulcan, val onSuccess: () ->
|
|||||||
id
|
id
|
||||||
)
|
)
|
||||||
|
|
||||||
data.messageList.add(messageObject)
|
data.messageIgnoreList.add(messageObject)
|
||||||
data.messageRecipientList.add(messageRecipientObject)
|
data.messageRecipientList.add(messageRecipientObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
|
@ -80,7 +80,7 @@ class VulcanApiMessagesSent(override val data: DataVulcan, val onSuccess: () ->
|
|||||||
data.messageRecipientList.add(messageRecipientObject)
|
data.messageRecipientList.add(messageRecipientObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
data.messageList.add(messageObject)
|
data.messageIgnoreList.add(messageObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
Metadata.TYPE_MESSAGE,
|
Metadata.TYPE_MESSAGE,
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.db.modules.messages;
|
package pl.szczodrzynski.edziennik.data.db.modules.messages;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.room.ColumnInfo;
|
import androidx.room.ColumnInfo;
|
||||||
import androidx.room.Entity;
|
import androidx.room.Entity;
|
||||||
import androidx.room.Ignore;
|
import androidx.room.Ignore;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Entity(tableName = "messages",
|
@Entity(tableName = "messages",
|
||||||
primaryKeys = {"profileId", "messageId"},
|
primaryKeys = {"profileId", "messageId"},
|
||||||
indices = {@Index(value = {"profileId"})})
|
indices = {@Index(value = {"profileId"})})
|
||||||
public class Message {
|
public class Message {
|
||||||
int profileId;
|
public int profileId;
|
||||||
|
|
||||||
@ColumnInfo(name = "messageId")
|
@ColumnInfo(name = "messageId")
|
||||||
public long id;
|
public long id;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.db.modules.messages;
|
package pl.szczodrzynski.edziennik.data.db.modules.messages;
|
||||||
|
|
||||||
import java.util.List;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.room.Dao;
|
import androidx.room.Dao;
|
||||||
import androidx.room.Insert;
|
import androidx.room.Insert;
|
||||||
@ -11,6 +10,8 @@ import androidx.room.RawQuery;
|
|||||||
import androidx.sqlite.db.SimpleSQLiteQuery;
|
import androidx.sqlite.db.SimpleSQLiteQuery;
|
||||||
import androidx.sqlite.db.SupportSQLiteQuery;
|
import androidx.sqlite.db.SupportSQLiteQuery;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata;
|
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata;
|
||||||
|
|
||||||
import static pl.szczodrzynski.edziennik.data.db.modules.messages.Message.TYPE_DELETED;
|
import static pl.szczodrzynski.edziennik.data.db.modules.messages.Message.TYPE_DELETED;
|
||||||
@ -23,6 +24,9 @@ public abstract class MessageDao {
|
|||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
public abstract long add(Message message);
|
public abstract long add(Message message);
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
public abstract void addAll(List<Message> messageList);
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||||
public abstract void addAllIgnore(List<Message> messageList);
|
public abstract void addAllIgnore(List<Message> messageList);
|
||||||
|
|
||||||
@ -56,6 +60,7 @@ public abstract class MessageDao {
|
|||||||
"ORDER BY addedDate DESC"));
|
"ORDER BY addedDate DESC"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public MessageFull getById(int profileId, long messageId) {
|
public MessageFull getById(int profileId, long messageId) {
|
||||||
return getOneNow(new SimpleSQLiteQuery("SELECT \n" +
|
return getOneNow(new SimpleSQLiteQuery("SELECT \n" +
|
||||||
"*, \n" +
|
"*, \n" +
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.db.modules.messages;
|
package pl.szczodrzynski.edziennik.data.db.modules.messages;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.room.Ignore;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import androidx.room.Ignore;
|
|
||||||
|
|
||||||
public class MessageFull extends Message {
|
public class MessageFull extends Message {
|
||||||
public String senderFullName = null;
|
public String senderFullName = null;
|
||||||
@Ignore
|
@Ignore
|
||||||
|
@Nullable
|
||||||
public List<MessageRecipientFull> recipients = null;
|
public List<MessageRecipientFull> recipients = null;
|
||||||
|
|
||||||
public MessageFull addRecipient(MessageRecipientFull recipient) {
|
public MessageFull addRecipient(MessageRecipientFull recipient) {
|
||||||
|
@ -0,0 +1,319 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2019-11-12.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.messages
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Environment
|
||||||
|
import android.text.Html
|
||||||
|
import android.text.TextUtils
|
||||||
|
import android.view.Gravity.CENTER_VERTICAL
|
||||||
|
import android.view.Gravity.END
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.ProgressBar
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import com.google.android.material.chip.Chip
|
||||||
|
import com.mikepenz.iconics.IconicsColor
|
||||||
|
import com.mikepenz.iconics.IconicsDrawable
|
||||||
|
import com.mikepenz.iconics.IconicsSize
|
||||||
|
import com.mikepenz.iconics.typeface.IIcon
|
||||||
|
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||||
|
import com.mikepenz.iconics.utils.sizeDp
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import org.greenrobot.eventbus.Subscribe
|
||||||
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.api.v2.events.MessageGetEvent
|
||||||
|
import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message.TYPE_SENT
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageFull
|
||||||
|
import pl.szczodrzynski.edziennik.databinding.MessageFragmentBinding
|
||||||
|
import pl.szczodrzynski.edziennik.onClick
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Anim
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Themes
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils.getStringFromFile
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils.readableFileSize
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
import pl.szczodrzynski.navlib.colorAttr
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
|
class MessageFragment : Fragment(), CoroutineScope {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "MessageFragment"
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var app: App
|
||||||
|
private lateinit var activity: MainActivity
|
||||||
|
private lateinit var b: MessageFragmentBinding
|
||||||
|
|
||||||
|
private lateinit var job: Job
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = job + Dispatchers.Main
|
||||||
|
|
||||||
|
private lateinit var message: MessageFull
|
||||||
|
private var attachmentList = mutableListOf<Attachment>()
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
activity = (getActivity() as MainActivity?) ?: return null
|
||||||
|
context ?: return null
|
||||||
|
app = activity.application as App
|
||||||
|
context!!.theme.applyStyle(Themes.appTheme, true)
|
||||||
|
b = MessageFragmentBinding.inflate(inflater)
|
||||||
|
job = Job()
|
||||||
|
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
|
||||||
|
|
||||||
|
b.closeButton.setImageDrawable(
|
||||||
|
IconicsDrawable(activity, CommunityMaterial.Icon2.cmd_window_close)
|
||||||
|
.colorAttr(activity, android.R.attr.textColorSecondary)
|
||||||
|
.sizeDp(12)
|
||||||
|
)
|
||||||
|
b.closeButton.setOnClickListener { activity.navigateUp() }
|
||||||
|
|
||||||
|
val messageId = arguments?.getLong("messageId")
|
||||||
|
if (messageId == null) {
|
||||||
|
activity.navigateUp()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
launch {
|
||||||
|
val deferred = async(Dispatchers.Default) {
|
||||||
|
val msg = app.db.messageDao().getById(App.profileId, messageId)?.also {
|
||||||
|
it.recipients = app.db.messageRecipientDao().getAllByMessageId(it.profileId, it.id)
|
||||||
|
if (it.body != null && !it.seen) {
|
||||||
|
app.db.metadataDao().setSeen(it.profileId, message, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg
|
||||||
|
}
|
||||||
|
val msg = deferred.await() ?: run {
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
message = msg
|
||||||
|
b.subject.text = message.subject
|
||||||
|
checkMessage()
|
||||||
|
}
|
||||||
|
|
||||||
|
// click to expand subject and sender
|
||||||
|
b.subject.onClick {
|
||||||
|
it.maxLines = if (it.maxLines == 30) 2 else 30
|
||||||
|
}
|
||||||
|
b.sender.onClick {
|
||||||
|
it.maxLines = if (it.maxLines == 30) 2 else 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
|
fun onMessageGetEvent(event: MessageGetEvent) {
|
||||||
|
// TODO remove this: message = event.message
|
||||||
|
showMessage()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkMessage() {
|
||||||
|
if (message.body == null) {
|
||||||
|
EdziennikTask.messageGet(App.profileId, message).enqueue(activity)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var readByAll = true
|
||||||
|
message.recipients?.forEach { recipient ->
|
||||||
|
if (recipient.id == -1L)
|
||||||
|
recipient.fullName = app.profile.accountNameLong ?: app.profile.studentNameLong
|
||||||
|
if (message.type == TYPE_SENT && recipient.readDate < 1)
|
||||||
|
readByAll = false
|
||||||
|
}
|
||||||
|
// if a sent msg is not read by everyone, download it again to check the read status
|
||||||
|
if (!readByAll) {
|
||||||
|
EdziennikTask.messageGet(App.profileId, message).enqueue(activity)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
showMessage()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showMessage() {
|
||||||
|
b.body.text = Html.fromHtml(message.body?.replace("\\[META:[A-z0-9]+;[0-9-]+]".toRegex(), ""))
|
||||||
|
b.date.text = getString(R.string.messages_date_time_format, Date.fromMillis(message.addedDate).formattedStringShort, Time.fromMillis(message.addedDate).stringHM)
|
||||||
|
|
||||||
|
val messageInfo = MessagesUtils.getMessageInfo(app, message, 40, 20, 14, 10)
|
||||||
|
b.profileBackground.setImageBitmap(messageInfo.profileImage)
|
||||||
|
b.sender.text = messageInfo.profileName
|
||||||
|
|
||||||
|
b.subject.text = message.subject
|
||||||
|
|
||||||
|
val messageRecipients = StringBuilder("<ul>")
|
||||||
|
message.recipients?.forEach { recipient ->
|
||||||
|
when (recipient.readDate) {
|
||||||
|
-1L -> messageRecipients.append(getString(
|
||||||
|
R.string.messages_recipients_list_unknown_state_format,
|
||||||
|
recipient.fullName
|
||||||
|
))
|
||||||
|
0L -> messageRecipients.append(getString(
|
||||||
|
R.string.messages_recipients_list_unread_format,
|
||||||
|
recipient.fullName
|
||||||
|
))
|
||||||
|
1L -> messageRecipients.append(getString(
|
||||||
|
R.string.messages_recipients_list_read_unknown_date_format,
|
||||||
|
recipient.fullName
|
||||||
|
))
|
||||||
|
else -> messageRecipients.append(getString(
|
||||||
|
R.string.messages_recipients_list_read_format,
|
||||||
|
recipient.fullName,
|
||||||
|
Date.fromMillis(recipient.readDate).formattedString,
|
||||||
|
Time.fromMillis(recipient.readDate).stringHM
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
messageRecipients.append("</ul>")
|
||||||
|
b.recipients.text = Html.fromHtml(messageRecipients.toString())
|
||||||
|
|
||||||
|
showAttachments()
|
||||||
|
|
||||||
|
b.progress.visibility = View.GONE
|
||||||
|
Anim.fadeIn(b.content, 200, null)
|
||||||
|
MessagesFragment.pageSelection = min(message.type, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showAttachments() {
|
||||||
|
if (message.attachmentIds != null) {
|
||||||
|
val insertPoint = b.attachments
|
||||||
|
|
||||||
|
val chipLayoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||||
|
chipLayoutParams.setMargins(0, Utils.dpToPx(8), 0, Utils.dpToPx(8))
|
||||||
|
|
||||||
|
val progressLayoutParams = FrameLayout.LayoutParams(Utils.dpToPx(18), Utils.dpToPx(18))
|
||||||
|
progressLayoutParams.setMargins(Utils.dpToPx(8), 0, Utils.dpToPx(8), 0)
|
||||||
|
progressLayoutParams.gravity = END or CENTER_VERTICAL
|
||||||
|
|
||||||
|
// CREATE VIEWS AND AN OBJECT FOR EVERY ATTACHMENT
|
||||||
|
|
||||||
|
message.attachmentNames.forEachIndexed { index, name ->
|
||||||
|
val messageId = message.id
|
||||||
|
val id = message.attachmentIds[index]
|
||||||
|
val size = message.attachmentSizes[index]
|
||||||
|
// create the parent
|
||||||
|
val attachmentLayout = FrameLayout(b.root.context)
|
||||||
|
attachmentLayout.setPadding(Utils.dpToPx(16), 0, Utils.dpToPx(16), 0)
|
||||||
|
|
||||||
|
val attachmentChip = Chip(attachmentLayout.context)
|
||||||
|
//attachmentChip.setChipBackgroundColorResource(ThemeUtils.getChipColorRes());
|
||||||
|
attachmentChip.layoutParams = chipLayoutParams
|
||||||
|
attachmentChip.height = Utils.dpToPx(40)
|
||||||
|
|
||||||
|
// show the file size or not
|
||||||
|
if (size == -1L)
|
||||||
|
attachmentChip.text = getString(R.string.messages_attachment_no_size_format, name)
|
||||||
|
else
|
||||||
|
attachmentChip.text = getString(R.string.messages_attachment_format, name, readableFileSize(size))
|
||||||
|
attachmentChip.ellipsize = TextUtils.TruncateAt.MIDDLE
|
||||||
|
|
||||||
|
// create an icon for the attachment
|
||||||
|
var icon: IIcon = CommunityMaterial.Icon.cmd_file
|
||||||
|
when (Utils.getExtensionFromFileName(name)) {
|
||||||
|
"txt" -> icon = CommunityMaterial.Icon.cmd_file_document
|
||||||
|
"doc", "docx", "odt", "rtf" -> icon = CommunityMaterial.Icon.cmd_file_word
|
||||||
|
"xls", "xlsx", "ods" -> icon = CommunityMaterial.Icon.cmd_file_excel
|
||||||
|
"ppt", "pptx", "odp" -> icon = CommunityMaterial.Icon.cmd_file_powerpoint
|
||||||
|
"pdf" -> icon = CommunityMaterial.Icon.cmd_file_pdf
|
||||||
|
"mp3", "wav", "aac" -> icon = CommunityMaterial.Icon.cmd_file_music
|
||||||
|
"mp4", "avi", "3gp", "mkv", "flv" -> icon = CommunityMaterial.Icon.cmd_file_video
|
||||||
|
"jpg", "jpeg", "png", "bmp", "gif" -> icon = CommunityMaterial.Icon.cmd_file_image
|
||||||
|
"zip", "rar", "tar", "7z" -> icon = CommunityMaterial.Icon.cmd_file_lock
|
||||||
|
}
|
||||||
|
attachmentChip.chipIcon = IconicsDrawable(activity).color(IconicsColor.colorRes(R.color.colorPrimary)).icon(icon).size(IconicsSize.dp(26))
|
||||||
|
attachmentChip.closeIcon = IconicsDrawable(activity).icon(CommunityMaterial.Icon.cmd_check).size(IconicsSize.dp(18)).color(IconicsColor.colorInt(Utils.getAttr(activity, android.R.attr.textColorPrimary)))
|
||||||
|
attachmentChip.isCloseIconVisible = false
|
||||||
|
// set the object's index in the attachmentList as the tag
|
||||||
|
attachmentChip.tag = index
|
||||||
|
attachmentChip.setOnClickListener { v ->
|
||||||
|
if (v.tag is Int) {
|
||||||
|
// TODO downloadAttachment(v.tag as Int)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attachmentLayout.addView(attachmentChip)
|
||||||
|
|
||||||
|
val attachmentProgress = ProgressBar(attachmentLayout.context)
|
||||||
|
attachmentProgress.layoutParams = progressLayoutParams
|
||||||
|
attachmentProgress.visibility = View.GONE
|
||||||
|
attachmentLayout.addView(attachmentProgress)
|
||||||
|
|
||||||
|
insertPoint.addView(attachmentLayout)
|
||||||
|
// create an object and add to the list
|
||||||
|
val a = Attachment(App.profileId, messageId, id, name, size, attachmentLayout, attachmentChip, attachmentProgress)
|
||||||
|
attachmentList.add(a)
|
||||||
|
// check if the file is already downloaded. Show the check icon if necessary and set `downloaded` to true.
|
||||||
|
checkAttachment(a)
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// no attachments found
|
||||||
|
b.attachmentsTitle.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkAttachment(attachment: Attachment) {
|
||||||
|
val storageDir = Environment.getExternalStoragePublicDirectory("Szkolny.eu")
|
||||||
|
storageDir.mkdirs()
|
||||||
|
|
||||||
|
val attachmentDataFile = File(storageDir, "." + attachment.profileId + "_" + attachment.messageId + "_" + attachment.attachmentId)
|
||||||
|
if (attachmentDataFile.exists()) {
|
||||||
|
try {
|
||||||
|
val attachmentFileName = getStringFromFile(attachmentDataFile)
|
||||||
|
val attachmentFile = File(attachmentFileName)
|
||||||
|
if (attachmentFile.exists()) {
|
||||||
|
attachment.downloaded = attachmentFileName
|
||||||
|
attachment.chip.isCloseIconVisible = true
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
//app.apiEdziennik.guiReportException(activity, 355, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
EventBus.getDefault().register(this)
|
||||||
|
super.onStart()
|
||||||
|
}
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
EventBus.getDefault().unregister(this)
|
||||||
|
}
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Attachment(
|
||||||
|
var profileId: Int,
|
||||||
|
var messageId: Long,
|
||||||
|
var attachmentId: Long,
|
||||||
|
var attachmentName: String,
|
||||||
|
var attachmentSize: Long,
|
||||||
|
var parent: FrameLayout,
|
||||||
|
var chip: Chip,
|
||||||
|
var progressBar: ProgressBar
|
||||||
|
) {
|
||||||
|
/**
|
||||||
|
* An absolute path of the downloaded file. `null` if not downloaded yet.
|
||||||
|
*/
|
||||||
|
internal var downloaded: String? = null
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,6 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.modules.messages
|
package pl.szczodrzynski.edziennik.ui.modules.messages
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Html
|
|
||||||
import android.text.InputType
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -10,18 +8,14 @@ import androidx.fragment.app.Fragment
|
|||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
import androidx.fragment.app.FragmentPagerAdapter
|
import androidx.fragment.app.FragmentPagerAdapter
|
||||||
import androidx.viewpager.widget.ViewPager
|
import androidx.viewpager.widget.ViewPager
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.api.v2.LOGIN_TYPE_LIBRUS
|
|
||||||
import pl.szczodrzynski.edziennik.api.v2.events.ApiTaskErrorEvent
|
import pl.szczodrzynski.edziennik.api.v2.events.ApiTaskErrorEvent
|
||||||
import pl.szczodrzynski.edziennik.api.v2.events.ApiTaskFinishedEvent
|
import pl.szczodrzynski.edziennik.api.v2.events.ApiTaskFinishedEvent
|
||||||
import pl.szczodrzynski.edziennik.api.v2.events.task.EdziennikTask
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message
|
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message
|
||||||
import pl.szczodrzynski.edziennik.databinding.FragmentMessagesBinding
|
import pl.szczodrzynski.edziennik.databinding.FragmentMessagesBinding
|
||||||
import pl.szczodrzynski.edziennik.utils.Themes
|
import pl.szczodrzynski.edziennik.utils.Themes
|
||||||
@ -92,7 +86,7 @@ class MessagesFragment : Fragment() {
|
|||||||
|
|
||||||
b.tabLayout.setupWithViewPager(b.viewPager)
|
b.tabLayout.setupWithViewPager(b.viewPager)
|
||||||
|
|
||||||
if (app.profile.loginStoreType == LOGIN_TYPE_LIBRUS && app.profile.getStudentData("accountPassword", null) == null) {
|
/*if (app.profile.loginStoreType == LOGIN_TYPE_LIBRUS && app.profile.getStudentData("accountPassword", null) == null) {
|
||||||
MaterialDialog.Builder(activity)
|
MaterialDialog.Builder(activity)
|
||||||
.title("Wiadomości w systemie Synergia")
|
.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.")
|
.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.")
|
||||||
@ -115,7 +109,7 @@ class MessagesFragment : Fragment() {
|
|||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
.show()
|
.show()
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
353
app/src/main/res/layout/message_fragment.xml
Normal file
353
app/src/main/res/layout/message_fragment.xml
Normal file
@ -0,0 +1,353 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (c) Kuba Szczodrzyński 2019-11-12.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<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">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="?attr/actionBarSize"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:background="@color/colorSurface_6dp">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/closeButton"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_marginTop="2dp"
|
||||||
|
android:background="?android:attr/actionBarItemBackground"
|
||||||
|
app:srcCompat="@android:drawable/ic_delete" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/subject"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:animateLayoutChanges="true"
|
||||||
|
android:background="?selectableItemBackground"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:textAppearance="@style/NavView.TextView.Title"
|
||||||
|
tools:ignore="HardcodedText"
|
||||||
|
tools:text="mobiDziennik - raport dzienny." />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="2dp"
|
||||||
|
android:background="@drawable/shadow_top" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:visibility="visible"
|
||||||
|
tools:visibility="gone"/>
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:id="@+id/content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/profileBackground"
|
||||||
|
android:layout_width="64dp"
|
||||||
|
android:layout_height="64dp"
|
||||||
|
android:padding="12dp"
|
||||||
|
app:srcCompat="@drawable/bg_circle" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/profileName"
|
||||||
|
android:layout_width="64dp"
|
||||||
|
android:layout_height="64dp"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:textColor="#ffffff"
|
||||||
|
android:textSize="20sp"
|
||||||
|
tools:text="JP"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/profileImage"
|
||||||
|
android:layout_width="64dp"
|
||||||
|
android:layout_height="64dp"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:srcCompat="@tools:sample/avatars[0]" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/sender"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="?selectableItemBackground"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:paddingLeft="8dp"
|
||||||
|
android:paddingTop="12dp"
|
||||||
|
android:paddingRight="8dp"
|
||||||
|
android:textAppearance="@style/NavView.TextView.Subtitle"
|
||||||
|
tools:text="Allegro - wysyłamy duużo wiadomości!!! Masz nowe oferty! Możesz kupić nowego laptopa! Ale super! Ehh, to jest nadawca a nie temat więc nwm czemu to tutaj wpisałem" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/date"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
|
android:textAppearance="@style/NavView.TextView.Small"
|
||||||
|
tools:text="14:26" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/body"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:autoLink="all"
|
||||||
|
android:minHeight="250dp"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="16dp"
|
||||||
|
android:textIsSelectable="true"
|
||||||
|
tools:text="To jest treść wiadomości.\n\nZazwyczaj ma wiele linijek.\n\nTak" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="?colorControlHighlight" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:text="Odbiorcy wiadomości:"
|
||||||
|
android:textAppearance="@style/NavView.TextView.Subtitle" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/recipients"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="16dp"
|
||||||
|
tools:text=" - Jan Kowalski, przeczytano: nie\n - Adam Dodatkowy, przeczytano: 20 marca, 17:35" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/attachmentsTitle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:text="Załączniki:"
|
||||||
|
android:textAppearance="@style/NavView.TextView.Subtitle" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/attachments"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="16dp"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<com.google.android.material.chip.Chip
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="middle"
|
||||||
|
android:text="Testowy plik.pdf"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:chipBackgroundColor="@color/mtrl_chip_background_color"
|
||||||
|
app:chipIcon="@drawable/googleg_standard_color_18"
|
||||||
|
app:chipMinHeight="36dp"
|
||||||
|
app:chipSurfaceColor="@color/mtrl_chip_surface_color"
|
||||||
|
app:closeIcon="@drawable/ic_error_outline"
|
||||||
|
app:closeIconVisible="true" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
style="?android:attr/progressBarStyle"
|
||||||
|
android:layout_width="18dp"
|
||||||
|
android:layout_height="18dp"
|
||||||
|
android:layout_gravity="center_vertical|end"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_marginRight="8dp" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="16dp"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<com.google.android.material.chip.Chip
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="middle"
|
||||||
|
android:text="Wyniki sprawdzianu z matematyki.pdf"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:chipIcon="@drawable/googleg_standard_color_18"
|
||||||
|
app:chipMinHeight="36dp" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
style="?android:attr/progressBarStyle"
|
||||||
|
android:layout_width="18dp"
|
||||||
|
android:layout_height="18dp"
|
||||||
|
android:layout_gravity="center_vertical|end"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_marginRight="8dp" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginLeft="4dp"
|
||||||
|
android:layout_marginRight="4dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/bg_rounded_ripple"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="4dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingRight="4dp"
|
||||||
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Odpowiedz"
|
||||||
|
android:textAppearance="@style/NavView.TextView.Small" />
|
||||||
|
|
||||||
|
<com.mikepenz.iconics.view.IconicsImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:padding="4dp"
|
||||||
|
app:iiv_color="?android:textColorSecondary"
|
||||||
|
app:iiv_icon="cmd-reply"
|
||||||
|
tools:srcCompat="@android:drawable/ic_menu_revert" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginLeft="4dp"
|
||||||
|
android:layout_marginRight="4dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/bg_rounded_ripple"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="4dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingRight="4dp"
|
||||||
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Przekaż dalej"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textAppearance="@style/NavView.TextView.Small" />
|
||||||
|
|
||||||
|
<com.mikepenz.iconics.view.IconicsImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:padding="4dp"
|
||||||
|
app:iiv_color="?android:textColorSecondary"
|
||||||
|
app:iiv_icon="cmd-share"
|
||||||
|
tools:srcCompat="@android:drawable/ic_media_ff" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginLeft="4dp"
|
||||||
|
android:layout_marginRight="4dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/bg_rounded_ripple"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="4dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingRight="4dp"
|
||||||
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Usuń"
|
||||||
|
android:textAppearance="@style/NavView.TextView.Small" />
|
||||||
|
|
||||||
|
<com.mikepenz.iconics.view.IconicsImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:padding="4dp"
|
||||||
|
app:iiv_color="?android:textColorSecondary"
|
||||||
|
app:iiv_icon="cmd-delete"
|
||||||
|
tools:srcCompat="@android:drawable/ic_menu_delete" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
</LinearLayout>
|
||||||
|
</layout>
|
Loading…
x
Reference in New Issue
Block a user