mirror of
https://github.com/bitfireAT/davx5-ose
synced 2024-10-15 15:59:18 +00:00
Rewrite WebdavMountsActivity
to Compose (#607)
* Migrated to Compose Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me> * Text hides when there are mounts Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me> * Fixed todo Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me> * Migrated to Compose Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me> * Text hides when there are mounts Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me> * Fixed todo Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me> * Removed vertical scroll Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me> * Added action for ClickableText Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me> * Fixed indentation Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me> * Changed layout Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me> * Removed overflow preferences Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me> * Fixed padding Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me> * Changed link color Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me> * Fixed preview Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me> * Fixed back arrow Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me> * Require explicit Context for helpUrl to make it work in Compose preview --------- Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me> Co-authored-by: Ricki Hirner <hirner@bitfire.at>
This commit is contained in:
parent
7e743f2dbd
commit
2e669812b1
|
@ -161,9 +161,9 @@
|
|||
|
||||
<activity
|
||||
android:name=".ui.webdav.WebdavMountsActivity"
|
||||
android:label="@string/webdav_mounts_title"
|
||||
android:exported="true"
|
||||
android:parentActivityName=".ui.AccountsActivity"
|
||||
android:exported="true" />
|
||||
android:theme="@style/AppTheme.NoActionBar" />
|
||||
<activity
|
||||
android:name=".ui.webdav.AddWebdavMountActivity"
|
||||
android:label="@string/webdav_add_mount_title"
|
||||
|
|
|
@ -22,6 +22,7 @@ import androidx.annotation.DrawableRes
|
|||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.browser.customtabs.CustomTabsClient
|
||||
import androidx.compose.material.LocalTextStyle
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
||||
|
@ -154,7 +155,10 @@ object UiUtils {
|
|||
start = start, end = end
|
||||
)
|
||||
addStyle(
|
||||
style.copy(textDecoration = TextDecoration.Underline),
|
||||
style.copy(
|
||||
textDecoration = TextDecoration.Underline,
|
||||
color = MaterialTheme.colors.secondary
|
||||
),
|
||||
start = start, end = end
|
||||
)
|
||||
}
|
||||
|
|
|
@ -4,81 +4,98 @@
|
|||
|
||||
package at.bitfire.davdroid.ui.webdav
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.provider.DocumentsContract
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.text.ClickableText
|
||||
import androidx.compose.material.AlertDialog
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.FloatingActionButton
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.LinearProgressIndicator
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.material.TopAppBar
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.automirrored.filled.Help
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.ExperimentalTextApi
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.app.ShareCompat
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.MediatorLiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import at.bitfire.davdroid.App
|
||||
import at.bitfire.davdroid.R
|
||||
import at.bitfire.davdroid.databinding.ActivityWebdavMountsBinding
|
||||
import at.bitfire.davdroid.databinding.WebdavMountsItemBinding
|
||||
import at.bitfire.davdroid.db.AppDatabase
|
||||
import at.bitfire.davdroid.db.WebDavDocument
|
||||
import at.bitfire.davdroid.db.WebDavMount
|
||||
import at.bitfire.davdroid.log.Logger
|
||||
import at.bitfire.davdroid.ui.UiUtils
|
||||
import at.bitfire.davdroid.ui.UiUtils.toAnnotatedString
|
||||
import at.bitfire.davdroid.ui.widget.SafeAndroidUriHandler
|
||||
import at.bitfire.davdroid.util.DavUtils
|
||||
import at.bitfire.davdroid.webdav.CredentialsStore
|
||||
import at.bitfire.davdroid.webdav.DavDocumentsProvider
|
||||
import com.google.accompanist.themeadapter.material.MdcTheme
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.HttpUrl
|
||||
import org.apache.commons.io.FileUtils
|
||||
import java.util.logging.Level
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
@AndroidEntryPoint
|
||||
class WebdavMountsActivity: AppCompatActivity() {
|
||||
|
||||
private lateinit var binding: ActivityWebdavMountsBinding
|
||||
companion object {
|
||||
|
||||
fun helpUrl(context: Context) =
|
||||
App.homepageUrl(context).buildUpon()
|
||||
.appendEncodedPath("manual/webdav_mounts.html")
|
||||
.build()
|
||||
|
||||
}
|
||||
|
||||
private val model by viewModels<Model>()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
binding = ActivityWebdavMountsBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
binding.webdavMountsSeeManual.text = HtmlCompat.fromHtml(getString(R.string.webdav_add_mount_empty_more_info, helpUrl()), 0)
|
||||
binding.webdavMountsSeeManual.movementMethod = LinkMovementMethod.getInstance()
|
||||
|
||||
val adapter = MountsAdapter(this, model)
|
||||
binding.list.adapter = adapter
|
||||
binding.list.layoutManager = LinearLayoutManager(this)
|
||||
model.mountInfos.observe(this, { mounts ->
|
||||
adapter.submitList(ArrayList(mounts))
|
||||
|
||||
val hasMounts = mounts.isNotEmpty()
|
||||
binding.list.visibility = if (hasMounts) View.VISIBLE else View.GONE
|
||||
binding.empty.visibility = if (hasMounts) View.GONE else View.VISIBLE
|
||||
})
|
||||
|
||||
val browser = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
private val browser = registerForActivityResult(StartActivityForResult()) { result ->
|
||||
result.data?.data?.let { uri ->
|
||||
ShareCompat.IntentBuilder(this)
|
||||
.setType(DavUtils.MIME_TYPE_ACCEPT_ALL)
|
||||
|
@ -86,40 +103,273 @@ class WebdavMountsActivity: AppCompatActivity() {
|
|||
.startChooser()
|
||||
}
|
||||
}
|
||||
model.browseIntent.observe(this, { intent ->
|
||||
if (intent != null)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContent {
|
||||
MdcTheme {
|
||||
CompositionLocalProvider(
|
||||
LocalUriHandler provides SafeAndroidUriHandler(this)
|
||||
) {
|
||||
val mountInfos by model.mountInfos.observeAsState(emptyList())
|
||||
|
||||
WebdavMountsContent(mountInfos)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
fun WebdavMountsContent(mountInfos: List<MountInfo>) {
|
||||
val context = LocalContext.current
|
||||
val uriHandler = LocalUriHandler.current
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
navigationIcon = {
|
||||
IconButton(
|
||||
onClick = ::finish
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
},
|
||||
title = { Text(stringResource(R.string.webdav_mounts_title)) },
|
||||
actions = {
|
||||
IconButton(
|
||||
onClick = { uriHandler.openUri(helpUrl(context).toString()) }
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.Help,
|
||||
contentDescription = stringResource(R.string.help)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
floatingActionButton = {
|
||||
FloatingActionButton(
|
||||
onClick = { startActivity(Intent(this, AddWebdavMountActivity::class.java)) }
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Add,
|
||||
contentDescription = stringResource(R.string.webdav_add_mount_add)
|
||||
)
|
||||
}
|
||||
}
|
||||
) { paddingValues ->
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
if (mountInfos.isEmpty()) {
|
||||
HintText()
|
||||
} else {
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp)
|
||||
.padding(paddingValues)
|
||||
) {
|
||||
items(mountInfos, key = { it.mount.id }, contentType = { "mount" }) {
|
||||
WebdavMountsItem(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@OptIn(ExperimentalTextApi::class)
|
||||
fun HintText() {
|
||||
val context = LocalContext.current
|
||||
val uriHandler = LocalUriHandler.current
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.webdav_mounts_empty),
|
||||
style = MaterialTheme.typography.h6,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 16.dp)
|
||||
)
|
||||
|
||||
val text = HtmlCompat.fromHtml(
|
||||
stringResource(
|
||||
R.string.webdav_add_mount_empty_more_info,
|
||||
helpUrl(context).toString()
|
||||
),
|
||||
0
|
||||
).toAnnotatedString()
|
||||
ClickableText(
|
||||
text = text,
|
||||
style = MaterialTheme.typography.body1,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = { position ->
|
||||
text.getUrlAnnotations(position, position + 1)
|
||||
.firstOrNull()
|
||||
?.let { uriHandler.openUri(it.item.url) }
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun WebdavMountsItem(info: MountInfo) {
|
||||
var showingDialog by remember { mutableStateOf(false) }
|
||||
if (showingDialog) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { showingDialog = false },
|
||||
title = { Text(stringResource(R.string.webdav_remove_mount_title)) },
|
||||
text = { Text(stringResource(R.string.webdav_remove_mount_text)) },
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
Logger.log.log(Level.INFO, "User removes mount point", info.mount)
|
||||
model.remove(info.mount)
|
||||
}
|
||||
) {
|
||||
Text(stringResource(R.string.dialog_remove))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(
|
||||
onClick = { showingDialog = false }
|
||||
) {
|
||||
Text(stringResource(R.string.dialog_deny))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp),
|
||||
backgroundColor = MaterialTheme.colors.onSecondary
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = info.mount.name,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 8.dp),
|
||||
style = MaterialTheme.typography.body1
|
||||
)
|
||||
Text(
|
||||
text = info.mount.url.toString(),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 8.dp),
|
||||
style = MaterialTheme.typography.caption
|
||||
)
|
||||
|
||||
val quotaUsed = info.rootDocument?.quotaUsed
|
||||
val quotaAvailable = info.rootDocument?.quotaAvailable
|
||||
if (quotaUsed != null && quotaAvailable != null) {
|
||||
val quotaTotal = quotaUsed + quotaAvailable
|
||||
val progress = quotaUsed.toFloat() / quotaTotal
|
||||
LinearProgressIndicator(
|
||||
progress = progress,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 12.dp)
|
||||
)
|
||||
Text(
|
||||
text = stringResource(
|
||||
R.string.webdav_mounts_quota_used_available,
|
||||
FileUtils.byteCountToDisplaySize(quotaUsed),
|
||||
FileUtils.byteCountToDisplaySize(quotaAvailable)
|
||||
),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
TextButton(
|
||||
onClick = {
|
||||
val authority = getString(R.string.webdav_authority)
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
type = "*/*"
|
||||
}
|
||||
val uri = DocumentsContract.buildRootUri(authority, info.mount.id.toString())
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri)
|
||||
}
|
||||
browser.launch(intent)
|
||||
})
|
||||
|
||||
binding.add.setOnClickListener {
|
||||
startActivity(Intent(this, AddWebdavMountActivity::class.java))
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.webdav_mounts_share_content).uppercase()
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.weight(1f))
|
||||
IconButton(
|
||||
onClick = { showingDialog = true }
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Delete,
|
||||
contentDescription = stringResource(R.string.webdav_mounts_unmount)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addMenuProvider(object : MenuProvider {
|
||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||
menuInflater.inflate(R.menu.activity_webdav_mounts, menu)
|
||||
@Preview(showBackground = true, showSystemUi = true)
|
||||
@Composable
|
||||
fun WebdavMountsContent_Preview() {
|
||||
MdcTheme {
|
||||
WebdavMountsContent(emptyList())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||
return when (menuItem.itemId) {
|
||||
R.id.help -> {
|
||||
onShowHelp()
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun onShowHelp() {
|
||||
UiUtils.launchUri(this, helpUrl())
|
||||
}
|
||||
|
||||
private fun helpUrl() =
|
||||
App.homepageUrl(this).buildUpon()
|
||||
.appendEncodedPath("manual/webdav_mounts.html")
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun WebdavMountsItem_Preview() {
|
||||
MdcTheme {
|
||||
WebdavMountsItem(
|
||||
info = MountInfo(
|
||||
mount = WebDavMount(
|
||||
id = 0,
|
||||
name = "Preview Webdav Mount",
|
||||
url = HttpUrl.Builder()
|
||||
.scheme("https")
|
||||
.host("example.com")
|
||||
.build()
|
||||
),
|
||||
rootDocument = WebDavDocument(
|
||||
mountId = 0,
|
||||
parentId = null,
|
||||
name = "Root",
|
||||
quotaAvailable = 1024 * 1024 * 1024,
|
||||
quotaUsed = 512 * 1024 * 1024
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
data class MountInfo(
|
||||
|
@ -127,76 +377,6 @@ class WebdavMountsActivity: AppCompatActivity() {
|
|||
val rootDocument: WebDavDocument?
|
||||
)
|
||||
|
||||
class MountsAdapter(
|
||||
val context: Context,
|
||||
val model: Model
|
||||
): ListAdapter<MountInfo, MountsAdapter.ViewHolder>(object: DiffUtil.ItemCallback<MountInfo>() {
|
||||
override fun areItemsTheSame(oldItem: MountInfo, newItem: MountInfo) =
|
||||
oldItem.mount.id == newItem.mount.id
|
||||
override fun areContentsTheSame(oldItem: MountInfo, newItem: MountInfo) =
|
||||
oldItem.mount.name == newItem.mount.name && oldItem.mount.url == newItem.mount.url &&
|
||||
oldItem.rootDocument?.quotaUsed == newItem.rootDocument?.quotaUsed &&
|
||||
oldItem.rootDocument?.quotaAvailable == newItem.rootDocument?.quotaAvailable
|
||||
}) {
|
||||
class ViewHolder(val binding: WebdavMountsItemBinding): RecyclerView.ViewHolder(binding.root)
|
||||
|
||||
val authority = context.getString(R.string.webdav_authority)
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
val binding = WebdavMountsItemBinding.inflate(inflater, parent, false)
|
||||
|
||||
return ViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val info = getItem(position)
|
||||
val binding = holder.binding
|
||||
binding.name.text = info.mount.name
|
||||
binding.url.text = info.mount.url.toString()
|
||||
|
||||
val quotaUsed = info.rootDocument?.quotaUsed
|
||||
val quotaAvailable = info.rootDocument?.quotaAvailable
|
||||
if (quotaUsed != null && quotaAvailable != null) {
|
||||
val quotaTotal = quotaUsed + quotaAvailable
|
||||
|
||||
binding.quotaProgress.visibility = View.VISIBLE
|
||||
binding.quotaProgress.progress = (quotaUsed*100 / quotaTotal).toInt()
|
||||
|
||||
binding.quota.visibility = View.VISIBLE
|
||||
binding.quota.text = context.getString(R.string.webdav_mounts_quota_used_available,
|
||||
FileUtils.byteCountToDisplaySize(quotaUsed),
|
||||
FileUtils.byteCountToDisplaySize(quotaAvailable)
|
||||
)
|
||||
} else {
|
||||
binding.quotaProgress.visibility = View.GONE
|
||||
binding.quota.visibility = View.GONE
|
||||
}
|
||||
|
||||
binding.browse.setOnClickListener {
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
intent.type = "*/*"
|
||||
val uri = DocumentsContract.buildRootUri(authority, info.mount.id.toString())
|
||||
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri)
|
||||
model.browseIntent.value = intent
|
||||
model.browseIntent.value = null
|
||||
}
|
||||
|
||||
binding.removeMountpoint.setOnClickListener {
|
||||
AlertDialog.Builder(context)
|
||||
.setTitle(R.string.webdav_remove_mount_title)
|
||||
.setMessage(R.string.webdav_remove_mount_text)
|
||||
.setPositiveButton(R.string.dialog_remove) { _, _ ->
|
||||
Logger.log.log(Level.INFO, "User removes mount point", info.mount)
|
||||
model.remove(info.mount)
|
||||
}
|
||||
.setNegativeButton(R.string.dialog_deny, null)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@HiltViewModel
|
||||
class Model @Inject constructor(
|
||||
|
@ -241,8 +421,6 @@ class WebdavMountsActivity: AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
val browseIntent = MutableLiveData<Intent>()
|
||||
|
||||
/**
|
||||
* Removes the mountpoint (deleting connection information)
|
||||
*/
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/activity_margin">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_margin="@dimen/activity_margin">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/list"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/empty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
style="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
android:text="@string/webdav_mounts_empty" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/webdav_mounts_see_manual"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TextAppearance.MaterialComponents.Body1"
|
||||
android:text="@string/webdav_add_mount_empty_more_info" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/add"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/fab_margin"
|
||||
android:layout_gravity="right|end|bottom"
|
||||
android:contentDescription="@string/webdav_add_mount_add"
|
||||
app:srcCompat="@drawable/ic_add_white" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -1,87 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/activity_margin">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:backgroundTint="@color/colorOnSecondary">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_margin="@dimen/card_padding">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
style="@style/TextAppearance.MaterialComponents.Body1"
|
||||
android:layout_marginBottom="8dp"
|
||||
tools:text="My WebDAV Server" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/url"
|
||||
app:layout_constraintTop_toBottomOf="@id/name"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:ellipsize="middle"
|
||||
style="@style/TextAppearance.MaterialComponents.Caption"
|
||||
tools:text="https://www.example.com/" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/quota_progress"
|
||||
app:layout_constraintTop_toBottomOf="@id/url"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||
android:progress="50"
|
||||
android:progressTint="@color/primaryColor" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/quota"
|
||||
app:layout_constraintTop_toBottomOf="@id/quota_progress"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="Quota used: 50 GB / available: 50 GB"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/browse"
|
||||
app:layout_constraintTop_toBottomOf="@id/quota"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
android:text="@string/webdav_mounts_share_content" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/remove_mountpoint"
|
||||
app:layout_constraintTop_toTopOf="@id/browse"
|
||||
app:layout_constraintBottom_toBottomOf="@id/browse"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:srcCompat="@drawable/ic_remove"
|
||||
app:tint="?android:attr/colorControlNormal"
|
||||
android:backgroundTint="@color/colorOnSecondary"
|
||||
android:contentDescription="@string/webdav_mounts_unmount" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</LinearLayout>
|
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/help"
|
||||
android:icon="@drawable/ic_help"
|
||||
android:title="@string/help"
|
||||
app:showAsAction="always" />
|
||||
|
||||
</menu>
|
Loading…
Reference in a new issue