diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 77d1bcec..502600a2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -118,11 +118,6 @@
android:configChanges="orientation|screenSize"
android:theme="@style/Theme.Revolt" />
-
-
{
+ downloadFile(autumnResource, resourceUrl)
+ true
+ }
+
+ R.id.mi_share_file -> {
+ shareFile(autumnResource, resourceUrl)
+ true
+ }
+
+ R.id.mi_share_link -> {
+ shareUrl(resourceUrl)
+ true
+ }
+
+ else -> false
+ }
}
+
+ player = ExoPlayer.Builder(this).build().apply {
+ setMediaItem(MediaItem.fromUri(resourceUrl))
+ prepare()
+ play()
+ }
+
+ binding.xpPlayer.player = player
+ binding.xpPlayer.setFullscreenButtonClickListener {
+ when (binding.alTop.visibility) {
+ android.view.View.VISIBLE -> {
+ binding.alTop.visibility = android.view.View.GONE
+ WindowInsetsControllerCompat(window, binding.root).let { controller ->
+ controller.hide(WindowInsetsCompat.Type.systemBars())
+ controller.systemBarsBehavior =
+ WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
+ }
+ binding.xpPlayer.background = ColorDrawable(Color.BLACK)
+ }
+
+ else -> {
+ binding.alTop.visibility = android.view.View.VISIBLE
+ WindowInsetsControllerCompat(window, binding.root).let { controller ->
+ controller.show(WindowInsetsCompat.Type.systemBars())
+ controller.systemBarsBehavior =
+ WindowInsetsControllerCompat.BEHAVIOR_DEFAULT
+ }
+ binding.xpPlayer.background = null
+ }
+ }
+ }
+
+
+ setContentView(binding.root)
}
-}
-@OptIn(ExperimentalMaterial3Api::class)
-@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
-@Composable
-fun VideoViewScreen(resource: AutumnResource, onClose: () -> Unit = {}) {
- val resourceUrl = "$REVOLT_FILES/attachments/${resource.id}/${resource.filename}"
+ override fun onDestroy() {
+ super.onDestroy()
+ player?.release()
+ }
- val context = LocalContext.current
- val coroutineScope = rememberCoroutineScope()
- val activityLauncher = rememberLauncherForActivityResult(
- ActivityResultContracts.StartActivityForResult()
- ) {}
-
- val shareSubmenuIsOpen = remember { mutableStateOf(false) }
- val snackbarHostState = remember { SnackbarHostState() }
-
- fun shareUrl() {
- shareSubmenuIsOpen.value = false
+ override fun onPause() {
+ super.onPause()
+ player?.pause()
+ }
+ private fun shareUrl(resourceUrl: String) {
val intent =
Intent(Intent.ACTION_SEND)
intent.type = "text/plain"
@@ -111,15 +133,13 @@ fun VideoViewScreen(resource: AutumnResource, onClose: () -> Unit = {}) {
)
val shareIntent = Intent.createChooser(intent, null)
- activityLauncher.launch(shareIntent)
+ startActivity(shareIntent)
}
- fun shareVideo() {
- shareSubmenuIsOpen.value = false
-
- coroutineScope.launch {
+ private fun shareFile(resource: AutumnResource, resourceUrl: String) {
+ lifecycleScope.launch {
val contentUri = getAttachmentContentUri(
- context,
+ this@VideoViewActivity,
resourceUrl,
resource.id!!,
resource.filename ?: "video"
@@ -128,19 +148,27 @@ fun VideoViewScreen(resource: AutumnResource, onClose: () -> Unit = {}) {
val intent =
Intent(Intent.ACTION_SEND)
intent.type = resource.contentType ?: "video/*"
+ intent.putExtra(
+ Intent.EXTRA_TITLE,
+ resource.filename
+ )
+ intent.putExtra(
+ Intent.EXTRA_SUBJECT,
+ resource.filename
+ )
intent.putExtra(
Intent.EXTRA_STREAM,
contentUri
)
val shareIntent = Intent.createChooser(intent, null)
- activityLauncher.launch(shareIntent)
+ startActivity(shareIntent)
}
}
- fun saveToGallery() {
- coroutineScope.launch {
- context.applicationContext.let {
+ private fun downloadFile(resource: AutumnResource, resourceUrl: String) {
+ lifecycleScope.launch {
+ this@VideoViewActivity.applicationContext.let {
it.contentResolver.insert(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
ContentValues().apply {
@@ -151,11 +179,11 @@ fun VideoViewScreen(resource: AutumnResource, onClose: () -> Unit = {}) {
}
)
}?.let { uri ->
- context.contentResolver.openOutputStream(uri).use { stream ->
+ this@VideoViewActivity.contentResolver.openOutputStream(uri).use { stream ->
val video = RevoltHttp.get(resourceUrl).readBytes()
stream?.write(video)
- context.applicationContext.let {
+ this@VideoViewActivity.applicationContext.let {
it.contentResolver.update(
uri,
ContentValues().apply {
@@ -166,145 +194,27 @@ fun VideoViewScreen(resource: AutumnResource, onClose: () -> Unit = {}) {
)
}
- val snackbar = snackbarHostState.showSnackbar(
- message = context.getString(R.string.media_viewer_saved),
- actionLabel = context.getString(R.string.media_viewer_open),
- duration = SnackbarDuration.Short
- )
-
- if (snackbar == SnackbarResult.ActionPerformed) {
+ Snackbar.make(
+ binding.xpPlayer,
+ R.string.media_viewer_saved,
+ Snackbar.LENGTH_SHORT
+ ).setAction(
+ R.string.media_viewer_open
+ ) {
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(uri, resource.contentType)
intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
- activityLauncher.launch(intent)
+ startActivity(intent)
}
- }
- }
- }
- }
-
- val player = remember {
- ExoPlayer.Builder(context).build().apply {
- setMediaItem(MediaItem.fromUri(resourceUrl))
- prepare()
- play()
- }
- }
-
- DisposableEffect(player) {
- onDispose {
- player.release()
- }
- }
-
- RevoltTheme(
- requestedTheme = GlobalState.theme,
- colourOverrides = SyncedSettings.android.colourOverrides
- ) {
- Scaffold(
- topBar = {
- TopAppBar(
- title = {
- Text(
- text = stringResource(
- id = R.string.media_viewer_title_video,
- resource.filename ?: resource.id!!
- ),
- maxLines = 1,
- overflow = TextOverflow.Ellipsis,
+ .setActionTextColor(
+ MaterialColors.getColor(
+ binding.xpPlayer,
+ com.google.android.material.R.attr.colorPrimary
+ )
)
- },
- navigationIcon = {
- IconButton(onClick = {
- onClose()
- }) {
- Icon(
- imageVector = Icons.AutoMirrored.Default.ArrowBack,
- contentDescription = stringResource(id = R.string.back)
- )
- }
- },
- actions = {
- IconButton(onClick = {
- shareSubmenuIsOpen.value = true
- }) {
- Icon(
- painter = painterResource(id = R.drawable.ic_share_24dp),
- contentDescription = stringResource(id = R.string.share)
- )
- }
-
- DropdownMenu(
- expanded = shareSubmenuIsOpen.value,
- onDismissRequest = {
- shareSubmenuIsOpen.value = false
- }
- ) {
- DropdownMenuItem(
- onClick = {
- shareUrl()
- },
- text = {
- Text(
- stringResource(id = R.string.media_viewer_share_url)
- )
- }
- )
- DropdownMenuItem(
- onClick = {
- shareVideo()
- },
- text = {
- Text(
- stringResource(
- id = R.string.media_viewer_share_video
- )
- )
- }
- )
- }
-
- IconButton(onClick = {
- saveToGallery()
- }) {
- Icon(
- painter = painterResource(id = R.drawable.ic_download_24dp),
- contentDescription = stringResource(
- id = R.string.media_viewer_save
- )
- )
- }
- }
- )
- },
- snackbarHost = { SnackbarHost(hostState = snackbarHostState) }
- ) { pv ->
- Surface(
- modifier = Modifier
- .padding(pv)
- .background(MaterialTheme.colorScheme.background)
- .fillMaxSize()
- ) {
- Box(
- modifier = Modifier
- .clip(RectangleShape)
- .fillMaxSize()
- ) {
- AndroidView(
- factory = { context ->
- PlayerView(context).apply {
- setShowBuffering(PlayerView.SHOW_BUFFERING_ALWAYS)
- }
- },
- update = {
- it.player = player
- },
- modifier = Modifier
- .fillMaxSize()
- .background(MaterialTheme.colorScheme.background)
- )
+ .show()
}
}
}
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/chat/revolt/activities/media/VideoViewActivity2.kt b/app/src/main/java/chat/revolt/activities/media/VideoViewActivity2.kt
deleted file mode 100644
index d5dcbe2b..00000000
--- a/app/src/main/java/chat/revolt/activities/media/VideoViewActivity2.kt
+++ /dev/null
@@ -1,220 +0,0 @@
-package chat.revolt.activities.media
-
-import android.content.ContentValues
-import android.content.Intent
-import android.graphics.Color
-import android.graphics.drawable.ColorDrawable
-import android.os.Build
-import android.os.Bundle
-import android.provider.MediaStore
-import android.util.Log
-import androidx.core.view.WindowCompat
-import androidx.core.view.WindowInsetsCompat
-import androidx.core.view.WindowInsetsControllerCompat
-import androidx.fragment.app.FragmentActivity
-import androidx.lifecycle.lifecycleScope
-import androidx.media3.common.MediaItem
-import androidx.media3.exoplayer.ExoPlayer
-import chat.revolt.R
-import chat.revolt.api.REVOLT_FILES
-import chat.revolt.api.RevoltHttp
-import chat.revolt.api.schemas.AutumnResource
-import chat.revolt.databinding.ActivityVideoplayerBinding
-import chat.revolt.provider.getAttachmentContentUri
-import com.google.android.material.color.MaterialColors
-import com.google.android.material.snackbar.Snackbar
-import io.ktor.client.request.get
-import io.ktor.client.statement.readBytes
-import kotlinx.coroutines.launch
-
-class VideoViewActivity2 : FragmentActivity() {
- private lateinit var binding: ActivityVideoplayerBinding
-
- private var player: ExoPlayer? = null
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
-
- val autumnResource = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
- intent.getParcelableExtra("autumnResource", AutumnResource::class.java)
- } else {
- @Suppress("DEPRECATION")
- intent.getParcelableExtra("autumnResource")
- }
-
- if (autumnResource?.id == null) {
- Log.e("VideoViewActivity", "No AutumnResource provided")
- finish()
- return
- }
-
- val resourceUrl =
- "$REVOLT_FILES/attachments/${autumnResource.id}/${autumnResource.filename}"
-
- WindowCompat.setDecorFitsSystemWindows(window, false)
-
- binding = ActivityVideoplayerBinding.inflate(layoutInflater)
-
- binding.tbTop.title = autumnResource.filename
- binding.tbTop.setNavigationOnClickListener { finish() }
- binding.tbTop.setOnMenuItemClickListener {
- when (it.itemId) {
- R.id.mi_save -> {
- downloadFile(autumnResource, resourceUrl)
- true
- }
-
- R.id.mi_share_file -> {
- shareFile(autumnResource, resourceUrl)
- true
- }
-
- R.id.mi_share_link -> {
- shareUrl(resourceUrl)
- true
- }
-
- else -> false
- }
- }
-
- player = ExoPlayer.Builder(this).build().apply {
- setMediaItem(MediaItem.fromUri(resourceUrl))
- prepare()
- play()
- }
-
- binding.xpPlayer.player = player
- binding.xpPlayer.setFullscreenButtonClickListener {
- when (binding.alTop.visibility) {
- android.view.View.VISIBLE -> {
- binding.alTop.visibility = android.view.View.GONE
- WindowInsetsControllerCompat(window, binding.root).let { controller ->
- controller.hide(WindowInsetsCompat.Type.systemBars())
- controller.systemBarsBehavior =
- WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
- }
- binding.xpPlayer.background = ColorDrawable(Color.BLACK)
- }
-
- else -> {
- binding.alTop.visibility = android.view.View.VISIBLE
- WindowInsetsControllerCompat(window, binding.root).let { controller ->
- controller.show(WindowInsetsCompat.Type.systemBars())
- controller.systemBarsBehavior =
- WindowInsetsControllerCompat.BEHAVIOR_DEFAULT
- }
- binding.xpPlayer.background = null
- }
- }
- }
-
-
- setContentView(binding.root)
- }
-
- override fun onDestroy() {
- super.onDestroy()
- player?.release()
- }
-
- override fun onPause() {
- super.onPause()
- player?.pause()
- }
-
- private fun shareUrl(resourceUrl: String) {
- val intent =
- Intent(Intent.ACTION_SEND)
- intent.type = "text/plain"
- intent.putExtra(
- Intent.EXTRA_TEXT,
- resourceUrl
- )
-
- val shareIntent = Intent.createChooser(intent, null)
- startActivity(shareIntent)
- }
-
- private fun shareFile(resource: AutumnResource, resourceUrl: String) {
- lifecycleScope.launch {
- val contentUri = getAttachmentContentUri(
- this@VideoViewActivity2,
- resourceUrl,
- resource.id!!,
- resource.filename ?: "video"
- )
-
- val intent =
- Intent(Intent.ACTION_SEND)
- intent.type = resource.contentType ?: "video/*"
- intent.putExtra(
- Intent.EXTRA_TITLE,
- resource.filename
- )
- intent.putExtra(
- Intent.EXTRA_SUBJECT,
- resource.filename
- )
- intent.putExtra(
- Intent.EXTRA_STREAM,
- contentUri
- )
-
- val shareIntent = Intent.createChooser(intent, null)
- startActivity(shareIntent)
- }
- }
-
- private fun downloadFile(resource: AutumnResource, resourceUrl: String) {
- lifecycleScope.launch {
- this@VideoViewActivity2.applicationContext.let {
- it.contentResolver.insert(
- MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
- ContentValues().apply {
- put(MediaStore.Video.Media.DISPLAY_NAME, resource.filename)
- put(MediaStore.Video.Media.MIME_TYPE, resource.contentType)
- put(MediaStore.Video.Media.RELATIVE_PATH, "Movies/Revolt")
- put(MediaStore.Video.Media.IS_PENDING, 1)
- }
- )
- }?.let { uri ->
- this@VideoViewActivity2.contentResolver.openOutputStream(uri).use { stream ->
- val video = RevoltHttp.get(resourceUrl).readBytes()
- stream?.write(video)
-
- this@VideoViewActivity2.applicationContext.let {
- it.contentResolver.update(
- uri,
- ContentValues().apply {
- put(MediaStore.Video.Media.IS_PENDING, 0)
- },
- null,
- null
- )
- }
-
- Snackbar.make(
- binding.xpPlayer,
- R.string.media_viewer_saved,
- Snackbar.LENGTH_SHORT
- ).setAction(
- R.string.media_viewer_open
- ) {
- val intent = Intent(Intent.ACTION_VIEW)
- intent.setDataAndType(uri, resource.contentType)
- intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
- startActivity(intent)
- }
- .setActionTextColor(
- MaterialColors.getColor(
- binding.xpPlayer,
- com.google.android.material.R.attr.colorPrimary
- )
- )
- .show()
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/chat/revolt/api/settings/FeatureFlags.kt b/app/src/main/java/chat/revolt/api/settings/FeatureFlags.kt
index 045180ee..da014bcb 100644
--- a/app/src/main/java/chat/revolt/api/settings/FeatureFlags.kt
+++ b/app/src/main/java/chat/revolt/api/settings/FeatureFlags.kt
@@ -30,19 +30,6 @@ sealed class MediaConversationsVariates {
data class Restricted(val predicate: () -> Boolean) : MediaConversationsVariates()
}
-@FeatureFlag("VideoViewActivity2")
-sealed class ViewViewActivity2Variates {
- @Treatment(
- "Enable the new XML-based video player activity for all users"
- )
- object Enabled : ViewViewActivity2Variates()
-
- @Treatment(
- "Enable the new XML-based video player activity for users that meet certain or all criteria (implementation-specific)"
- )
- data class Restricted(val predicate: () -> Boolean) : ViewViewActivity2Variates()
-}
-
object FeatureFlags {
@FeatureFlag("LabsAccessControl")
var labsAccessControl by mutableStateOf(
@@ -68,17 +55,4 @@ object FeatureFlags {
is MediaConversationsVariates.Enabled -> true
is MediaConversationsVariates.Restricted -> (mediaConversations as MediaConversationsVariates.Restricted).predicate()
}
-
- @FeatureFlag("VideoViewActivity2")
- var videoViewActivity2 by mutableStateOf(
- ViewViewActivity2Variates.Restricted {
- RevoltAPI.selfId == SpecialUsers.JENNIFER
- }
- )
-
- val videoViewActivity2Granted: Boolean
- get() = when (videoViewActivity2) {
- is ViewViewActivity2Variates.Enabled -> true
- is ViewViewActivity2Variates.Restricted -> (videoViewActivity2 as ViewViewActivity2Variates.Restricted).predicate()
- }
}
diff --git a/app/src/main/java/chat/revolt/components/chat/Message.kt b/app/src/main/java/chat/revolt/components/chat/Message.kt
index 3be5412e..e65acc43 100644
--- a/app/src/main/java/chat/revolt/components/chat/Message.kt
+++ b/app/src/main/java/chat/revolt/components/chat/Message.kt
@@ -54,7 +54,6 @@ import androidx.compose.ui.unit.sp
import chat.revolt.R
import chat.revolt.activities.media.ImageViewActivity
import chat.revolt.activities.media.VideoViewActivity
-import chat.revolt.activities.media.VideoViewActivity2
import chat.revolt.api.REVOLT_FILES
import chat.revolt.api.RevoltAPI
import chat.revolt.api.internals.BrushCompat
@@ -67,7 +66,6 @@ import chat.revolt.api.routes.channel.unreact
import chat.revolt.api.routes.microservices.january.asJanuaryProxyUrl
import chat.revolt.api.schemas.AutumnResource
import chat.revolt.api.schemas.User
-import chat.revolt.api.settings.FeatureFlags
import chat.revolt.api.settings.GlobalState
import chat.revolt.api.settings.MessageReplyStyle
import chat.revolt.callbacks.Action
@@ -389,10 +387,7 @@ fun Message(
attachmentView.launch(
Intent(
context,
- when (FeatureFlags.videoViewActivity2Granted) {
- true -> VideoViewActivity2::class.java
- else -> VideoViewActivity::class.java
- }
+ VideoViewActivity::class.java
).apply {
putExtra("autumnResource", attachment)
}