Clean after Benoit's review
This commit is contained in:
parent
82b4415f7d
commit
06cc2f527e
|
@ -15,6 +15,9 @@
|
|||
*/
|
||||
package im.vector.matrix.android.api.session.integrationmanager
|
||||
|
||||
/**
|
||||
* This class holds configuration of integration manager.
|
||||
*/
|
||||
data class IntegrationManagerConfig(
|
||||
val uiUrl: String,
|
||||
val apiUrl: String,
|
||||
|
@ -22,9 +25,21 @@ data class IntegrationManagerConfig(
|
|||
) {
|
||||
|
||||
// Order matters, first is preferred
|
||||
/**
|
||||
* The kind of config, it will reflect where the data is coming from.
|
||||
*/
|
||||
enum class Kind {
|
||||
/**
|
||||
* Defined in UserAccountData
|
||||
*/
|
||||
ACCOUNT,
|
||||
/**
|
||||
* Defined in Wellknown
|
||||
*/
|
||||
HOMESERVER,
|
||||
/**
|
||||
* Fallback value, hardcoded by the SDK
|
||||
*/
|
||||
DEFAULT
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,39 +19,98 @@ package im.vector.matrix.android.api.session.integrationmanager
|
|||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
|
||||
/**
|
||||
* This is the entry point to manage integration. You can grab an instance of this service through an active session.
|
||||
*/
|
||||
interface IntegrationManagerService {
|
||||
|
||||
/**
|
||||
* This listener allow you to observe change related to integrations.
|
||||
*/
|
||||
interface Listener {
|
||||
/**
|
||||
* Is called whenever integration is enabled or disabled, comes from user account data.
|
||||
*/
|
||||
fun onIsEnabledChanged(enabled: Boolean) {
|
||||
// No-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Is called whenever configs from user account data or wellknown are updated.
|
||||
*/
|
||||
fun onConfigurationChanged(configs: List<IntegrationManagerConfig>) {
|
||||
// No-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Is called whenever widget permissions from user account data are updated.
|
||||
*/
|
||||
fun onWidgetPermissionsChanged(widgets: Map<String, Boolean>) {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener to observe changes.
|
||||
*/
|
||||
fun addListener(listener: Listener)
|
||||
|
||||
/**
|
||||
* Removes a previously added listener.
|
||||
*/
|
||||
fun removeListener(listener: Listener)
|
||||
|
||||
/**
|
||||
* Return the list of current configurations, sorted by kind. First one is preferred.
|
||||
* See [IntegrationManagerConfig.Kind]
|
||||
*/
|
||||
fun getOrderedConfigs(): List<IntegrationManagerConfig>
|
||||
|
||||
/**
|
||||
* Return the preferred current configuration.
|
||||
* See [IntegrationManagerConfig.Kind]
|
||||
*/
|
||||
fun getPreferredConfig(): IntegrationManagerConfig
|
||||
|
||||
/**
|
||||
* Returns true if integration is enabled, false otherwise.
|
||||
*/
|
||||
fun isIntegrationEnabled(): Boolean
|
||||
|
||||
/**
|
||||
* Offers to enable or disable the integration.
|
||||
* @param enable the param to change
|
||||
* @param callback the matrix callback to listen for result.
|
||||
* @return Cancelable
|
||||
*/
|
||||
fun setIntegrationEnabled(enable: Boolean, callback: MatrixCallback<Unit>): Cancelable
|
||||
|
||||
/**
|
||||
* Offers to allow or disallow a widget.
|
||||
* @param stateEventId the eventId of the state event defining the widget.
|
||||
* @param allowed the param to change
|
||||
* @param callback the matrix callback to listen for result.
|
||||
* @return Cancelable
|
||||
*/
|
||||
fun setWidgetAllowed(stateEventId: String, allowed: Boolean, callback: MatrixCallback<Unit>): Cancelable
|
||||
|
||||
/**
|
||||
* Returns true if the widget is allowed, false otherwise.
|
||||
* @param stateEventId the eventId of the state event defining the widget.
|
||||
*/
|
||||
fun isWidgetAllowed(stateEventId: String): Boolean
|
||||
|
||||
/**
|
||||
* Offers to allow or disallow a native widget domain.
|
||||
* @param widgetType the widget type to check for
|
||||
* @param domain the domain to check for
|
||||
*/
|
||||
fun setNativeWidgetDomainAllowed(widgetType: String, domain: String, allowed: Boolean, callback: MatrixCallback<Unit>): Cancelable
|
||||
|
||||
fun isNativeWidgetAllowed(widgetType: String, domain: String?): Boolean
|
||||
/**
|
||||
* Returns true if the widget domain is allowed, false otherwise.
|
||||
* @param widgetType the widget type to check for
|
||||
* @param domain the domain to check for
|
||||
*/
|
||||
fun isNativeWidgetDomainAllowed(widgetType: String, domain: String): Boolean
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.widgets
|
||||
package im.vector.matrix.android.api.session.widgets
|
||||
|
||||
import im.vector.matrix.android.api.failure.Failure
|
||||
|
|
@ -23,12 +23,32 @@ import im.vector.matrix.android.api.session.events.model.Content
|
|||
import im.vector.matrix.android.api.util.Cancelable
|
||||
import im.vector.matrix.android.api.session.widgets.model.Widget
|
||||
|
||||
|
||||
/**
|
||||
* This is the entry point to manage widgets. You can grab an instance of this service through an active session.
|
||||
*/
|
||||
interface WidgetService {
|
||||
|
||||
/**
|
||||
* Returns an instance of [WidgetURLFormatter].
|
||||
*/
|
||||
fun getWidgetURLFormatter(): WidgetURLFormatter
|
||||
|
||||
/**
|
||||
* Returns an instance of [WidgetPostAPIMediator].
|
||||
* This is to be used for "admin" widgets so you can interact through JS.
|
||||
*/
|
||||
fun getWidgetPostAPIMediator(): WidgetPostAPIMediator
|
||||
|
||||
/**
|
||||
* Returns the current room widgets defined through state events.
|
||||
* Some widgets can be deactivated, so be sure to check for isActive if needed.
|
||||
*
|
||||
* @param roomId the room where you want to fetch widgets
|
||||
* @param widgetId if you want to fetch for some particular widget
|
||||
* @param widgetTypes if you want to filter some widget type.
|
||||
* @param excludedTypes if you want to exclude some widget type.
|
||||
*/
|
||||
fun getRoomWidgets(
|
||||
roomId: String,
|
||||
widgetId: QueryStringValue = QueryStringValue.NoCondition,
|
||||
|
@ -36,6 +56,15 @@ interface WidgetService {
|
|||
excludedTypes: Set<String>? = null
|
||||
): List<Widget>
|
||||
|
||||
/**
|
||||
* Returns the live room widgets so you can listen to them.
|
||||
* Some widgets can be deactivated, so be sure to check for isActive.
|
||||
*
|
||||
* @param roomId the room where you want to fetch widgets
|
||||
* @param widgetId if you want to fetch for some particular widget
|
||||
* @param widgetTypes if you want to filter some widget type.
|
||||
* @param excludedTypes if you want to exclude some widget type.
|
||||
*/
|
||||
fun getRoomWidgetsLive(
|
||||
roomId: String,
|
||||
widgetId: QueryStringValue = QueryStringValue.NoCondition,
|
||||
|
@ -43,19 +72,53 @@ interface WidgetService {
|
|||
excludedTypes: Set<String>? = null
|
||||
): LiveData<List<Widget>>
|
||||
|
||||
/**
|
||||
* Returns the current user widgets.
|
||||
* Some widgets can be deactivated, so be sure to check for isActive.
|
||||
*
|
||||
* @param widgetTypes if you want to filter some widget type.
|
||||
* @param excludedTypes if you want to exclude some widget type.
|
||||
*/
|
||||
fun getUserWidgets(
|
||||
widgetTypes: Set<String>? = null,
|
||||
excludedTypes: Set<String>? = null
|
||||
): List<Widget>
|
||||
|
||||
/**
|
||||
* Returns the live user widgets so you can listen to them.
|
||||
* Some widgets can be deactivated, so be sure to check for isActive.
|
||||
*
|
||||
* @param widgetTypes if you want to filter some widget type.
|
||||
* @param excludedTypes if you want to exclude some widget type.
|
||||
*/
|
||||
fun getUserWidgetsLive(
|
||||
widgetTypes: Set<String>? = null,
|
||||
excludedTypes: Set<String>? = null
|
||||
): LiveData<List<Widget>>
|
||||
|
||||
/**
|
||||
* Creates a new widget in a room. It makes sure you have the rights to handle this.
|
||||
*
|
||||
* @param roomId: the room where you want to deactivate the widget.
|
||||
* @param widgetId: the widget to deactivate.
|
||||
* @param callback the matrix callback to listen for result.
|
||||
* @return Cancelable
|
||||
*/
|
||||
fun createRoomWidget(roomId: String, widgetId: String, content: Content, callback: MatrixCallback<Widget>): Cancelable
|
||||
|
||||
/**
|
||||
* Deactivate a widget in a room. It makes sure you have the rights to handle this.
|
||||
*
|
||||
* @param roomId: the room where you want to deactivate the widget.
|
||||
* @param widgetId: the widget to deactivate.
|
||||
* @param callback the matrix callback to listen for result.
|
||||
* @return Cancelable
|
||||
*/
|
||||
fun destroyRoomWidget(roomId: String, widgetId: String, callback: MatrixCallback<Unit>): Cancelable
|
||||
|
||||
/**
|
||||
* Returns true if you can add/remove widgets. It goes through
|
||||
* @param roomId the room where you want to administrate widgets.
|
||||
*/
|
||||
fun hasPermissionsToHandleWidgets(roomId: String): Boolean
|
||||
}
|
||||
|
|
|
@ -20,6 +20,12 @@ interface WidgetURLFormatter {
|
|||
/**
|
||||
* Takes care of fetching a scalar token if required and build the final url.
|
||||
* This methods can throw, you should take care of handling failure.
|
||||
*
|
||||
* @param baseUrl the baseUrl which will be checked for scalar token
|
||||
* @param params additional params you want to append to the base url.
|
||||
* @param forceFetchScalarToken if true, you will force to fetch a new scalar token
|
||||
* from the server (only if the base url is whitelisted)
|
||||
* @param bypassWhitelist if true, the base url will be considered as whitelisted
|
||||
*/
|
||||
suspend fun format(
|
||||
baseUrl: String,
|
||||
|
|
|
@ -16,19 +16,19 @@
|
|||
|
||||
package im.vector.matrix.android.api.session.widgets.model
|
||||
|
||||
sealed class WidgetType(open val preferred: String, open val legacy: String) {
|
||||
sealed class WidgetType(open val preferred: String, open val legacy: String = preferred) {
|
||||
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)
|
||||
object TradingView : WidgetType("m.tradingview")
|
||||
object Spotify : WidgetType("m.spotify")
|
||||
object Video : WidgetType("m.video")
|
||||
object GoogleDoc : WidgetType("m.googledoc")
|
||||
object GoogleCalendar : WidgetType("m.googlecalendar")
|
||||
object Etherpad : WidgetType("m.etherpad")
|
||||
object StickerPicker : WidgetType("m.stickerpicker")
|
||||
object Grafana : WidgetType("m.grafana")
|
||||
object Custom : WidgetType("m.custom")
|
||||
object IntegrationManager : WidgetType("m.integration_manager")
|
||||
data class Fallback(override val preferred: String) : WidgetType(preferred)
|
||||
|
||||
fun matches(type: String?): Boolean {
|
||||
return type == preferred || type == legacy
|
||||
|
@ -58,7 +58,7 @@ sealed class WidgetType(open val preferred: String, open val legacy: String) {
|
|||
val matchingType = DEFINED_TYPES.firstOrNull {
|
||||
it.matches(type)
|
||||
}
|
||||
return matchingType ?: Fallback(type, type)
|
||||
return matchingType ?: Fallback(type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ internal class AccountDataMapper @Inject constructor(moshi: Moshi) {
|
|||
fun map(entity: UserAccountDataEntity): UserAccountDataEvent {
|
||||
return UserAccountDataEvent(
|
||||
type = entity.type ?: "",
|
||||
content = entity.contentStr?.let { adapter.fromJson(it) } ?: emptyMap()
|
||||
content = entity.contentStr?.let { adapter.fromJson(it) }.orEmpty()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,14 +21,16 @@ import im.vector.matrix.android.api.auth.data.Versions
|
|||
import im.vector.matrix.android.api.auth.data.isLoginAndRegistrationSupportedBySdk
|
||||
import im.vector.matrix.android.api.auth.wellknown.WellknownResult
|
||||
import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilities
|
||||
import im.vector.matrix.android.internal.wellknown.GetWellknownTask
|
||||
import im.vector.matrix.android.internal.database.model.HomeServerCapabilitiesEntity
|
||||
import im.vector.matrix.android.internal.database.query.getOrCreate
|
||||
import im.vector.matrix.android.internal.di.UserId
|
||||
import im.vector.matrix.android.internal.network.executeRequest
|
||||
import im.vector.matrix.android.internal.session.integrationmanager.IntegrationManagerConfigExtractor
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
import im.vector.matrix.android.internal.util.awaitTransaction
|
||||
import im.vector.matrix.android.internal.wellknown.GetWellknownTask
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import timber.log.Timber
|
||||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -39,6 +41,7 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
|
|||
private val monarchy: Monarchy,
|
||||
private val eventBus: EventBus,
|
||||
private val getWellknownTask: GetWellknownTask,
|
||||
private val configExtractor: IntegrationManagerConfigExtractor,
|
||||
@UserId
|
||||
private val userId: String
|
||||
) : GetHomeServerCapabilitiesTask {
|
||||
|
@ -102,8 +105,14 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
|
|||
|
||||
if (getWellknownResult != null && getWellknownResult is WellknownResult.Prompt) {
|
||||
homeServerCapabilitiesEntity.defaultIdentityServerUrl = getWellknownResult.identityServerUrl
|
||||
}
|
||||
|
||||
// We are also checking for integration manager configurations
|
||||
val config = configExtractor.extract(getWellknownResult.wellKnown)
|
||||
if (config != null) {
|
||||
Timber.v("Extracted integration config : $config")
|
||||
realm.insertOrUpdate(config)
|
||||
}
|
||||
}
|
||||
homeServerCapabilitiesEntity.lastUpdatedTimestamp = Date().time
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import com.squareup.moshi.Json
|
|||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class AllowedWidgetsContent(
|
||||
internal data class AllowedWidgetsContent(
|
||||
/**
|
||||
* Map of stateEventId to Allowed
|
||||
*/
|
||||
|
|
|
@ -60,7 +60,7 @@ internal class DefaultIntegrationManagerService @Inject constructor(private val
|
|||
return integrationManager.setNativeWidgetDomainAllowed(widgetType, domain, allowed, callback)
|
||||
}
|
||||
|
||||
override fun isNativeWidgetAllowed(widgetType: String, domain: String?): Boolean {
|
||||
return integrationManager.isNativeWidgetAllowed(widgetType, domain)
|
||||
override fun isNativeWidgetDomainAllowed(widgetType: String, domain: String): Boolean {
|
||||
return integrationManager.isNativeWidgetDomainAllowed(widgetType, domain)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,6 @@ internal class IntegrationManager @Inject constructor(@UserId private val userId
|
|||
}
|
||||
|
||||
fun start() {
|
||||
refreshWellknown()
|
||||
lifecycleRegistry.currentState = Lifecycle.State.STARTED
|
||||
observeWellknownConfig()
|
||||
accountDataDataSource
|
||||
|
@ -209,7 +208,7 @@ internal class IntegrationManager @Inject constructor(@UserId private val userId
|
|||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
fun isNativeWidgetAllowed(widgetType: String, domain: String?): Boolean {
|
||||
fun isNativeWidgetDomainAllowed(widgetType: String, domain: String?): Boolean {
|
||||
val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountData.TYPE_ALLOWED_WIDGETS)
|
||||
val currentContent = currentAllowedWidgets?.content?.toModel<AllowedWidgetsContent>()
|
||||
return currentContent?.native?.get(widgetType)?.get(domain) ?: false
|
||||
|
@ -273,25 +272,6 @@ internal class IntegrationManager @Inject constructor(@UserId private val userId
|
|||
.firstOrNull()?.widgetContent
|
||||
}
|
||||
|
||||
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) },
|
||||
|
|
|
@ -24,5 +24,5 @@ import im.vector.matrix.android.api.session.integrationmanager.IntegrationManage
|
|||
internal abstract class IntegrationManagerModule {
|
||||
|
||||
@Binds
|
||||
abstract fun bindIntegrationManagerService(integrationManagerService: DefaultIntegrationManagerService): IntegrationManagerService
|
||||
abstract fun bindIntegrationManagerService(service: DefaultIntegrationManagerService): IntegrationManagerService
|
||||
}
|
||||
|
|
|
@ -20,6 +20,6 @@ import com.squareup.moshi.Json
|
|||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class IntegrationManagerWidgetData(
|
||||
internal data class IntegrationManagerWidgetData(
|
||||
@Json(name = "api_url") val apiUrl: String? = null
|
||||
)
|
||||
|
|
|
@ -20,6 +20,6 @@ import com.squareup.moshi.Json
|
|||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class IntegrationProvisioningContent(
|
||||
internal data class IntegrationProvisioningContent(
|
||||
@Json(name = "enabled") val enabled: Boolean
|
||||
)
|
||||
|
|
|
@ -118,6 +118,7 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,
|
|||
else -> {
|
||||
val params = SendStateTask.Params(
|
||||
roomId = roomId,
|
||||
stateKey = null,
|
||||
eventType = EventType.STATE_ROOM_ENCRYPTION,
|
||||
body = mapOf(
|
||||
"algorithm" to algorithm
|
||||
|
|
|
@ -346,7 +346,7 @@ internal class LocalEchoEventFactory @Inject constructor(
|
|||
return createMessageEvent(roomId, content)
|
||||
}
|
||||
|
||||
private fun createMessageEvent(roomId: String, content: Any? = null): Event {
|
||||
private fun createMessageEvent(roomId: String, content: MessageContent? = null): Event {
|
||||
return createEvent(roomId, EventType.MESSAGE, content.toContent())
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ internal class DefaultStateService @AssistedInject constructor(@Assisted private
|
|||
): Cancelable {
|
||||
val params = SendStateTask.Params(
|
||||
roomId = roomId,
|
||||
stateKey = stateKey,
|
||||
eventType = eventType,
|
||||
body = body
|
||||
)
|
||||
|
|
|
@ -26,7 +26,7 @@ import javax.inject.Inject
|
|||
internal interface SendStateTask : Task<SendStateTask.Params, Unit> {
|
||||
data class Params(
|
||||
val roomId: String,
|
||||
val stateKey: String? = null,
|
||||
val stateKey: String?,
|
||||
val eventType: String,
|
||||
val body: JsonDict
|
||||
)
|
||||
|
|
|
@ -20,6 +20,6 @@ import com.squareup.moshi.Json
|
|||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class RegisterWidgetResponse(
|
||||
internal data class RegisterWidgetResponse(
|
||||
@Json(name = "scalar_token") val scalarToken: String?
|
||||
)
|
||||
|
|
|
@ -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.WidgetManagementFailure
|
||||
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
|
||||
|
|
|
@ -39,13 +39,13 @@ internal abstract class WidgetModule {
|
|||
}
|
||||
|
||||
@Binds
|
||||
abstract fun bindWidgetService(widgetService: DefaultWidgetService): WidgetService
|
||||
abstract fun bindWidgetService(service: DefaultWidgetService): WidgetService
|
||||
|
||||
@Binds
|
||||
abstract fun bindWidgetURLBuilder(widgetURLBuilder: DefaultWidgetURLFormatter): WidgetURLFormatter
|
||||
abstract fun bindWidgetURLBuilder(formatter: DefaultWidgetURLFormatter): WidgetURLFormatter
|
||||
|
||||
@Binds
|
||||
abstract fun bindWidgetPostAPIMediator(widgetPostMessageAPIProvider: DefaultWidgetPostAPIMediator): WidgetPostAPIMediator
|
||||
abstract fun bindWidgetPostAPIMediator(mediator: DefaultWidgetPostAPIMediator): WidgetPostAPIMediator
|
||||
|
||||
@Binds
|
||||
abstract fun bindCreateWidgetTask(task: DefaultCreateWidgetTask): CreateWidgetTask
|
||||
|
|
|
@ -20,7 +20,7 @@ import android.content.Context
|
|||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class WidgetPostMessageAPIProvider @Inject constructor(private val context: Context) {
|
||||
internal class WidgetPostMessageAPIProvider @Inject constructor(private val context: Context) {
|
||||
|
||||
private var postMessageAPIString: String? = null
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ internal interface WidgetsAPI {
|
|||
* @param requestOpenIdTokenResponse the body content (Ref: https://github.com/matrix-org/matrix-doc/pull/1961)
|
||||
*/
|
||||
@POST("register")
|
||||
fun register(@Body requestOpenIdTokenResponse: RequestOpenIdTokenResponse, @Query("v") version: String?): Call<RegisterWidgetResponse>
|
||||
fun register(@Body body: RequestOpenIdTokenResponse, @Query("v") version: String?): Call<RegisterWidgetResponse>
|
||||
|
||||
@GET("account")
|
||||
fun validateToken(@Query("scalar_token") scalarToken: String?, @Query("v") version: String?): Call<Unit>
|
||||
|
|
|
@ -21,7 +21,7 @@ import im.vector.matrix.android.api.failure.MatrixError
|
|||
import im.vector.matrix.android.internal.network.executeRequest
|
||||
import im.vector.matrix.android.internal.session.openid.GetOpenIdTokenTask
|
||||
import im.vector.matrix.android.internal.session.widgets.RegisterWidgetResponse
|
||||
import im.vector.matrix.android.internal.session.widgets.WidgetManagementFailure
|
||||
import im.vector.matrix.android.api.session.widgets.WidgetManagementFailure
|
||||
import im.vector.matrix.android.internal.session.widgets.WidgetsAPI
|
||||
import im.vector.matrix.android.internal.session.widgets.WidgetsAPIProvider
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
|
|
|
@ -123,7 +123,7 @@ interface ScreenComponent {
|
|||
fun inject(activity: BigImageViewerActivity)
|
||||
fun inject(activity: InviteUsersToRoomActivity)
|
||||
fun inject(activity: ReviewTermsActivity)
|
||||
fun inject(widgetActivity: WidgetActivity)
|
||||
fun inject(activity: WidgetActivity)
|
||||
|
||||
/* ==========================================================================================
|
||||
* BottomSheets
|
||||
|
|
|
@ -202,7 +202,8 @@ class RoomDetailFragment @Inject constructor(
|
|||
VectorInviteView.Callback,
|
||||
JumpToReadMarkerView.Callback,
|
||||
AttachmentTypeSelectorView.Callback,
|
||||
AttachmentsHelper.Callback, RoomWidgetsBannerView.Callback {
|
||||
AttachmentsHelper.Callback,
|
||||
RoomWidgetsBannerView.Callback {
|
||||
|
||||
companion object {
|
||||
|
||||
|
@ -327,8 +328,6 @@ class RoomDetailFragment @Inject constructor(
|
|||
private fun displayPromptForIntegrationManager() {
|
||||
// The Sticker picker widget is not installed yet. Propose the user to install it
|
||||
val builder = AlertDialog.Builder(requireContext())
|
||||
// Use the builder context
|
||||
// Use the builder context
|
||||
val v: View = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_no_sticker_pack, null)
|
||||
builder
|
||||
.setView(v)
|
||||
|
|
|
@ -66,7 +66,6 @@ data class RoomDetailViewState(
|
|||
val syncState: SyncState = SyncState.Idle,
|
||||
val highlightedEventId: String? = null,
|
||||
val unreadState: UnreadState = UnreadState.Unknown,
|
||||
val menuItemsVisibility: SparseArray<Boolean> = SparseArray(4),
|
||||
val canShowJumpToReadMarker: Boolean = true
|
||||
) : MvRxState {
|
||||
|
||||
|
|
|
@ -22,17 +22,19 @@ import com.airbnb.epoxy.EpoxyModelClass
|
|||
import com.airbnb.epoxy.EpoxyModelWithHolder
|
||||
import im.vector.matrix.android.api.session.widgets.model.Widget
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.ClickListener
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotx.core.epoxy.onClick
|
||||
|
||||
@EpoxyModelClass(layout = R.layout.item_room_widget)
|
||||
abstract class RoomWidgetItem : EpoxyModelWithHolder<RoomWidgetItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute lateinit var widget: Widget
|
||||
@EpoxyAttribute var widgetClicked: (() -> Unit)? = null
|
||||
@EpoxyAttribute var widgetClicked: ClickListener? = null
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
holder.widgetName.text = widget.name
|
||||
holder.view.setOnClickListener { widgetClicked?.invoke() }
|
||||
holder.view.onClick(widgetClicked)
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
|
|
|
@ -27,12 +27,10 @@ class WidgetAPICallback(private val postAPIMediator: WidgetPostAPIMediator,
|
|||
private val stringProvider: StringProvider) : MatrixCallback<Any> {
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
super.onFailure(failure)
|
||||
postAPIMediator.sendError(stringProvider.getString(R.string.widget_integration_failed_to_send_request), eventData)
|
||||
}
|
||||
|
||||
override fun onSuccess(data: Any) {
|
||||
super.onSuccess(data)
|
||||
postAPIMediator.sendSuccess(eventData)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,9 +80,11 @@ class WidgetActivity : VectorBaseActivity(), ToolbarConfigurable, WidgetViewMode
|
|||
}
|
||||
|
||||
override fun initUiAndData() {
|
||||
val widgetArgs: WidgetArgs = intent?.extras?.getParcelable(MvRx.KEY_ARG)
|
||||
?: return
|
||||
|
||||
val widgetArgs: WidgetArgs? = intent?.extras?.getParcelable(MvRx.KEY_ARG)
|
||||
if (widgetArgs == null) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
configure(toolbar)
|
||||
toolbar.isVisible = widgetArgs.kind.nameRes != 0
|
||||
viewModel.observeViewEvents {
|
||||
|
|
|
@ -34,7 +34,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.internal.session.widgets.WidgetManagementFailure
|
||||
import im.vector.matrix.android.api.session.widgets.WidgetManagementFailure
|
||||
import im.vector.matrix.android.internal.util.awaitCallback
|
||||
import im.vector.matrix.rx.mapOptional
|
||||
import im.vector.matrix.rx.rx
|
||||
|
|
|
@ -34,6 +34,7 @@ import im.vector.riotx.core.extensions.withArgs
|
|||
import im.vector.riotx.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import im.vector.riotx.features.widgets.WidgetArgs
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_room_widget_permission.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomWidgetPermissionBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
||||
|
@ -42,18 +43,6 @@ class RoomWidgetPermissionBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
|
||||
private val viewModel: RoomWidgetPermissionViewModel by activityViewModel()
|
||||
|
||||
@BindView(R.id.bottom_sheet_widget_permission_shared_info)
|
||||
lateinit var sharedInfoTextView: TextView
|
||||
|
||||
@BindView(R.id.bottom_sheet_widget_permission_owner_id)
|
||||
lateinit var authorIdText: TextView
|
||||
|
||||
@BindView(R.id.bottom_sheet_widget_permission_owner_display_name)
|
||||
lateinit var authorNameText: TextView
|
||||
|
||||
@BindView(R.id.bottom_sheet_widget_permission_owner_avatar)
|
||||
lateinit var authorAvatarView: ImageView
|
||||
|
||||
@Inject lateinit var avatarRenderer: AvatarRenderer
|
||||
|
||||
override val showExpanded = true
|
||||
|
@ -65,10 +54,10 @@ class RoomWidgetPermissionBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
override fun invalidate() = withState(viewModel) { state ->
|
||||
super.invalidate()
|
||||
val permissionData = state.permissionData() ?: return@withState
|
||||
authorIdText.text = permissionData.widget.senderInfo?.userId ?: ""
|
||||
authorNameText.text = permissionData.widget.senderInfo?.disambiguatedDisplayName
|
||||
widgetPermissionOwnerId.text = permissionData.widget.senderInfo?.userId ?: ""
|
||||
widgetPermissionOwnerDisplayName.text = permissionData.widget.senderInfo?.disambiguatedDisplayName
|
||||
permissionData.widget.senderInfo?.toMatrixItem()?.also {
|
||||
avatarRenderer.render(it, authorAvatarView)
|
||||
avatarRenderer.render(it, widgetPermissionOwnerAvatar)
|
||||
}
|
||||
|
||||
val domain = permissionData.widgetDomain ?: ""
|
||||
|
@ -96,18 +85,17 @@ class RoomWidgetPermissionBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
}
|
||||
}
|
||||
infoBuilder.append("\n")
|
||||
|
||||
sharedInfoTextView.text = infoBuilder
|
||||
widgetPermissionSharedInfo.text = infoBuilder
|
||||
}
|
||||
|
||||
@OnClick(R.id.bottom_sheet_widget_permission_decline_button)
|
||||
@OnClick(R.id.widgetPermissionDecline)
|
||||
fun doDecline() {
|
||||
viewModel.handle(RoomWidgetPermissionActions.BlockWidget)
|
||||
// optimistic dismiss
|
||||
dismiss()
|
||||
}
|
||||
|
||||
@OnClick(R.id.bottom_sheet_widget_permission_continue_button)
|
||||
@OnClick(R.id.widgetPermissionContinue)
|
||||
fun doAccept() {
|
||||
viewModel.handle(RoomWidgetPermissionActions.AllowWidget)
|
||||
// optimistic dismiss
|
||||
|
|
|
@ -17,17 +17,18 @@
|
|||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/room_widget_permission_title"
|
||||
android:textSize="20sp"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_widget_permission_h2_text"
|
||||
android:id="@+id/widgetPermissionHeader2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/layout_horizontal_margin"
|
||||
android:layout_marginEnd="@dimen/layout_horizontal_margin"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/room_widget_permission_added_by"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<LinearLayout
|
||||
|
@ -39,7 +40,7 @@
|
|||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/bottom_sheet_widget_permission_owner_avatar"
|
||||
android:id="@+id/widgetPermissionOwnerAvatar"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center"
|
||||
|
@ -54,33 +55,35 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_widget_permission_owner_display_name"
|
||||
android:id="@+id/widgetPermissionOwnerDisplayName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="?riotx_text_primary"
|
||||
tools:text="User name" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_widget_permission_owner_id"
|
||||
android:id="@+id/widgetPermissionOwnerId"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:textSize="14sp"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
tools:text="\@foo:matrix.org" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_sheet_widget_permission_shared_info"
|
||||
android:id="@+id/widgetPermissionSharedInfo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/layout_horizontal_margin"
|
||||
android:layout_marginTop="@dimen/layout_vertical_margin_big"
|
||||
android:layout_marginEnd="@dimen/layout_horizontal_margin"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="16sp"
|
||||
tools:text="@string/room_widget_permission_shared_info_title" />
|
||||
|
||||
|
@ -91,16 +94,16 @@
|
|||
android:gravity="end"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/bottom_sheet_widget_permission_decline_button"
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/widgetPermissionDecline"
|
||||
style="@style/VectorButtonStyleDestructive"
|
||||
android:layout_marginEnd="@dimen/layout_vertical_margin"
|
||||
android:layout_marginRight="@dimen/layout_vertical_margin"
|
||||
android:text="@string/decline"
|
||||
android:textAllCaps="true"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bottom_sheet_widget_permission_continue_button"
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/widgetPermissionContinue"
|
||||
style="@style/VectorButtonStylePositive"
|
||||
android:layout_marginEnd="@dimen/layout_vertical_margin"
|
||||
android:layout_marginRight="@dimen/layout_vertical_margin"
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
android:layout_gravity="center"
|
||||
android:layout_marginStart="@dimen/layout_horizontal_margin"
|
||||
android:layout_marginEnd="@dimen/layout_horizontal_margin"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textStyle="bold"
|
||||
tools:text="Fail to load widget " />
|
||||
</LinearLayout>
|
||||
|
|
|
@ -105,6 +105,7 @@
|
|||
|
||||
<im.vector.riotx.core.preference.VectorSwitchPreference
|
||||
android:key="SETTINGS_ALLOW_INTEGRATIONS_KEY"
|
||||
android:persistent="false"
|
||||
android:title="@string/settings_integration_allow" />
|
||||
|
||||
<im.vector.riotx.core.preference.VectorPreference
|
||||
|
|
Loading…
Reference in New Issue