forked from github/szkolny
[Messages] Add new attachments view. Allow replying to deleted messages.
This commit is contained in:
parent
0e4d609bbf
commit
8a4866cb62
@ -5,28 +5,16 @@
|
||||
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 android.widget.Toast
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
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.typeface.library.szkolny.font.SzkolnyFont
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import kotlinx.coroutines.*
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
@ -34,9 +22,6 @@ import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
|
||||
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent.Companion.TYPE_FINISHED
|
||||
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent.Companion.TYPE_PROGRESS
|
||||
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
|
||||
@ -47,14 +32,9 @@ import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||
import pl.szczodrzynski.edziennik.databinding.MessageFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.utils.Anim
|
||||
import pl.szczodrzynski.edziennik.utils.BetterLink
|
||||
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
|
||||
|
||||
@ -72,7 +52,6 @@ class MessageFragment : Fragment(), CoroutineScope {
|
||||
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
|
||||
@ -238,9 +217,9 @@ class MessageFragment : Fragment(), CoroutineScope {
|
||||
|
||||
b.subject.text = message.subject
|
||||
|
||||
b.replyButton.isVisible = message.type == TYPE_RECEIVED
|
||||
b.replyButton.isVisible = message.type == TYPE_RECEIVED || message.type == TYPE_DELETED
|
||||
b.deleteButton.isVisible = message.type == TYPE_RECEIVED
|
||||
if (message.type == TYPE_RECEIVED) {
|
||||
if (message.type == TYPE_RECEIVED || message.type == TYPE_DELETED) {
|
||||
activity.navView.apply {
|
||||
bottomBar.apply {
|
||||
fabEnable = true
|
||||
@ -291,173 +270,21 @@ class MessageFragment : Fragment(), CoroutineScope {
|
||||
MessagesFragment.pageSelection = min(message.type, 1)
|
||||
}
|
||||
|
||||
private val attachmentOnClick = { v: View ->
|
||||
if (v.tag is Int) {
|
||||
downloadAttachment(v.tag as Int)
|
||||
}
|
||||
}
|
||||
|
||||
private val attachmentOnLongClick = { v: View ->
|
||||
(v.tag as? Int)?.let { tag ->
|
||||
val popupMenu = PopupMenu(v.context, v)
|
||||
popupMenu.menu.add(0, tag, 0, R.string.messages_attachment_download_again)
|
||||
popupMenu.setOnMenuItemClickListener {
|
||||
downloadAttachment(it.itemId, forceDownload = true)
|
||||
true
|
||||
}
|
||||
popupMenu.show()
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
private fun showAttachments() {
|
||||
if (message.attachmentIds != null) {
|
||||
val insertPoint = b.attachments
|
||||
insertPoint.removeAllViews()
|
||||
|
||||
val chipLayoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
chipLayoutParams.setMargins(0, 8.dp, 0, 0)
|
||||
|
||||
val progressLayoutParams = FrameLayout.LayoutParams(18.dp, 18.dp)
|
||||
progressLayoutParams.setMargins(8.dp, 0, 8.dp, 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?.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)
|
||||
|
||||
val attachmentChip = Chip(attachmentLayout.context)
|
||||
//attachmentChip.setChipBackgroundColorResource(ThemeUtils.getChipColorRes());
|
||||
attachmentChip.layoutParams = chipLayoutParams
|
||||
attachmentChip.chipMinHeight = 40.dp.toFloat()
|
||||
//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
|
||||
val icon: IIcon = when (Utils.getExtensionFromFileName(name)) {
|
||||
"doc", "docx", "odt", "rtf" -> SzkolnyFont.Icon.szf_file_word_outline
|
||||
"xls", "xlsx", "ods" -> SzkolnyFont.Icon.szf_file_excel_outline
|
||||
"ppt", "pptx", "odp" -> SzkolnyFont.Icon.szf_file_powerpoint_outline
|
||||
"pdf" -> SzkolnyFont.Icon.szf_file_pdf_outline
|
||||
"mp3", "wav", "aac" -> SzkolnyFont.Icon.szf_file_music_outline
|
||||
"mp4", "avi", "3gp", "mkv", "flv" -> SzkolnyFont.Icon.szf_file_video_outline
|
||||
"jpg", "jpeg", "png", "bmp", "gif" -> SzkolnyFont.Icon.szf_file_image_outline
|
||||
"zip", "rar", "tar", "7z" -> SzkolnyFont.Icon.szf_zip_box_outline
|
||||
"html", "cpp", "c", "h", "css", "java", "py" -> SzkolnyFont.Icon.szf_file_code_outline
|
||||
else -> CommunityMaterial.Icon.cmd_file_document_outline
|
||||
}
|
||||
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.onClick(attachmentOnClick)
|
||||
attachmentChip.onLongClick(attachmentOnLongClick)
|
||||
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
|
||||
if (message.attachmentIds.isNullOrEmpty() || message.attachmentNames.isNullOrEmpty()) {
|
||||
b.attachmentsTitle.isVisible = false
|
||||
b.attachmentsFragment.isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun downloadAttachment(index: Int, forceDownload: Boolean = false) {
|
||||
val attachment = attachmentList[index]
|
||||
|
||||
if (!forceDownload && attachment.downloaded != null) {
|
||||
Utils.openFile(activity, File(attachment.downloaded))
|
||||
return
|
||||
}
|
||||
|
||||
attachment.chip.isEnabled = false
|
||||
attachment.chip.setTextColor(Themes.getSecondaryTextColor(activity))
|
||||
attachment.progressBar.visibility = View.VISIBLE
|
||||
|
||||
EdziennikTask.attachmentGet(
|
||||
App.profileId,
|
||||
message,
|
||||
attachment.attachmentId,
|
||||
attachment.attachmentName
|
||||
).enqueue(activity)
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||
fun onAttachmentGetEvent(event: AttachmentGetEvent) {
|
||||
EventBus.getDefault().removeStickyEvent(event)
|
||||
attachmentList.firstOrNull { it.profileId == event.profileId
|
||||
&& it.messageId == event.ownerId
|
||||
&& it.attachmentId == event.attachmentId }?.let { attachment ->
|
||||
|
||||
when (event.eventType) {
|
||||
TYPE_FINISHED -> {
|
||||
// save the downloaded file name
|
||||
attachment.downloaded = event.fileName
|
||||
|
||||
// set the correct name (and size)
|
||||
if (attachment.attachmentSize == -1L)
|
||||
attachment.chip.text = getString(R.string.messages_attachment_no_size_format, attachment.attachmentName)
|
||||
else
|
||||
attachment.chip.text = getString(R.string.messages_attachment_format, attachment.attachmentName, readableFileSize(attachment.attachmentSize))
|
||||
|
||||
// hide the progress bar and show a tick icon
|
||||
attachment.progressBar.visibility = View.GONE
|
||||
attachment.chip.isEnabled = true
|
||||
attachment.chip.setTextColor(Themes.getPrimaryTextColor(activity))
|
||||
attachment.chip.isCloseIconVisible = true
|
||||
|
||||
// open the file
|
||||
Utils.openFile(activity, File(attachment.downloaded))
|
||||
}
|
||||
|
||||
TYPE_PROGRESS -> {
|
||||
attachment.chip.text = getString(R.string.messages_attachment_downloading_format, attachment.attachmentName, event.bytesWritten.toFloat() / 1000000)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
else {
|
||||
b.attachmentsTitle.isVisible = true
|
||||
b.attachmentsFragment.isVisible = true
|
||||
b.attachmentsFragment.init(Bundle().also {
|
||||
it.putInt("profileId", message.profileId)
|
||||
it.putLongArray("attachmentIds", message.attachmentIds!!.toLongArray())
|
||||
it.putStringArray("attachmentNames", message.attachmentNames!!.toTypedArray())
|
||||
//if (message.attachmentSizes.isNotNullNorEmpty())
|
||||
// it.putLongArray("attachmentSizes", message.attachmentSizes!!.toLongArray())
|
||||
}, owner = message)
|
||||
}
|
||||
}
|
||||
|
||||
@ -473,20 +300,4 @@ class MessageFragment : Fragment(), CoroutineScope {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ class MessagesListFragment : LazyFragment(), CoroutineScope {
|
||||
(b.list.layoutManager as? LinearLayoutManager)?.let { layoutManager ->
|
||||
if (topPosition != NO_POSITION && topPosition > layoutManager.findLastCompletelyVisibleItemPosition()) {
|
||||
b.list.scrollToPosition(topPosition)
|
||||
} else if (bottomPosition != NO_POSITION && bottomPosition < layoutManager.findFirstCompletelyVisibleItemPosition()) {
|
||||
} else if (bottomPosition != NO_POSITION && bottomPosition < layoutManager.findFirstVisibleItemPosition()) {
|
||||
b.list.scrollToPosition(bottomPosition)
|
||||
}
|
||||
topPosition = NO_POSITION
|
||||
@ -121,7 +121,7 @@ class MessagesListFragment : LazyFragment(), CoroutineScope {
|
||||
super.onDestroy()
|
||||
if (!isAdded) return
|
||||
onPageDestroy?.invoke(position, Bundle(
|
||||
"topPosition" to (b.list.layoutManager as? LinearLayoutManager)?.findFirstCompletelyVisibleItemPosition(),
|
||||
"topPosition" to (b.list.layoutManager as? LinearLayoutManager)?.findFirstVisibleItemPosition(),
|
||||
"bottomPosition" to (b.list.layoutManager as? LinearLayoutManager)?.findLastCompletelyVisibleItemPosition()
|
||||
))
|
||||
}
|
||||
|
@ -179,71 +179,12 @@
|
||||
android:text="Załączniki:"
|
||||
android:textAppearance="@style/NavView.TextView.Subtitle" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/attachments"
|
||||
<pl.szczodrzynski.edziennik.ui.modules.views.AttachmentsView
|
||||
android:id="@+id/attachmentsFragment"
|
||||
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" />
|
||||
|
||||
<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>
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
Loading…
Reference in New Issue
Block a user