diff --git a/app/src/main/java/com/bnyro/recorder/App.kt b/app/src/main/java/com/bnyro/recorder/App.kt index 9ee36a78..e2025d19 100644 --- a/app/src/main/java/com/bnyro/recorder/App.kt +++ b/app/src/main/java/com/bnyro/recorder/App.kt @@ -1,11 +1,16 @@ package com.bnyro.recorder import android.app.Application +import com.bnyro.recorder.util.FileRepository +import com.bnyro.recorder.util.FileRepositoryImpl import com.bnyro.recorder.util.NotificationHelper import com.bnyro.recorder.util.Preferences import com.bnyro.recorder.util.ShortcutHelper class App : Application() { + val fileRepository: FileRepository by lazy { + FileRepositoryImpl(this) + } override fun onCreate() { super.onCreate() Preferences.init(this) diff --git a/app/src/main/java/com/bnyro/recorder/enums/SortOrder.kt b/app/src/main/java/com/bnyro/recorder/enums/SortOrder.kt index d5ae5933..e7dea0ae 100644 --- a/app/src/main/java/com/bnyro/recorder/enums/SortOrder.kt +++ b/app/src/main/java/com/bnyro/recorder/enums/SortOrder.kt @@ -1,6 +1,7 @@ package com.bnyro.recorder.enums enum class SortOrder { + DEFAULT, ALPHABETIC, ALPHABETIC_REV, SIZE, diff --git a/app/src/main/java/com/bnyro/recorder/receivers/FinishedNotificationReceiver.kt b/app/src/main/java/com/bnyro/recorder/receivers/FinishedNotificationReceiver.kt index 0e0b4e95..08a890d3 100644 --- a/app/src/main/java/com/bnyro/recorder/receivers/FinishedNotificationReceiver.kt +++ b/app/src/main/java/com/bnyro/recorder/receivers/FinishedNotificationReceiver.kt @@ -4,15 +4,16 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import androidx.core.app.NotificationManagerCompat +import com.bnyro.recorder.App import com.bnyro.recorder.services.RecorderService import com.bnyro.recorder.util.IntentHelper import com.bnyro.recorder.util.NotificationHelper -import com.bnyro.recorder.util.StorageHelper class FinishedNotificationReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val fileName = intent.getStringExtra(RecorderService.FILE_NAME_EXTRA_KEY) ?: return - val file = StorageHelper.getOutputDir(context).findFile(fileName) + val file = (context.applicationContext as App).fileRepository + .getOutputDir().findFile(fileName) when (intent.getStringExtra(RecorderService.ACTION_EXTRA_KEY)) { RecorderService.SHARE_ACTION -> file?.let { IntentHelper.shareFile(context, it) } diff --git a/app/src/main/java/com/bnyro/recorder/services/AudioRecorderService.kt b/app/src/main/java/com/bnyro/recorder/services/AudioRecorderService.kt index ab22541a..25c52b8b 100644 --- a/app/src/main/java/com/bnyro/recorder/services/AudioRecorderService.kt +++ b/app/src/main/java/com/bnyro/recorder/services/AudioRecorderService.kt @@ -1,12 +1,12 @@ package com.bnyro.recorder.services +import com.bnyro.recorder.App import com.bnyro.recorder.R import com.bnyro.recorder.enums.AudioChannels import com.bnyro.recorder.enums.AudioDeviceSource import com.bnyro.recorder.obj.AudioFormat import com.bnyro.recorder.util.PlayerHelper import com.bnyro.recorder.util.Preferences -import com.bnyro.recorder.util.StorageHelper class AudioRecorderService : RecorderService() { override val notificationTitle: String @@ -38,8 +38,7 @@ class AudioRecorderService : RecorderService() { setOutputFormat(audioFormat.format) setAudioEncoder(audioFormat.codec) - outputFile = StorageHelper.getOutputFile( - this@AudioRecorderService, + outputFile = (application as App).fileRepository.getOutputFile( audioFormat.extension ) fileDescriptor = contentResolver.openFileDescriptor(outputFile!!.uri, "w") diff --git a/app/src/main/java/com/bnyro/recorder/services/LosslessRecorderService.kt b/app/src/main/java/com/bnyro/recorder/services/LosslessRecorderService.kt index 2ba04f63..5e779763 100644 --- a/app/src/main/java/com/bnyro/recorder/services/LosslessRecorderService.kt +++ b/app/src/main/java/com/bnyro/recorder/services/LosslessRecorderService.kt @@ -7,10 +7,10 @@ import android.media.MediaRecorder import android.os.Build import androidx.annotation.RequiresApi import androidx.documentfile.provider.DocumentFile +import com.bnyro.recorder.App import com.bnyro.recorder.R import com.bnyro.recorder.enums.RecorderState import com.bnyro.recorder.util.PcmConverter -import com.bnyro.recorder.util.StorageHelper import java.io.File import kotlin.concurrent.thread import kotlin.experimental.and @@ -110,9 +110,11 @@ class LosslessRecorderService : RecorderService() { private fun convertToWav() { val inputStream = contentResolver.openInputStream(outputFile?.uri ?: return) ?: return - val outputStream = StorageHelper.getOutputFile(this, FILE_NAME_EXTENSION_WAV).let { - contentResolver.openOutputStream(it.uri) ?: return - } + val outputStream = (application as App).fileRepository + .getOutputFile(FILE_NAME_EXTENSION_WAV) + .let { + contentResolver.openOutputStream(it.uri) ?: return + } pcmConverter?.convertToWave(inputStream, outputStream, BUFFER_SIZE_IN_BYTES) outputFile?.delete() } diff --git a/app/src/main/java/com/bnyro/recorder/services/ScreenRecorderService.kt b/app/src/main/java/com/bnyro/recorder/services/ScreenRecorderService.kt index ce57e48e..c2e6e1d6 100644 --- a/app/src/main/java/com/bnyro/recorder/services/ScreenRecorderService.kt +++ b/app/src/main/java/com/bnyro/recorder/services/ScreenRecorderService.kt @@ -13,6 +13,7 @@ import android.util.DisplayMetrics import android.util.Log import android.view.Display import androidx.activity.result.ActivityResult +import com.bnyro.recorder.App import com.bnyro.recorder.R import com.bnyro.recorder.enums.AudioChannels import com.bnyro.recorder.enums.AudioDeviceSource @@ -21,7 +22,6 @@ import com.bnyro.recorder.enums.VideoFormat import com.bnyro.recorder.obj.VideoResolution import com.bnyro.recorder.util.PlayerHelper import com.bnyro.recorder.util.Preferences -import com.bnyro.recorder.util.StorageHelper class ScreenRecorderService : RecorderService() { override val notificationTitle: String @@ -115,10 +115,8 @@ class ScreenRecorderService : RecorderService() { null ) - outputFile = StorageHelper.getOutputFile( - this@ScreenRecorderService, - videoFormat.extension - ) + outputFile = (application as App).fileRepository + .getOutputFile(videoFormat.extension) fileDescriptor = contentResolver.openFileDescriptor(outputFile!!.uri, "w") setOutputFile(fileDescriptor?.fileDescriptor) diff --git a/app/src/main/java/com/bnyro/recorder/ui/components/NamingPatternPref.kt b/app/src/main/java/com/bnyro/recorder/ui/components/NamingPatternPref.kt index 20fb9ea4..c69db8c8 100644 --- a/app/src/main/java/com/bnyro/recorder/ui/components/NamingPatternPref.kt +++ b/app/src/main/java/com/bnyro/recorder/ui/components/NamingPatternPref.kt @@ -14,8 +14,8 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.bnyro.recorder.R import com.bnyro.recorder.ui.common.DialogButton +import com.bnyro.recorder.util.FileRepositoryImpl import com.bnyro.recorder.util.Preferences -import com.bnyro.recorder.util.StorageHelper @Composable fun NamingPatternPref() { @@ -48,7 +48,7 @@ fun NamingPatternPref() { mutableStateOf( Preferences.getString( Preferences.namingPatternKey, - StorageHelper.DEFAULT_NAMING_PATTERN + FileRepositoryImpl.DEFAULT_NAMING_PATTERN ) ) } diff --git a/app/src/main/java/com/bnyro/recorder/ui/components/PlayerView.kt b/app/src/main/java/com/bnyro/recorder/ui/components/PlayerView.kt index 1b504d13..2d864762 100644 --- a/app/src/main/java/com/bnyro/recorder/ui/components/PlayerView.kt +++ b/app/src/main/java/com/bnyro/recorder/ui/components/PlayerView.kt @@ -14,31 +14,20 @@ import androidx.compose.material3.TabRow import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalView import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.bnyro.recorder.R -import com.bnyro.recorder.obj.RecordingItemData -import com.bnyro.recorder.ui.dialogs.ConfirmationDialog import com.bnyro.recorder.ui.models.PlayerModel import kotlinx.coroutines.launch @OptIn(ExperimentalFoundationApi::class) @Composable fun PlayerView( - showVideoModeInitially: Boolean, - showDeleteDialog: Boolean, - selectedFiles: MutableState>, - onDeleteAllDialogDismissed: () -> Unit + showVideoModeInitially: Boolean ) { - val playerModel: PlayerModel = viewModel() - val context = LocalContext.current - - LaunchedEffect(Unit) { - playerModel.loadFiles(context) - } + val playerModel: PlayerModel = viewModel(factory = PlayerModel.Factory) Column( modifier = Modifier.fillMaxSize() @@ -90,32 +79,15 @@ fun PlayerView( ) { index -> when (index) { 0 -> RecordingItemList( - items = playerModel.recordingItems.filter { it.isAudio }, - selectedFiles, + items = playerModel.audioRecordingItems, isVideoList = false ) 1 -> RecordingItemList( - items = playerModel.recordingItems.filter { it.isVideo }, - selectedFiles, + items = playerModel.screenRecordingItems, isVideoList = true ) } } } - - if (showDeleteDialog) { - ConfirmationDialog( - title = if (selectedFiles.value.isEmpty()) R.string.delete_all else R.string.delete, - onDismissRequest = onDeleteAllDialogDismissed - ) { - val filesToDelete = - selectedFiles.value.takeIf { it.isNotEmpty() } ?: playerModel.recordingItems - filesToDelete.forEach { - if (it.recordingFile.exists()) it.recordingFile.delete() - playerModel.recordingItems.remove(it) - selectedFiles.value -= it - } - } - } } diff --git a/app/src/main/java/com/bnyro/recorder/ui/components/RecordingItem.kt b/app/src/main/java/com/bnyro/recorder/ui/components/RecordingItem.kt index 8895ddb6..35919e21 100644 --- a/app/src/main/java/com/bnyro/recorder/ui/components/RecordingItem.kt +++ b/app/src/main/java/com/bnyro/recorder/ui/components/RecordingItem.kt @@ -51,7 +51,7 @@ fun RecordingItem( onClick: (wasLongClick: Boolean) -> Unit, startPlayingAudio: () -> Unit ) { - val playerModel: PlayerModel = viewModel() + val playerModel: PlayerModel = viewModel(factory = PlayerModel.Factory) val context = LocalContext.current val view = LocalView.current val haptic = LocalHapticFeedback.current @@ -215,9 +215,7 @@ fun RecordingItem( confirmButton = { DialogButton(stringResource(R.string.okay)) { recordingFile.renameTo(fileName) - val index = playerModel.files.indexOf(recordingFile) - playerModel.files.removeAt(index) - playerModel.files.add(index, recordingFile) + playerModel.loadFiles() showRenameDialog = false } }, @@ -236,7 +234,7 @@ fun RecordingItem( ) { playerModel.stopPlaying() recordingFile.delete() - playerModel.files.remove(recordingFile) + playerModel.loadFiles() } } diff --git a/app/src/main/java/com/bnyro/recorder/ui/components/RecordingItemList.kt b/app/src/main/java/com/bnyro/recorder/ui/components/RecordingItemList.kt index f43b924f..f266b0b4 100644 --- a/app/src/main/java/com/bnyro/recorder/ui/components/RecordingItemList.kt +++ b/app/src/main/java/com/bnyro/recorder/ui/components/RecordingItemList.kt @@ -16,7 +16,6 @@ import androidx.compose.material.icons.filled.VideoFile import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext @@ -30,7 +29,6 @@ import com.bnyro.recorder.ui.models.PlayerModel @Composable fun RecordingItemList( items: List, - selectedFiles: MutableState>, isVideoList: Boolean, playerModel: PlayerModel = viewModel() ) { @@ -46,15 +44,15 @@ fun RecordingItemList( items(items) { RecordingItem( it, - isSelected = selectedFiles.value.contains(it), + isSelected = playerModel.selectedFiles.contains(it), onClick = { wasLongPress -> when { - wasLongPress -> selectedFiles.value += it - selectedFiles.value.isNotEmpty() -> { - if (selectedFiles.value.contains(it)) { - selectedFiles.value -= it + wasLongPress -> playerModel.selectedFiles += it + playerModel.selectedFiles.isNotEmpty() -> { + if (playerModel.selectedFiles.contains(it)) { + playerModel.selectedFiles -= it } else { - selectedFiles.value += it + playerModel.selectedFiles += it } } } diff --git a/app/src/main/java/com/bnyro/recorder/ui/models/PlayerModel.kt b/app/src/main/java/com/bnyro/recorder/ui/models/PlayerModel.kt index 4ded9ac5..531ae214 100644 --- a/app/src/main/java/com/bnyro/recorder/ui/models/PlayerModel.kt +++ b/app/src/main/java/com/bnyro/recorder/ui/models/PlayerModel.kt @@ -1,85 +1,63 @@ package com.bnyro.recorder.ui.models import android.content.Context -import android.media.MediaMetadataRetriever import android.media.MediaPlayer -import android.provider.OpenableColumns import android.util.Log import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue -import androidx.compose.runtime.toMutableStateList import androidx.documentfile.provider.DocumentFile import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY import androidx.lifecycle.viewModelScope -import com.bnyro.recorder.enums.RecorderType +import androidx.lifecycle.viewmodel.initializer +import androidx.lifecycle.viewmodel.viewModelFactory +import com.bnyro.recorder.App import com.bnyro.recorder.enums.SortOrder import com.bnyro.recorder.obj.RecordingItemData +import com.bnyro.recorder.util.FileRepository import com.bnyro.recorder.util.PlayerHelper -import com.bnyro.recorder.util.StorageHelper import java.io.IOException -import kotlin.math.absoluteValue -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -class PlayerModel : ViewModel() { +class PlayerModel(private val fileRepository: FileRepository) : ViewModel() { var isPlaying by mutableStateOf(false) var player by mutableStateOf(null) var currentPlayingFile by mutableStateOf(null) - var files = mutableStateListOf() + var selectedFiles by mutableStateOf(listOf()) - val recordingItems = mutableStateListOf() + private var sortOrder = SortOrder.DEFAULT - fun loadFiles(context: Context) { + var audioRecordingItems by mutableStateOf(listOf()) + var screenRecordingItems by mutableStateOf(listOf()) + + init { + loadFiles() + } + + fun loadFiles() { viewModelScope.launch { - withContext(Dispatchers.IO) { - files = getAvailableFiles(context).toMutableStateList() - } - loadRecordingItems(context) + audioRecordingItems = fileRepository.getAudioRecordingItems(sortOrder) + screenRecordingItems = fileRepository.getVideoRecordingItems(sortOrder) } } - fun sortRecordingItems(context: Context, sortOrder: SortOrder) { - files = when (sortOrder) { - SortOrder.ALPHABETIC -> files.sortedBy { it.name } - SortOrder.ALPHABETIC_REV -> files.sortedByDescending { it.name } - SortOrder.SIZE_REV -> files.sortedBy { - context.contentResolver.query(it.uri, null, null, null, null)?.use { cursor -> - cursor.getLong(cursor.getColumnIndex(OpenableColumns.SIZE).absoluteValue) - } - } - - SortOrder.SIZE -> files.sortedByDescending { - context.contentResolver.query(it.uri, null, null, null, null)?.use { cursor -> - cursor.getLong(cursor.getColumnIndex(OpenableColumns.SIZE).absoluteValue) - } - } - }.toMutableStateList() - loadRecordingItems(context) + fun sortItems(newSortOrder: SortOrder) { + if (newSortOrder == sortOrder) return + sortOrder = newSortOrder + loadFiles() } - private fun loadRecordingItems(context: Context) { + fun deleteFiles() { viewModelScope.launch { - recordingItems.clear() - files.forEach { file -> - if (file.name.orEmpty() - .endsWith("mp4" /* Currently there are only mp4 video files*/) - ) { - val thumbnail = - MediaMetadataRetriever().apply { - setDataSource( - context, - file.uri - ) - }.frameAtTime - recordingItems.add(RecordingItemData(file, RecorderType.VIDEO, thumbnail)) - } else { - recordingItems.add(RecordingItemData(file, RecorderType.AUDIO)) - } + if (selectedFiles.isEmpty()) { + fileRepository.deleteAllFiles() + loadFiles() + return@launch } + fileRepository.deleteSelectedFiles(selectedFiles.map { it.recordingFile }) + loadFiles() } } @@ -121,13 +99,18 @@ class PlayerModel : ViewModel() { isPlaying = true } - private fun getAvailableFiles(context: Context): List { - return StorageHelper.getOutputDir(context).listFiles().filter { it.isFile }.toList() - } - private fun getMediaPlayer(): MediaPlayer { return MediaPlayer().apply { setAudioAttributes(PlayerHelper.getAudioAttributes()) } } + + companion object { + val Factory = viewModelFactory { + initializer { + val application = (this[APPLICATION_KEY] as App) + PlayerModel(application.fileRepository) + } + } + } } diff --git a/app/src/main/java/com/bnyro/recorder/ui/screens/PlayerScreen.kt b/app/src/main/java/com/bnyro/recorder/ui/screens/PlayerScreen.kt index 7cb6f5c3..d957ce3d 100644 --- a/app/src/main/java/com/bnyro/recorder/ui/screens/PlayerScreen.kt +++ b/app/src/main/java/com/bnyro/recorder/ui/screens/PlayerScreen.kt @@ -20,15 +20,14 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.bnyro.recorder.R import com.bnyro.recorder.enums.SortOrder -import com.bnyro.recorder.obj.RecordingItemData import com.bnyro.recorder.ui.common.ClickableIcon import com.bnyro.recorder.ui.components.PlayerView +import com.bnyro.recorder.ui.dialogs.ConfirmationDialog import com.bnyro.recorder.ui.models.PlayerModel @OptIn(ExperimentalMaterial3Api::class) @@ -42,10 +41,7 @@ fun PlayerScreen( var selectedSortOrder by remember { mutableStateOf(SortOrder.ALPHABETIC) } - val selectedFiles = remember { - mutableStateOf(listOf()) - } - val playerModel: PlayerModel = viewModel() + val playerModel: PlayerModel = viewModel(factory = PlayerModel.Factory) val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior( rememberTopAppBarState() @@ -71,43 +67,39 @@ fun PlayerScreen( } val sortOptions = listOf( - SortOrder.ALPHABETIC, - SortOrder.ALPHABETIC_REV, - SortOrder.SIZE, - SortOrder.SIZE_REV - ) - val sortOptionNames = listOf( - R.string.alphabetic, - R.string.alphabetic_rev, - R.string.size, - R.string.size_rev + SortOrder.DEFAULT to R.string.default_sort, + SortOrder.ALPHABETIC to R.string.alphabetic, + SortOrder.ALPHABETIC_REV to R.string.alphabetic_rev, + SortOrder.SIZE to R.string.size, + SortOrder.SIZE_REV to R.string.size_rev ) DropdownMenu(showDropDown, { showDropDown = false }) { - val context = LocalContext.current - sortOptions.forEachIndexed { index, sortOrder -> + sortOptions.forEach { sortOrder -> DropdownMenuItem( text = { - Text(stringResource(sortOptionNames[index])) + Text(stringResource(sortOrder.second)) }, onClick = { - selectedSortOrder = sortOrder - playerModel.sortRecordingItems(context, sortOrder) + selectedSortOrder = sortOrder.first + playerModel.sortItems(sortOrder.first) showDropDown = false } ) } } } - if (selectedFiles.value.isNotEmpty()) { - val selectedAll = selectedFiles.value.size == playerModel.files.size + if (playerModel.selectedFiles.isNotEmpty()) { + val selectedAll = + playerModel.selectedFiles.size == playerModel.audioRecordingItems.size + playerModel.screenRecordingItems.size Checkbox( modifier = Modifier.align(Alignment.CenterVertically), checked = selectedAll, onCheckedChange = { if (selectedAll) { - selectedFiles.value = listOf() + playerModel.selectedFiles = listOf() } else { - selectedFiles.value = playerModel.recordingItems + playerModel.selectedFiles = + playerModel.screenRecordingItems + playerModel.audioRecordingItems } } ) @@ -129,12 +121,17 @@ fun PlayerScreen( .padding(horizontal = 16.dp) ) { PlayerView( - showVideoModeInitially, - showDeleteDialog, - selectedFiles - ) { - showDeleteDialog = false - } + showVideoModeInitially + ) + } + } + + if (showDeleteDialog) { + ConfirmationDialog( + title = if (playerModel.selectedFiles.isEmpty()) R.string.delete_all else R.string.delete, + onDismissRequest = { showDeleteDialog = false } + ) { + playerModel.deleteFiles() } } } diff --git a/app/src/main/java/com/bnyro/recorder/util/FileRepository.kt b/app/src/main/java/com/bnyro/recorder/util/FileRepository.kt new file mode 100644 index 00000000..40ea77fd --- /dev/null +++ b/app/src/main/java/com/bnyro/recorder/util/FileRepository.kt @@ -0,0 +1,128 @@ +package com.bnyro.recorder.util + +import android.annotation.SuppressLint +import android.content.Context +import android.media.MediaMetadataRetriever +import android.net.Uri +import androidx.documentfile.provider.DocumentFile +import com.bnyro.recorder.enums.RecorderType +import com.bnyro.recorder.enums.SortOrder +import com.bnyro.recorder.obj.RecordingItemData +import java.text.SimpleDateFormat +import java.util.Calendar +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +interface FileRepository { + suspend fun getVideoRecordingItems(sortOrder: SortOrder): List + suspend fun getAudioRecordingItems(sortOrder: SortOrder): List + suspend fun deleteSelectedFiles(files: List) + suspend fun deleteAllFiles() + fun getOutputFile(extension: String): DocumentFile + fun getOutputDir(): DocumentFile +} + +class FileRepositoryImpl(val context: Context) : FileRepository { + + private fun getVideoFiles(): List = + getOutputDir().listFiles().filter { + it.isFile && it.name.orEmpty().endsWith("mp4") + } + + private fun getAudioFiles(): List = + getOutputDir().listFiles().filter { + it.isFile && !it.name.orEmpty().endsWith("mp4") + } + + override suspend fun getVideoRecordingItems(sortOrder: SortOrder): List { + val items = withContext(Dispatchers.IO) { + getVideoFiles().sortedBy(sortOrder).map { + val thumbnail = + MediaMetadataRetriever().apply { + setDataSource( + context, + it.uri + ) + }.frameAtTime + RecordingItemData(it, RecorderType.VIDEO, thumbnail) + } + } + return items + } + + override suspend fun getAudioRecordingItems(sortOrder: SortOrder): List { + val items = withContext(Dispatchers.IO) { + getAudioFiles().sortedBy(sortOrder).map { RecordingItemData(it, RecorderType.AUDIO) } + } + return items + } + + override suspend fun deleteSelectedFiles(files: List) { + withContext(Dispatchers.IO) { + files.forEach { + if (it.exists()) it.delete() + } + } + } + + override suspend fun deleteAllFiles() { + withContext(Dispatchers.IO) { + getOutputDir().listFiles().forEach { + if (it.isFile) it.delete() + } + } + } + + override fun getOutputFile(extension: String): DocumentFile { + val currentTimeMillis = Calendar.getInstance().time + val currentDateTime = dateTimeFormat.format(currentTimeMillis) + val currentDate = currentDateTime.split("_").first() + val currentTime = currentDateTime.split("_").last() + + val fileName = Preferences.getString( + Preferences.namingPatternKey, + DEFAULT_NAMING_PATTERN + ) + .replace("%d", currentDate) + .replace("%t", currentTime) + .replace("%m", currentTimeMillis.time.toString()) + .replace("%s", currentTimeMillis.time.div(1000).toString()) + + val recordingFile = getOutputDir().createFile("audio/*", "$fileName.$extension") + return recordingFile!! + } + + override fun getOutputDir(): DocumentFile { + val prefDir = Preferences.prefs.getString(Preferences.targetFolderKey, "") + val audioDir = when { + prefDir.isNullOrBlank() -> { + val dir = context.getExternalFilesDir(null) ?: context.filesDir + DocumentFile.fromFile(dir) + } + + else -> DocumentFile.fromTreeUri(context, Uri.parse(prefDir)) + } + return audioDir!! + } + + companion object { + @SuppressLint("SimpleDateFormat") + private val dateTimeFormat = SimpleDateFormat("yyyy-MM-dd_HH-mm-ss") + const val DEFAULT_NAMING_PATTERN = "%d_%t" + } +} + +fun List.sortedBy(sortOrder: SortOrder): List { + return when (sortOrder) { + SortOrder.DEFAULT -> this + SortOrder.ALPHABETIC -> sortedBy { it.name } + SortOrder.ALPHABETIC_REV -> sortedByDescending { it.name } + SortOrder.SIZE_REV -> sortedBy { + it.length() + } + + SortOrder.SIZE -> sortedByDescending { + it.length() + } + } +} diff --git a/app/src/main/java/com/bnyro/recorder/util/StorageHelper.kt b/app/src/main/java/com/bnyro/recorder/util/StorageHelper.kt deleted file mode 100644 index 077ae225..00000000 --- a/app/src/main/java/com/bnyro/recorder/util/StorageHelper.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.bnyro.recorder.util - -import android.annotation.SuppressLint -import android.content.Context -import android.net.Uri -import androidx.documentfile.provider.DocumentFile -import java.text.SimpleDateFormat -import java.util.Calendar - -object StorageHelper { - @SuppressLint("SimpleDateFormat") - private val dateTimeFormat = SimpleDateFormat("yyyy-MM-dd_HH-mm-ss") - const val DEFAULT_NAMING_PATTERN = "%d_%t" - - fun getOutputFile(context: Context, extension: String): DocumentFile { - val currentTimeMillis = Calendar.getInstance().time - val currentDateTime = dateTimeFormat.format(currentTimeMillis) - val currentDate = currentDateTime.split("_").first() - val currentTime = currentDateTime.split("_").last() - - val fileName = Preferences.getString(Preferences.namingPatternKey, DEFAULT_NAMING_PATTERN) - .replace("%d", currentDate) - .replace("%t", currentTime) - .replace("%m", currentTimeMillis.time.toString()) - .replace("%s", currentTimeMillis.time.div(1000).toString()) - - val recordingFile = getOutputDir(context).createFile("audio/*", "$fileName.$extension") - return recordingFile!! - } - - fun getOutputDir(context: Context): DocumentFile { - val prefDir = Preferences.prefs.getString(Preferences.targetFolderKey, "") - val audioDir = when { - prefDir.isNullOrBlank() -> { - val dir = context.getExternalFilesDir(null) ?: context.filesDir - DocumentFile.fromFile(dir) - } - else -> DocumentFile.fromTreeUri(context, Uri.parse(prefDir)) - } - return audioDir!! - } -} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5c087c35..f2ee7d96 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -67,4 +67,5 @@ Screen Record Annotation Show annotation tool during screen recording Amoled Dark + Default \ No newline at end of file