mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-08-04 12:24:00 +01:00
Notify user when a video is trimmed.
This commit is contained in:
committed by
Michelle Tang
parent
cfce0ad8f1
commit
635b5795ea
@@ -214,6 +214,10 @@ class MediaSelectionActivity :
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(this::handleError)
|
||||
|
||||
lifecycleDisposable += viewModel.videoTrimmedEvents
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { Toast.makeText(this, R.string.MediaReviewFragment__video_trimmed_to_fit, Toast.LENGTH_SHORT).show() }
|
||||
|
||||
onBackPressedDispatcher.addCallback(OnBackPressed())
|
||||
|
||||
if (savedInstanceState == null && intent.getBooleanExtra(IS_FOR_QUICK_RESTORE, false)) {
|
||||
|
||||
+30
-13
@@ -82,6 +82,9 @@ class MediaSelectionViewModel(
|
||||
val mediaErrors: BehaviorSubject<MediaValidator.FilterError> = BehaviorSubject.createDefault(MediaValidator.FilterError.None)
|
||||
val hudCommands: Observable<HudCommand> = internalHudCommands
|
||||
|
||||
private val _videoTrimmedEvents = PublishSubject.create<Unit>()
|
||||
val videoTrimmedEvents: Observable<Unit> = _videoTrimmedEvents
|
||||
|
||||
private val disposables = CompositeDisposable()
|
||||
|
||||
private val isMeteredDisposable: Disposable = repository.isMetered.subscribe { metered ->
|
||||
@@ -167,19 +170,20 @@ class MediaSelectionViewModel(
|
||||
.populateAndFilterMedia(newSelectionList, getMediaConstraints(), store.state.maxSelection, store.state.isStory)
|
||||
.subscribe { filterResult ->
|
||||
if (filterResult.filteredMedia.isNotEmpty()) {
|
||||
store.update {
|
||||
val initializedVideoEditorStates = filterResult.filteredMedia.filterNot { media -> it.editorStateMap.containsKey(media.uri) }
|
||||
.filter { media -> MediaUtil.isNonGifVideo(media) }
|
||||
.associate { video: Media ->
|
||||
val duration = video.duration.milliseconds.inWholeMicroseconds
|
||||
val maxDuration = it.calculateMaxVideoDurationUs(video.duration.milliseconds)
|
||||
if (MediaConstraints.isVideoTranscodeAvailable() && duration >= maxDuration) {
|
||||
video.uri to VideoTrimData(true, duration, 0, maxDuration)
|
||||
} else {
|
||||
video.uri to VideoTrimData(false, duration, 0, duration)
|
||||
}
|
||||
val existingState = store.state
|
||||
val initializedVideoEditorStates = filterResult.filteredMedia.filterNot { media -> existingState.editorStateMap.containsKey(media.uri) }
|
||||
.filter { media -> MediaUtil.isNonGifVideo(media) }
|
||||
.associate { video: Media ->
|
||||
val duration = video.duration.milliseconds.inWholeMicroseconds
|
||||
val maxDuration = existingState.calculateMaxVideoDurationUs(video.duration.milliseconds)
|
||||
if (MediaConstraints.isVideoTranscodeAvailable() && duration >= maxDuration) {
|
||||
video.uri to VideoTrimData(true, duration, 0, maxDuration)
|
||||
} else {
|
||||
video.uri to VideoTrimData(false, duration, 0, duration)
|
||||
}
|
||||
}
|
||||
|
||||
store.update {
|
||||
val updatedCameraFirstCapture = if (it.cameraFirstCapture != null) {
|
||||
filterResult.filteredMedia.find { filtered -> filtered.uri == it.cameraFirstCapture.uri }
|
||||
} else {
|
||||
@@ -194,6 +198,10 @@ class MediaSelectionViewModel(
|
||||
)
|
||||
}
|
||||
|
||||
if (initializedVideoEditorStates.any { (_, data) -> data.isDurationEdited }) {
|
||||
_videoTrimmedEvents.onNext(Unit)
|
||||
}
|
||||
|
||||
selectedMediaSubject.onNext(filterResult.filteredMedia)
|
||||
|
||||
val newMedia = filterResult.filteredMedia.toSet().intersect(media).toList()
|
||||
@@ -335,13 +343,22 @@ class MediaSelectionViewModel(
|
||||
store.update { it.copy(quality = sentMediaQuality, isPreUploadEnabled = false, transcodingConfigs = TranscodingConfigProvider.getConfigsForMediaQuality(sentMediaQuality)) }
|
||||
repository.uploadRepository.cancelAllUploads()
|
||||
|
||||
var videoTrimmed = false
|
||||
store.state.selectedMedia.forEach { mediaItem ->
|
||||
if (MediaUtil.isVideoType(mediaItem.contentType) && MediaConstraints.isVideoTranscodeAvailable()) {
|
||||
val uri = mediaItem.uri
|
||||
val data = store.state.getOrCreateVideoTrimData(uri)
|
||||
onEditVideoDuration(totalDurationUs = data.totalInputDurationUs, startTimeUs = data.startTimeUs, endTimeUs = data.endTimeUs, touchEnabled = true, uri = uri)
|
||||
val before = store.state.getOrCreateVideoTrimData(uri)
|
||||
onEditVideoDuration(totalDurationUs = before.totalInputDurationUs, startTimeUs = before.startTimeUs, endTimeUs = before.endTimeUs, touchEnabled = true, uri = uri)
|
||||
val after = store.state.getOrCreateVideoTrimData(uri)
|
||||
if (after.getDuration() < before.getDuration()) {
|
||||
videoTrimmed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (videoTrimmed) {
|
||||
_videoTrimmedEvents.onNext(Unit)
|
||||
}
|
||||
}
|
||||
|
||||
fun setMessage(text: CharSequence?) {
|
||||
|
||||
@@ -6392,6 +6392,7 @@
|
||||
<string name="MediaReviewFragment__one_or_more_items_were_too_large">One or more items were too large</string>
|
||||
<string name="MediaReviewFragment__one_or_more_items_were_invalid">One or more items were invalid</string>
|
||||
<string name="MediaReviewFragment__too_many_items_selected">Too many items selected</string>
|
||||
<string name="MediaReviewFragment__video_trimmed_to_fit">Your video was trimmed to fit within the size limit</string>
|
||||
<!-- Small notification presented to the user when they set their video to view-once mode -->
|
||||
<string name="MediaReviewFragment__video_set_to_view_once">Video set to view once</string>
|
||||
<!-- Small notification presented to the user when they set their photo to view-once mode -->
|
||||
|
||||
@@ -469,6 +469,10 @@ class MediaSendViewModel(
|
||||
)
|
||||
}
|
||||
|
||||
if (initializedVideoEditorStates.any { (_, editorState) -> editorState.videoTrimData.isDurationEdited }) {
|
||||
internalSnackbarEvents.trySend(SnackbarEvent(message = R.string.MediaSendViewModel__video_trimmed_to_fit))
|
||||
}
|
||||
|
||||
// Update story requirements
|
||||
updateStorySendRequirements(filterResult.filteredMedia)
|
||||
|
||||
@@ -607,11 +611,11 @@ class MediaSendViewModel(
|
||||
preUploadController.cancelAllUploads()
|
||||
|
||||
// Re-clamp video durations based on new quality
|
||||
var videoTrimmed = false
|
||||
snapshot.selectedMedia.forEach { mediaItem ->
|
||||
if (isNonGifVideo(mediaItem) && repository.isVideoTranscodeAvailable()) {
|
||||
val existingData = snapshot.editorStateMap[mediaItem.uri] as? EditorState.VideoTrim
|
||||
if (existingData != null) {
|
||||
val maxVideoDurationUs = getMaxVideoDurationUs(existingData.videoTrimData.totalInputDurationUs.microseconds)
|
||||
onEditVideoDuration(
|
||||
totalDurationUs = existingData.videoTrimData.totalInputDurationUs,
|
||||
startTimeUs = existingData.videoTrimData.startTimeUs,
|
||||
@@ -619,9 +623,17 @@ class MediaSendViewModel(
|
||||
touchEnabled = true,
|
||||
uri = mediaItem.uri
|
||||
)
|
||||
val updatedData = state.value.editorStateMap[mediaItem.uri] as? EditorState.VideoTrim
|
||||
if (updatedData != null && updatedData.videoTrimData.getDuration() < existingData.videoTrimData.getDuration()) {
|
||||
videoTrimmed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (videoTrimmed) {
|
||||
internalSnackbarEvents.trySend(SnackbarEvent(message = R.string.MediaSendViewModel__video_trimmed_to_fit))
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
@@ -97,6 +97,8 @@
|
||||
<string name="MediaSendViewModel__error_recording_video">Error recording video</string>
|
||||
<!-- Displayed when there is an error capturing image -->
|
||||
<string name="MediaSendViewModel__error_taking_photo">Error taking photo</string>
|
||||
<!-- Displayed when a video was automatically trimmed so it fits within the size limit -->
|
||||
<string name="MediaSendViewModel__video_trimmed_to_fit">Your video was trimmed to fit within the size limit</string>
|
||||
|
||||
<!-- The title of a dialog notifying that a user was found matching a scanned QR code. The placeholder is a username. Usernames are always latin characters. -->
|
||||
<string name="UsernameScannedDialog__username_dialog_title">Found %1$s</string>
|
||||
|
||||
Reference in New Issue
Block a user