Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/src/main/java/org/monogram/app/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import org.monogram.domain.repository.PushProvider
import org.monogram.presentation.core.util.AppPreferences
import org.monogram.presentation.core.util.LocalVideoPlayerPool
import org.monogram.presentation.core.util.NightMode
import org.monogram.presentation.features.chats.currentChat.components.chats.LocalLinkHandler
import org.monogram.presentation.features.chats.conversation.ui.message.LocalLinkHandler
import org.monogram.presentation.root.DefaultAppComponentContext
import org.monogram.presentation.root.DefaultRootComponent
import org.monogram.presentation.root.RootComponent
Expand Down
18 changes: 10 additions & 8 deletions app/src/main/java/org/monogram/app/MainContent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ import org.monogram.app.components.MobileLayout
import org.monogram.app.components.ProxyConfirmSheet
import org.monogram.app.components.TabletLayout
import org.monogram.presentation.core.util.LocalTabletInterfaceEnabled
import org.monogram.presentation.features.chats.currentChat.chatContent.ChatContentViewers
import org.monogram.presentation.features.chats.currentChat.components.StickerSetSheet
import org.monogram.presentation.features.chats.conversation.ui.StickerSetSheet
import org.monogram.presentation.features.chats.conversation.ui.content.ChatContentViewers
import org.monogram.presentation.features.profile.ProfileViewers
import org.monogram.presentation.features.stickers.core.toDomain
import org.monogram.presentation.root.RootComponent
Expand Down Expand Up @@ -172,12 +172,14 @@ fun MainContent(

when (activeChild) {
is RootComponent.Child.ChatDetailChild -> {
val chatState by activeChild.component.state.collectAsState()
ChatContentViewers(
state = chatState,
component = activeChild.component,
localClipboard = localClipboard
)
if (isExpanded && isTabletInterfaceEnabled) {
val chatState by activeChild.component.state.collectAsState()
ChatContentViewers(
state = chatState,
component = activeChild.component,
localClipboard = localClipboard
)
}
}
is RootComponent.Child.ProfileChild -> {
val profileState by activeChild.component.state.subscribeAsState()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.monogram.app.R
import org.monogram.presentation.features.chats.chatList.components.AvatarTopAppBar
import org.monogram.presentation.features.chats.list.components.AvatarTopAppBar
import org.monogram.presentation.root.RootComponent

@OptIn(ExperimentalMaterial3Api::class)
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/java/org/monogram/app/components/RenderChild.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package org.monogram.app.components

import androidx.compose.runtime.Composable
import org.monogram.presentation.features.auth.AuthContent
import org.monogram.presentation.features.chats.chatList.ChatListContent
import org.monogram.presentation.features.chats.currentChat.ChatContent
import org.monogram.presentation.features.chats.newChat.NewChatContent
import org.monogram.presentation.features.chats.conversation.ChatContent
import org.monogram.presentation.features.chats.creation.NewChatContent
import org.monogram.presentation.features.chats.list.ChatListContent
import org.monogram.presentation.features.profile.ProfileContent
import org.monogram.presentation.features.profile.admin.AdminManageContent
import org.monogram.presentation.features.profile.admin.ChatEditContent
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/org/monogram/app/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import org.monogram.domain.repository.CacheProvider
import org.monogram.domain.repository.EditorSnippetProvider
import org.monogram.domain.repository.ExternalNavigator
import org.monogram.domain.repository.MessageDisplayer
import org.monogram.presentation.core.media.ExoPlayerCache
import org.monogram.presentation.core.media.VideoPlayerPool
import org.monogram.presentation.core.util.AppPreferences
import org.monogram.presentation.core.util.BotPreferences
import org.monogram.presentation.core.util.CachePreferences
Expand All @@ -34,8 +36,6 @@ import org.monogram.presentation.core.util.ExternalNavigatorImpl
import org.monogram.presentation.core.util.IDownloadUtils
import org.monogram.presentation.core.util.ToastMessageDisplayer
import org.monogram.presentation.di.uiModule
import org.monogram.presentation.features.chats.currentChat.components.ExoPlayerCache
import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool
import org.monogram.presentation.settings.storage.CacheController

@SuppressLint("WrongConstant")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,15 @@ interface MessageRemoteDataSource {
suspend fun getMessageThread(chatId: Long, messageId: Long): TdApi.MessageThreadInfo?
suspend fun getMessages(chatId: Long, fromMessageId: Long, offset: Int, limit: Int, threadId: Long?): TdApi.Messages?
suspend fun getChatHistory(chatId: Long, fromMessageId: Long, offset: Int, limit: Int): TdApi.Messages?
suspend fun searchChatMessages(chatId: Long, query: String, fromMessageId: Long, limit: Int, filter: TdApi.SearchMessagesFilter, threadId: Long?): TdApi.FoundChatMessages?
suspend fun searchChatMessages(
chatId: Long,
query: String,
fromMessageId: Long,
limit: Int,
filter: TdApi.SearchMessagesFilter,
threadId: Long?,
senderId: Long? = null
): TdApi.FoundChatMessages?
suspend fun getChatPinnedMessage(chatId: Long): TdApi.Message?
suspend fun getPollVoters(chatId: Long, messageId: Long, optionId: Int, offset: Int, limit: Int): TdApi.PollVoters?
suspend fun getMessageViewers(chatId: Long, messageId: Long): TdApi.MessageViewers?
Expand Down Expand Up @@ -163,7 +171,8 @@ interface MessageRemoteDataSource {
query: String,
fromMessageId: Long,
limit: Int,
threadId: Long?
threadId: Long?,
senderId: Long? = null
): SearchChatMessagesResult

suspend fun getPollVotersModels(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ class TdMessageRemoteDataSource(
private suspend fun <T : TdApi.Object> safeExecute(function: TdApi.Function<T>): T? {
return try {
gateway.execute(function)
} catch (e: CancellationException) {
throw e
} catch (e: Exception) {
Log.e("TdMessageRemote", "Error executing ${function.javaClass.simpleName}", e)
null
Expand Down Expand Up @@ -370,12 +372,20 @@ class TdMessageRemoteDataSource(
}
}

override suspend fun searchChatMessages(chatId: Long, query: String, fromMessageId: Long, limit: Int, filter: TdApi.SearchMessagesFilter, threadId: Long?): TdApi.FoundChatMessages? {
override suspend fun searchChatMessages(
chatId: Long,
query: String,
fromMessageId: Long,
limit: Int,
filter: TdApi.SearchMessagesFilter,
threadId: Long?,
senderId: Long?
): TdApi.FoundChatMessages? {
val request = TdApi.SearchChatMessages().apply {
this.chatId = chatId
this.topicId = if (threadId != null) TdApi.MessageTopicForum(threadId.toInt()) else null
this.topicId = resolveSearchTopicId(chatId, threadId)
this.query = query
this.senderId = null
this.senderId = senderId?.let(TdApi::MessageSenderUser)
this.fromMessageId = fromMessageId
this.offset = 0
this.limit = limit
Expand All @@ -384,8 +394,23 @@ class TdMessageRemoteDataSource(
return safeExecute(request)
}

override suspend fun searchMessages(chatId: Long, query: String, fromMessageId: Long, limit: Int, threadId: Long?): SearchChatMessagesResult {
val result = searchChatMessages(chatId, query, fromMessageId, limit, TdApi.SearchMessagesFilterEmpty(), threadId)
override suspend fun searchMessages(
chatId: Long,
query: String,
fromMessageId: Long,
limit: Int,
threadId: Long?,
senderId: Long?
): SearchChatMessagesResult {
val result = searchChatMessages(
chatId = chatId,
query = query,
fromMessageId = fromMessageId,
limit = limit,
filter = TdApi.SearchMessagesFilterEmpty(),
threadId = threadId,
senderId = senderId
)
if (result != null) {
val chat = getChat(chatId)
val lastReadInbox = chat?.lastReadInboxMessageId ?: 0L
Expand All @@ -395,16 +420,36 @@ class TdMessageRemoteDataSource(
scope.async {
try {
withTimeout(5000) { messageMapper.mapMessageToModelSync(msg, lastReadInbox, lastReadOutbox, isChatOpen = true) }
} catch (e: CancellationException) {
throw e
} catch (e: Exception) {
Log.e("TdMessageRemote", "Error mapping search message ${msg.id}", e)
createFallbackMessage(msg)
}
}
}.awaitAll()
return SearchChatMessagesResult(models, result.totalCount, result.nextFromMessageId)
val nextCursor = result.nextFromMessageId.takeIf { it != 0L }
?: models.lastOrNull()?.id
?: 0L
return SearchChatMessagesResult(
messages = models,
totalCount = result.totalCount,
nextFromMessageId = if (models.size < result.totalCount) nextCursor else 0L
)
} else return SearchChatMessagesResult(emptyList(), 0, 0L)
}

private suspend fun resolveSearchTopicId(chatId: Long, threadId: Long?): TdApi.MessageTopic? {
if (threadId == null || threadId == 0L) return null

val chat = getChat(chatId)
return if (chat?.viewAsTopics == true) {
TdApi.MessageTopicForum(threadId.toInt())
} else {
TdApi.MessageTopicThread(threadId)
}
}

private suspend fun loadMessages(chatId: Long, fromMessageId: Long, offset: Int, limit: Int, threadId: Long? = null): List<MessageModel> = withContext(dispatcherProvider.io) {
val historyResult = getChatHistoryInternal(chatId, fromMessageId, offset, limit, threadId)
?: throw IllegalStateException(
Expand All @@ -423,6 +468,8 @@ class TdMessageRemoteDataSource(
async {
try {
withTimeout(5000) { messageMapper.mapMessageToModelSync(msg, lastReadInbox, lastReadOutbox, isChatOpen = true) }
} catch (e: CancellationException) {
throw e
} catch (e: Exception) {
Log.e("TdMessageRemote", "Error mapping message ${msg.id}", e)
createFallbackMessage(msg)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -842,9 +842,17 @@ class MessageRepositoryImpl(
query: String,
fromMessageId: Long,
limit: Int,
threadId: Long?
threadId: Long?,
senderId: Long?
): SearchChatMessagesResult = withContext(dispatcherProvider.io) {
messageRemoteDataSource.searchMessages(chatId, query, fromMessageId, limit, threadId)
messageRemoteDataSource.searchMessages(
chatId,
query,
fromMessageId,
limit,
threadId,
senderId
)
}

override fun updateVisibleRange(chatId: Long, visibleMessageIds: List<Long>, nearbyMessageIds: List<Long>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ interface MessageRepository :
query: String,
fromMessageId: Long = 0,
limit: Int = 50,
threadId: Long? = null
threadId: Long? = null,
senderId: Long? = null
): SearchChatMessagesResult

fun updateVisibleRange(chatId: Long, visibleMessageIds: List<Long>, nearbyMessageIds: List<Long>)
Expand Down
73 changes: 65 additions & 8 deletions presentation/src/main/cpp/native-lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,36 +517,36 @@ bool processVideoNative(const char* inputPath, const char* outputPath,

extern "C" {
JNIEXPORT jlong JNICALL
Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_create(
Java_org_monogram_presentation_core_media_NativeVideoRenderer_create(
JNIEnv* env, jobject instance, jobject surface, jboolean useAlpha, jboolean removeBlackBg) {
auto* renderer = new NativeVideoRenderer(env, instance, surface, useAlpha, removeBlackBg);
renderer->start();
return reinterpret_cast<jlong>(renderer);
}

JNIEXPORT void JNICALL
Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_destroy(
Java_org_monogram_presentation_core_media_NativeVideoRenderer_destroy(
JNIEnv* env, jobject /* this */, jlong handle) {
auto* renderer = reinterpret_cast<NativeVideoRenderer*>(handle);
delete renderer;
}

JNIEXPORT void JNICALL
Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_updateSize(
Java_org_monogram_presentation_core_media_NativeVideoRenderer_updateSize(
JNIEnv* env, jobject /* this */, jlong handle, jint width, jint height) {
auto* renderer = reinterpret_cast<NativeVideoRenderer*>(handle);
renderer->updateSize(width, height);
}

JNIEXPORT void JNICALL
Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_notifyFrameAvailable(
Java_org_monogram_presentation_core_media_NativeVideoRenderer_notifyFrameAvailable(
JNIEnv* env, jobject /* this */, jlong handle) {
auto* renderer = reinterpret_cast<NativeVideoRenderer*>(handle);
renderer->onFrameAvailable();
}

JNIEXPORT void JNICALL
Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_setFilter(
Java_org_monogram_presentation_core_media_NativeVideoRenderer_setFilter(
JNIEnv* env, jobject /* this */, jlong handle, jfloatArray matrix) {
auto* renderer = reinterpret_cast<NativeVideoRenderer*>(handle);
if (matrix == nullptr) {
Expand All @@ -559,12 +559,58 @@ Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideo
}

JNIEXPORT void JNICALL
Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_setOverlayTexture(
Java_org_monogram_presentation_core_media_NativeVideoRenderer_setOverlayTexture(
JNIEnv* env, jobject /* this */, jlong handle, jint textureId) {
auto* renderer = reinterpret_cast<NativeVideoRenderer*>(handle);
renderer->setOverlayTexture(textureId);
}

JNIEXPORT jlong JNICALL
Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_create(
JNIEnv *env, jobject instance, jobject surface, jboolean useAlpha, jboolean removeBlackBg) {
return Java_org_monogram_presentation_core_media_NativeVideoRenderer_create(
env, instance, surface, useAlpha, removeBlackBg
);
}

JNIEXPORT void JNICALL
Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_destroy(
JNIEnv *env, jobject instance, jlong handle) {
Java_org_monogram_presentation_core_media_NativeVideoRenderer_destroy(env, instance, handle);
}

JNIEXPORT void JNICALL
Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_updateSize(
JNIEnv *env, jobject instance, jlong handle, jint width, jint height) {
Java_org_monogram_presentation_core_media_NativeVideoRenderer_updateSize(
env, instance, handle, width, height
);
}

JNIEXPORT void JNICALL
Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_notifyFrameAvailable(
JNIEnv *env, jobject instance, jlong handle) {
Java_org_monogram_presentation_core_media_NativeVideoRenderer_notifyFrameAvailable(
env, instance, handle
);
}

JNIEXPORT void JNICALL
Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_setFilter(
JNIEnv *env, jobject instance, jlong handle, jfloatArray matrix) {
Java_org_monogram_presentation_core_media_NativeVideoRenderer_setFilter(
env, instance, handle, matrix
);
}

JNIEXPORT void JNICALL
Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_setOverlayTexture(
JNIEnv *env, jobject instance, jlong handle, jint textureId) {
Java_org_monogram_presentation_core_media_NativeVideoRenderer_setOverlayTexture(
env, instance, handle, textureId
);
}

JNIEXPORT jlong JNICALL
Java_org_monogram_presentation_features_stickers_core_VpxWrapper_create(JNIEnv* env, jobject thiz) {
return (jlong) new VpxDecoder();
Expand Down Expand Up @@ -603,7 +649,7 @@ Java_org_monogram_presentation_features_stickers_core_VpxWrapper_getHeight(JNIEn
}

JNIEXPORT jboolean JNICALL
Java_org_monogram_presentation_features_chats_currentChat_editor_video_VideoEditorUtils_processVideoNative(
Java_org_monogram_presentation_features_chats_conversation_editor_video_VideoEditorUtils_processVideoNative(
JNIEnv* env, jclass clazz,
jstring inputPath, jstring outputPath,
jlong startMs, jlong endMs,
Expand All @@ -629,4 +675,15 @@ Java_org_monogram_presentation_features_chats_currentChat_editor_video_VideoEdit
return result;
}

}
JNIEXPORT jboolean JNICALL
Java_org_monogram_presentation_features_chats_currentChat_editor_video_VideoEditorUtils_processVideoNative(
JNIEnv *env, jclass clazz,
jstring inputPath, jstring outputPath,
jlong startMs, jlong endMs,
jint targetHeight, jint bitrate, jboolean muteAudio, jfloatArray filterMatrix) {
return Java_org_monogram_presentation_features_chats_conversation_editor_video_VideoEditorUtils_processVideoNative(
env, clazz, inputPath, outputPath, startMs, endMs, targetHeight, bitrate, muteAudio, filterMatrix
);
}

}
Loading