mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-09-23 18:11:37 +02:00
Add take video functionality
Add take video button to new post screen I18N
This commit is contained in:
@@ -29,6 +29,7 @@ import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.CameraAlt
|
||||
import androidx.compose.material.icons.filled.Videocam
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
@@ -152,3 +153,99 @@ fun getPhotoUri(context: Context): Uri {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@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 {
|
||||
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(Date())
|
||||
val storageDir: File? = context.getExternalFilesDir(Environment.DIRECTORY_MOVIES)
|
||||
return File
|
||||
.createTempFile(
|
||||
"MP4_${timeStamp}_",
|
||||
".mp4",
|
||||
storageDir,
|
||||
).let {
|
||||
FileProvider.getUriForFile(
|
||||
context,
|
||||
"${context.packageName}.provider",
|
||||
it,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@@ -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.SelectedMedia
|
||||
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.navigation.navs.Nav
|
||||
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) {
|
||||
// These should be hashtag recommendations the user selects in the future.
|
||||
// val hashtag = stringRes(R.string.poll_hashtag)
|
||||
|
@@ -160,6 +160,7 @@
|
||||
<string name="failed_to_save_the_video">Failed to save the video</string>
|
||||
<string name="upload_image">Upload Image</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_title">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