Widgets: observe wellknown for integ config and open Jitsi in browser

This commit is contained in:
ganfra 2020-05-29 12:23:36 +02:00
parent 00f2d0249f
commit 7df8b3a9bf
29 changed files with 213 additions and 86 deletions

View File

@ -36,7 +36,7 @@ import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
import im.vector.matrix.android.internal.crypto.store.PrivateKeysInfo
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
import im.vector.matrix.android.internal.session.widgets.Widget
import im.vector.matrix.android.api.session.widgets.model.Widget
import io.reactivex.Observable
import io.reactivex.Single

View File

@ -27,7 +27,7 @@ interface IntegrationManagerService {
//No-op
}
fun onConfigurationChanged(config: IntegrationManagerConfig) {
fun onConfigurationChanged(configs: List<IntegrationManagerConfig>) {
//No-op
}

View File

@ -20,9 +20,8 @@ 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
import im.vector.matrix.android.api.session.widgets.model.Widget
interface WidgetService {

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package im.vector.matrix.android.internal.session.widgets
package im.vector.matrix.android.api.session.widgets.model
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.room.sender.SenderInfo
@ -26,7 +26,8 @@ data class Widget(
val widgetId: String,
val senderInfo: SenderInfo?,
val isAddedByMe: Boolean,
val computedUrl: String?
val computedUrl: String?,
val type: WidgetType
) {
val isActive = widgetContent.isActive()

View File

@ -0,0 +1,64 @@
/*
* 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.matrix.android.api.session.widgets.model
sealed class WidgetType(open val preferred: String, open val legacy: String) {
object Jitsi : WidgetType("m.jitsi", "jitsi")
object TradingView : WidgetType("m.tradingview", "m.tradingview")
object Spotify : WidgetType("m.spotify", "m.spotify")
object Video : WidgetType("m.video", "m.video")
object GoogleDoc : WidgetType("m.googledoc", "m.googledoc")
object GoogleCalendar : WidgetType("m.googlecalendar", "m.googlecalendar")
object Etherpad : WidgetType("m.etherpad", "m.etherpad")
object StickerPicker : WidgetType("m.stickerpicker", "m.stickerpicker")
object Grafana : WidgetType("m.grafana", "m.grafana")
object Custom : WidgetType("m.custom", "m.custom")
object IntegrationManager : WidgetType("m.integration_manager", "m.integration_manager")
data class Fallback(override val preferred: String, override val legacy: String) : WidgetType(preferred, legacy)
fun matches(type: String?): Boolean {
return type == preferred || type == legacy
}
fun values(): Set<String>{
return setOf(preferred, legacy)
}
companion object {
private val DEFINED_TYPES = listOf(
Jitsi,
TradingView,
Spotify,
Video,
GoogleDoc,
GoogleCalendar,
Etherpad,
StickerPicker,
Grafana,
Custom,
IntegrationManager
)
fun fromString(type: String): WidgetType {
val matchingType = DEFINED_TYPES.firstOrNull {
it.matches(type)
}
return matchingType ?: Fallback(type, type)
}
}
}

View File

@ -56,6 +56,7 @@ import io.realm.annotations.RealmModule
RoomMemberSummaryEntity::class,
CurrentStateEventEntity::class,
UserAccountDataEntity::class,
ScalarTokenEntity::class
ScalarTokenEntity::class,
WellknownIntegrationManagerConfigEntity::class
])
internal class SessionRealmModule

View File

@ -0,0 +1,29 @@
/*
* 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.matrix.android.internal.database.model
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
internal open class WellknownIntegrationManagerConfigEntity(
@PrimaryKey var id: Long = 0,
var apiUrl: String = "",
var uiUrl: String = ""
) : RealmObject() {
companion object
}

View File

@ -19,14 +19,19 @@ package im.vector.matrix.android.internal.session.integrationmanager
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.R
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.auth.wellknown.WellknownResult
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.integrationmanager.IntegrationManagerConfig
import im.vector.matrix.android.api.session.integrationmanager.IntegrationManagerService
import im.vector.matrix.android.api.session.widgets.model.WidgetContent
import im.vector.matrix.android.api.session.widgets.model.WidgetType
import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.api.util.NoOpCancellable
import im.vector.matrix.android.internal.database.model.WellknownIntegrationManagerConfigEntity
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.extensions.observeNotNull
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
@ -38,6 +43,9 @@ import im.vector.matrix.android.internal.session.widgets.helper.extractWidgetSeq
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import im.vector.matrix.android.internal.util.StringProvider
import im.vector.matrix.android.internal.util.awaitTransaction
import im.vector.matrix.android.internal.wellknown.GetWellknownTask
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@ -54,14 +62,16 @@ import javax.inject.Inject
*
*/
@SessionScope
internal class IntegrationManager @Inject constructor(private val taskExecutor: TaskExecutor,
internal class IntegrationManager @Inject constructor(@UserId private val userId: String,
private val taskExecutor: TaskExecutor,
private val monarchy: Monarchy,
private val stringProvider: StringProvider,
private val updateUserAccountDataTask: UpdateUserAccountDataTask,
private val accountDataDataSource: AccountDataDataSource,
private val getWellknownTask: GetWellknownTask,
private val configExtractor: IntegrationManagerConfigExtractor,
private val widgetFactory: WidgetFactory) {
private val currentConfigs = ArrayList<IntegrationManagerConfig>()
private val lifecycleOwner: LifecycleOwner = LifecycleOwner { lifecycleRegistry }
private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(lifecycleOwner)
@ -80,7 +90,9 @@ internal class IntegrationManager @Inject constructor(private val taskExecutor:
}
fun start() {
refreshWellknown()
lifecycleRegistry.currentState = Lifecycle.State.STARTED
observeWellknownConfig()
accountDataDataSource
.getLiveAccountDataEvent(UserAccountData.TYPE_ALLOWED_WIDGETS)
.observeNotNull(lifecycleOwner) {
@ -102,13 +114,7 @@ internal class IntegrationManager @Inject constructor(private val taskExecutor:
.observeNotNull(lifecycleOwner) {
val integrationManagerContent = it.getOrNull()?.asIntegrationManagerWidgetContent()
val config = integrationManagerContent?.extractIntegrationManagerConfig()
val accountConfig = currentConfigs.firstOrNull { currentConfig ->
currentConfig.kind == IntegrationManagerConfig.Kind.ACCOUNT
}
if (config != null && accountConfig == null) {
currentConfigs.add(config)
notifyConfigurationChanged(config)
}
updateCurrentConfigs(IntegrationManagerConfig.Kind.ACCOUNT, config)
}
}
@ -209,12 +215,11 @@ internal class IntegrationManager @Inject constructor(private val taskExecutor:
return currentContent?.native?.get(widgetType)?.get(domain) ?: false
}
private fun notifyConfigurationChanged(config: IntegrationManagerConfig) {
Timber.v("On configuration changed : $config")
private fun notifyConfigurationChanged() {
synchronized(listeners) {
listeners.forEach {
try {
it.onConfigurationChanged(config)
it.onConfigurationChanged(currentConfigs)
} catch (t: Throwable) {
Timber.e(t, "Failed to notify listener")
}
@ -248,30 +253,6 @@ internal class IntegrationManager @Inject constructor(private val taskExecutor:
}
}
/*
private fun getStoreWellknownIM(): List<IntegrationManagerConfig> {
val prefs = context.getSharedPreferences(PREFS_IM, Context.MODE_PRIVATE)
return prefs.getString(WELLKNOWN_KEY, null)?.let {
try {
Gson().fromJson<List<WellKnownManagerConfig>>(it,
object : TypeToken<List<WellKnownManagerConfig>>() {}.type)
} catch (any: Throwable) {
emptyList<WellKnownManagerConfig>()
}
} ?: emptyList<WellKnownManagerConfig>()
}
private fun setStoreWellknownIM(list: List<WellKnownManagerConfig>) {
val prefs = context.getSharedPreferences(PREFS_IM, Context.MODE_PRIVATE)
try {
val serialized = Gson().toJson(list)
prefs.edit().putString(WELLKNOWN_KEY, serialized).apply()
} catch (any: Throwable) {
//nop
}
}
*/
private fun WidgetContent.extractIntegrationManagerConfig(): IntegrationManagerConfig? {
if (url.isNullOrBlank()) {
return null
@ -287,14 +268,50 @@ internal class IntegrationManager @Inject constructor(private val taskExecutor:
private fun UserAccountDataEvent.asIntegrationManagerWidgetContent(): WidgetContent? {
return extractWidgetSequence(widgetFactory)
.filter {
it.widgetContent.type == INTEGRATION_MANAGER_WIDGET
WidgetType.IntegrationManager == it.type
}
.firstOrNull()?.widgetContent
}
companion object {
private const val INTEGRATION_MANAGER_WIDGET = "m.integration_manager"
private const val PREFS_IM = "IntegrationManager.Storage"
private const val WELLKNOWN_KEY = "WellKnown"
private fun refreshWellknown() {
taskExecutor.executorScope.launch {
val params = GetWellknownTask.Params(matrixId = userId)
val wellknownResult = try {
getWellknownTask.execute(params)
} catch (failure: Throwable) {
Timber.v("Get wellknown failed: $failure")
null
}
if (wellknownResult != null && wellknownResult is WellknownResult.Prompt) {
val config = configExtractor.extract(wellknownResult.wellKnown) ?: return@launch
Timber.v("Extracted config: $config")
monarchy.awaitTransaction {
it.insertOrUpdate(config)
}
}
}
}
private fun observeWellknownConfig() {
val liveData = monarchy.findAllMappedWithChanges(
{ it.where(WellknownIntegrationManagerConfigEntity::class.java) },
{ IntegrationManagerConfig(it.uiUrl, it.apiUrl, IntegrationManagerConfig.Kind.HOMESERVER) }
)
liveData.observeNotNull(lifecycleOwner) {
val config = it.firstOrNull()
updateCurrentConfigs(IntegrationManagerConfig.Kind.HOMESERVER, config)
}
}
private fun updateCurrentConfigs(kind: IntegrationManagerConfig.Kind, config: IntegrationManagerConfig?) {
val hasBeenRemoved = currentConfigs.removeAll { currentConfig ->
currentConfig.kind == kind
}
if (config != null) {
currentConfigs.add(config)
}
if (hasBeenRemoved || config != null) {
notifyConfigurationChanged()
}
}
}

View File

@ -17,13 +17,12 @@
package im.vector.matrix.android.internal.session.integrationmanager
import im.vector.matrix.android.api.auth.data.WellKnown
import im.vector.matrix.android.api.session.integrationmanager.IntegrationManagerConfig
import im.vector.matrix.android.internal.database.model.WellknownIntegrationManagerConfigEntity
import javax.inject.Inject
internal class IntegrationManagerConfigExtractor @Inject constructor() {
fun extract(wellKnown: WellKnown): List<IntegrationManagerConfig> {
val managers = ArrayList<IntegrationManagerConfig>()
fun extract(wellKnown: WellKnown): WellknownIntegrationManagerConfigEntity? {
wellKnown.integrations?.get("managers")?.let {
(it as? List<*>)?.let { configs ->
configs.forEach { config ->
@ -33,16 +32,16 @@ internal class IntegrationManagerConfigExtractor @Inject constructor() {
if (apiUrl != null
&& apiUrl.startsWith("https://")
&& uiUrl!!.startsWith("https://")) {
managers.add(IntegrationManagerConfig(
return WellknownIntegrationManagerConfigEntity(
apiUrl = apiUrl,
uiUrl = uiUrl,
kind = IntegrationManagerConfig.Kind.HOMESERVER
))
uiUrl = uiUrl
)
}
}
}
}
}
return managers
return null
}
}

View File

@ -23,6 +23,7 @@ import im.vector.matrix.android.api.session.events.model.Content
import im.vector.matrix.android.api.session.widgets.WidgetPostAPIMediator
import im.vector.matrix.android.api.session.widgets.WidgetService
import im.vector.matrix.android.api.session.widgets.WidgetURLFormatter
import im.vector.matrix.android.api.session.widgets.model.Widget
import im.vector.matrix.android.api.util.Cancelable
import javax.inject.Inject

View File

@ -45,7 +45,7 @@ internal class DefaultWidgetURLFormatter @Inject constructor(private val integra
integrationManager.removeListener(this)
}
override fun onConfigurationChanged(config: IntegrationManagerConfig) {
override fun onConfigurationChanged(configs: List<IntegrationManagerConfig>) {
setupWithConfiguration()
}

View File

@ -30,6 +30,7 @@ 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.model.Widget
import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.session.SessionScope

View File

@ -20,7 +20,7 @@ import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.util.JsonDict
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
import im.vector.matrix.android.internal.session.widgets.Widget
import im.vector.matrix.android.api.session.widgets.model.Widget
internal fun UserAccountDataEvent.extractWidgetSequence(widgetFactory: WidgetFactory): Sequence<Widget> {
return content.asSequence()

View File

@ -19,12 +19,13 @@ package im.vector.matrix.android.internal.session.widgets.helper
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.sender.SenderInfo
import im.vector.matrix.android.api.session.widgets.model.Widget
import im.vector.matrix.android.api.session.widgets.model.WidgetContent
import im.vector.matrix.android.api.session.widgets.model.WidgetType
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper
import im.vector.matrix.android.internal.session.user.UserDataSource
import im.vector.matrix.android.internal.session.widgets.Widget
import io.realm.Realm
import io.realm.RealmConfiguration
import java.net.URLEncoder
@ -38,6 +39,7 @@ internal class WidgetFactory @Inject constructor(@SessionDatabase private val re
val widgetContent = widgetEvent.content.toModel<WidgetContent>()
if (widgetContent?.url == null) return null
val widgetId = widgetEvent.stateKey ?: return null
val type = widgetContent.type ?: return null
val senderInfo = if (widgetEvent.senderId == null || widgetEvent.roomId == null) {
null
} else {
@ -54,7 +56,15 @@ internal class WidgetFactory @Inject constructor(@SessionDatabase private val re
}
val isAddedByMe = widgetEvent.senderId == userId
val computedUrl = widgetContent.computeURL(widgetEvent.roomId)
return Widget(widgetContent, widgetEvent, widgetId, senderInfo, isAddedByMe, computedUrl)
return Widget(
widgetContent = widgetContent,
event = widgetEvent,
widgetId = widgetId,
senderInfo = senderInfo,
isAddedByMe = isAddedByMe,
computedUrl = computedUrl,
type = WidgetType.fromString(type)
)
}
private fun WidgetContent.computeURL(roomId: String?): String? {

View File

@ -83,6 +83,7 @@ import im.vector.matrix.android.api.session.room.send.SendState
import im.vector.matrix.android.api.session.room.timeline.Timeline
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent
import im.vector.matrix.android.api.session.widgets.model.WidgetType
import im.vector.matrix.android.api.util.MatrixItem
import im.vector.matrix.android.api.util.toMatrixItem
import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt
@ -337,7 +338,7 @@ class RoomDetailFragment @Inject constructor(
context = requireContext(),
roomId = roomDetailArgs.roomId,
integId = null,
screen = StickerPickerConstants.WIDGET_NAME
screen = WidgetType.StickerPicker.preferred
)
}
.setNegativeButton(R.string.no, null)

View File

@ -17,7 +17,7 @@
package im.vector.riotx.features.home.room.detail
import androidx.annotation.StringRes
import im.vector.matrix.android.internal.session.widgets.Widget
import im.vector.matrix.android.api.session.widgets.model.Widget
import im.vector.riotx.core.platform.VectorViewEvents
import im.vector.riotx.features.command.Command
import java.io.File

View File

@ -27,7 +27,7 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.api.session.sync.SyncState
import im.vector.matrix.android.api.session.user.model.User
import im.vector.matrix.android.api.util.MatrixItem
import im.vector.matrix.android.internal.session.widgets.Widget
import im.vector.matrix.android.api.session.widgets.model.Widget
/**
* Describes the current send mode:

View File

@ -17,6 +17,7 @@
package im.vector.riotx.features.home.room.detail.sticker
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.widgets.model.WidgetType
import im.vector.riotx.features.home.room.detail.RoomDetailViewEvents
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@ -26,7 +27,7 @@ class StickerPickerActionHandler @Inject constructor(private val session: Sessio
suspend fun handle(): RoomDetailViewEvents = withContext(Dispatchers.Default) {
// Search for the sticker picker widget in the user account
val stickerWidget = session.widgetService().getUserWidgets(setOf(StickerPickerConstants.WIDGET_NAME)).firstOrNull()
val stickerWidget = session.widgetService().getUserWidgets(WidgetType.StickerPicker.values()).firstOrNull { it.isActive }
if (stickerWidget == null || stickerWidget.computedUrl.isNullOrBlank()) {
RoomDetailViewEvents.DisplayPromptForIntegrationManager
} else {

View File

@ -17,6 +17,5 @@
package im.vector.riotx.features.home.room.detail.sticker
object StickerPickerConstants {
const val WIDGET_NAME = "m.stickerpicker"
const val STICKER_PICKER_REQUEST_CODE = 16000
}

View File

@ -17,7 +17,7 @@
package im.vector.riotx.features.home.room.detail.widget
import com.airbnb.epoxy.TypedEpoxyController
import im.vector.matrix.android.internal.session.widgets.Widget
import im.vector.matrix.android.api.session.widgets.model.Widget
import javax.inject.Inject
/**

View File

@ -20,7 +20,7 @@ import android.widget.TextView
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
import com.airbnb.epoxy.EpoxyModelWithHolder
import im.vector.matrix.android.internal.session.widgets.Widget
import im.vector.matrix.android.api.session.widgets.model.Widget
import im.vector.riotx.R
import im.vector.riotx.core.epoxy.VectorEpoxyHolder

View File

@ -20,7 +20,7 @@ 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.matrix.android.api.session.widgets.model.Widget
import im.vector.riotx.R
import kotlinx.android.synthetic.main.view_room_widgets_banner.view.*

View File

@ -21,13 +21,15 @@ import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import com.airbnb.mvrx.parentFragmentViewModel
import com.airbnb.mvrx.withState
import im.vector.matrix.android.internal.session.widgets.Widget
import im.vector.matrix.android.api.session.widgets.model.Widget
import im.vector.matrix.android.api.session.widgets.model.WidgetType
import im.vector.riotx.R
import im.vector.riotx.core.di.ScreenComponent
import im.vector.riotx.core.extensions.cleanup
import im.vector.riotx.core.extensions.configureWith
import im.vector.riotx.core.platform.VectorBaseBottomSheetDialogFragment
import im.vector.riotx.core.resources.ColorProvider
import im.vector.riotx.core.utils.openUrlInExternalBrowser
import im.vector.riotx.features.home.room.detail.RoomDetailViewModel
import im.vector.riotx.features.home.room.detail.RoomDetailViewState
import im.vector.riotx.features.navigation.Navigator
@ -73,9 +75,14 @@ class RoomWidgetsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomWidget
}
override fun didSelectWidget(widget: Widget) = withState(roomDetailViewModel) {
if (widget.type == WidgetType.Jitsi) {
openUrlInExternalBrowser(requireContext(), widget.computedUrl)
dismiss()
} else {
navigator.openRoomWidget(requireContext(), it.roomId, widget)
dismiss()
}
}
companion object {
fun newInstance(): RoomWidgetsBottomSheet {

View File

@ -31,7 +31,7 @@ import im.vector.matrix.android.api.session.crypto.verification.IncomingSasVerif
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom
import im.vector.matrix.android.api.session.terms.TermsService
import im.vector.matrix.android.api.util.MatrixItem
import im.vector.matrix.android.internal.session.widgets.Widget
import im.vector.matrix.android.api.session.widgets.model.Widget
import im.vector.riotx.R
import im.vector.riotx.core.di.ActiveSessionHolder
import im.vector.riotx.core.error.fatalError

View File

@ -24,7 +24,7 @@ import androidx.fragment.app.Fragment
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom
import im.vector.matrix.android.api.session.terms.TermsService
import im.vector.matrix.android.api.util.MatrixItem
import im.vector.matrix.android.internal.session.widgets.Widget
import im.vector.matrix.android.api.session.widgets.model.Widget
import im.vector.riotx.features.home.room.detail.sticker.StickerPickerConstants
import im.vector.riotx.features.media.ImageContentRenderer
import im.vector.riotx.features.media.VideoContentRenderer

View File

@ -98,13 +98,11 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
}
private val integrationServiceListener = object : IntegrationManagerService.Listener {
override fun onConfigurationChanged(config: IntegrationManagerConfig) {
super.onConfigurationChanged(config)
override fun onConfigurationChanged(configs: List<IntegrationManagerConfig>) {
refreshIntegrationManagerSettings()
}
override fun onIsEnabledChanged(enabled: Boolean) {
super.onIsEnabledChanged(enabled)
refreshIntegrationManagerSettings()
}
}

View File

@ -16,7 +16,7 @@
package im.vector.riotx.features.widgets
import im.vector.matrix.android.internal.session.widgets.Widget
import im.vector.matrix.android.api.session.widgets.model.Widget
import im.vector.riotx.core.di.ActiveSessionHolder
import javax.inject.Inject

View File

@ -20,9 +20,9 @@ import androidx.annotation.StringRes
import com.airbnb.mvrx.Async
import com.airbnb.mvrx.MvRxState
import com.airbnb.mvrx.Uninitialized
import im.vector.matrix.android.internal.session.widgets.Widget
import im.vector.matrix.android.api.session.widgets.model.Widget
import im.vector.matrix.android.api.session.widgets.model.WidgetType
import im.vector.riotx.R
import im.vector.riotx.features.home.room.detail.sticker.StickerPickerConstants
enum class WidgetStatus {
UNKNOWN,
@ -31,14 +31,13 @@ enum class WidgetStatus {
}
enum class WidgetKind(@StringRes val nameRes: Int, val screenId: String?) {
ROOM(R.string.room_widget_activity_title,null),
STICKER_PICKER(R.string.title_activity_choose_sticker, StickerPickerConstants.WIDGET_NAME),
ROOM(R.string.room_widget_activity_title, null),
STICKER_PICKER(R.string.title_activity_choose_sticker, WidgetType.StickerPicker.preferred),
INTEGRATION_MANAGER(0, null);
fun isAdmin(): Boolean {
return this == STICKER_PICKER || this == INTEGRATION_MANAGER
}
}
data class WidgetViewState(

View File

@ -19,7 +19,7 @@ package im.vector.riotx.features.widgets.permissions
import com.airbnb.mvrx.Async
import com.airbnb.mvrx.MvRxState
import com.airbnb.mvrx.Uninitialized
import im.vector.matrix.android.internal.session.widgets.Widget
import im.vector.matrix.android.api.session.widgets.model.Widget
import im.vector.riotx.features.widgets.WidgetArgs
data class RoomWidgetPermissionViewState(