mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-20 03:59:35 +01:00
Show Accept Call Button in Chat
- added call_started_message.xml - added CallStartedViewHolder.kt - added CallStartedMessageInterface.kt - Both join audio and join video buttons - Gets destroyed if call ends, persists despite state changes Signed-off-by: Julius Linus <julius.linus@nextcloud.com>
This commit is contained in:
parent
703f2c021d
commit
6db2f34a25
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Julius Linus
|
||||||
|
* Copyright (C) 2023 Julius Linus <julius.linus@nextcloud.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.nextcloud.talk.adapters.messages
|
||||||
|
|
||||||
|
interface CallStartedMessageInterface {
|
||||||
|
fun joinAudioCall()
|
||||||
|
fun joinVideoCall()
|
||||||
|
}
|
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Julius Linus
|
||||||
|
* Copyright (C) 2023 Julius Linus <julius.linus@nextcloud.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.adapters.messages
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.view.View
|
||||||
|
import autodagger.AutoInjector
|
||||||
|
import coil.Coil.imageLoader
|
||||||
|
import coil.request.ImageRequest
|
||||||
|
import coil.target.Target
|
||||||
|
import coil.transform.CircleCropTransformation
|
||||||
|
import com.nextcloud.talk.application.NextcloudTalkApplication
|
||||||
|
import com.nextcloud.talk.databinding.CallStartedMessageBinding
|
||||||
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
|
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||||
|
import com.nextcloud.talk.users.UserManager
|
||||||
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
|
import com.stfalcon.chatkit.messages.MessageHolders
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
|
class CallStartedViewHolder(incomingView: View, payload: Any) :
|
||||||
|
MessageHolders.BaseIncomingMessageViewHolder<ChatMessage>(incomingView, payload) {
|
||||||
|
private val binding: CallStartedMessageBinding = CallStartedMessageBinding.bind(incomingView)
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var context: Context
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var userManager: UserManager
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var viewThemeUtils: ViewThemeUtils
|
||||||
|
|
||||||
|
private lateinit var messageInterface: CallStartedMessageInterface
|
||||||
|
|
||||||
|
override fun onBind(message: ChatMessage) {
|
||||||
|
super.onBind(message)
|
||||||
|
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
|
||||||
|
themeBackground()
|
||||||
|
setUpAvatarProfile(message)
|
||||||
|
binding.callAuthorChip.text = message.actorDisplayName
|
||||||
|
binding.joinVideoCall.setOnClickListener { messageInterface.joinVideoCall() }
|
||||||
|
binding.joinAudioCall.setOnClickListener { messageInterface.joinAudioCall() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun themeBackground() {
|
||||||
|
binding.callStartedBackground.apply {
|
||||||
|
viewThemeUtils.talk.themeOutgoingMessageBubble(this, grouped = true, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.callAuthorChip.apply {
|
||||||
|
viewThemeUtils.material.colorChipBackground(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setUpAvatarProfile(message: ChatMessage) {
|
||||||
|
val user = userManager.currentUser.blockingGet()
|
||||||
|
val url: String = if (message.actorType == "guests" || message.actorType == "guest") {
|
||||||
|
ApiUtils.getUrlForGuestAvatar(
|
||||||
|
user!!.baseUrl,
|
||||||
|
message.actorDisplayName,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ApiUtils.getUrlForAvatar(user!!.baseUrl, message.actorDisplayName, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
val imageRequest: ImageRequest = ImageRequest.Builder(context)
|
||||||
|
.data(url)
|
||||||
|
.crossfade(true)
|
||||||
|
.transformations(CircleCropTransformation())
|
||||||
|
.target(object : Target {
|
||||||
|
override fun onStart(placeholder: Drawable?) {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(error: Drawable?) {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSuccess(result: Drawable) {
|
||||||
|
binding.callAuthorChip.chipIcon = result
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
|
||||||
|
imageLoader(context).enqueue(imageRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun assignCallStartedMessageInterface(inf: CallStartedMessageInterface) {
|
||||||
|
messageInterface = inf
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun viewDetached() {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun viewAttached() {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun viewRecycled() {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
var TAG: String? = CallStartedViewHolder::class.simpleName
|
||||||
|
}
|
||||||
|
}
|
@ -77,6 +77,8 @@ public class TalkMessagesListAdapter<M extends IMessage> extends MessagesListAda
|
|||||||
|
|
||||||
} else if (holder instanceof SystemMessageViewHolder) {
|
} else if (holder instanceof SystemMessageViewHolder) {
|
||||||
((SystemMessageViewHolder) holder).assignSystemMessageInterface(chatActivity);
|
((SystemMessageViewHolder) holder).assignSystemMessageInterface(chatActivity);
|
||||||
|
} else if (holder instanceof CallStartedViewHolder) {
|
||||||
|
((CallStartedViewHolder) holder).assignCallStartedMessageInterface(chatActivity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,6 +121,8 @@ import com.nextcloud.talk.R
|
|||||||
import com.nextcloud.talk.activities.BaseActivity
|
import com.nextcloud.talk.activities.BaseActivity
|
||||||
import com.nextcloud.talk.activities.CallActivity
|
import com.nextcloud.talk.activities.CallActivity
|
||||||
import com.nextcloud.talk.activities.TakePhotoActivity
|
import com.nextcloud.talk.activities.TakePhotoActivity
|
||||||
|
import com.nextcloud.talk.adapters.messages.CallStartedMessageInterface
|
||||||
|
import com.nextcloud.talk.adapters.messages.CallStartedViewHolder
|
||||||
import com.nextcloud.talk.adapters.messages.CommonMessageInterface
|
import com.nextcloud.talk.adapters.messages.CommonMessageInterface
|
||||||
import com.nextcloud.talk.adapters.messages.IncomingLinkPreviewMessageViewHolder
|
import com.nextcloud.talk.adapters.messages.IncomingLinkPreviewMessageViewHolder
|
||||||
import com.nextcloud.talk.adapters.messages.IncomingLocationMessageViewHolder
|
import com.nextcloud.talk.adapters.messages.IncomingLocationMessageViewHolder
|
||||||
@ -268,7 +270,8 @@ class ChatActivity :
|
|||||||
VoiceMessageInterface,
|
VoiceMessageInterface,
|
||||||
CommonMessageInterface,
|
CommonMessageInterface,
|
||||||
PreviewMessageInterface,
|
PreviewMessageInterface,
|
||||||
SystemMessageInterface {
|
SystemMessageInterface,
|
||||||
|
CallStartedMessageInterface {
|
||||||
|
|
||||||
var active = false
|
var active = false
|
||||||
|
|
||||||
@ -377,6 +380,8 @@ class ChatActivity :
|
|||||||
var typedWhileTypingTimerIsRunning: Boolean = false
|
var typedWhileTypingTimerIsRunning: Boolean = false
|
||||||
val typingParticipants = HashMap<String, TypingParticipant>()
|
val typingParticipants = HashMap<String, TypingParticipant>()
|
||||||
|
|
||||||
|
var callStarted = false
|
||||||
|
|
||||||
private val localParticipantMessageListener = object : SignalingMessageReceiver.LocalParticipantMessageListener {
|
private val localParticipantMessageListener = object : SignalingMessageReceiver.LocalParticipantMessageListener {
|
||||||
override fun onSwitchTo(token: String?) {
|
override fun onSwitchTo(token: String?) {
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
@ -946,6 +951,17 @@ class ChatActivity :
|
|||||||
R.layout.item_custom_outcoming_preview_message
|
R.layout.item_custom_outcoming_preview_message
|
||||||
)
|
)
|
||||||
|
|
||||||
|
messageHolders.registerContentType(
|
||||||
|
CONTENT_TYPE_CALL_STARTED,
|
||||||
|
CallStartedViewHolder::class.java,
|
||||||
|
payload,
|
||||||
|
R.layout.call_started_message,
|
||||||
|
CallStartedViewHolder::class.java,
|
||||||
|
payload,
|
||||||
|
R.layout.call_started_message,
|
||||||
|
this
|
||||||
|
)
|
||||||
|
|
||||||
messageHolders.registerContentType(
|
messageHolders.registerContentType(
|
||||||
CONTENT_TYPE_SYSTEM_MESSAGE,
|
CONTENT_TYPE_SYSTEM_MESSAGE,
|
||||||
SystemMessageViewHolder::class.java,
|
SystemMessageViewHolder::class.java,
|
||||||
@ -1808,7 +1824,7 @@ class ChatActivity :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mediaPlayerHandler.postDelayed(this, 15)
|
mediaPlayerHandler.postDelayed(this, MILISEC_15)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -3189,6 +3205,31 @@ class ChatActivity :
|
|||||||
Integer.parseInt(it)
|
Integer.parseInt(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
val mostRecentCallSystemMessage = adapter?.items?.first {
|
||||||
|
it.item is ChatMessage &&
|
||||||
|
(it.item as ChatMessage).systemMessageType in
|
||||||
|
listOf(
|
||||||
|
ChatMessage.SystemMessageType.CALL_STARTED,
|
||||||
|
ChatMessage.SystemMessageType.CALL_JOINED,
|
||||||
|
ChatMessage.SystemMessageType.CALL_LEFT,
|
||||||
|
ChatMessage.SystemMessageType.CALL_ENDED,
|
||||||
|
ChatMessage.SystemMessageType.CALL_TRIED,
|
||||||
|
ChatMessage.SystemMessageType.CALL_ENDED_EVERYONE,
|
||||||
|
ChatMessage.SystemMessageType.CALL_MISSED
|
||||||
|
)
|
||||||
|
}?.item
|
||||||
|
|
||||||
|
if (mostRecentCallSystemMessage != null) {
|
||||||
|
processMostRecentMessage(
|
||||||
|
mostRecentCallSystemMessage as ChatMessage,
|
||||||
|
chatMessageList
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (e: java.util.NoSuchElementException) {
|
||||||
|
Log.d(TAG, "No System messages found $e")
|
||||||
|
}
|
||||||
|
|
||||||
updateReadStatusOfAllMessages(newXChatLastCommonRead)
|
updateReadStatusOfAllMessages(newXChatLastCommonRead)
|
||||||
adapter?.notifyDataSetChanged()
|
adapter?.notifyDataSetChanged()
|
||||||
|
|
||||||
@ -4230,10 +4271,39 @@ class ChatActivity :
|
|||||||
CONTENT_TYPE_LINK_PREVIEW -> message.isLinkPreview()
|
CONTENT_TYPE_LINK_PREVIEW -> message.isLinkPreview()
|
||||||
CONTENT_TYPE_SYSTEM_MESSAGE -> !TextUtils.isEmpty(message.systemMessage)
|
CONTENT_TYPE_SYSTEM_MESSAGE -> !TextUtils.isEmpty(message.systemMessage)
|
||||||
CONTENT_TYPE_UNREAD_NOTICE_MESSAGE -> message.id == "-1"
|
CONTENT_TYPE_UNREAD_NOTICE_MESSAGE -> message.id == "-1"
|
||||||
|
CONTENT_TYPE_CALL_STARTED -> message.id == "-2"
|
||||||
|
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun processMostRecentMessage(recent: ChatMessage, chatMessageList: List<ChatMessage>) {
|
||||||
|
when (recent.systemMessageType) {
|
||||||
|
ChatMessage.SystemMessageType.CALL_STARTED -> { // add CallStartedMessage with id -2
|
||||||
|
if (!callStarted) {
|
||||||
|
val callStartedChatMessage = ChatMessage()
|
||||||
|
callStartedChatMessage.jsonMessageId = CALL_STARTED_ID
|
||||||
|
callStartedChatMessage.actorId = "-2"
|
||||||
|
val name = if (recent.actorDisplayName.isNullOrEmpty()) "Guest" else recent.actorDisplayName
|
||||||
|
callStartedChatMessage.actorDisplayName = name
|
||||||
|
callStartedChatMessage.actorType = recent.actorType
|
||||||
|
callStartedChatMessage.timestamp = chatMessageList[0].timestamp
|
||||||
|
callStartedChatMessage.message = null
|
||||||
|
adapter?.addToStart(callStartedChatMessage, false)
|
||||||
|
callStarted = true
|
||||||
|
}
|
||||||
|
} // remove CallStartedMessage with id -2
|
||||||
|
ChatMessage.SystemMessageType.CALL_ENDED,
|
||||||
|
ChatMessage.SystemMessageType.CALL_MISSED,
|
||||||
|
ChatMessage.SystemMessageType.CALL_TRIED,
|
||||||
|
ChatMessage.SystemMessageType.CALL_ENDED_EVERYONE -> {
|
||||||
|
adapter?.deleteById("-2")
|
||||||
|
callStarted = false
|
||||||
|
} // remove message of id -2
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
||||||
fun onMessageEvent(webSocketCommunicationEvent: WebSocketCommunicationEvent) {
|
fun onMessageEvent(webSocketCommunicationEvent: WebSocketCommunicationEvent) {
|
||||||
/*
|
/*
|
||||||
@ -4367,6 +4437,14 @@ class ChatActivity :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun joinAudioCall() {
|
||||||
|
startACall(true, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun joinVideoCall() {
|
||||||
|
startACall(false, false)
|
||||||
|
}
|
||||||
|
|
||||||
private fun logConversationInfos(methodName: String) {
|
private fun logConversationInfos(methodName: String) {
|
||||||
Log.d(TAG, " |-----------------------------------------------")
|
Log.d(TAG, " |-----------------------------------------------")
|
||||||
Log.d(TAG, " | method: $methodName")
|
Log.d(TAG, " | method: $methodName")
|
||||||
@ -4379,12 +4457,13 @@ class ChatActivity :
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val TAG = ChatActivity::class.simpleName
|
private val TAG = ChatActivity::class.simpleName
|
||||||
private const val CONTENT_TYPE_SYSTEM_MESSAGE: Byte = 1
|
private const val CONTENT_TYPE_CALL_STARTED: Byte = 1
|
||||||
private const val CONTENT_TYPE_UNREAD_NOTICE_MESSAGE: Byte = 2
|
private const val CONTENT_TYPE_SYSTEM_MESSAGE: Byte = 2
|
||||||
private const val CONTENT_TYPE_LOCATION: Byte = 3
|
private const val CONTENT_TYPE_UNREAD_NOTICE_MESSAGE: Byte = 3
|
||||||
private const val CONTENT_TYPE_VOICE_MESSAGE: Byte = 4
|
private const val CONTENT_TYPE_LOCATION: Byte = 4
|
||||||
private const val CONTENT_TYPE_POLL: Byte = 5
|
private const val CONTENT_TYPE_VOICE_MESSAGE: Byte = 5
|
||||||
private const val CONTENT_TYPE_LINK_PREVIEW: Byte = 6
|
private const val CONTENT_TYPE_POLL: Byte = 6
|
||||||
|
private const val CONTENT_TYPE_LINK_PREVIEW: Byte = 7
|
||||||
private const val NEW_MESSAGES_POPUP_BUBBLE_DELAY: Long = 200
|
private const val NEW_MESSAGES_POPUP_BUBBLE_DELAY: Long = 200
|
||||||
private const val GET_ROOM_INFO_DELAY_NORMAL: Long = 30000
|
private const val GET_ROOM_INFO_DELAY_NORMAL: Long = 30000
|
||||||
private const val GET_ROOM_INFO_DELAY_LOBBY: Long = 5000
|
private const val GET_ROOM_INFO_DELAY_LOBBY: Long = 5000
|
||||||
@ -4417,7 +4496,6 @@ class ChatActivity :
|
|||||||
private const val FULLY_OPAQUE_INT: Int = 255
|
private const val FULLY_OPAQUE_INT: Int = 255
|
||||||
private const val SEMI_TRANSPARENT_INT: Int = 99
|
private const val SEMI_TRANSPARENT_INT: Int = 99
|
||||||
private const val VOICE_MESSAGE_SEEKBAR_BASE = 1000
|
private const val VOICE_MESSAGE_SEEKBAR_BASE = 1000
|
||||||
private const val SECOND: Long = 1000
|
|
||||||
private const val NO_PREVIOUS_MESSAGE_ID: Int = -1
|
private const val NO_PREVIOUS_MESSAGE_ID: Int = -1
|
||||||
private const val GROUPED_MESSAGES_THRESHOLD = 4
|
private const val GROUPED_MESSAGES_THRESHOLD = 4
|
||||||
private const val GROUPED_MESSAGES_SAME_AUTHOR_THRESHOLD = 5
|
private const val GROUPED_MESSAGES_SAME_AUTHOR_THRESHOLD = 5
|
||||||
@ -4447,5 +4525,7 @@ class ChatActivity :
|
|||||||
private const val TYPING_INTERVAL_TO_SEND_NEXT_TYPING_MESSAGE = 1000L
|
private const val TYPING_INTERVAL_TO_SEND_NEXT_TYPING_MESSAGE = 1000L
|
||||||
private const val TYPING_STARTED_SIGNALING_MESSAGE_TYPE = "startedTyping"
|
private const val TYPING_STARTED_SIGNALING_MESSAGE_TYPE = "startedTyping"
|
||||||
private const val TYPING_STOPPED_SIGNALING_MESSAGE_TYPE = "stoppedTyping"
|
private const val TYPING_STOPPED_SIGNALING_MESSAGE_TYPE = "stoppedTyping"
|
||||||
|
private const val CALL_STARTED_ID = -2
|
||||||
|
private const val MILISEC_15: Long = 15
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
90
app/src/main/res/layout/call_started_message.xml
Normal file
90
app/src/main/res/layout/call_started_message.xml
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
~ Nextcloud Talk application
|
||||||
|
~
|
||||||
|
~ @author Julius Linus
|
||||||
|
~ Copyright (C) 2023 Julius Linus <julius.linus@nextcloud.com>
|
||||||
|
~
|
||||||
|
~ This program is free software: you can redistribute it and/or modify
|
||||||
|
~ it under the terms of the GNU General Public License as published by
|
||||||
|
~ the Free Software Foundation, either version 3 of the License, or
|
||||||
|
~ at your option) any later version.
|
||||||
|
~
|
||||||
|
~ This program is distributed in the hope that it will be useful,
|
||||||
|
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
~ GNU General Public License for more details.
|
||||||
|
~
|
||||||
|
~ You should have received a copy of the GNU General Public License
|
||||||
|
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/call_started_background"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="@dimen/standard_double_margin"
|
||||||
|
android:padding="@dimen/standard_padding"
|
||||||
|
tools:background="@drawable/shape_grouped_outcoming_message"
|
||||||
|
tools:backgroundTint="@color/colorPrimaryDark">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/standard_margin"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<com.google.android.material.chip.Chip
|
||||||
|
android:id="@+id/call_author_chip"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="@dimen/standard_quarter_margin"
|
||||||
|
app:chipIcon="@drawable/accent_circle"
|
||||||
|
app:chipCornerRadius="@dimen/dialogBorderRadius"
|
||||||
|
tools:text="Jessica Fox" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/started_a_call" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/join_video_call"
|
||||||
|
style="@style/Widget.Material3.Button.Icon"
|
||||||
|
android:backgroundTint="@color/nc_darkGreen"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="@dimen/standard_half_margin"
|
||||||
|
app:icon="@drawable/ic_videocam_grey_600_24dp"
|
||||||
|
app:iconTint="@color/white"
|
||||||
|
android:alpha="0.8"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:text="@string/video_call" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/join_audio_call"
|
||||||
|
style="@style/Widget.Material3.Button.Icon"
|
||||||
|
android:backgroundTint="@color/nc_darkGreen"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="@dimen/standard_half_margin"
|
||||||
|
android:alpha="0.8"
|
||||||
|
app:icon="@drawable/ic_phone"
|
||||||
|
app:iconTint="@color/white"
|
||||||
|
android:text="@string/audio_call"
|
||||||
|
android:textColor="@color/white" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -706,6 +706,9 @@ How to translate with transifex:
|
|||||||
<string name="custom">Custom</string>
|
<string name="custom">Custom</string>
|
||||||
<string name="set">Set</string>
|
<string name="set">Set</string>
|
||||||
<string name="calendar">Calendar</string>
|
<string name="calendar">Calendar</string>
|
||||||
|
<string name="video_call">Video Call</string>
|
||||||
|
<string name="audio_call">Audio Call</string>
|
||||||
|
<string name="started_a_call">started a call</string>
|
||||||
<string name="nc_settings_phone_book_integration_phone_number_dialog_429">Error 429 Too Many Requests</string>
|
<string name="nc_settings_phone_book_integration_phone_number_dialog_429">Error 429 Too Many Requests</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user