android: Ability to delete app files and media (#1072)

* Ability to delete app files and media

* section title, corrections

* remove icon

* change translation

* revert disabled unless stopped

Co-authored-by: JRoberts <8711996+jr-simplex@users.noreply.github.com>
This commit is contained in:
Stanislav Dmitrenko
2022-09-20 11:36:11 +03:00
committed by GitHub
parent 012115b330
commit 267207cc15
4 changed files with 82 additions and 2 deletions

View File

@@ -62,6 +62,7 @@ fun DatabaseView(
importArchiveAlert(m, context, uri, progressIndicator)
}
}
val appFilesCountAndSize = remember { mutableStateOf(directoryFileCountAndSize(getAppFilesDirectory(context))) }
LaunchedEffect(m.chatRunning) {
runChat.value = m.chatRunning.value ?: true
}
@@ -78,10 +79,12 @@ fun DatabaseView(
chatArchiveName,
chatArchiveTime,
chatLastStart,
appFilesCountAndSize,
startChat = { startChat(m, runChat, chatLastStart, m.chatDbChanged) },
stopChatAlert = { stopChatAlert(m, runChat, context) },
exportArchive = { exportArchive(context, m, progressIndicator, chatArchiveName, chatArchiveTime, chatArchiveFile, saveArchiveLauncher) },
deleteChatAlert = { deleteChatAlert(m, progressIndicator) },
deleteAppFilesAndMedia = { deleteFilesAndMediaAlert(context, appFilesCountAndSize) },
showSettingsModal
)
if (progressIndicator.value) {
@@ -112,10 +115,12 @@ fun DatabaseLayout(
chatArchiveName: MutableState<String?>,
chatArchiveTime: MutableState<Instant?>,
chatLastStart: MutableState<Instant?>,
appFilesCountAndSize: MutableState<Pair<Int, Long>>,
startChat: () -> Unit,
stopChatAlert: () -> Unit,
exportArchive: () -> Unit,
deleteChatAlert: () -> Unit,
deleteAppFilesAndMedia: () -> Unit,
showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit)
) {
val stopped = !runChat
@@ -196,6 +201,28 @@ fun DatabaseLayout(
stringResource(R.string.stop_chat_to_enable_database_actions)
}
)
SectionSpacer()
SectionView(stringResource(R.string.files_section)) {
val deleteFilesDisabled = operationsDisabled || appFilesCountAndSize.value.first == 0
SectionItemView(
deleteAppFilesAndMedia,
disabled = deleteFilesDisabled
) {
Text(
stringResource(R.string.delete_files_and_media),
color = if (deleteFilesDisabled) HighOrLowlight else Color.Red
)
}
}
val (count, size) = appFilesCountAndSize.value
SectionTextFooter(
if (count == 0) {
stringResource(R.string.no_received_app_files)
} else {
String.format(stringResource(R.string.total_files_count_and_size), count, formatBytes(size))
}
)
}
}
@@ -502,6 +529,21 @@ private fun deleteChat(m: ChatModel, progressIndicator: MutableState<Boolean>) {
}
}
private fun deleteFilesAndMediaAlert(context: Context, appFilesCountAndSize: MutableState<Pair<Int, Long>>) {
AlertManager.shared.showAlertDialog(
title = generalGetString(R.string.delete_files_and_media_question),
text = generalGetString(R.string.delete_files_and_media_desc),
confirmText = generalGetString(R.string.delete_verb),
onConfirm = { deleteFiles(appFilesCountAndSize, context) },
destructive = true
)
}
private fun deleteFiles(appFilesCountAndSize: MutableState<Pair<Int, Long>>, context: Context) {
deleteAppFiles(context)
appFilesCountAndSize.value = directoryFileCountAndSize(getAppFilesDirectory(context))
}
private fun operationEnded(m: ChatModel, progressIndicator: MutableState<Boolean>, alert: () -> Unit) {
m.chatDbChanged.value = true
progressIndicator.value = false
@@ -527,10 +569,12 @@ fun PreviewDatabaseLayout() {
chatArchiveName = remember { mutableStateOf("dummy_archive") },
chatArchiveTime = remember { mutableStateOf(Clock.System.now()) },
chatLastStart = remember { mutableStateOf(Clock.System.now()) },
appFilesCountAndSize = remember { mutableStateOf(0 to 0L) },
startChat = {},
stopChatAlert = {},
exportArchive = {},
deleteChatAlert = {},
deleteAppFilesAndMedia = {},
showSettingsModal = { {} }
)
}

View File

@@ -24,8 +24,7 @@ import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.*
import androidx.core.content.FileProvider
import androidx.core.text.HtmlCompat
import chat.simplex.app.BuildConfig
import chat.simplex.app.SimplexApp
import chat.simplex.app.*
import chat.simplex.app.model.CIFile
import kotlinx.coroutines.*
import java.io.*
@@ -405,6 +404,31 @@ fun removeFile(context: Context, fileName: String): Boolean {
return fileDeleted
}
fun deleteAppFiles(context: Context) {
val dir = File(getAppFilesDirectory(context))
try {
dir.list()?.forEach {
removeFile(context, it)
}
} catch (e: java.lang.Exception) {
Log.e(TAG, "Util deleteAppFiles error: ${e.stackTraceToString()}")
}
}
fun directoryFileCountAndSize(dir: String): Pair<Int, Long> { // count, size in bytes
var fileCount = 0
var bytes = 0L
try {
File(dir).listFiles()?.forEach {
fileCount++
bytes += it.length()
}
} catch (e: java.lang.Exception) {
Log.e(TAG, "Util directoryFileCountAndSize error: ${e.stackTraceToString()}")
}
return fileCount to bytes
}
fun ByteArray.toBase64String() = Base64.encodeToString(this, Base64.DEFAULT)
fun String.toByteArrayFromBase64() = Base64.decode(this, Base64.DEFAULT)

View File

@@ -556,6 +556,12 @@
<string name="restart_the_app_to_create_a_new_chat_profile">Перезапустите приложение, чтобы создать новый профиль.</string>
<string name="you_must_use_the_most_recent_version_of_database">Используйте самую последнюю версию архива чата и ТОЛЬКО на одном устройстве, иначе вы можете перестать получать сообщения от некоторых контактов.</string>
<string name="stop_chat_to_enable_database_actions">Остановите чат, чтобы разблокировать операции с архивом чата.</string>
<string name="files_section">ФАЙЛЫ</string>
<string name="delete_files_and_media">Удалить файлы и медиа</string>
<string name="delete_files_and_media_question">Удалить файлы и медиа?</string>
<string name="delete_files_and_media_desc">Это действие нельзя отменить — все полученные и отправленные файлы будут удалены. Изображения останутся в низком разрешении.</string>
<string name="no_received_app_files">Нет полученных или отправленных файлов</string>
<string name="total_files_count_and_size">%d файл(ов) общим размером %s</string>
<!-- DatabaseEncryptionView.kt -->
<string name="save_passphrase_in_keychain">Сохранить пароль в Keystore</string>

View File

@@ -557,6 +557,12 @@
<string name="restart_the_app_to_create_a_new_chat_profile">Restart the app to create a new chat profile.</string>
<string name="you_must_use_the_most_recent_version_of_database">You must use the most recent version of your chat database on one device ONLY, otherwise you may stop receiving the messages from some contacts.</string>
<string name="stop_chat_to_enable_database_actions">Stop chat to enable database actions.</string>
<string name="files_section">FILES</string>
<string name="delete_files_and_media">Delete files \&amp; media</string>
<string name="delete_files_and_media_question">Delete files and media?</string>
<string name="delete_files_and_media_desc">This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain.</string>
<string name="no_received_app_files">No received or sent files</string>
<string name="total_files_count_and_size">%d file(s) with total size of %s</string>
<!-- DatabaseEncryptionView.kt -->
<string name="save_passphrase_in_keychain">Save passphrase in Keystore</string>