feat: Add VideoRecorderQualityTile

This commit is contained in:
Myzel394 2023-12-02 18:23:15 +01:00
parent 7cf2e14df2
commit e7989e2eba
No known key found for this signature in database
GPG Key ID: 79CC92F37B3E1A2B
4 changed files with 151 additions and 6 deletions

View File

@ -379,14 +379,21 @@ data class VideoRecorderSettings(
return copy(targetedVideoBitRate = bitRate)
}
fun setQuality(quality: String): VideoRecorderSettings {
return copy(quality = quality)
fun setQuality(quality: Quality?): VideoRecorderSettings {
val invertedMap = QUALITY_NAME_QUALITY_MAP.entries.associateBy({ it.value }, { it.key })
return copy(quality = quality?.let { invertedMap[it] })
}
fun setTargetFrameRate(frameRate: Int?): VideoRecorderSettings {
return copy(targetFrameRate = frameRate)
}
fun getQuality(): Quality? =
quality?.let {
QUALITY_NAME_QUALITY_MAP[it]!!
}
fun getQualitySelector(): QualitySelector? =
quality?.let {
QualitySelector.from(
@ -428,6 +435,19 @@ data class VideoRecorderSettings(
120,
240,
)
val AVAILABLE_QUALITIES = listOf(
Quality.HIGHEST,
Quality.UHD,
Quality.FHD,
Quality.HD,
Quality.SD,
Quality.LOWEST,
)
val EXAMPLE_QUALITY_VALUES = listOf(
null,
) + AVAILABLE_QUALITIES
}
}

View File

@ -0,0 +1,118 @@
package app.myzel394.alibi.ui.components.SettingsScreen.Tiles
import android.media.MediaRecorder
import androidx.camera.video.Quality
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.HighQuality
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import app.myzel394.alibi.R
import app.myzel394.alibi.dataStore
import app.myzel394.alibi.db.AppSettings
import app.myzel394.alibi.db.VideoRecorderSettings
import app.myzel394.alibi.ui.components.atoms.ExampleListRoulette
import app.myzel394.alibi.ui.components.atoms.SettingsTile
import app.myzel394.alibi.ui.utils.IconResource
import com.maxkeppeker.sheets.core.models.base.Header
import com.maxkeppeker.sheets.core.models.base.IconSource
import com.maxkeppeker.sheets.core.models.base.rememberUseCaseState
import com.maxkeppeler.sheets.input.models.InputHeader
import com.maxkeppeler.sheets.list.ListDialog
import com.maxkeppeler.sheets.list.models.ListOption
import com.maxkeppeler.sheets.list.models.ListSelection
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun VideoRecorderQualityTile(
settings: AppSettings,
) {
val QUALITY_NAME_TEXT_MAP = mapOf<Quality, String>(
Quality.HIGHEST to stringResource(R.string.ui_settings_value_videoQuality_values_highest),
Quality.UHD to stringResource(R.string.ui_settings_value_videoQuality_values_uhd),
Quality.FHD to stringResource(R.string.ui_settings_value_videoQuality_values_fhd),
Quality.HD to stringResource(R.string.ui_settings_value_videoQuality_values_hd),
Quality.SD to stringResource(R.string.ui_settings_value_videoQuality_values_sd),
Quality.LOWEST to stringResource(R.string.ui_settings_value_videoQuality_values_lowest),
)
val scope = rememberCoroutineScope()
val showDialog = rememberUseCaseState()
val dataStore = LocalContext.current.dataStore
fun updateValue(quality: Quality?) {
scope.launch {
dataStore.updateData {
it.setVideoRecorderSettings(
it.videoRecorderSettings.setQuality(quality)
)
}
}
}
ListDialog(
state = showDialog,
header = Header.Default(
title = stringResource(R.string.ui_settings_option_videoQualityTile_title),
icon = IconSource(
painter = IconResource.fromImageVector(Icons.Default.HighQuality)
.asPainterResource(),
contentDescription = null,
),
),
selection = ListSelection.Single(
showRadioButtons = true,
options = VideoRecorderSettings.AVAILABLE_QUALITIES.map { quality ->
ListOption(
titleText = QUALITY_NAME_TEXT_MAP[quality]!!,
selected = settings.videoRecorderSettings.quality == quality.toString(),
)
}.toList()
) { index, _ ->
val quality = VideoRecorderSettings.AVAILABLE_QUALITIES[index]
updateValue(quality)
},
)
SettingsTile(
title = stringResource(R.string.ui_settings_option_videoQualityTile_title),
leading = {
Icon(
Icons.Default.HighQuality,
contentDescription = null,
)
},
trailing = {
Button(
onClick = showDialog::show,
colors = ButtonDefaults.filledTonalButtonColors(
containerColor = MaterialTheme.colorScheme.surfaceVariant,
),
shape = MaterialTheme.shapes.medium,
) {
Text(
QUALITY_NAME_TEXT_MAP[settings.videoRecorderSettings.getQuality()]
?: stringResource(
R.string.ui_settings_value_auto_label
)
)
}
},
extra = {
ExampleListRoulette(
items = listOf(null),
onItemSelected = ::updateValue,
) {
Text(stringResource(R.string.ui_settings_value_auto_label))
}
},
)
}

View File

@ -38,11 +38,12 @@ import app.myzel394.alibi.R
import app.myzel394.alibi.dataStore
import app.myzel394.alibi.ui.SUPPORTS_DARK_MODE_NATIVELY
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.AboutTile
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.AudioRecorderEncoderTile
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.VideoRecorderFrameRateTile
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.CustomNotificationTile
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.DeleteRecordingsImmediatelyTile
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.DividerTitle
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.AudioRecorderEncoderTile
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.VideoRecorderQualityTile
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.ImportExport
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.InAppLanguagePicker
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.IntervalDurationTile
@ -158,13 +159,11 @@ fun SettingsScreen(
DividerTitle(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
.fillMaxWidth(),
title = stringResource(R.string.ui_settings_sections_audio_title),
description = stringResource(R.string.ui_settings_sections_audio_description),
)
AudioRecorderShowAllMicrophonesTile(settings = settings)
VideoRecorderFrameRateTile(settings = settings)
AudioRecorderSamplingRateTile(settings = settings)
AudioRecorderEncoderTile(
snackbarHostState = snackbarHostState,
@ -176,6 +175,7 @@ fun SettingsScreen(
title = stringResource(R.string.ui_settings_sections_video_title),
description = stringResource(R.string.ui_settings_sections_video_description),
)
VideoRecorderQualityTile(settings = settings)
VideoRecorderBitrateTile(settings = settings)
VideoRecorderFrameRateTile(settings = settings)
}

View File

@ -131,4 +131,11 @@
<string name="ui_settings_option_videoTargetedFrameRate_title">Targeted Frame Rate</string>
<string name="ui_settings_option_videoTargetedFrameRate_description">How many frames per second should be recorded.</string>
<string name="ui_settings_option_videoTargetedFrameRate_explanation">The actual frame rate may be different. This can for example happen if the device is not able to record with the specified frame rate.</string>
<string name="ui_settings_option_videoQualityTile_title">Quality</string>
<string name="ui_settings_value_videoQuality_values_highest">Highest</string>
<string name="ui_settings_value_videoQuality_values_uhd">Ultra HD</string>
<string name="ui_settings_value_videoQuality_values_fhd">Full HD</string>
<string name="ui_settings_value_videoQuality_values_hd">HD</string>
<string name="ui_settings_value_videoQuality_values_sd">Standard</string>
<string name="ui_settings_value_videoQuality_values_lowest">Lowest</string>
</resources>