mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-16 20:10:04 +03:00
Merge branch 'develop' into feature/bma/url_preview_fixes
This commit is contained in:
commit
d2c912e5c4
16 changed files with 122 additions and 74 deletions
|
@ -1,4 +1,4 @@
|
||||||
Changes in Element 1.X.X (2020-XX-XX)
|
Changes in Element 1.0.17 (2020-XX-XX)
|
||||||
===================================================
|
===================================================
|
||||||
|
|
||||||
Features ✨:
|
Features ✨:
|
||||||
|
@ -8,10 +8,12 @@ Improvements 🙌:
|
||||||
- Open image from URL Preview (#2705)
|
- Open image from URL Preview (#2705)
|
||||||
|
|
||||||
Bugfix 🐛:
|
Bugfix 🐛:
|
||||||
|
- Bug in WidgetContent.computeURL() (#2767)
|
||||||
- Duplicate thumbs | Mobile reactions for 👍 and 👎 are not the same as web (#2776)
|
- Duplicate thumbs | Mobile reactions for 👍 and 👎 are not the same as web (#2776)
|
||||||
- Join room by alias other federation error (#2778)
|
- Join room by alias other federation error (#2778)
|
||||||
- HTML unescaping for URL preview (#2766)
|
- HTML unescaping for URL preview (#2766)
|
||||||
- URL preview on reply fallback (#2756)
|
- URL preview on reply fallback (#2756)
|
||||||
|
- RTL: some arrows should be rotated in RTL (#2757)
|
||||||
|
|
||||||
Translations 🗣:
|
Translations 🗣:
|
||||||
-
|
-
|
||||||
|
@ -26,7 +28,7 @@ Test:
|
||||||
-
|
-
|
||||||
|
|
||||||
Other changes:
|
Other changes:
|
||||||
-
|
- Change app name from "Element (Riot.im)" to "Element"
|
||||||
|
|
||||||
Changes in Element 1.0.16 (2020-02-04)
|
Changes in Element 1.0.16 (2020-02-04)
|
||||||
===================================================
|
===================================================
|
||||||
|
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionSha256Sum=3db89524a3981819ff28c3f979236c1274a726e146ced0c8a2020417f9bc0782
|
distributionSha256Sum=1433372d903ffba27496f8d5af24265310d2da0d78bf6b4e5138831d4fe066e9
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-all.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
|
@ -97,10 +97,11 @@ interface WidgetService {
|
||||||
): LiveData<List<Widget>>
|
): LiveData<List<Widget>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new widget in a room. It makes sure you have the rights to handle this.
|
* Creates and send 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 roomId the room where you want to create the widget.
|
||||||
* @param widgetId: the widget to deactivate.
|
* @param widgetId the widget to create.
|
||||||
|
* @param content the content of the widget
|
||||||
* @param callback the matrix callback to listen for result.
|
* @param callback the matrix callback to listen for result.
|
||||||
* @return Cancelable
|
* @return Cancelable
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -35,3 +35,10 @@ fun StringBuilder.appendParamToUrl(param: String, value: String): StringBuilder
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun StringBuilder.appendParamsToUrl(params: Map<String, String>): StringBuilder {
|
||||||
|
params.forEach { (param, value) ->
|
||||||
|
appendParamToUrl(param, value)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
|
@ -20,11 +20,12 @@ import org.matrix.android.sdk.api.MatrixConfiguration
|
||||||
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerConfig
|
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerConfig
|
||||||
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
|
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
|
||||||
import org.matrix.android.sdk.api.session.widgets.WidgetURLFormatter
|
import org.matrix.android.sdk.api.session.widgets.WidgetURLFormatter
|
||||||
|
import org.matrix.android.sdk.api.util.appendParamToUrl
|
||||||
|
import org.matrix.android.sdk.api.util.appendParamsToUrl
|
||||||
import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
|
import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
|
||||||
import org.matrix.android.sdk.internal.session.SessionScope
|
import org.matrix.android.sdk.internal.session.SessionScope
|
||||||
import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManager
|
import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManager
|
||||||
import org.matrix.android.sdk.internal.session.widgets.token.GetScalarTokenTask
|
import org.matrix.android.sdk.internal.session.widgets.token.GetScalarTokenTask
|
||||||
import java.net.URLEncoder
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@SessionScope
|
@SessionScope
|
||||||
|
@ -90,25 +91,4 @@ internal class DefaultWidgetURLFormatter @Inject constructor(private val integra
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun StringBuilder.appendParamsToUrl(params: Map<String, String>): StringBuilder {
|
|
||||||
params.forEach { (param, value) ->
|
|
||||||
appendParamToUrl(param, value)
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun StringBuilder.appendParamToUrl(param: String, value: String): StringBuilder {
|
|
||||||
if (contains("?")) {
|
|
||||||
append("&")
|
|
||||||
} else {
|
|
||||||
append("?")
|
|
||||||
}
|
|
||||||
|
|
||||||
append(param)
|
|
||||||
append("=")
|
|
||||||
append(URLEncoder.encode(value, "utf-8"))
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,23 +65,31 @@ internal class WidgetFactory @Inject constructor(private val userDataSource: Use
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ref: https://github.com/matrix-org/matrix-widget-api/blob/master/src/templating/url-template.ts#L29-L33
|
||||||
private fun WidgetContent.computeURL(roomId: String?, widgetId: String): String? {
|
private fun WidgetContent.computeURL(roomId: String?, widgetId: String): String? {
|
||||||
var computedUrl = url ?: return null
|
var computedUrl = url ?: return null
|
||||||
val myUser = userDataSource.getUser(userId)
|
val myUser = userDataSource.getUser(userId)
|
||||||
computedUrl = computedUrl
|
|
||||||
.replace("\$matrix_user_id", userId)
|
|
||||||
.replace("\$matrix_display_name", myUser?.displayName ?: userId)
|
|
||||||
.replace("\$matrix_avatar_url", myUser?.avatarUrl ?: "")
|
|
||||||
.replace("\$matrix_widget_id", widgetId)
|
|
||||||
|
|
||||||
if (roomId != null) {
|
val keyValue = data.mapKeys { "\$${it.key}" }.toMutableMap()
|
||||||
computedUrl = computedUrl.replace("\$matrix_room_id", roomId)
|
|
||||||
}
|
keyValue[WIDGET_PATTERN_MATRIX_USER_ID] = userId
|
||||||
for ((key, value) in data) {
|
keyValue[WIDGET_PATTERN_MATRIX_DISPLAY_NAME] = myUser?.getBestName() ?: userId
|
||||||
if (value is String) {
|
keyValue[WIDGET_PATTERN_MATRIX_AVATAR_URL] = myUser?.avatarUrl ?: ""
|
||||||
computedUrl = computedUrl.replace("$$key", URLEncoder.encode(value, "utf-8"))
|
keyValue[WIDGET_PATTERN_MATRIX_WIDGET_ID] = widgetId
|
||||||
}
|
keyValue[WIDGET_PATTERN_MATRIX_ROOM_ID] = roomId ?: ""
|
||||||
|
|
||||||
|
for ((key, value) in keyValue) {
|
||||||
|
computedUrl = computedUrl.replace(key, URLEncoder.encode(value.toString(), "utf-8"))
|
||||||
}
|
}
|
||||||
return computedUrl
|
return computedUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
// Value to be replaced in URLS
|
||||||
|
const val WIDGET_PATTERN_MATRIX_USER_ID = "\$matrix_user_id"
|
||||||
|
const val WIDGET_PATTERN_MATRIX_DISPLAY_NAME = "\$matrix_display_name"
|
||||||
|
const val WIDGET_PATTERN_MATRIX_AVATAR_URL = "\$matrix_avatar_url"
|
||||||
|
const val WIDGET_PATTERN_MATRIX_WIDGET_ID = "\$matrix_widget_id"
|
||||||
|
const val WIDGET_PATTERN_MATRIX_ROOM_ID = "\$matrix_room_id"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,7 +210,7 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
release {
|
release {
|
||||||
resValue "string", "app_name", "Element (Riot.im)"
|
resValue "string", "app_name", "Element"
|
||||||
|
|
||||||
resValue "bool", "debug_mode", "false"
|
resValue "bool", "debug_mode", "false"
|
||||||
buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
|
buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package im.vector.app.features.call.conference
|
package im.vector.app.features.call.conference
|
||||||
|
|
||||||
import android.net.Uri
|
|
||||||
import com.airbnb.mvrx.Fail
|
import com.airbnb.mvrx.Fail
|
||||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
import com.airbnb.mvrx.Success
|
import com.airbnb.mvrx.Success
|
||||||
|
@ -64,14 +63,12 @@ class JitsiCallViewModel @AssistedInject constructor(
|
||||||
.subscribe {
|
.subscribe {
|
||||||
val jitsiWidget = it.firstOrNull()
|
val jitsiWidget = it.firstOrNull()
|
||||||
if (jitsiWidget != null) {
|
if (jitsiWidget != null) {
|
||||||
val uri = Uri.parse(jitsiWidget.computedUrl)
|
|
||||||
val confId = uri.getQueryParameter("confId")
|
|
||||||
val ppt = jitsiWidget.computedUrl?.let { url -> JitsiWidgetProperties(url, stringProvider) }
|
val ppt = jitsiWidget.computedUrl?.let { url -> JitsiWidgetProperties(url, stringProvider) }
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
widget = Success(jitsiWidget),
|
widget = Success(jitsiWidget),
|
||||||
jitsiUrl = "https://${ppt?.domain}",
|
jitsiUrl = "https://${ppt?.domain}",
|
||||||
confId = confId ?: "",
|
confId = ppt?.confId ?: "",
|
||||||
subject = roomName ?: ""
|
subject = roomName ?: ""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,11 @@ package im.vector.app.features.call.conference
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
|
import java.net.URLDecoder
|
||||||
|
|
||||||
class JitsiWidgetProperties(private val uriString: String, val stringProvider: StringProvider) {
|
class JitsiWidgetProperties(private val uriString: String, val stringProvider: StringProvider) {
|
||||||
val domain: String by lazy { configs["conferenceDomain"] ?: stringProvider.getString(R.string.preferred_jitsi_domain) }
|
val domain: String by lazy { configs["conferenceDomain"] ?: stringProvider.getString(R.string.preferred_jitsi_domain) }
|
||||||
|
val confId: String? by lazy { configs["conferenceId"] }
|
||||||
val displayName: String? by lazy { configs["displayName"] }
|
val displayName: String? by lazy { configs["displayName"] }
|
||||||
val avatarUrl: String? by lazy { configs["avatarUrl"] }
|
val avatarUrl: String? by lazy { configs["avatarUrl"] }
|
||||||
|
|
||||||
|
@ -30,8 +32,9 @@ class JitsiWidgetProperties(private val uriString: String, val stringProvider: S
|
||||||
private val configs: Map<String, String?> by lazy {
|
private val configs: Map<String, String?> by lazy {
|
||||||
configString?.split("&")
|
configString?.split("&")
|
||||||
?.map { it.split("=") }
|
?.map { it.split("=") }
|
||||||
?.map { (key, value) -> key to value }
|
?.filter { it.size == 2 }
|
||||||
|
?.map { (key, value) -> key to URLDecoder.decode(value, "UTF-8") }
|
||||||
?.toMap()
|
?.toMap()
|
||||||
?: mapOf()
|
.orEmpty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.jitsi.meet.sdk.JitsiMeetConferenceOptions
|
||||||
import org.jitsi.meet.sdk.JitsiMeetView
|
import org.jitsi.meet.sdk.JitsiMeetView
|
||||||
import org.jitsi.meet.sdk.JitsiMeetViewListener
|
import org.jitsi.meet.sdk.JitsiMeetViewListener
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
|
import timber.log.Timber
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -154,13 +155,19 @@ class VectorJitsiActivity : VectorBaseActivity<ActivityJitsiBinding>(), JitsiMee
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onConferenceTerminated(p0: MutableMap<String, Any>?) {
|
override fun onConferenceTerminated(p0: MutableMap<String, Any>?) {
|
||||||
finish()
|
Timber.v("JitsiMeetViewListener.onConferenceTerminated()")
|
||||||
|
// Do not finish if there is an error
|
||||||
|
if (p0?.get("error") == null) {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onConferenceJoined(p0: MutableMap<String, Any>?) {
|
override fun onConferenceJoined(p0: MutableMap<String, Any>?) {
|
||||||
|
Timber.v("JitsiMeetViewListener.onConferenceJoined()")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onConferenceWillJoin(p0: MutableMap<String, Any>?) {
|
override fun onConferenceWillJoin(p0: MutableMap<String, Any>?) {
|
||||||
|
Timber.v("JitsiMeetViewListener.onConferenceWillJoin()")
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -91,6 +91,7 @@ import org.matrix.android.sdk.api.session.room.timeline.getRelationContent
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.getTextEditableContent
|
import org.matrix.android.sdk.api.session.room.timeline.getTextEditableContent
|
||||||
import org.matrix.android.sdk.api.session.widgets.model.Widget
|
import org.matrix.android.sdk.api.session.widgets.model.Widget
|
||||||
import org.matrix.android.sdk.api.session.widgets.model.WidgetType
|
import org.matrix.android.sdk.api.session.widgets.model.WidgetType
|
||||||
|
import org.matrix.android.sdk.api.util.appendParamToUrl
|
||||||
import org.matrix.android.sdk.api.util.toOptional
|
import org.matrix.android.sdk.api.util.toOptional
|
||||||
import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode
|
import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode
|
||||||
import org.matrix.android.sdk.internal.util.awaitCallback
|
import org.matrix.android.sdk.internal.util.awaitCallback
|
||||||
|
@ -400,15 +401,19 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
// We use the default element wrapper for this widget
|
// We use the default element wrapper for this widget
|
||||||
// https://github.com/vector-im/element-web/blob/develop/docs/jitsi-dev.md
|
// https://github.com/vector-im/element-web/blob/develop/docs/jitsi-dev.md
|
||||||
val url = "https://app.element.io/jitsi.html" +
|
// https://github.com/matrix-org/matrix-react-sdk/blob/develop/src/utils/WidgetUtils.ts#L469
|
||||||
"?confId=$confId" +
|
val url = buildString {
|
||||||
"#conferenceDomain=\$domain" +
|
append("https://app.element.io/jitsi.html")
|
||||||
"&conferenceId=\$conferenceId" +
|
appendParamToUrl("confId", confId)
|
||||||
"&isAudioOnly=${!action.withVideo}" +
|
append("#conferenceDomain=\$domain")
|
||||||
"&displayName=\$matrix_display_name" +
|
append("&conferenceId=\$conferenceId")
|
||||||
"&avatarUrl=\$matrix_avatar_url" +
|
append("&isAudioOnly=\$isAudioOnly")
|
||||||
"&userId=\$matrix_user_id"
|
append("&displayName=\$matrix_display_name")
|
||||||
|
append("&avatarUrl=\$matrix_avatar_url")
|
||||||
|
append("&userId=\$matrix_user_id")
|
||||||
|
append("&roomId=\$matrix_room_id")
|
||||||
|
append("&theme=\$theme")
|
||||||
|
}
|
||||||
val widgetEventContent = mapOf(
|
val widgetEventContent = mapOf(
|
||||||
"url" to url,
|
"url" to url,
|
||||||
"type" to WidgetType.Jitsi.legacy,
|
"type" to WidgetType.Jitsi.legacy,
|
||||||
|
|
|
@ -16,11 +16,16 @@
|
||||||
|
|
||||||
package im.vector.app.features.widgets
|
package im.vector.app.features.widgets
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
|
import im.vector.app.features.themes.ThemeUtils
|
||||||
import org.matrix.android.sdk.api.session.widgets.model.Widget
|
import org.matrix.android.sdk.api.session.widgets.model.Widget
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class WidgetArgsBuilder @Inject constructor(private val sessionHolder: ActiveSessionHolder) {
|
class WidgetArgsBuilder @Inject constructor(
|
||||||
|
private val sessionHolder: ActiveSessionHolder,
|
||||||
|
private val context: Context
|
||||||
|
) {
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
fun buildIntegrationManagerArgs(roomId: String, integId: String?, screen: String?): WidgetArgs {
|
fun buildIntegrationManagerArgs(roomId: String, integId: String?, screen: String?): WidgetArgs {
|
||||||
|
@ -38,7 +43,8 @@ class WidgetArgsBuilder @Inject constructor(private val sessionHolder: ActiveSes
|
||||||
urlParams = mapOf(
|
urlParams = mapOf(
|
||||||
"screen" to normalizedScreen,
|
"screen" to normalizedScreen,
|
||||||
"integ_id" to integId,
|
"integ_id" to integId,
|
||||||
"room_id" to roomId
|
"room_id" to roomId,
|
||||||
|
"theme" to getTheme()
|
||||||
).filterNotNull()
|
).filterNotNull()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -54,7 +60,8 @@ class WidgetArgsBuilder @Inject constructor(private val sessionHolder: ActiveSes
|
||||||
widgetId = widgetId,
|
widgetId = widgetId,
|
||||||
urlParams = mapOf(
|
urlParams = mapOf(
|
||||||
"widgetId" to widgetId,
|
"widgetId" to widgetId,
|
||||||
"room_id" to roomId
|
"room_id" to roomId,
|
||||||
|
"theme" to getTheme()
|
||||||
).filterNotNull()
|
).filterNotNull()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -66,7 +73,10 @@ class WidgetArgsBuilder @Inject constructor(private val sessionHolder: ActiveSes
|
||||||
baseUrl = baseUrl,
|
baseUrl = baseUrl,
|
||||||
kind = WidgetKind.ROOM,
|
kind = WidgetKind.ROOM,
|
||||||
roomId = roomId,
|
roomId = roomId,
|
||||||
widgetId = widgetId
|
widgetId = widgetId,
|
||||||
|
urlParams = mapOf(
|
||||||
|
"theme" to getTheme()
|
||||||
|
).filterNotNull()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,4 +84,12 @@ class WidgetArgsBuilder @Inject constructor(private val sessionHolder: ActiveSes
|
||||||
private fun Map<String, String?>.filterNotNull(): Map<String, String> {
|
private fun Map<String, String?>.filterNotNull(): Map<String, String> {
|
||||||
return filterValues { it != null } as Map<String, String>
|
return filterValues { it != null } as Map<String, String>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getTheme(): String {
|
||||||
|
return if (ThemeUtils.isLightTheme(context)) {
|
||||||
|
"light"
|
||||||
|
} else {
|
||||||
|
"dark"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
16
vector/src/main/res/drawable-ldrtl/ic_arrow_right.xml
Normal file
16
vector/src/main/res/drawable-ldrtl/ic_arrow_right.xml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:width="7dp"
|
||||||
|
android:height="12dp"
|
||||||
|
android:viewportWidth="7"
|
||||||
|
android:viewportHeight="12">
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:pathData="M6,11l-5,-5 5,-5"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:strokeColor="#2E2F32"
|
||||||
|
android:strokeLineCap="round"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
tools:strokeColor="#FFAF0F" />
|
||||||
|
</vector>
|
|
@ -1,14 +1,16 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:width="7dp"
|
android:width="7dp"
|
||||||
android:height="12dp"
|
android:height="12dp"
|
||||||
android:viewportWidth="7"
|
android:viewportWidth="7"
|
||||||
android:viewportHeight="12">
|
android:viewportHeight="12">
|
||||||
<path
|
<path
|
||||||
android:pathData="M1,11l5,-5 -5,-5"
|
android:fillColor="#00000000"
|
||||||
android:strokeLineJoin="round"
|
android:fillType="evenOdd"
|
||||||
android:strokeWidth="2"
|
android:pathData="M1,11l5,-5 -5,-5"
|
||||||
android:fillColor="#00000000"
|
android:strokeWidth="2"
|
||||||
android:fillType="evenOdd"
|
android:strokeColor="#2E2F32"
|
||||||
android:strokeColor="#2E2F32"
|
android:strokeLineCap="round"
|
||||||
android:strokeLineCap="round"/>
|
android:strokeLineJoin="round"
|
||||||
|
tools:strokeColor="#FFAF0F" />
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
@ -84,6 +84,7 @@
|
||||||
android:insetRight="0dp"
|
android:insetRight="0dp"
|
||||||
android:insetBottom="0dp"
|
android:insetBottom="0dp"
|
||||||
android:padding="0dp"
|
android:padding="0dp"
|
||||||
|
android:rotationY="@integer/rtl_mirror_flip"
|
||||||
app:cornerRadius="17dp"
|
app:cornerRadius="17dp"
|
||||||
app:icon="@drawable/ic_qr_code_add"
|
app:icon="@drawable/ic_qr_code_add"
|
||||||
app:iconGravity="textStart"
|
app:iconGravity="textStart"
|
||||||
|
|
|
@ -44,12 +44,13 @@
|
||||||
android:id="@+id/messageVerificationRequestStub"
|
android:id="@+id/messageVerificationRequestStub"
|
||||||
style="@style/TimelineContentStubBaseParams"
|
style="@style/TimelineContentStubBaseParams"
|
||||||
android:layout="@layout/item_timeline_event_verification_stub"
|
android:layout="@layout/item_timeline_event_verification_stub"
|
||||||
tools:visibility="gone" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<ViewStub
|
<ViewStub
|
||||||
android:id="@+id/messageVerificationDoneStub"
|
android:id="@+id/messageVerificationDoneStub"
|
||||||
style="@style/TimelineContentStubBaseParams"
|
style="@style/TimelineContentStubBaseParams"
|
||||||
android:layout="@layout/item_timeline_event_status_tile_stub"
|
android:layout="@layout/item_timeline_event_status_tile_stub"
|
||||||
|
tools:layout_marginTop="180dp"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
@ -59,8 +60,8 @@
|
||||||
android:id="@+id/messageE2EDecoration"
|
android:id="@+id/messageE2EDecoration"
|
||||||
android:layout_width="16dp"
|
android:layout_width="16dp"
|
||||||
android:layout_height="16dp"
|
android:layout_height="16dp"
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:layout_alignTop="@id/viewStubContainer"
|
android:layout_alignTop="@id/viewStubContainer"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
android:layout_toStartOf="@id/viewStubContainer"
|
android:layout_toStartOf="@id/viewStubContainer"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:src="@drawable/ic_shield_warning"
|
tools:src="@drawable/ic_shield_warning"
|
||||||
|
@ -70,11 +71,11 @@
|
||||||
android:id="@+id/messageFailToSendIndicator"
|
android:id="@+id/messageFailToSendIndicator"
|
||||||
android:layout_width="14dp"
|
android:layout_width="14dp"
|
||||||
android:layout_height="14dp"
|
android:layout_height="14dp"
|
||||||
|
android:layout_alignTop="@+id/viewStubContainer"
|
||||||
android:layout_marginStart="2dp"
|
android:layout_marginStart="2dp"
|
||||||
|
android:layout_toEndOf="@+id/viewStubContainer"
|
||||||
android:src="@drawable/ic_warning_badge"
|
android:src="@drawable/ic_warning_badge"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:layout_toEndOf="@+id/viewStubContainer"
|
|
||||||
android:layout_alignTop="@+id/viewStubContainer"
|
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue