mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-17 11:28:06 +00:00
Various UI improvements
This commit is contained in:
parent
76b41b693b
commit
cd3b9e1422
14 changed files with 127 additions and 53 deletions
|
|
@ -278,6 +278,13 @@ class ConversationFragment : GenericFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
viewModel.conferenceToJoinEvent.observe(viewLifecycleOwner) {
|
||||
it.consume { conferenceUri ->
|
||||
Log.i("$TAG Requesting to go to waiting room for conference URI [$conferenceUri]")
|
||||
sharedViewModel.goToMeetingWaitingRoomEvent.value = Event(conferenceUri)
|
||||
}
|
||||
}
|
||||
|
||||
binding.root.setKeyboardInsetListener { keyboardVisible ->
|
||||
if (keyboardVisible) {
|
||||
viewModel.isEmojiPickerOpen.value = false
|
||||
|
|
|
|||
|
|
@ -55,7 +55,10 @@ class ConversationsFragment : GenericFragment() {
|
|||
}
|
||||
|
||||
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
|
||||
if (findNavController().currentDestination?.id == R.id.startConversationFragment) {
|
||||
if (
|
||||
findNavController().currentDestination?.id == R.id.startConversationFragment ||
|
||||
findNavController().currentDestination?.id == R.id.meetingWaitingRoomFragment
|
||||
) {
|
||||
// Holds fragment in place while new contact fragment slides over it
|
||||
return AnimationUtils.loadAnimation(activity, R.anim.hold)
|
||||
}
|
||||
|
|
@ -115,9 +118,12 @@ class ConversationsFragment : GenericFragment() {
|
|||
|
||||
sharedViewModel.showStartConversationEvent.observe(viewLifecycleOwner) {
|
||||
it.consume {
|
||||
Log.i("$TAG Navigating to start conversation fragment")
|
||||
val action = ConversationsFragmentDirections.actionConversationsFragmentToStartConversationFragment()
|
||||
findNavController().navigate(action)
|
||||
if (findNavController().currentDestination?.id == R.id.conversationsFragment) {
|
||||
Log.i("$TAG Navigating to start conversation fragment")
|
||||
val action =
|
||||
ConversationsFragmentDirections.actionConversationsFragmentToStartConversationFragment()
|
||||
findNavController().navigate(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -136,6 +142,19 @@ class ConversationsFragment : GenericFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
sharedViewModel.goToMeetingWaitingRoomEvent.observe(viewLifecycleOwner) {
|
||||
it.consume { uri ->
|
||||
if (findNavController().currentDestination?.id == R.id.conversationsFragment) {
|
||||
Log.i("$TAG Navigating to meeting waiting room fragment with URI [$uri]")
|
||||
val action =
|
||||
ConversationsFragmentDirections.actionConversationsFragmentToMeetingWaitingRoomFragment(
|
||||
uri
|
||||
)
|
||||
findNavController().navigate(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sharedViewModel.navigateToContactsEvent.observe(viewLifecycleOwner) {
|
||||
it.consume {
|
||||
if (findNavController().currentDestination?.id == R.id.conversationsFragment) {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ class ChatMessageModel @WorkerThread constructor(
|
|||
val replyToMessageId: String?,
|
||||
val isGroupedWithPreviousOne: Boolean,
|
||||
val isGroupedWithNextOne: Boolean,
|
||||
val onContentClicked: ((file: String) -> Unit)? = null
|
||||
private val onContentClicked: ((file: String) -> Unit)? = null,
|
||||
private val onJoinConferenceClicked: ((uri: String) -> Unit)? = null
|
||||
) {
|
||||
companion object {
|
||||
private const val TAG = "[Chat Message Model]"
|
||||
|
|
@ -207,8 +208,12 @@ class ChatMessageModel @WorkerThread constructor(
|
|||
fun joinConference() {
|
||||
coreContext.postOnCoreThread {
|
||||
if (::meetingConferenceUri.isInitialized) {
|
||||
Log.i("$TAG Calling conference URI [${meetingConferenceUri.asStringUriOnly()}]")
|
||||
coreContext.startCall(meetingConferenceUri)
|
||||
val uri = meetingConferenceUri.asStringUriOnly()
|
||||
coreContext.postOnMainThread {
|
||||
onJoinConferenceClicked?.invoke(uri)
|
||||
}
|
||||
/*Log.i("$TAG Calling conference URI [${meetingConferenceUri.asStringUriOnly()}]")
|
||||
coreContext.startCall(meetingConferenceUri)*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -347,9 +352,12 @@ class ChatMessageModel @WorkerThread constructor(
|
|||
meetingDay.postValue(TimestampUtils.dayOfWeek(timestamp))
|
||||
meetingDayNumber.postValue(TimestampUtils.dayOfMonth(timestamp))
|
||||
|
||||
// TODO: fixme
|
||||
var count = 0
|
||||
for (info in conferenceInfo.participantInfos) {
|
||||
count += 1
|
||||
}
|
||||
meetingParticipants.postValue(
|
||||
AppUtils.getFormattedString(R.string.conference_participants_list_title, "24")
|
||||
AppUtils.getFormattedString(R.string.conference_participants_list_title, "$count")
|
||||
)
|
||||
|
||||
meetingFound.postValue(true)
|
||||
|
|
|
|||
|
|
@ -222,10 +222,22 @@ class ConversationModel @WorkerThread constructor(val chatRoom: ChatRoom) {
|
|||
|
||||
@WorkerThread
|
||||
private fun updateLastMessageStatus(message: ChatMessage) {
|
||||
val text = LinphoneUtils.getTextDescribingMessage(message)
|
||||
lastMessageText.postValue(text)
|
||||
|
||||
val isOutgoing = message.isOutgoing
|
||||
|
||||
val text = LinphoneUtils.getTextDescribingMessage(message)
|
||||
if (isGroup && !isOutgoing) {
|
||||
val fromAddress = message.fromAddress
|
||||
val sender = coreContext.contactsManager.findContactByAddress(fromAddress)
|
||||
val name = sender?.name ?: LinphoneUtils.getDisplayName(fromAddress)
|
||||
val senderName = AppUtils.getFormattedString(
|
||||
R.string.conversations_last_message_format,
|
||||
name
|
||||
)
|
||||
lastMessageText.postValue("$senderName $text")
|
||||
} else {
|
||||
lastMessageText.postValue(text)
|
||||
}
|
||||
|
||||
isLastMessageOutgoing.postValue(isOutgoing)
|
||||
if (isOutgoing) {
|
||||
lastMessageIcon.postValue(LinphoneUtils.getChatIconResId(message.state))
|
||||
|
|
@ -258,8 +270,7 @@ class ConversationModel @WorkerThread constructor(val chatRoom: ChatRoom) {
|
|||
TimestampUtils.timeToString(chatRoom.lastUpdateTime)
|
||||
}
|
||||
TimestampUtils.isYesterday(timestamp) -> {
|
||||
val time = TimestampUtils.timeToString(chatRoom.lastUpdateTime)
|
||||
AppUtils.getFormattedString(R.string.conversation_yesterday_timestamp, time)
|
||||
AppUtils.getString(R.string.yesterday)
|
||||
}
|
||||
else -> {
|
||||
TimestampUtils.toString(chatRoom.lastUpdateTime, onlyDate = true)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ class EventLogModel @WorkerThread constructor(
|
|||
isFromGroup: Boolean,
|
||||
isGroupedWithPreviousOne: Boolean,
|
||||
isGroupedWithNextOne: Boolean,
|
||||
onContentClicked: ((file: String) -> Unit)? = null
|
||||
onContentClicked: ((file: String) -> Unit)? = null,
|
||||
onJoinConferenceClicked: ((uri: String) -> Unit)? = null
|
||||
) {
|
||||
companion object {
|
||||
private const val TAG = "[Event Log Model]"
|
||||
|
|
@ -68,7 +69,8 @@ class EventLogModel @WorkerThread constructor(
|
|||
chatMessage.replyMessageId,
|
||||
isGroupedWithPreviousOne,
|
||||
isGroupedWithNextOne,
|
||||
onContentClicked
|
||||
onContentClicked,
|
||||
onJoinConferenceClicked
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,10 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
|
|||
MutableLiveData<Event<String>>()
|
||||
}
|
||||
|
||||
val conferenceToJoinEvent: MutableLiveData<Event<String>> by lazy {
|
||||
MutableLiveData<Event<String>>()
|
||||
}
|
||||
|
||||
val chatRoomFoundEvent = MutableLiveData<Event<Boolean>>()
|
||||
|
||||
lateinit var chatRoom: ChatRoom
|
||||
|
|
@ -120,10 +124,14 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
|
|||
avatarModel,
|
||||
LinphoneUtils.isChatRoomAGroup(chatRoom),
|
||||
group,
|
||||
true
|
||||
) { file ->
|
||||
fileToDisplayEvent.postValue(Event(file))
|
||||
}
|
||||
true,
|
||||
{ file ->
|
||||
fileToDisplayEvent.postValue(Event(file))
|
||||
},
|
||||
{ conferenceUri ->
|
||||
conferenceToJoinEvent.postValue(Event(conferenceUri))
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
events.postValue(list)
|
||||
|
|
@ -411,10 +419,14 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
|
|||
avatar,
|
||||
groupChatRoom,
|
||||
index > 0,
|
||||
index == groupedEventLogs.size - 1
|
||||
) { file ->
|
||||
fileToDisplayEvent.postValue(Event(file))
|
||||
}
|
||||
index == groupedEventLogs.size - 1,
|
||||
{ file ->
|
||||
fileToDisplayEvent.postValue(Event(file))
|
||||
},
|
||||
{ conferenceUri ->
|
||||
conferenceToJoinEvent.postValue(Event(conferenceUri))
|
||||
}
|
||||
)
|
||||
eventsList.add(model)
|
||||
|
||||
index += 1
|
||||
|
|
|
|||
|
|
@ -54,7 +54,10 @@ class MeetingsFragment : GenericFragment() {
|
|||
}
|
||||
|
||||
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
|
||||
if (findNavController().currentDestination?.id == R.id.scheduleMeetingFragment) {
|
||||
if (
|
||||
findNavController().currentDestination?.id == R.id.scheduleMeetingFragment ||
|
||||
findNavController().currentDestination?.id == R.id.meetingWaitingRoomFragment
|
||||
) {
|
||||
// Holds fragment in place while new contact fragment slides over it
|
||||
return AnimationUtils.loadAnimation(activity, R.anim.hold)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@
|
|||
|
||||
<ViewStub
|
||||
android:id="@+id/meeting_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="@dimen/chat_bubble_meeting_invite_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="@{model.meetingFound ? View.VISIBLE : View.GONE, default=gone}"
|
||||
android:layout="@layout/chat_bubble_meeting_invite_content"
|
||||
|
|
|
|||
|
|
@ -10,9 +10,8 @@
|
|||
</data>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="@dimen/chat_bubble_meeting_invite_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="300dp"
|
||||
android:background="@drawable/shape_squircle_white_r10_background">
|
||||
|
||||
<View
|
||||
|
|
@ -156,7 +155,7 @@
|
|||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style_300"
|
||||
android:id="@+id/participants"
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
|
|
@ -169,6 +168,7 @@
|
|||
android:drawableStart="@drawable/users"
|
||||
android:drawablePadding="4dp"
|
||||
app:drawableTint="@color/gray_main2_600"
|
||||
app:layout_constraintHorizontal_chainStyle="spread_inside"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/join"
|
||||
app:layout_constraintTop_toBottomOf="@id/description"/>
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@
|
|||
|
||||
<ViewStub
|
||||
android:id="@+id/meeting_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="@dimen/chat_bubble_meeting_invite_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="@{model.meetingFound ? View.VISIBLE : View.GONE, default=gone}"
|
||||
android:layout="@layout/chat_bubble_meeting_invite_content"
|
||||
|
|
|
|||
|
|
@ -62,12 +62,19 @@
|
|||
app:layout_constraintStart_toStartOf="@id/avatar"
|
||||
app:layout_constraintBottom_toBottomOf="@id/avatar"/>
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/unread_count_right_border"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="start"
|
||||
app:constraint_referenced_ids="ephemeral, muted, date_time, last_sent_message_status" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/right_border"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="start"
|
||||
app:constraint_referenced_ids="notifications_count, date_time" />
|
||||
app:constraint_referenced_ids="notifications_count, date_time, ephemeral, muted, last_sent_message_status" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style"
|
||||
|
|
@ -124,19 +131,7 @@
|
|||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/name"
|
||||
app:layout_constraintEnd_toStartOf="@id/date_time"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/last_sent_message_status"
|
||||
android:layout_width="@dimen/small_icon_size"
|
||||
android:layout_height="@dimen/small_icon_size"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:src="@{model.lastMessageIcon, default=@drawable/check}"
|
||||
android:visibility="@{model.isLastMessageOutgoing ? View.VISIBLE : View.GONE}"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/name"
|
||||
app:layout_constraintBottom_toBottomOf="@id/name"
|
||||
app:tint="@color/orange_main_500" />
|
||||
app:layout_constraintEnd_toStartOf="@id/unread_count_right_border"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style_300"
|
||||
|
|
@ -147,9 +142,21 @@
|
|||
android:text="@{model.dateTime, default=`16:45`}"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@color/gray_main2_500"
|
||||
app:layout_constraintEnd_toStartOf="@id/last_sent_message_status"
|
||||
app:layout_constraintTop_toTopOf="@id/last_sent_message_status"
|
||||
app:layout_constraintBottom_toBottomOf="@id/last_sent_message_status" />
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/name"
|
||||
app:layout_constraintBottom_toBottomOf="@id/name" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/last_sent_message_status"
|
||||
android:layout_width="@dimen/small_icon_size"
|
||||
android:layout_height="@dimen/small_icon_size"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:src="@{model.lastMessageIcon, default=@drawable/check}"
|
||||
android:visibility="@{model.isLastMessageOutgoing ? View.VISIBLE : View.GONE}"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/date_time"
|
||||
app:layout_constraintBottom_toTopOf="@id/separator"
|
||||
app:tint="@color/orange_main_500" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/muted"
|
||||
|
|
@ -158,7 +165,7 @@
|
|||
android:layout_marginEnd="10dp"
|
||||
android:src="@drawable/bell_simple_slash"
|
||||
android:visibility="@{model.isMuted ? View.VISIBLE : View.GONE}"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/last_sent_message_status"
|
||||
app:layout_constraintTop_toBottomOf="@id/date_time"
|
||||
app:layout_constraintBottom_toTopOf="@id/separator"
|
||||
app:tint="@color/gray_main2_400" />
|
||||
|
|
|
|||
|
|
@ -220,6 +220,12 @@
|
|||
app:enterAnim="@anim/slide_in"
|
||||
app:popExitAnim="@anim/slide_out"
|
||||
app:launchSingleTop="true" />
|
||||
<action
|
||||
android:id="@+id/action_conversationsFragment_to_meetingWaitingRoomFragment"
|
||||
app:destination="@id/meetingWaitingRoomFragment"
|
||||
app:enterAnim="@anim/slide_in"
|
||||
app:popExitAnim="@anim/slide_out"
|
||||
app:launchSingleTop="true" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
|
|
@ -260,10 +266,8 @@
|
|||
<action
|
||||
android:id="@+id/action_meetingsFragment_to_meetingWaitingRoomFragment"
|
||||
app:destination="@id/meetingWaitingRoomFragment"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_in_left"
|
||||
app:popExitAnim="@anim/slide_out_right"
|
||||
app:enterAnim="@anim/slide_in"
|
||||
app:popExitAnim="@anim/slide_out"
|
||||
app:launchSingleTop="true" />
|
||||
</fragment>
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@
|
|||
<dimen name="chat_bubble_long_press_emoji_reaction_size">30sp</dimen>
|
||||
<dimen name="chat_bubble_grid_image_size">88dp</dimen>
|
||||
<dimen name="chat_bubble_big_image_max_size">150dp</dimen>
|
||||
<dimen name="chat_bubble_meeting_invite_width">271dp</dimen>
|
||||
<dimen name="chat_bubble_max_width">291dp</dimen>
|
||||
<dimen name="chat_bubble_images_rounded_corner_radius">5dp</dimen>
|
||||
<dimen name="chat_bubble_start_margin_when_avatar_displayed">10dp</dimen>
|
||||
|
|
|
|||
|
|
@ -340,13 +340,13 @@
|
|||
<string name="call_incoming_for_account">Incoming call for %s</string>
|
||||
|
||||
<string name="conversations_list_empty">No conversation for the moment…</string>
|
||||
<string name="conversations_last_message_format">%s:</string>
|
||||
<string name="conversation_action_mark_as_read">Mark as read</string>
|
||||
<string name="conversation_action_mute">Mute</string>
|
||||
<string name="conversation_action_unmute">Un-mute</string>
|
||||
<string name="conversation_action_call">Call</string>
|
||||
<string name="conversation_action_delete">Delete conversation</string>
|
||||
<string name="conversation_action_leave_group">Leave the group</string>
|
||||
<string name="conversation_yesterday_timestamp">Yesterday at %s</string>
|
||||
<string name="new_conversation_title">New conversation</string>
|
||||
<string name="new_conversation_search_bar_filter_hint">Search contact</string>
|
||||
<string name="new_conversation_create_group">Create a group conversation</string>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue