Invitation : start polishing but theme has to be rework. Waiting for Nad inputs.

This commit is contained in:
ganfra 2019-05-13 19:23:02 +02:00 committed by ganfra
parent c39cfbe2ae
commit f60a5f568f
13 changed files with 149 additions and 33 deletions

View File

@ -26,6 +26,8 @@ import android.text.Editable
import android.text.Spannable import android.text.Spannable
import android.view.View import android.view.View
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.airbnb.epoxy.EpoxyVisibilityTracker import com.airbnb.epoxy.EpoxyVisibilityTracker
@ -51,12 +53,7 @@ import im.vector.riotredesign.core.extensions.observeEvent
import im.vector.riotredesign.core.glide.GlideApp import im.vector.riotredesign.core.glide.GlideApp
import im.vector.riotredesign.core.platform.ToolbarConfigurable import im.vector.riotredesign.core.platform.ToolbarConfigurable
import im.vector.riotredesign.core.platform.VectorBaseFragment import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.core.utils.PERMISSIONS_FOR_TAKING_PHOTO import im.vector.riotredesign.core.utils.*
import im.vector.riotredesign.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_CAMERA
import im.vector.riotredesign.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_NATIVE_CAMERA
import im.vector.riotredesign.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_NATIVE_VIDEO_CAMERA
import im.vector.riotredesign.core.utils.checkPermissions
import im.vector.riotredesign.core.utils.openCamera
import im.vector.riotredesign.features.autocomplete.command.AutocompleteCommandPresenter import im.vector.riotredesign.features.autocomplete.command.AutocompleteCommandPresenter
import im.vector.riotredesign.features.autocomplete.command.CommandAutocompletePolicy import im.vector.riotredesign.features.autocomplete.command.CommandAutocompletePolicy
import im.vector.riotredesign.features.autocomplete.user.AutocompleteUserPresenter import im.vector.riotredesign.features.autocomplete.user.AutocompleteUserPresenter
@ -333,12 +330,15 @@ class RoomDetailFragment : VectorBaseFragment(), TimelineEventController.Callbac
private fun renderState(state: RoomDetailViewState) { private fun renderState(state: RoomDetailViewState) {
renderRoomSummary(state) renderRoomSummary(state)
val summary = state.asyncRoomSummary() val summary = state.asyncRoomSummary()
val inviter = state.inviter()
if (summary?.membership == Membership.JOIN) { if (summary?.membership == Membership.JOIN) {
timelineEventController.setTimeline(state.timeline) timelineEventController.setTimeline(state.timeline)
inviteView.visibility = View.GONE inviteView.visibility = View.GONE
} else if (summary?.membership == Membership.INVITE) { } else if (summary?.membership == Membership.INVITE && inviter != null) {
inviteView.visibility = View.VISIBLE inviteView.visibility = View.VISIBLE
inviteView.render(summary) inviteView.render(inviter, VectorInviteView.Mode.LARGE)
} else {
//TODO : close the screen
} }
} }



View File

@ -19,11 +19,13 @@ package im.vector.riotredesign.features.home.room.detail
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.ViewModelContext import com.airbnb.mvrx.ViewModelContext
import com.jakewharton.rxrelay2.BehaviorRelay import com.jakewharton.rxrelay2.BehaviorRelay
import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.content.ContentAttachmentData import im.vector.matrix.android.api.session.content.ContentAttachmentData
import im.vector.matrix.android.api.session.room.model.Membership
import im.vector.matrix.android.api.session.room.model.message.MessageType import im.vector.matrix.android.api.session.room.model.message.MessageType
import im.vector.matrix.rx.rx import im.vector.matrix.rx.rx
import im.vector.riotredesign.core.platform.VectorViewModel import im.vector.riotredesign.core.platform.VectorViewModel
@ -62,6 +64,7 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
init { init {
observeRoomSummary() observeRoomSummary()
observeEventDisplayedActions() observeEventDisplayedActions()
observeInvitationState()
room.loadRoomMembersIfNeeded() room.loadRoomMembersIfNeeded()
timeline.start() timeline.start()
setState { copy(timeline = this@RoomDetailViewModel.timeline) } setState { copy(timeline = this@RoomDetailViewModel.timeline) }
@ -240,6 +243,18 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
} }
} }


private fun observeInvitationState() {
asyncSubscribe(RoomDetailViewState::asyncRoomSummary) { summary ->
if (summary.membership == Membership.INVITE) {
summary.lastMessage?.sender?.let { senderId ->
session.getUser(senderId)
}?.also {
setState { copy(inviter = Success(it)) }
}
}
}
}

override fun onCleared() { override fun onCleared() {
timeline.dispose() timeline.dispose()
super.onCleared() super.onCleared()

View File

@ -22,11 +22,13 @@ import com.airbnb.mvrx.Uninitialized
import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.timeline.Timeline import im.vector.matrix.android.api.session.room.timeline.Timeline
import im.vector.matrix.android.api.session.room.timeline.TimelineData import im.vector.matrix.android.api.session.room.timeline.TimelineData
import im.vector.matrix.android.api.session.user.model.User


data class RoomDetailViewState( data class RoomDetailViewState(
val roomId: String, val roomId: String,
val eventId: String?, val eventId: String?,
val timeline: Timeline? = null, val timeline: Timeline? = null,
val inviter: Async<User> = Uninitialized,
val asyncRoomSummary: Async<RoomSummary> = Uninitialized, val asyncRoomSummary: Async<RoomSummary> = Uninitialized,
val asyncTimelineData: Async<TimelineData> = Uninitialized val asyncTimelineData: Async<TimelineData> = Uninitialized
) : MvRxState { ) : MvRxState {

View File

@ -21,7 +21,9 @@ import android.graphics.Color
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import im.vector.matrix.android.api.session.room.model.RoomSummary import androidx.core.view.setPadding
import androidx.core.view.updateLayoutParams
import im.vector.matrix.android.api.session.user.model.User
import im.vector.riotredesign.R import im.vector.riotredesign.R
import im.vector.riotredesign.features.home.AvatarRenderer import im.vector.riotredesign.features.home.AvatarRenderer
import kotlinx.android.synthetic.main.vector_invite_view.view.* import kotlinx.android.synthetic.main.vector_invite_view.view.*
@ -34,19 +36,33 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib
fun onRejectInvite() fun onRejectInvite()
} }


enum class Mode {
LARGE,
SMALL
}

var callback: Callback? = null var callback: Callback? = null


init { init {
View.inflate(context, R.layout.vector_invite_view, this) View.inflate(context, R.layout.vector_invite_view, this)
layoutParams = ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT, ConstraintLayout.LayoutParams.MATCH_PARENT)
setBackgroundColor(Color.WHITE) setBackgroundColor(Color.WHITE)
inviteRejectView.setOnClickListener { callback?.onRejectInvite() } inviteRejectView.setOnClickListener { callback?.onRejectInvite() }
inviteAcceptView.setOnClickListener { callback?.onAcceptInvite() } inviteAcceptView.setOnClickListener { callback?.onAcceptInvite() }
} }


fun render(roomSummary: RoomSummary) { fun render(sender: User, mode: Mode = Mode.LARGE) {
AvatarRenderer.render(roomSummary.avatarUrl, roomSummary.roomId, roomSummary.displayName, inviteAvatarView) if (mode == Mode.LARGE) {
inviteIdentifierView.text = roomSummary.lastMessage?.sender updateLayoutParams { height = ConstraintLayout.LayoutParams.MATCH_CONSTRAINT }
inviteNameView.text = roomSummary.displayName AvatarRenderer.render(sender.avatarUrl, sender.userId, sender.displayName, inviteAvatarView)
inviteIdentifierView.text = sender.userId
inviteNameView.text = sender.displayName
inviteLabelView.text = context.getString(R.string.send_you_invite)
} else {
updateLayoutParams { height = ConstraintLayout.LayoutParams.WRAP_CONTENT }
inviteAvatarView.visibility = View.GONE
inviteIdentifierView.visibility = View.GONE
inviteNameView.visibility = View.GONE
inviteLabelView.text = context.getString(R.string.invited_by, sender.userId)
}
} }
} }

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2019 New Vector Ltd
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@android:color/transparent"/>
<stroke android:width="1dp" android:color="?attr/colorAccent" />
</shape>
</item>
</selector>

View File

@ -142,11 +142,13 @@
<im.vector.riotredesign.features.invite.VectorInviteView <im.vector.riotredesign.features.invite.VectorInviteView
android:id="@+id/inviteView" android:id="@+id/inviteView"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="wrap_content"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar" /> app:layout_constraintTop_toBottomOf="@+id/toolbar"
app:layout_constraintVertical_bias="1.0" />


</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -25,27 +25,30 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="40dp" android:layout_marginTop="40dp"
android:text="Matthew" android:textAppearance="@style/TextAppearance.Vector.Title"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/inviteAvatarView" /> app:layout_constraintTop_toBottomOf="@id/inviteAvatarView"
tools:text="Matthew" />


<TextView <TextView
android:id="@+id/inviteIdentifierView" android:id="@+id/inviteIdentifierView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:text="\@matthew:matrix.org" android:textAppearance="@style/TextAppearance.Vector.Subtitle"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/inviteNameView" /> app:layout_constraintTop_toBottomOf="@id/inviteNameView"
tools:text="\@matthew:matrix.org" />


<TextView <TextView
android:id="@+id/inviteLabelView" android:id="@+id/inviteLabelView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="40dp" android:layout_marginTop="40dp"
android:text="@string/notice_room_invite_you" android:text="@string/send_you_invite"
android:textAppearance="@style/TextAppearance.Vector.Subtitle2"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/inviteIdentifierView" /> app:layout_constraintTop_toBottomOf="@id/inviteIdentifierView" />
@ -54,7 +57,7 @@
android:id="@+id/inviteRejectView" android:id="@+id/inviteRejectView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="24dp" android:layout_marginTop="16dp"
android:layout_marginRight="4dp" android:layout_marginRight="4dp"
android:text="@string/reject" android:text="@string/reject"
app:layout_constraintEnd_toStartOf="@+id/inviteAcceptView" app:layout_constraintEnd_toStartOf="@+id/inviteAcceptView"
@ -73,5 +76,10 @@
app:layout_constraintStart_toEndOf="@+id/inviteRejectView" app:layout_constraintStart_toEndOf="@+id/inviteRejectView"
app:layout_constraintTop_toTopOf="@id/inviteRejectView" /> app:layout_constraintTop_toTopOf="@id/inviteRejectView" />


<Space
android:layout_height="16dp"
android:layout_width="match_parent"
app:layout_constraintTop_toBottomOf="@id/inviteAcceptView"/>



</merge> </merge>

View File

@ -3,7 +3,6 @@
<color name="pale_grey">#f2f5f8</color> <color name="pale_grey">#f2f5f8</color>
<color name="dark">#2e3649</color> <color name="dark">#2e3649</color>
<color name="pale_teal">#7ac9a1</color> <color name="pale_teal">#7ac9a1</color>
<color name="black">#212121</color>
<color name="deep_sky_blue">#007aff</color> <color name="deep_sky_blue">#007aff</color>
<color name="rosy_pink">#f56679</color> <color name="rosy_pink">#f56679</color>
<color name="bluey_grey">#a5a5a6</color> <color name="bluey_grey">#a5a5a6</color>
@ -18,4 +17,9 @@
<color name="brown_grey">#a5a5a5</color> <color name="brown_grey">#a5a5a5</color>
<color name="grey_lynch">#61708B</color> <color name="grey_lynch">#61708B</color>


<color name="black">#000000</color>
<color name="black_87">#de000000</color>
<color name="black_38">#61000000</color>
<color name="black_37">#5d000000</color>

</resources> </resources>

View File

@ -4,5 +4,7 @@
<!-- Strings not defined in Riot --> <!-- Strings not defined in Riot -->
<string name="global_retry">"Retry"</string> <string name="global_retry">"Retry"</string>
<string name="room_list_empty">"Join a room to start using the app."</string> <string name="room_list_empty">"Join a room to start using the app."</string>
<string name="send_you_invite">"Sent you an invitation"</string>
<string name="invited_by">Invited by %s</string>


</resources> </resources>

View File

@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>


<style name="Widget.Button" parent="Widget.AppCompat.Button"> <style name="Widget.Vector.Button" parent="Widget.AppCompat.Button">
<item name="android:minHeight">48dp</item> <item name="android:minHeight">48dp</item>
<item name="android:background">?attr/colorAccent</item> <item name="android:minWidth">128dp</item>
<item name="android:textColor">@android:color/white</item> <item name="android:paddingRight">8dp</item>
<item name="android:paddingLeft">8dp</item>
<item name="android:textAllCaps">true</item>
</style> </style>



</resources> </resources>

View File

@ -1,5 +1,40 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?><!--
<resources> ~ Copyright 2019 New Vector Ltd
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->


<resources xmlns:android="http://schemas.android.com/apk/res/android">

<style name="TextAppearance.Vector.Title" parent="TextAppearance.AppCompat">
<item name="android:textSize">16sp</item>
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@color/black_87</item>
</style>

<style name="TextAppearance.Vector.Subtitle" parent="TextAppearance.AppCompat">
<item name="android:textSize">14sp</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@color/black_37</item>
</style>

<style name="TextAppearance.Vector.Subtitle2" parent="TextAppearance.AppCompat">
<item name="android:textSize">14sp</item>
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@color/black_38</item>
</style>


</resources> </resources>

View File

@ -6,12 +6,14 @@
<style name="AppTheme.Base.Light" parent="Theme.MaterialComponents.Light.NoActionBar.Bridge"> <style name="AppTheme.Base.Light" parent="Theme.MaterialComponents.Light.NoActionBar.Bridge">
<item name="colorPrimaryDark">@color/primary_color_dark_light</item> <item name="colorPrimaryDark">@color/primary_color_dark_light</item>
<item name="colorPrimary">@color/primary_color_light</item> <item name="colorPrimary">@color/primary_color_light</item>
<item name="colorPrimaryVariant">@color/primary_color_dark_light</item>
<item name="colorSecondary">@color/accent_color_light</item>
<item name="colorOnSecondary">@android:color/white</item>
<item name="colorAccent">@color/accent_color_light</item> <item name="colorAccent">@color/accent_color_light</item>


<item name="android:textColorPrimary">@color/primary_text_color_selector_light</item> <item name="android:textColorPrimary">@color/black_87</item>
<item name="android:textColorSecondary">@color/riot_secondary_text_color_light</item> <item name="android:textColorSecondary">@color/black_38</item>
<!-- Default color for text View --> <item name="android:textColorTertiary">@color/black_37</item>
<item name="android:textColorTertiary">@color/riot_tertiary_text_color_light</item>


<item name="android:textColorLink">@color/link_color_light</item> <item name="android:textColorLink">@color/link_color_light</item>


@ -22,6 +24,9 @@
<item name="android:colorBackground">@color/riot_primary_background_color_light</item> <item name="android:colorBackground">@color/riot_primary_background_color_light</item>
<item name="vctr_bottom_nav_background_color">#FFF3F8FD</item> <item name="vctr_bottom_nav_background_color">#FFF3F8FD</item>


<!-- default button -->
<item name="android:buttonStyle">@style/Widget.Vector.Button</item>

<!-- waiting view background --> <!-- waiting view background -->
<item name="vctr_waiting_background_color">#AAAAAAAA</item> <item name="vctr_waiting_background_color">#AAAAAAAA</item>



View File

@ -24,6 +24,8 @@
<item name="vctr_bottom_nav_background_color">@color/riot_primary_background_color_status <item name="vctr_bottom_nav_background_color">@color/riot_primary_background_color_status
</item> </item>


<item name="buttonStyle">@style/Widget.Vector.Button</item>

<!-- waiting view background --> <!-- waiting view background -->
<item name="vctr_waiting_background_color">#AAAAAAAA</item> <item name="vctr_waiting_background_color">#AAAAAAAA</item>