Convert FilesControlSet to compose

pull/1931/head
Alex Baker 2 years ago
parent 9b3f5a0c65
commit 3fa9040549

@ -10,39 +10,46 @@ import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.tasks.R
import org.tasks.compose.DisabledText
import org.tasks.compose.collectAsStateLifecycleAware
import org.tasks.data.TaskAttachment
import org.tasks.data.TaskAttachmentDao
import org.tasks.databinding.ControlSetFilesBinding
import org.tasks.dialogs.AddAttachmentDialog
import org.tasks.dialogs.DialogBuilder
import org.tasks.files.FileHelper
import org.tasks.preferences.Preferences
import org.tasks.ui.TaskEditControlFragment
import java.util.*
import org.tasks.ui.TaskEditControlComposeFragment
import javax.inject.Inject
@AndroidEntryPoint
class FilesControlSet : TaskEditControlFragment() {
@Inject lateinit var activity: Activity
class FilesControlSet : TaskEditControlComposeFragment() {
@Inject lateinit var taskAttachmentDao: TaskAttachmentDao
@Inject lateinit var dialogBuilder: DialogBuilder
@Inject lateinit var preferences: Preferences
private lateinit var attachmentContainer: LinearLayout
private lateinit var addAttachment: TextView
override fun createView(savedInstanceState: Bundle?) {
val task = viewModel.task!!
val task = viewModel.task
if (savedInstanceState == null) {
if (task.hasTransitory(TaskAttachment.KEY)) {
for (uri in (task.getTransitory<ArrayList<Uri>>(TaskAttachment.KEY))!!) {
@ -50,26 +57,53 @@ class FilesControlSet : TaskEditControlFragment() {
}
}
}
lifecycleScope.launch {
taskAttachmentDao
.getAttachments(task.uuid)
.forEach { addAttachment(it) }
}
}
private fun addAttachment() {
AddAttachmentDialog.newAddAttachmentDialog(this).show(parentFragmentManager, FRAG_TAG_ADD_ATTACHMENT_DIALOG)
AddAttachmentDialog.newAddAttachmentDialog(this)
.show(parentFragmentManager, FRAG_TAG_ADD_ATTACHMENT_DIALOG)
}
override fun bind(parent: ViewGroup?) =
ControlSetFilesBinding.inflate(layoutInflater, parent, true).let {
attachmentContainer = it.attachmentContainer
addAttachment = it.addAttachment.apply {
setOnClickListener { addAttachment() }
@Composable
override fun Body() {
val attachments =
taskAttachmentDao.watchAttachments(viewModel.task.uuid)
.collectAsStateLifecycleAware(initial = emptyList()).value
Column(
modifier = Modifier.padding(top = if (attachments.isEmpty()) 0.dp else 8.dp),
) {
attachments.forEach {
Row(
modifier = Modifier
.clickable { showFile(it) },
verticalAlignment = CenterVertically,
) {
Text(
text = it.name!!,
modifier = Modifier.weight(1f),
)
IconButton(onClick = { deleteAttachment(it) }) {
Icon(
imageVector = Icons.Outlined.Delete,
contentDescription = stringResource(
id = R.string.delete
)
)
}
}
}
it.root
DisabledText(
text = stringResource(id = R.string.add_attachment),
modifier = Modifier
.fillMaxWidth()
.clickable { addAttachment() }
.padding(
top = if (attachments.isEmpty()) 20.dp else 8.dp,
bottom = 20.dp,
)
)
}
}
override val icon = R.drawable.ic_outline_attachment_24px
@ -80,7 +114,7 @@ class FilesControlSet : TaskEditControlFragment() {
if (resultCode == Activity.RESULT_OK) {
val uri = data!!.data
copyToAttachmentDirectory(uri)
FileHelper.delete(activity, uri)
FileHelper.delete(requireContext(), uri)
}
} else if (requestCode == AddAttachmentDialog.REQUEST_STORAGE || requestCode == AddAttachmentDialog.REQUEST_GALLERY) {
if (resultCode == Activity.RESULT_OK) {
@ -99,34 +133,19 @@ class FilesControlSet : TaskEditControlFragment() {
}
}
private fun addAttachment(taskAttachment: TaskAttachment) {
val fileRow = requireActivity().layoutInflater.inflate(R.layout.file_row, attachmentContainer, false)
fileRow.tag = taskAttachment
attachmentContainer.addView(fileRow)
addAttachment(taskAttachment, fileRow)
}
private fun addAttachment(taskAttachment: TaskAttachment, fileRow: View) {
val nameView = fileRow.findViewById<TextView>(R.id.file_text)
val name = LEFT_TO_RIGHT_MARK.toString() + taskAttachment.name
nameView.text = name
nameView.setOnClickListener { showFile(taskAttachment) }
val clearFile = fileRow.findViewById<View>(R.id.clear)
clearFile.setOnClickListener {
dialogBuilder
.newDialog(R.string.premium_remove_file_confirm)
.setPositiveButton(R.string.ok) { _, _ ->
lifecycleScope.launch {
withContext(NonCancellable) {
taskAttachmentDao.delete(taskAttachment)
FileHelper.delete(context, taskAttachment.parseUri())
}
attachmentContainer.removeView(fileRow)
}
private fun deleteAttachment(attachment: TaskAttachment) {
dialogBuilder
.newDialog(R.string.premium_remove_file_confirm)
.setPositiveButton(R.string.ok) { _, _ ->
lifecycleScope.launch {
withContext(NonCancellable) {
taskAttachmentDao.delete(attachment)
FileHelper.delete(context, attachment.parseUri())
}
.setNegativeButton(R.string.cancel, null)
.show()
}
}
}
.setNegativeButton(R.string.cancel, null)
.show()
}
@SuppressLint("NewApi")
@ -140,18 +159,16 @@ class FilesControlSet : TaskEditControlFragment() {
private fun newAttachment(output: Uri) {
val attachment = TaskAttachment(
viewModel.task!!.uuid,
viewModel.task.uuid,
output,
FileHelper.getFilename(requireContext(), output)!!)
lifecycleScope.launch {
taskAttachmentDao.createNew(attachment)
addAttachment(attachment)
}
}
companion object {
const val TAG = R.string.TEA_ctrl_files_pref
private const val FRAG_TAG_ADD_ATTACHMENT_DIALOG = "frag_tag_add_attachment_dialog"
private const val LEFT_TO_RIGHT_MARK = '\u200e'
}
}

@ -3,6 +3,7 @@ package org.tasks.data
import androidx.room.*
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.helper.UUIDHelper
import kotlinx.coroutines.flow.Flow
@Dao
abstract class TaskAttachmentDao {
@ -15,6 +16,9 @@ abstract class TaskAttachmentDao {
@Query("SELECT * FROM task_attachments")
abstract suspend fun getAttachments(): List<TaskAttachment>
@Query("SELECT * FROM task_attachments WHERE task_id = :taskUuid")
abstract fun watchAttachments(taskUuid: String): Flow<List<TaskAttachment>>
@Delete
abstract suspend fun delete(taskAttachment: TaskAttachment)

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
** Copyright (c) 2012 Todoroo Inc
**
** See the file "LICENSE" for the full license governing this code.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/attachment_container"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="50"
android:layout_gravity="start"
android:gravity="start"
android:orientation="horizontal">
<TextView
android:id="@+id/add_attachment"
style="@style/TaskEditTextPrimary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:hint="@string/add_attachment"
android:textAlignment="viewStart"/>
</LinearLayout>
</LinearLayout>

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
** Copyright (c) 2012 Todoroo Inc
**
** See the file "LICENSE" for the full license governing this code.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/keyline_first">
<include layout="@layout/control_set_clear_button"/>
<TextView
android:id="@+id/file_text"
style="@android:style/TextAppearance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_gravity="start"
android:layout_toStartOf="@id/clear"
android:gravity="start"
android:textDirection="locale"
tools:ignore="UnusedAttribute"/>
</RelativeLayout>
Loading…
Cancel
Save