Merge pull request #1443 from davotoula/capture-and-post-video
Capture and post video
This commit is contained in:
+3
-2
@@ -84,14 +84,15 @@ class MediaCompressor {
|
|||||||
val videoQuality =
|
val videoQuality =
|
||||||
when (mediaQuality) {
|
when (mediaQuality) {
|
||||||
CompressorQuality.VERY_LOW -> VideoQuality.VERY_LOW
|
CompressorQuality.VERY_LOW -> VideoQuality.VERY_LOW
|
||||||
CompressorQuality.LOW -> VideoQuality.LOW
|
// Override user selection LOW to use VERY_LOW for better video streaming experience
|
||||||
|
CompressorQuality.LOW -> VideoQuality.VERY_LOW
|
||||||
CompressorQuality.MEDIUM -> VideoQuality.MEDIUM
|
CompressorQuality.MEDIUM -> VideoQuality.MEDIUM
|
||||||
CompressorQuality.HIGH -> VideoQuality.HIGH
|
CompressorQuality.HIGH -> VideoQuality.HIGH
|
||||||
CompressorQuality.VERY_HIGH -> VideoQuality.VERY_HIGH
|
CompressorQuality.VERY_HIGH -> VideoQuality.VERY_HIGH
|
||||||
else -> VideoQuality.MEDIUM
|
else -> VideoQuality.MEDIUM
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d("MediaCompressor", "Using video compression $mediaQuality")
|
Log.d("MediaCompressor", "Using video compression $videoQuality")
|
||||||
|
|
||||||
val result =
|
val result =
|
||||||
withTimeoutOrNull(30000) {
|
withTimeoutOrNull(30000) {
|
||||||
|
|||||||
+106
-5
@@ -29,6 +29,7 @@ import androidx.activity.result.contract.ActivityResultContracts
|
|||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.CameraAlt
|
import androidx.compose.material.icons.filled.CameraAlt
|
||||||
|
import androidx.compose.material.icons.filled.Videocam
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
@@ -136,14 +137,114 @@ fun PictureButton(onClick: () -> Unit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPhotoUri(context: Context): Uri {
|
fun getPhotoUri(context: Context): Uri =
|
||||||
|
getMediaUri(
|
||||||
|
context = context,
|
||||||
|
filePrefix = "JPEG",
|
||||||
|
fileExtension = ".jpg",
|
||||||
|
storageDir = Environment.DIRECTORY_PICTURES,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TakeVideoButton(onVideoTaken: (ImmutableList<SelectedMedia>) -> Unit) {
|
||||||
|
var showCamera by remember { mutableStateOf(false) }
|
||||||
|
if (showCamera) {
|
||||||
|
TakeVideo(
|
||||||
|
onVideoTaken = { uri ->
|
||||||
|
showCamera = false
|
||||||
|
if (uri.isNotEmpty()) {
|
||||||
|
onVideoTaken(uri)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoButton { showCamera = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalPermissionsApi::class)
|
||||||
|
@Composable
|
||||||
|
fun TakeVideo(onVideoTaken: (ImmutableList<SelectedMedia>) -> Unit) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
var videoUri by remember { mutableStateOf<Uri?>(null) }
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
val launcher =
|
||||||
|
rememberLauncherForActivityResult(
|
||||||
|
contract = ActivityResultContracts.CaptureVideo(),
|
||||||
|
) { success ->
|
||||||
|
if (success) {
|
||||||
|
videoUri?.let {
|
||||||
|
onVideoTaken(persistentListOf(SelectedMedia(it, "video/mp4")))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
onVideoTaken(persistentListOf())
|
||||||
|
}
|
||||||
|
videoUri = null
|
||||||
|
}
|
||||||
|
|
||||||
|
val cameraPermissionState =
|
||||||
|
rememberPermissionState(
|
||||||
|
Manifest.permission.CAMERA,
|
||||||
|
onPermissionResult = {
|
||||||
|
if (it) {
|
||||||
|
scope.launch(Dispatchers.IO) {
|
||||||
|
videoUri = getVideoUri(context)
|
||||||
|
videoUri?.let { launcher.launch(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if (cameraPermissionState.status.isGranted) {
|
||||||
|
LaunchedEffect(key1 = Unit) {
|
||||||
|
launch(Dispatchers.IO) {
|
||||||
|
videoUri = getVideoUri(context)
|
||||||
|
videoUri?.let { launcher.launch(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LaunchedEffect(key1 = Unit) {
|
||||||
|
cameraPermissionState.launchPermissionRequest()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun VideoButton(onClick: () -> Unit) {
|
||||||
|
IconButton(
|
||||||
|
onClick = onClick,
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Videocam,
|
||||||
|
contentDescription = stringRes(id = R.string.record_a_video),
|
||||||
|
modifier = Modifier.height(22.dp),
|
||||||
|
tint = MaterialTheme.colorScheme.onBackground,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getVideoUri(context: Context): Uri =
|
||||||
|
getMediaUri(
|
||||||
|
context = context,
|
||||||
|
filePrefix = "MP4",
|
||||||
|
fileExtension = ".mp4",
|
||||||
|
storageDir = Environment.DIRECTORY_MOVIES,
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun getMediaUri(
|
||||||
|
context: Context,
|
||||||
|
filePrefix: String,
|
||||||
|
fileExtension: String,
|
||||||
|
storageDir: String,
|
||||||
|
): Uri {
|
||||||
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(Date())
|
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(Date())
|
||||||
val storageDir: File? = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
|
val storageDirectory: File? = context.getExternalFilesDir(storageDir)
|
||||||
return File
|
return File
|
||||||
.createTempFile(
|
.createTempFile(
|
||||||
"JPEG_${timeStamp}_",
|
"${filePrefix}_${timeStamp}_",
|
||||||
".jpg",
|
fileExtension,
|
||||||
storageDir,
|
storageDirectory,
|
||||||
).let {
|
).let {
|
||||||
FileProvider.getUriForFile(
|
FileProvider.getUriForFile(
|
||||||
context,
|
context,
|
||||||
|
|||||||
+7
@@ -53,6 +53,7 @@ import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType
|
|||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectFromGallery
|
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectFromGallery
|
||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.TakePictureButton
|
import com.vitorpamplona.amethyst.ui.actions.uploads.TakePictureButton
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.uploads.TakeVideoButton
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.Nav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.Nav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.topbars.PostingTopBar
|
import com.vitorpamplona.amethyst.ui.navigation.topbars.PostingTopBar
|
||||||
import com.vitorpamplona.amethyst.ui.note.BaseUserPicture
|
import com.vitorpamplona.amethyst.ui.note.BaseUserPicture
|
||||||
@@ -390,6 +391,12 @@ private fun BottomRowActions(postViewModel: CommentPostViewModel) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
TakeVideoButton(
|
||||||
|
onVideoTaken = {
|
||||||
|
postViewModel.selectImage(it)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
ForwardZapToButton(postViewModel.wantsForwardZapTo) {
|
ForwardZapToButton(postViewModel.wantsForwardZapTo) {
|
||||||
postViewModel.wantsForwardZapTo = !postViewModel.wantsForwardZapTo
|
postViewModel.wantsForwardZapTo = !postViewModel.wantsForwardZapTo
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-1
@@ -41,6 +41,7 @@ import androidx.compose.foundation.rememberScrollState
|
|||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.AddPhotoAlternate
|
import androidx.compose.material.icons.filled.AddPhotoAlternate
|
||||||
|
import androidx.compose.material.icons.filled.Videocam
|
||||||
import androidx.compose.material.icons.outlined.CameraAlt
|
import androidx.compose.material.icons.outlined.CameraAlt
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
@@ -85,6 +86,7 @@ import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType
|
|||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectFromGallery
|
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectFromGallery
|
||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.TakePictureButton
|
import com.vitorpamplona.amethyst.ui.actions.uploads.TakePictureButton
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.uploads.TakeVideoButton
|
||||||
import com.vitorpamplona.amethyst.ui.components.ThinPaddingTextField
|
import com.vitorpamplona.amethyst.ui.components.ThinPaddingTextField
|
||||||
import com.vitorpamplona.amethyst.ui.components.ZoomableContentView
|
import com.vitorpamplona.amethyst.ui.components.ZoomableContentView
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
@@ -408,7 +410,26 @@ private fun BottomRowActions(
|
|||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Outlined.CameraAlt,
|
imageVector = Icons.Outlined.CameraAlt,
|
||||||
contentDescription = stringRes(id = R.string.upload_image),
|
contentDescription = stringRes(id = R.string.take_a_picture),
|
||||||
|
modifier = Modifier.height(22.dp),
|
||||||
|
tint = MaterialTheme.colorScheme.placeholderText,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (postViewModel.room != null) {
|
||||||
|
TakeVideoButton(
|
||||||
|
onVideoTaken = { postViewModel.pickedMedia(it) },
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
accountViewModel.toastManager.toast(R.string.messages_cant_upload_title, R.string.messages_cant_upload_explainer)
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Videocam,
|
||||||
|
contentDescription = stringRes(id = R.string.record_a_video),
|
||||||
modifier = Modifier.height(22.dp),
|
modifier = Modifier.height(22.dp),
|
||||||
tint = MaterialTheme.colorScheme.placeholderText,
|
tint = MaterialTheme.colorScheme.placeholderText,
|
||||||
)
|
)
|
||||||
|
|||||||
+7
@@ -53,6 +53,7 @@ import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType
|
|||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectFromGallery
|
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectFromGallery
|
||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.TakePictureButton
|
import com.vitorpamplona.amethyst.ui.actions.uploads.TakePictureButton
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.uploads.TakeVideoButton
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.Nav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.Nav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.topbars.PostingTopBar
|
import com.vitorpamplona.amethyst.ui.navigation.topbars.PostingTopBar
|
||||||
@@ -370,6 +371,12 @@ private fun BottomRowActions(postViewModel: NewProductViewModel) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
TakeVideoButton(
|
||||||
|
onVideoTaken = {
|
||||||
|
postViewModel.selectImage(it)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
ForwardZapToButton(postViewModel.wantsForwardZapTo) {
|
ForwardZapToButton(postViewModel.wantsForwardZapTo) {
|
||||||
postViewModel.wantsForwardZapTo = !postViewModel.wantsForwardZapTo
|
postViewModel.wantsForwardZapTo = !postViewModel.wantsForwardZapTo
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -60,6 +60,7 @@ import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType
|
|||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectFromGallery
|
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectFromGallery
|
||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.TakePictureButton
|
import com.vitorpamplona.amethyst.ui.actions.uploads.TakePictureButton
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.uploads.TakeVideoButton
|
||||||
import com.vitorpamplona.amethyst.ui.components.getActivity
|
import com.vitorpamplona.amethyst.ui.components.getActivity
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.Nav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.Nav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.topbars.PostingTopBar
|
import com.vitorpamplona.amethyst.ui.navigation.topbars.PostingTopBar
|
||||||
@@ -431,6 +432,12 @@ private fun BottomRowActions(postViewModel: ShortNotePostViewModel) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
TakeVideoButton(
|
||||||
|
onVideoTaken = {
|
||||||
|
postViewModel.selectImage(it)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
if (postViewModel.canUsePoll) {
|
if (postViewModel.canUsePoll) {
|
||||||
// These should be hashtag recommendations the user selects in the future.
|
// These should be hashtag recommendations the user selects in the future.
|
||||||
// val hashtag = stringRes(R.string.poll_hashtag)
|
// val hashtag = stringRes(R.string.poll_hashtag)
|
||||||
|
|||||||
+7
@@ -61,6 +61,7 @@ import com.vitorpamplona.amethyst.ui.actions.UrlUserTagTransformation
|
|||||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType
|
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType
|
||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectFromGallery
|
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectFromGallery
|
||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.TakePictureButton
|
import com.vitorpamplona.amethyst.ui.actions.uploads.TakePictureButton
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.uploads.TakeVideoButton
|
||||||
import com.vitorpamplona.amethyst.ui.components.ThinPaddingTextField
|
import com.vitorpamplona.amethyst.ui.components.ThinPaddingTextField
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.Nav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.Nav
|
||||||
@@ -320,6 +321,12 @@ private fun BottomRowActions(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
TakeVideoButton(
|
||||||
|
onVideoTaken = {
|
||||||
|
postViewModel.selectImage(it)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
ForwardZapToButton(postViewModel.wantsForwardZapTo) {
|
ForwardZapToButton(postViewModel.wantsForwardZapTo) {
|
||||||
postViewModel.wantsForwardZapTo = !postViewModel.wantsForwardZapTo
|
postViewModel.wantsForwardZapTo = !postViewModel.wantsForwardZapTo
|
||||||
}
|
}
|
||||||
|
|||||||
+31
-1
@@ -33,6 +33,7 @@ import androidx.compose.foundation.shape.CircleShape
|
|||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.AddPhotoAlternate
|
import androidx.compose.material.icons.filled.AddPhotoAlternate
|
||||||
import androidx.compose.material.icons.filled.CameraAlt
|
import androidx.compose.material.icons.filled.CameraAlt
|
||||||
|
import androidx.compose.material.icons.filled.Videocam
|
||||||
import androidx.compose.material.icons.outlined.Close
|
import androidx.compose.material.icons.outlined.Close
|
||||||
import androidx.compose.material3.FloatingActionButton
|
import androidx.compose.material3.FloatingActionButton
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
@@ -53,6 +54,7 @@ import com.vitorpamplona.amethyst.ui.actions.NewMediaView
|
|||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.GallerySelect
|
import com.vitorpamplona.amethyst.ui.actions.uploads.GallerySelect
|
||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.TakePicture
|
import com.vitorpamplona.amethyst.ui.actions.uploads.TakePicture
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.uploads.TakeVideo
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.painterRes
|
import com.vitorpamplona.amethyst.ui.painterRes
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
@@ -78,6 +80,8 @@ fun NewImageButton(
|
|||||||
|
|
||||||
var wantsToPostFromCamera by remember { mutableStateOf(false) }
|
var wantsToPostFromCamera by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
var wantsToPostFromVideo by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
var pickedURIs by remember { mutableStateOf<ImmutableList<SelectedMedia>>(persistentListOf()) }
|
var pickedURIs by remember { mutableStateOf<ImmutableList<SelectedMedia>>(persistentListOf()) }
|
||||||
|
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
@@ -97,6 +101,13 @@ fun NewImageButton(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wantsToPostFromVideo) {
|
||||||
|
TakeVideo { uri ->
|
||||||
|
wantsToPostFromVideo = false
|
||||||
|
pickedURIs = uri
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (wantsToPostFromGallery) {
|
if (wantsToPostFromGallery) {
|
||||||
GallerySelect(
|
GallerySelect(
|
||||||
onImageUri = { uri ->
|
onImageUri = { uri ->
|
||||||
@@ -134,7 +145,26 @@ fun NewImageButton(
|
|||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Default.CameraAlt,
|
imageVector = Icons.Default.CameraAlt,
|
||||||
contentDescription = stringRes(id = R.string.upload_image),
|
contentDescription = stringRes(id = R.string.take_a_picture),
|
||||||
|
modifier = Modifier.size(26.dp),
|
||||||
|
tint = Color.White,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(20.dp))
|
||||||
|
|
||||||
|
FloatingActionButton(
|
||||||
|
onClick = {
|
||||||
|
wantsToPostFromVideo = true
|
||||||
|
isOpen = false
|
||||||
|
},
|
||||||
|
modifier = Size55Modifier,
|
||||||
|
shape = CircleShape,
|
||||||
|
containerColor = MaterialTheme.colorScheme.primary,
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Videocam,
|
||||||
|
contentDescription = stringRes(id = R.string.record_a_video),
|
||||||
modifier = Modifier.size(26.dp),
|
modifier = Modifier.size(26.dp),
|
||||||
tint = Color.White,
|
tint = Color.White,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -148,6 +148,7 @@
|
|||||||
<string name="failed_to_save_the_video">Nepodařilo se uložit video</string>
|
<string name="failed_to_save_the_video">Nepodařilo se uložit video</string>
|
||||||
<string name="upload_image">Nahrát obrázek</string>
|
<string name="upload_image">Nahrát obrázek</string>
|
||||||
<string name="take_a_picture">Pořiďte fotografii</string>
|
<string name="take_a_picture">Pořiďte fotografii</string>
|
||||||
|
<string name="record_a_video">Nahrát video</string>
|
||||||
<string name="record_a_message">Nahrajte zprávu</string>
|
<string name="record_a_message">Nahrajte zprávu</string>
|
||||||
<string name="record_a_message_title">Nahrajte zprávu</string>
|
<string name="record_a_message_title">Nahrajte zprávu</string>
|
||||||
<string name="record_a_message_description">Stiskněte a podržte pro nahrání zprávy</string>
|
<string name="record_a_message_description">Stiskněte a podržte pro nahrání zprávy</string>
|
||||||
|
|||||||
@@ -947,6 +947,7 @@ anz der Bedingungen ist erforderlich</string>
|
|||||||
<string name="signer_not_found_exception_description">Wurde die Signierer-App deinstalliert? Überprüfe, ob sie installiert ist und dieses Konto enthält. Melde dich ab und wieder an, falls sich die App geändert hat.</string>
|
<string name="signer_not_found_exception_description">Wurde die Signierer-App deinstalliert? Überprüfe, ob sie installiert ist und dieses Konto enthält. Melde dich ab und wieder an, falls sich die App geändert hat.</string>
|
||||||
<string name="no_description">Keine Beschreibung gefunden</string>
|
<string name="no_description">Keine Beschreibung gefunden</string>
|
||||||
<string name="take_a_picture">Ein Foto aufnehmen</string>
|
<string name="take_a_picture">Ein Foto aufnehmen</string>
|
||||||
|
<string name="record_a_video">Video aufnehmen</string>
|
||||||
<string name="record_a_message">Eine Nachricht aufnehmen</string>
|
<string name="record_a_message">Eine Nachricht aufnehmen</string>
|
||||||
<string name="record_a_message_title">Eine Nachricht aufnehmen</string>
|
<string name="record_a_message_title">Eine Nachricht aufnehmen</string>
|
||||||
<string name="record_a_message_description">Zum Aufnehmen einer Nachricht gedrückt halten</string>
|
<string name="record_a_message_description">Zum Aufnehmen einer Nachricht gedrückt halten</string>
|
||||||
|
|||||||
@@ -148,6 +148,7 @@
|
|||||||
<string name="failed_to_save_the_video">Falha ao salvar o vídeo</string>
|
<string name="failed_to_save_the_video">Falha ao salvar o vídeo</string>
|
||||||
<string name="upload_image">Enviar Imagem</string>
|
<string name="upload_image">Enviar Imagem</string>
|
||||||
<string name="take_a_picture">Tirar uma foto</string>
|
<string name="take_a_picture">Tirar uma foto</string>
|
||||||
|
<string name="record_a_video">Gravar um vídeo</string>
|
||||||
<string name="record_a_message">Gravar uma mensagem</string>
|
<string name="record_a_message">Gravar uma mensagem</string>
|
||||||
<string name="record_a_message_title">Gravar uma mensagem</string>
|
<string name="record_a_message_title">Gravar uma mensagem</string>
|
||||||
<string name="record_a_message_description">Clique e segure para gravar uma mensagem</string>
|
<string name="record_a_message_description">Clique e segure para gravar uma mensagem</string>
|
||||||
|
|||||||
@@ -148,6 +148,7 @@
|
|||||||
<string name="failed_to_save_the_video">Det gick inte att spara videon</string>
|
<string name="failed_to_save_the_video">Det gick inte att spara videon</string>
|
||||||
<string name="upload_image">Ladda upp bilden</string>
|
<string name="upload_image">Ladda upp bilden</string>
|
||||||
<string name="take_a_picture">Ta en bild</string>
|
<string name="take_a_picture">Ta en bild</string>
|
||||||
|
<string name="record_a_video">Spela in video</string>
|
||||||
<string name="record_a_message">Spela in ett meddelande</string>
|
<string name="record_a_message">Spela in ett meddelande</string>
|
||||||
<string name="record_a_message_title">Spela in ett meddelande</string>
|
<string name="record_a_message_title">Spela in ett meddelande</string>
|
||||||
<string name="record_a_message_description">Tryck och håll in för att spela in ett meddelande</string>
|
<string name="record_a_message_description">Tryck och håll in för att spela in ett meddelande</string>
|
||||||
|
|||||||
@@ -160,6 +160,7 @@
|
|||||||
<string name="failed_to_save_the_video">Failed to save the video</string>
|
<string name="failed_to_save_the_video">Failed to save the video</string>
|
||||||
<string name="upload_image">Upload Image</string>
|
<string name="upload_image">Upload Image</string>
|
||||||
<string name="take_a_picture">Take a picture</string>
|
<string name="take_a_picture">Take a picture</string>
|
||||||
|
<string name="record_a_video">Record a video</string>
|
||||||
<string name="record_a_message">Record a message</string>
|
<string name="record_a_message">Record a message</string>
|
||||||
<string name="record_a_message_title">Record a message</string>
|
<string name="record_a_message_title">Record a message</string>
|
||||||
<string name="record_a_message_description">Click and hold to record a message</string>
|
<string name="record_a_message_description">Click and hold to record a message</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user