From cb80d8d349e788c1f44ab0c33e6f7d823771f377 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 28 May 2020 17:08:57 +0200 Subject: [PATCH] Widget: add active widgets --- .../android/api/session/events/model/Event.kt | 2 +- .../api/session/events/model/EventType.kt | 25 +------- .../room/powerlevels/PowerLevelsHelper.kt | 26 +------- .../api/session/widgets/WidgetService.kt | 5 +- .../internal/session/sync/RoomSyncHandler.kt | 2 +- .../session/widgets/CreateWidgetTask.kt | 5 +- .../internal/session/widgets/WidgetManager.kt | 7 +-- .../home/room/detail/RoomDetailFragment.kt | 16 ++++- .../helper/MessageInformationDataFactory.kt | 2 +- .../detail/widget/RoomWidgetsBannerView.kt | 59 +++++++++++++++++++ .../features/widgets/WidgetPostAPIHandler.kt | 2 +- .../riotx/features/widgets/WidgetViewModel.kt | 4 +- .../res/drawable/bg_active_widgets_banner.xml | 5 ++ .../main/res/layout/fragment_room_detail.xml | 26 ++++++-- .../res/layout/view_room_widgets_banner.xml | 36 +++++++++++ vector/src/main/res/values/colors_riotx.xml | 5 ++ vector/src/main/res/values/strings.xml | 1 + vector/src/main/res/values/theme_black.xml | 1 + vector/src/main/res/values/theme_dark.xml | 1 + vector/src/main/res/values/theme_light.xml | 1 + 20 files changed, 162 insertions(+), 69 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/features/home/room/detail/widget/RoomWidgetsBannerView.kt create mode 100644 vector/src/main/res/drawable/bg_active_widgets_banner.xml create mode 100644 vector/src/main/res/layout/view_room_widgets_banner.xml diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt index d3780ebe60..1d2b839c64 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt @@ -98,7 +98,7 @@ data class Event( * @return true if event is state event. */ fun isStateEvent(): Boolean { - return EventType.isStateEvent(getClearType()) + return stateKey != null } // ============================================================================================================== diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EventType.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EventType.kt index 3cdd433516..a33b9e70df 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EventType.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EventType.kt @@ -38,6 +38,8 @@ object EventType { // State Events + const val STATE_ROOM_WIDGET_LEGACY = "im.vector.modular.widgets" + const val STATE_ROOM_WIDGET = "m.widget" const val STATE_ROOM_NAME = "m.room.name" const val STATE_ROOM_TOPIC = "m.room.topic" const val STATE_ROOM_AVATAR = "m.room.avatar" @@ -84,29 +86,6 @@ object EventType { // Unwedging internal const val DUMMY = "m.dummy" - private val STATE_EVENTS = listOf( - STATE_ROOM_NAME, - STATE_ROOM_TOPIC, - STATE_ROOM_AVATAR, - STATE_ROOM_MEMBER, - STATE_ROOM_THIRD_PARTY_INVITE, - STATE_ROOM_CREATE, - STATE_ROOM_JOIN_RULES, - STATE_ROOM_GUEST_ACCESS, - STATE_ROOM_POWER_LEVELS, - STATE_ROOM_ALIASES, - STATE_ROOM_TOMBSTONE, - STATE_ROOM_CANONICAL_ALIAS, - STATE_ROOM_HISTORY_VISIBILITY, - STATE_ROOM_RELATED_GROUPS, - STATE_ROOM_PINNED_EVENT, - STATE_ROOM_ENCRYPTION - ) - - fun isStateEvent(type: String): Boolean { - return STATE_EVENTS.contains(type) - } - fun isCallEvent(type: String): Boolean { return type == CALL_INVITE || type == CALL_CANDIDATES diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/powerlevels/PowerLevelsHelper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/powerlevels/PowerLevelsHelper.kt index 697b5213ef..4afb954f39 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/powerlevels/PowerLevelsHelper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/powerlevels/PowerLevelsHelper.kt @@ -17,7 +17,6 @@ package im.vector.matrix.android.api.session.room.powerlevels -import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.room.model.PowerLevelsContent /** @@ -44,11 +43,11 @@ class PowerLevelsHelper(private val powerLevelsContent: PowerLevelsContent) { * @param userId the user id * @return true if the user can send this type of event */ - fun isAllowedToSend(eventType: String, userId: String): Boolean { - return if (eventType.isNotEmpty() && userId.isNotEmpty()) { + fun isAllowedToSend(isState: Boolean, eventType: String?, userId: String): Boolean { + return if (userId.isNotEmpty()) { val powerLevel = getUserPowerLevel(userId) val minimumPowerLevel = powerLevelsContent.events[eventType] - ?: if (EventType.isStateEvent(eventType)) { + ?: if (isState) { powerLevelsContent.stateDefault } else { powerLevelsContent.eventsDefault @@ -57,25 +56,6 @@ class PowerLevelsHelper(private val powerLevelsContent: PowerLevelsContent) { } else false } - /** - * Tell if an user can send an event of a certain type - * - * @param eventType the event type to check for - * @param userId the user id - * @return true if the user can send this type of event - */ - fun isAllowedToSend(isState: Boolean, userId: String): Boolean { - return if (userId.isNotEmpty()) { - val powerLevel = getUserPowerLevel(userId) - val minimumPowerLevel = if (isState) { - powerLevelsContent.stateDefault - } else { - powerLevelsContent.eventsDefault - } - powerLevel >= minimumPowerLevel - } else false - } - /** * Get the notification level for a dedicated key. * diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/widgets/WidgetService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/widgets/WidgetService.kt index 86b7139a2b..f0475a657c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/widgets/WidgetService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/widgets/WidgetService.kt @@ -20,15 +20,12 @@ import androidx.lifecycle.LiveData import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.query.QueryStringValue import im.vector.matrix.android.api.session.events.model.Content +import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.internal.session.widgets.Widget interface WidgetService { - companion object { - const val WIDGET_EVENT_TYPE = "im.vector.modular.widgets" - } - fun getWidgetURLFormatter(): WidgetURLFormatter fun getWidgetPostAPIMediator(): WidgetPostAPIMediator diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt index 8c21d23a8c..efe11f2b68 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt @@ -240,7 +240,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle eventIds.add(event.eventId) val ageLocalTs = event.unsignedData?.age?.let { syncLocalTimestampMillis - it } val eventEntity = event.toEntity(roomId, SendState.SYNCED, ageLocalTs).copyToRealmOrIgnore(realm) - if (event.isStateEvent() && event.stateKey != null) { + if (event.stateKey != null) { CurrentStateEventEntity.getOrCreate(realm, roomId, event.stateKey, event.type).apply { eventId = event.eventId root = eventEntity diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/CreateWidgetTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/CreateWidgetTask.kt index 5b602df7b6..b472f79f20 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/CreateWidgetTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/CreateWidgetTask.kt @@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.session.widgets import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.session.events.model.Content +import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.widgets.WidgetService import im.vector.matrix.android.internal.database.awaitNotEmptyResult import im.vector.matrix.android.internal.database.model.CurrentStateEventEntity @@ -48,14 +49,14 @@ internal class DefaultCreateWidgetTask @Inject constructor(private val monarchy: executeRequest(eventBus) { apiCall = roomAPI.sendStateEvent( roomId = params.roomId, - stateEventType = WidgetService.WIDGET_EVENT_TYPE, + stateEventType = EventType.STATE_ROOM_WIDGET_LEGACY, stateKey = params.widgetId, params = params.content ) } awaitNotEmptyResult(monarchy.realmConfiguration, 30_000L) { CurrentStateEventEntity - .whereStateKey(it, params.roomId, type = WidgetService.WIDGET_EVENT_TYPE, stateKey = params.widgetId) + .whereStateKey(it, params.roomId, type = EventType.STATE_ROOM_WIDGET_LEGACY, stateKey = params.widgetId) .and() .equalTo(CurrentStateEventEntityFields.ROOT.SENDER, userId) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/WidgetManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/WidgetManager.kt index 517979e8c8..d273faa972 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/WidgetManager.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/WidgetManager.kt @@ -30,7 +30,6 @@ import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.integrationmanager.IntegrationManagerService import im.vector.matrix.android.api.session.room.model.PowerLevelsContent import im.vector.matrix.android.api.session.room.powerlevels.PowerLevelsHelper -import im.vector.matrix.android.api.session.widgets.WidgetService import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.session.SessionScope @@ -75,7 +74,7 @@ internal class WidgetManager @Inject constructor(private val integrationManager: excludedTypes: Set? = null ): LiveData> { // Get all im.vector.modular.widgets state events in the room - val liveWidgetEvents = stateEventDataSource.getStateEventsLive(roomId, setOf(WidgetService.WIDGET_EVENT_TYPE), widgetId) + val liveWidgetEvents = stateEventDataSource.getStateEventsLive(roomId, setOf(EventType.STATE_ROOM_WIDGET, EventType.STATE_ROOM_WIDGET_LEGACY), widgetId) return Transformations.map(liveWidgetEvents) { widgetEvents -> widgetEvents.mapEventsToWidgets(widgetTypes, excludedTypes) } @@ -88,7 +87,7 @@ internal class WidgetManager @Inject constructor(private val integrationManager: excludedTypes: Set? = null ): List { // Get all im.vector.modular.widgets state events in the room - val widgetEvents: List = stateEventDataSource.getStateEvents(roomId, setOf(WidgetService.WIDGET_EVENT_TYPE), widgetId) + val widgetEvents: List = stateEventDataSource.getStateEvents(roomId, setOf(EventType.STATE_ROOM_WIDGET, EventType.STATE_ROOM_WIDGET_LEGACY), widgetId) return widgetEvents.mapEventsToWidgets(widgetTypes, excludedTypes) } @@ -185,6 +184,6 @@ internal class WidgetManager @Inject constructor(private val integrationManager: fun hasPermissionsToHandleWidgets(roomId: String): Boolean { val powerLevelsEvent = stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition) val powerLevelsContent = powerLevelsEvent?.content?.toModel() ?: return false - return PowerLevelsHelper(powerLevelsContent).isAllowedToSend(EventType.STATE_ROOM_POWER_LEVELS, userId) + return PowerLevelsHelper(powerLevelsContent).isAllowedToSend(true, null, userId) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt index 5f41daaeaf..031d66420e 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt @@ -147,6 +147,7 @@ import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformatio import im.vector.riotx.features.home.room.detail.timeline.item.MessageTextItem import im.vector.riotx.features.home.room.detail.timeline.item.ReadReceiptData import im.vector.riotx.features.home.room.detail.timeline.reactions.ViewReactionsBottomSheet +import im.vector.riotx.features.home.room.detail.widget.RoomWidgetsBannerView import im.vector.riotx.features.html.EventHtmlRenderer import im.vector.riotx.features.html.PillImageSpan import im.vector.riotx.features.invite.VectorInviteView @@ -199,7 +200,7 @@ class RoomDetailFragment @Inject constructor( VectorInviteView.Callback, JumpToReadMarkerView.Callback, AttachmentTypeSelectorView.Callback, - AttachmentsHelper.Callback { + AttachmentsHelper.Callback, RoomWidgetsBannerView.Callback { companion object { @@ -264,6 +265,8 @@ class RoomDetailFragment @Inject constructor( setupNotificationView() setupJumpToReadMarkerView() setupJumpToBottomView() + setupWidgetsBannerView() + roomToolbarContentView.debouncedClicks { navigator.openRoomProfile(requireActivity(), roomDetailArgs.roomId) } @@ -311,6 +314,10 @@ class RoomDetailFragment @Inject constructor( } } + private fun setupWidgetsBannerView() { + roomWidgetsBannerView.callback = this + } + private fun openStickerPicker(event: RoomDetailViewEvents.OpenStickerPicker) { navigator.openStickerPicker(this, roomDetailArgs.roomId, event.widget) } @@ -323,7 +330,7 @@ class RoomDetailFragment @Inject constructor( val v: View = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_no_sticker_pack, null) builder .setView(v) - .setPositiveButton(R.string.yes) { _, _-> + .setPositiveButton(R.string.yes) { _, _ -> // Open integration manager, to the sticker installation page navigator.openIntegrationManager( context = requireContext(), @@ -719,6 +726,7 @@ class RoomDetailFragment @Inject constructor( val summary = state.asyncRoomSummary() val inviter = state.asyncInviter() if (summary?.membership == Membership.JOIN) { + roomWidgetsBannerView.render(state.activeRoomWidgets()) scrollOnHighlightedEventCallback.timeline = roomDetailViewModel.timeline timelineEventController.update(state) inviteView.visibility = View.GONE @@ -1455,4 +1463,8 @@ class RoomDetailFragment @Inject constructor( val formattedContact = contactAttachment.toHumanReadable() roomDetailViewModel.handle(RoomDetailAction.SendMessage(formattedContact, false)) } + + override fun onViewWidgetsClicked() { + Toast.makeText(requireContext(), "Show widgets", Toast.LENGTH_SHORT).show() + } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt index 9a912b5af3..c36dc5af9b 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt @@ -158,7 +158,7 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses } } } else { - if (EventType.isStateEvent(event.root.type)) { + if (event.root.isStateEvent()) { // Do not warn for state event, they are always in clear E2EDecoration.NONE } else { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/widget/RoomWidgetsBannerView.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/widget/RoomWidgetsBannerView.kt new file mode 100644 index 0000000000..e4225e5f8d --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/widget/RoomWidgetsBannerView.kt @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020 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. + */ + +package im.vector.riotx.features.home.room.detail.widget + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import android.widget.RelativeLayout +import im.vector.matrix.android.internal.session.widgets.Widget +import im.vector.riotx.R +import kotlinx.android.synthetic.main.view_room_widgets_banner.view.* + +class RoomWidgetsBannerView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : RelativeLayout(context, attrs, defStyleAttr) { + + interface Callback { + fun onViewWidgetsClicked() + } + + var callback: Callback? = null + + init { + setupView() + } + + private fun setupView() { + inflate(context, R.layout.view_room_widgets_banner, this) + setBackgroundResource(R.drawable.bg_active_widgets_banner) + setOnClickListener { + callback?.onViewWidgetsClicked() + } + } + + fun render(widgets: List?) { + if (widgets.isNullOrEmpty()) { + visibility = View.GONE + } else { + visibility = View.VISIBLE + activeWidgetsLabel.text = context.resources.getQuantityString(R.plurals.active_widgets, widgets.size, widgets.size) + } + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/widgets/WidgetPostAPIHandler.kt b/vector/src/main/java/im/vector/riotx/features/widgets/WidgetPostAPIHandler.kt index 9bab752cba..6c1c03f481 100644 --- a/vector/src/main/java/im/vector/riotx/features/widgets/WidgetPostAPIHandler.kt +++ b/vector/src/main/java/im/vector/riotx/features/widgets/WidgetPostAPIHandler.kt @@ -154,7 +154,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo val canSend = if (powerLevelsContent == null) { false } else { - PowerLevelsHelper(powerLevelsContent).isAllowedToSend(eventType, session.myUserId) + PowerLevelsHelper(powerLevelsContent).isAllowedToSend(isState, eventType, session.myUserId) } if (canSend) { Timber.d("## canSendEvent() returns true") diff --git a/vector/src/main/java/im/vector/riotx/features/widgets/WidgetViewModel.kt b/vector/src/main/java/im/vector/riotx/features/widgets/WidgetViewModel.kt index 68b02ea3b1..5d7e576058 100644 --- a/vector/src/main/java/im/vector/riotx/features/widgets/WidgetViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/widgets/WidgetViewModel.kt @@ -92,7 +92,7 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi } private fun subscribeToWidget() { - asyncSubscribe(WidgetViewState::asyncWidget){ + asyncSubscribe(WidgetViewState::asyncWidget) { setState { copy(widgetName = it.name) } } } @@ -113,7 +113,7 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi .mapOptional { it.content.toModel() } .unwrap() .map { - PowerLevelsHelper(it).isAllowedToSend(true, session.myUserId) + PowerLevelsHelper(it).isAllowedToSend(true, null, session.myUserId) }.subscribe { setState { copy(canManageWidgets = it) } }.disposeOnClear() diff --git a/vector/src/main/res/drawable/bg_active_widgets_banner.xml b/vector/src/main/res/drawable/bg_active_widgets_banner.xml new file mode 100644 index 0000000000..c8b67bc1ff --- /dev/null +++ b/vector/src/main/res/drawable/bg_active_widgets_banner.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/vector/src/main/res/layout/fragment_room_detail.xml b/vector/src/main/res/layout/fragment_room_detail.xml index 08750d569c..590f533e3b 100644 --- a/vector/src/main/res/layout/fragment_room_detail.xml +++ b/vector/src/main/res/layout/fragment_room_detail.xml @@ -108,15 +108,31 @@ app:layout_constraintTop_toBottomOf="@id/syncStateView" tools:listitem="@layout/item_timeline_event_base" /> - + app:layout_constraintTop_toBottomOf="@id/syncStateView"> + + + + + + + + + + + + + diff --git a/vector/src/main/res/values/colors_riotx.xml b/vector/src/main/res/values/colors_riotx.xml index 238fcbd6a2..cf09d25581 100644 --- a/vector/src/main/res/values/colors_riotx.xml +++ b/vector/src/main/res/values/colors_riotx.xml @@ -175,6 +175,11 @@ #FF22262E #FF090A0C + + #EBEFF5 + #27303A + #27303A + #FFF8E3 diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 36532f25e3..695b43c46e 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1116,6 +1116,7 @@ 1 active widget %d active widgets + "VIEW" Widget diff --git a/vector/src/main/res/values/theme_black.xml b/vector/src/main/res/values/theme_black.xml index f3f84a36d8..1dbe9654d0 100644 --- a/vector/src/main/res/values/theme_black.xml +++ b/vector/src/main/res/values/theme_black.xml @@ -33,6 +33,7 @@ @color/riotx_touch_guard_bg_black @color/riotx_attachment_selector_background_black @color/riotx_attachment_selector_border_black + @color/riotx_room_active_widgets_banner_black @drawable/highlighted_message_background_black diff --git a/vector/src/main/res/values/theme_dark.xml b/vector/src/main/res/values/theme_dark.xml index a2be367e55..b95fed586c 100644 --- a/vector/src/main/res/values/theme_dark.xml +++ b/vector/src/main/res/values/theme_dark.xml @@ -31,6 +31,7 @@ @color/riotx_touch_guard_bg_dark @color/riotx_attachment_selector_background_dark @color/riotx_attachment_selector_border_dark + @color/riotx_room_active_widgets_banner_dark @color/riotx_keys_backup_banner_accent_color_dark diff --git a/vector/src/main/res/values/theme_light.xml b/vector/src/main/res/values/theme_light.xml index 9709172f9d..36c267f160 100644 --- a/vector/src/main/res/values/theme_light.xml +++ b/vector/src/main/res/values/theme_light.xml @@ -32,6 +32,7 @@ @color/riotx_keys_backup_banner_accent_color_light @color/riotx_attachment_selector_background_light @color/riotx_attachment_selector_border_light + @color/riotx_room_active_widgets_banner_light @drawable/highlighted_message_background_light