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.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
|
||||||
@@ -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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+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)
|
||||||
|
|||||||
@@ -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