mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2024-12-17 17:20:21 +01:00
Merge branch 'master' into remote-desktop
This commit is contained in:
+7
@@ -48,6 +48,7 @@ actual class RecorderNative: RecorderInterface {
|
||||
recStartedAt = System.currentTimeMillis()
|
||||
progressJob = CoroutineScope(Dispatchers.Default).launch {
|
||||
while(isActive) {
|
||||
keepScreenOn(true)
|
||||
onProgressUpdate(progress(), false)
|
||||
delay(50)
|
||||
}
|
||||
@@ -84,6 +85,7 @@ actual class RecorderNative: RecorderInterface {
|
||||
progressJob = null
|
||||
filePath = null
|
||||
recorder = null
|
||||
keepScreenOn(false)
|
||||
return (realDuration(path) ?: 0).also { recStartedAt = null }
|
||||
}
|
||||
|
||||
@@ -170,6 +172,7 @@ actual object AudioPlayer: AudioPlayerInterface {
|
||||
progressJob = CoroutineScope(Dispatchers.Default).launch {
|
||||
onProgressUpdate(player.currentPosition, TrackState.PLAYING)
|
||||
while(isActive && player.isPlaying) {
|
||||
keepScreenOn(true)
|
||||
// Even when current position is equal to duration, the player has isPlaying == true for some time,
|
||||
// so help to make the playback stopped in UI immediately
|
||||
if (player.currentPosition == player.duration) {
|
||||
@@ -187,6 +190,7 @@ actual object AudioPlayer: AudioPlayerInterface {
|
||||
if (isActive) {
|
||||
onProgressUpdate(player.duration, TrackState.PAUSED)
|
||||
}
|
||||
keepScreenOn(false)
|
||||
onProgressUpdate(null, TrackState.PAUSED)
|
||||
}
|
||||
return player.duration
|
||||
@@ -196,6 +200,7 @@ actual object AudioPlayer: AudioPlayerInterface {
|
||||
progressJob?.cancel()
|
||||
progressJob = null
|
||||
player.pause()
|
||||
keepScreenOn(false)
|
||||
return player.currentPosition
|
||||
}
|
||||
|
||||
@@ -203,6 +208,7 @@ actual object AudioPlayer: AudioPlayerInterface {
|
||||
if (currentlyPlaying.value == null) return
|
||||
player.stop()
|
||||
stopListener()
|
||||
keepScreenOn(false)
|
||||
}
|
||||
|
||||
override fun stop(item: ChatItem) = stop(item.file?.fileName)
|
||||
@@ -263,6 +269,7 @@ actual object AudioPlayer: AudioPlayerInterface {
|
||||
override fun pause(audioPlaying: MutableState<Boolean>, pro: MutableState<Int>) {
|
||||
pro.value = pause()
|
||||
audioPlaying.value = false
|
||||
keepScreenOn(false)
|
||||
}
|
||||
|
||||
override fun seekTo(ms: Int, pro: MutableState<Int>, filePath: String?) {
|
||||
|
||||
+2
-3
@@ -1,13 +1,10 @@
|
||||
package chat.simplex.common.platform
|
||||
|
||||
import android.media.MediaMetadataRetriever
|
||||
import android.media.session.PlaybackState
|
||||
import android.net.Uri
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import chat.simplex.common.helpers.toUri
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.res.MR
|
||||
import com.google.android.exoplayer2.*
|
||||
@@ -134,6 +131,7 @@ actual class VideoPlayer actual constructor(
|
||||
player.addListener(object: Player.Listener{
|
||||
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
||||
super.onIsPlayingChanged(isPlaying)
|
||||
keepScreenOn(isPlaying)
|
||||
// Produce non-ideal transition from stopped to playing state while showing preview image in ChatView
|
||||
// videoPlaying.value = isPlaying
|
||||
}
|
||||
@@ -192,6 +190,7 @@ actual class VideoPlayer actual constructor(
|
||||
|
||||
override fun release(remove: Boolean) {
|
||||
player.release()
|
||||
keepScreenOn(false)
|
||||
if (remove) {
|
||||
VideoPlayerHolder.players.remove(uri to gallery)
|
||||
}
|
||||
|
||||
+2
@@ -196,12 +196,14 @@ actual fun ActiveCallView() {
|
||||
chatModel.activeCallViewIsVisible.value = true
|
||||
// After the first call, End command gets added to the list which prevents making another calls
|
||||
chatModel.callCommand.removeAll { it is WCallCommand.End }
|
||||
keepScreenOn(true)
|
||||
onDispose {
|
||||
activity.volumeControlStream = prevVolumeControlStream
|
||||
// Unlock orientation
|
||||
activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
||||
chatModel.activeCallViewIsVisible.value = false
|
||||
chatModel.callCommand.clear()
|
||||
keepScreenOn(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -11,6 +11,7 @@ import android.text.Spanned
|
||||
import android.text.SpannedString
|
||||
import android.text.style.*
|
||||
import android.util.Base64
|
||||
import android.view.WindowManager
|
||||
import androidx.compose.ui.graphics.*
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.*
|
||||
@@ -43,6 +44,17 @@ fun Resources.getText(id: StringResource, vararg args: Any): CharSequence {
|
||||
return HtmlCompat.fromHtml(formattedHtml, HtmlCompat.FROM_HTML_MODE_LEGACY)
|
||||
}
|
||||
|
||||
fun keepScreenOn(on: Boolean) {
|
||||
val window = mainActivity.get()?.window ?: return
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
if (on) {
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
} else {
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
actual fun escapedHtmlToAnnotatedString(text: String, density: Density): AnnotatedString {
|
||||
return spannableStringToAnnotatedString(HtmlCompat.fromHtml(text, HtmlCompat.FROM_HTML_MODE_LEGACY), density)
|
||||
}
|
||||
|
||||
+1
-1
@@ -137,7 +137,7 @@ fun saveAnimImage(uri: URI, encrypted: Boolean): CryptoFile? {
|
||||
val destFileName = generateNewFileName("IMG", ext)
|
||||
val destFile = File(getAppFilePath(destFileName))
|
||||
if (encrypted) {
|
||||
val args = writeCryptoFile(destFile.absolutePath, uri.inputStream()?.readAllBytes() ?: return null)
|
||||
val args = writeCryptoFile(destFile.absolutePath, uri.inputStream()?.readBytes() ?: return null)
|
||||
CryptoFile(destFileName, args)
|
||||
} else {
|
||||
Files.copy(uri.inputStream(), destFile.toPath())
|
||||
|
||||
+2
-3
@@ -11,8 +11,7 @@ import dev.icerock.moko.resources.compose.stringResource
|
||||
import androidx.compose.ui.unit.sp
|
||||
import chat.simplex.common.model.ChatModel
|
||||
import chat.simplex.common.model.PendingContactConnection
|
||||
import chat.simplex.common.views.helpers.ModalManager
|
||||
import chat.simplex.common.views.helpers.withApi
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.views.usersettings.UserAddressView
|
||||
import chat.simplex.res.MR
|
||||
|
||||
@@ -24,7 +23,7 @@ enum class CreateLinkTab {
|
||||
fun CreateLinkView(m: ChatModel, initialSelection: CreateLinkTab) {
|
||||
val selection = remember { mutableStateOf(initialSelection) }
|
||||
val connReqInvitation = rememberSaveable { m.connReqInv }
|
||||
val contactConnection: MutableState<PendingContactConnection?> = rememberSaveable { mutableStateOf(null) }
|
||||
val contactConnection: MutableState<PendingContactConnection?> = rememberSaveable(stateSaver = serializableSaver()) { mutableStateOf(null) }
|
||||
val creatingConnReq = rememberSaveable { mutableStateOf(false) }
|
||||
LaunchedEffect(selection.value) {
|
||||
if (
|
||||
|
||||
+1
-2
@@ -170,9 +170,8 @@ actual fun isAnimImage(uri: URI, drawable: Any?): Boolean {
|
||||
return path.endsWith(".gif") || path.endsWith(".webp")
|
||||
}
|
||||
|
||||
@Suppress("NewApi")
|
||||
actual fun loadImageBitmap(inputStream: InputStream): ImageBitmap =
|
||||
Image.makeFromEncoded(inputStream.readAllBytes()).toComposeImageBitmap()
|
||||
Image.makeFromEncoded(inputStream.readBytes()).toComposeImageBitmap()
|
||||
|
||||
// https://stackoverflow.com/a/68926993
|
||||
fun BufferedImage.rotate(angle: Double): BufferedImage {
|
||||
|
||||
+1
-2
@@ -189,12 +189,11 @@ fun startServer(onResponse: (WVAPIMessage) -> Unit): NanoWSD {
|
||||
val server = object: NanoWSD(SERVER_HOST, SERVER_PORT) {
|
||||
override fun openWebSocket(session: IHTTPSession): WebSocket = MyWebSocket(onResponse, session)
|
||||
|
||||
@Suppress("NewApi")
|
||||
fun resourcesToResponse(path: String): Response {
|
||||
val uri = Class.forName("chat.simplex.common.AppKt").getResource("/assets/www$path") ?: return resourceNotFound
|
||||
val response = newFixedLengthResponse(
|
||||
Status.OK, getMimeTypeForFile(uri.file),
|
||||
uri.openStream().readAllBytes()
|
||||
uri.openStream().readBytes()
|
||||
)
|
||||
response.setKeepAlive(true)
|
||||
response.setUseGzip(true)
|
||||
|
||||
Reference in New Issue
Block a user