Merge branch 'develop' into feature/fix_widget

This commit is contained in:
ganfra 2020-06-22 10:21:39 +02:00
commit 8de0bdca93
32 changed files with 126 additions and 82 deletions

View File

@ -5,10 +5,11 @@ Features ✨:
- -
Improvements 🙌: Improvements 🙌:
- - "Add Matrix app" menu is now always visible (#1495)
Bugfix 🐛: Bugfix 🐛:
- - Fix dark theme issue on login screen (#1097)
- Incomplete predicate in RealmCryptoStore#getOutgoingRoomKeyRequest (#1519)
Translations 🗣: Translations 🗣:
- -
@ -18,6 +19,7 @@ SDK API changes ⚠️:
Build 🧱: Build 🧱:
- Enable code optimization (Proguard) - Enable code optimization (Proguard)
- SDK is now API level 21 minimum, and so RiotX (#405)
Other changes: Other changes:
- -

View File

@ -19,7 +19,11 @@ An Android Studio template has been added to the project to help creating all fi
To install the template (to be done only once): To install the template (to be done only once):
- Go to folder `./tools/template`. - Go to folder `./tools/template`.
- Run the script `./configure.sh`. - Mac OSX: Run the script `./configure.sh`.
Linux: Run `ANDROID_STUDIO=/path/to/android-studio ./configure`
- e.g. `ANDROID_STUDIO=/usr/local/android-studio ./configure`
- Restart Android Studio. - Restart Android Studio.
To create a new screen: To create a new screen:

View File

@ -11,8 +11,8 @@ RiotX is an Android Matrix Client currently in beta but in active development.
It is a total rewrite of [Riot-Android](https://github.com/vector-im/riot-android) with a new user experience. RiotX will become the official replacement as soon as all features are implemented. It is a total rewrite of [Riot-Android](https://github.com/vector-im/riot-android) with a new user experience. RiotX will become the official replacement as soon as all features are implemented.
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" alt="Get it on Google Play" height="60">](https://play.google.com/store/apps/details?id=im.vector.riotx) [<img src="resources/img/google-play-badge.png" alt="Get it on Google Play" height="60">](https://play.google.com/store/apps/details?id=im.vector.riotx)
[<img src="https://f-droid.org/badge/get-it-on.png" alt="Get it on F-Droid" height="60">](https://f-droid.org/app/im.vector.riotx) [<img src="resources/img/f-droid-badge.png" alt="Get it on F-Droid" height="60">](https://f-droid.org/app/im.vector.riotx)
Nightly build: [![Buildkite](https://badge.buildkite.com/657d3db27364448d69d54f66c690f7788bc6aa80a7628e37f3.svg?branch=develop)](https://buildkite.com/matrix-dot-org/riotx-android/builds?branch=develop) Nightly build: [![Buildkite](https://badge.buildkite.com/657d3db27364448d69d54f66c690f7788bc6aa80a7628e37f3.svg?branch=develop)](https://buildkite.com/matrix-dot-org/riotx-android/builds?branch=develop)

View File

@ -6,7 +6,7 @@ android {
compileSdkVersion 29 compileSdkVersion 29
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 21
targetSdkVersion 29 targetSdkVersion 29
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"

View File

@ -23,7 +23,7 @@ android {
testOptions.unitTests.includeAndroidResources = true testOptions.unitTests.includeAndroidResources = true
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 21
targetSdkVersion 29 targetSdkVersion 29
versionCode 1 versionCode 1
versionName "0.0.1" versionName "0.0.1"

View File

@ -90,7 +90,7 @@ class KeyShareTests : InstrumentedTest {
} catch (failure: Throwable) { } catch (failure: Throwable) {
} }
val outgoingRequestBefore = aliceSession2.cryptoService().getOutgoingRoomKeyRequest() val outgoingRequestsBefore = aliceSession2.cryptoService().getOutgoingRoomKeyRequests()
// Try to request // Try to request
aliceSession2.cryptoService().requestRoomKeyForEvent(receivedEvent.root) aliceSession2.cryptoService().requestRoomKeyForEvent(receivedEvent.root)
@ -100,10 +100,10 @@ class KeyShareTests : InstrumentedTest {
var outGoingRequestId: String? = null var outGoingRequestId: String? = null
mTestHelper.retryPeriodicallyWithLatch(waitLatch) { mTestHelper.retryPeriodicallyWithLatch(waitLatch) {
aliceSession2.cryptoService().getOutgoingRoomKeyRequest() aliceSession2.cryptoService().getOutgoingRoomKeyRequests()
.filter { req -> .filter { req ->
// filter out request that was known before // filter out request that was known before
!outgoingRequestBefore.any { req.requestId == it.requestId } !outgoingRequestsBefore.any { req.requestId == it.requestId }
} }
.let { .let {
val outgoing = it.firstOrNull { it.sessionId == eventMegolmSessionId } val outgoing = it.firstOrNull { it.sessionId == eventMegolmSessionId }
@ -115,10 +115,10 @@ class KeyShareTests : InstrumentedTest {
Log.v("TEST", "=======> Outgoing requet Id is $outGoingRequestId") Log.v("TEST", "=======> Outgoing requet Id is $outGoingRequestId")
val outgoingRequestAfter = aliceSession2.cryptoService().getOutgoingRoomKeyRequest() val outgoingRequestAfter = aliceSession2.cryptoService().getOutgoingRoomKeyRequests()
// We should have a new request // We should have a new request
Assert.assertTrue(outgoingRequestAfter.size > outgoingRequestBefore.size) Assert.assertTrue(outgoingRequestAfter.size > outgoingRequestsBefore.size)
Assert.assertNotNull(outgoingRequestAfter.first { it.sessionId == eventMegolmSessionId }) Assert.assertNotNull(outgoingRequestAfter.first { it.sessionId == eventMegolmSessionId })
// The first session should see an incoming request // The first session should see an incoming request
@ -126,7 +126,7 @@ class KeyShareTests : InstrumentedTest {
mTestHelper.waitWithLatch { latch -> mTestHelper.waitWithLatch { latch ->
mTestHelper.retryPeriodicallyWithLatch(latch) { mTestHelper.retryPeriodicallyWithLatch(latch) {
// DEBUG LOGS // DEBUG LOGS
aliceSession.cryptoService().getIncomingRoomKeyRequest().let { aliceSession.cryptoService().getIncomingRoomKeyRequests().let {
Log.v("TEST", "Incoming request Session 1 (looking for $outGoingRequestId)") Log.v("TEST", "Incoming request Session 1 (looking for $outGoingRequestId)")
Log.v("TEST", "=========================") Log.v("TEST", "=========================")
it.forEach { keyRequest -> it.forEach { keyRequest ->
@ -135,7 +135,7 @@ class KeyShareTests : InstrumentedTest {
Log.v("TEST", "=========================") Log.v("TEST", "=========================")
} }
val incoming = aliceSession.cryptoService().getIncomingRoomKeyRequest().firstOrNull { it.requestId == outGoingRequestId } val incoming = aliceSession.cryptoService().getIncomingRoomKeyRequests().firstOrNull { it.requestId == outGoingRequestId }
incoming?.state == GossipingRequestState.REJECTED incoming?.state == GossipingRequestState.REJECTED
} }
} }
@ -155,7 +155,7 @@ class KeyShareTests : InstrumentedTest {
mTestHelper.waitWithLatch { latch -> mTestHelper.waitWithLatch { latch ->
mTestHelper.retryPeriodicallyWithLatch(latch) { mTestHelper.retryPeriodicallyWithLatch(latch) {
aliceSession.cryptoService().getIncomingRoomKeyRequest().let { aliceSession.cryptoService().getIncomingRoomKeyRequests().let {
Log.v("TEST", "Incoming request Session 1") Log.v("TEST", "Incoming request Session 1")
Log.v("TEST", "=========================") Log.v("TEST", "=========================")
it.forEach { it.forEach {
@ -171,7 +171,7 @@ class KeyShareTests : InstrumentedTest {
Thread.sleep(6_000) Thread.sleep(6_000)
mTestHelper.waitWithLatch { latch -> mTestHelper.waitWithLatch { latch ->
mTestHelper.retryPeriodicallyWithLatch(latch) { mTestHelper.retryPeriodicallyWithLatch(latch) {
aliceSession2.cryptoService().getOutgoingRoomKeyRequest().let { aliceSession2.cryptoService().getOutgoingRoomKeyRequests().let {
it.any { it.requestBody?.sessionId == eventMegolmSessionId && it.state == OutgoingGossipingRequestState.CANCELLED } it.any { it.requestBody?.sessionId == eventMegolmSessionId && it.state == OutgoingGossipingRequestState.CANCELLED }
} }
} }

View File

@ -138,7 +138,9 @@ interface CryptoService {
fun removeSessionListener(listener: NewSessionListener) fun removeSessionListener(listener: NewSessionListener)
fun getOutgoingRoomKeyRequest(): List<OutgoingRoomKeyRequest> fun getOutgoingRoomKeyRequests(): List<OutgoingRoomKeyRequest>
fun getIncomingRoomKeyRequest(): List<IncomingRoomKeyRequest>
fun getIncomingRoomKeyRequests(): List<IncomingRoomKeyRequest>
fun getGossipingEventsTrail(): List<Event> fun getGossipingEventsTrail(): List<Event>
} }

View File

@ -21,6 +21,9 @@ import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass import com.squareup.moshi.JsonClass
import im.vector.matrix.android.api.util.JsonDict import im.vector.matrix.android.api.util.JsonDict
/**
* Ref: https://github.com/matrix-org/matrix-doc/issues/1236
*/
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class WidgetContent( data class WidgetContent(
@Json(name = "creatorUserId") val creatorUserId: String? = null, @Json(name = "creatorUserId") val creatorUserId: String? = null,

View File

@ -32,6 +32,9 @@ private val DEFINED_TYPES by lazy {
) )
} }
/**
* Ref: https://github.com/matrix-org/matrix-doc/issues/1236
*/
sealed class WidgetType(open val preferred: String, open val legacy: String = preferred) { sealed class WidgetType(open val preferred: String, open val legacy: String = preferred) {
object Jitsi : WidgetType("m.jitsi", "jitsi") object Jitsi : WidgetType("m.jitsi", "jitsi")
object TradingView : WidgetType("m.tradingview") object TradingView : WidgetType("m.tradingview")

View File

@ -1262,11 +1262,11 @@ internal class DefaultCryptoService @Inject constructor(
return "DefaultCryptoService of $userId ($deviceId)" return "DefaultCryptoService of $userId ($deviceId)"
} }
override fun getOutgoingRoomKeyRequest(): List<OutgoingRoomKeyRequest> { override fun getOutgoingRoomKeyRequests(): List<OutgoingRoomKeyRequest> {
return cryptoStore.getOutgoingRoomKeyRequests() return cryptoStore.getOutgoingRoomKeyRequests()
} }
override fun getIncomingRoomKeyRequest(): List<IncomingRoomKeyRequest> { override fun getIncomingRoomKeyRequests(): List<IncomingRoomKeyRequest> {
return cryptoStore.getIncomingRoomKeyRequests() return cryptoStore.getIncomingRoomKeyRequests()
} }

View File

@ -897,9 +897,9 @@ internal class RealmCryptoStore @Inject constructor(
it.toOutgoingGossipingRequest() as? OutgoingRoomKeyRequest it.toOutgoingGossipingRequest() as? OutgoingRoomKeyRequest
}.firstOrNull { }.firstOrNull {
it.requestBody?.algorithm == requestBody.algorithm it.requestBody?.algorithm == requestBody.algorithm
it.requestBody?.roomId == requestBody.roomId && it.requestBody?.roomId == requestBody.roomId
it.requestBody?.senderKey == requestBody.senderKey && it.requestBody?.senderKey == requestBody.senderKey
it.requestBody?.sessionId == requestBody.sessionId && it.requestBody?.sessionId == requestBody.sessionId
} }
} }
@ -1266,7 +1266,7 @@ internal class RealmCryptoStore @Inject constructor(
deviceInfoEntity.trustLevelEntity = it deviceInfoEntity.trustLevelEntity = it
} }
} else { } else {
locallyVerified?.let { trustEntity.locallyVerified = it } locallyVerified?.let { trustEntity.locallyVerified = it }
trustEntity.crossSignedVerified = crossSignedVerified trustEntity.crossSignedVerified = crossSignedVerified
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -17,8 +17,9 @@
# #
echo "Configure RiotX Template..." echo "Configure RiotX Template..."
if [ -z ${ANDROID_STUDIO+x} ]; then ANDROID_STUDIO="/Applications/Android Studio.app/Contents"; fi
{ {
ln -s $(pwd)/RiotXFeature /Applications/Android\ Studio.app/Contents/plugins/android/lib/templates/other ln -s $(pwd)/RiotXFeature "${ANDROID_STUDIO%/}/plugins/android/lib/templates/other"
} && { } && {
echo "Please restart Android Studio." echo "Please restart Android Studio."
} }

View File

@ -107,9 +107,8 @@ android {
compileSdkVersion 29 compileSdkVersion 29
defaultConfig { defaultConfig {
applicationId "im.vector.riotx" applicationId "im.vector.riotx"
// Set to API 19 because motionLayout is min API 18. // Set to API 21: see #405
// In the future we may consider using an alternative of MotionLayout to support API 16. But for security reason, maybe not. minSdkVersion 21
minSdkVersion 19
targetSdkVersion 29 targetSdkVersion 29
multiDexEnabled true multiDexEnabled true

View File

@ -315,7 +315,7 @@ class RoomDetailFragment @Inject constructor(
is RoomDetailViewEvents.SendMessageResult -> renderSendMessageResult(it) is RoomDetailViewEvents.SendMessageResult -> renderSendMessageResult(it)
RoomDetailViewEvents.DisplayPromptForIntegrationManager -> displayPromptForIntegrationManager() RoomDetailViewEvents.DisplayPromptForIntegrationManager -> displayPromptForIntegrationManager()
is RoomDetailViewEvents.OpenStickerPicker -> openStickerPicker(it) is RoomDetailViewEvents.OpenStickerPicker -> openStickerPicker(it)
is RoomDetailViewEvents.DisplayEnableIntegrationsWarning -> displayEnableIntegrationsWarning() is RoomDetailViewEvents.DisplayEnableIntegrationsWarning -> displayDisabledIntegrationDialog()
is RoomDetailViewEvents.OpenIntegrationManager -> openIntegrationManager() is RoomDetailViewEvents.OpenIntegrationManager -> openIntegrationManager()
}.exhaustive }.exhaustive
} }
@ -354,17 +354,6 @@ class RoomDetailFragment @Inject constructor(
.show() .show()
} }
private fun displayEnableIntegrationsWarning() {
AlertDialog.Builder(requireContext())
.setTitle(R.string.integration_manager_not_enabled_title)
.setMessage(R.string.integration_manager_not_enabled_msg)
.setPositiveButton(R.string.open_settings) { _, _ ->
navigator.openSettings(requireContext(), VectorSettingsActivity.EXTRA_DIRECT_ACCESS_GENERAL)
}
.setNegativeButton(R.string.cancel, null)
.show()
}
private fun handleJoinedToAnotherRoom(action: RoomDetailViewEvents.JoinRoomCommandSuccess) { private fun handleJoinedToAnotherRoom(action: RoomDetailViewEvents.JoinRoomCommandSuccess) {
updateComposerText("") updateComposerText("")
lockSendButton = false lockSendButton = false
@ -496,6 +485,17 @@ class RoomDetailFragment @Inject constructor(
} }
} }
private fun displayDisabledIntegrationDialog() {
AlertDialog.Builder(requireActivity())
.setTitle(R.string.disabled_integration_dialog_title)
.setMessage(R.string.disabled_integration_dialog_content)
.setPositiveButton(R.string.settings) { _, _ ->
navigator.openSettings(requireActivity(), VectorSettingsActivity.EXTRA_DIRECT_ACCESS_GENERAL)
}
.setNegativeButton(R.string.cancel, null)
.show()
}
private fun renderRegularMode(text: String) { private fun renderRegularMode(text: String) {
autoCompleter.exitSpecialMode() autoCompleter.exitSpecialMode()
composerLayout.collapse() composerLayout.collapse()

View File

@ -21,17 +21,17 @@ import android.os.Parcelable
import android.view.View import android.view.View
import butterknife.OnClick import butterknife.OnClick
import com.airbnb.mvrx.args import com.airbnb.mvrx.args
import im.vector.matrix.android.internal.auth.registration.LocalizedFlowDataLoginTerms
import im.vector.riotx.R import im.vector.riotx.R
import im.vector.riotx.core.extensions.cleanup import im.vector.riotx.core.extensions.cleanup
import im.vector.riotx.core.extensions.configureWith import im.vector.riotx.core.extensions.configureWith
import im.vector.riotx.core.extensions.toReducedUrl import im.vector.riotx.core.extensions.toReducedUrl
import im.vector.riotx.core.utils.openUrlInExternalBrowser import im.vector.riotx.core.utils.openUrlInChromeCustomTab
import im.vector.riotx.features.login.AbstractLoginFragment import im.vector.riotx.features.login.AbstractLoginFragment
import im.vector.riotx.features.login.LoginAction import im.vector.riotx.features.login.LoginAction
import im.vector.riotx.features.login.LoginViewState import im.vector.riotx.features.login.LoginViewState
import kotlinx.android.parcel.Parcelize import kotlinx.android.parcel.Parcelize
import kotlinx.android.synthetic.main.fragment_login_terms.* import kotlinx.android.synthetic.main.fragment_login_terms.*
import im.vector.matrix.android.internal.auth.registration.LocalizedFlowDataLoginTerms
import javax.inject.Inject import javax.inject.Inject
@Parcelize @Parcelize
@ -95,7 +95,7 @@ class LoginTermsFragment @Inject constructor(
localizedFlowDataLoginTerms.localizedUrl localizedFlowDataLoginTerms.localizedUrl
?.takeIf { it.isNotBlank() } ?.takeIf { it.isNotBlank() }
?.let { ?.let {
openUrlInExternalBrowser(requireContext(), it) openUrlInChromeCustomTab(requireContext(), null, it)
} }
} }

View File

@ -59,7 +59,7 @@ class VectorSettingsActivity : VectorBaseActivity(),
if (isFirstCreation()) { if (isFirstCreation()) {
// display the fragment // display the fragment
when (intent.getIntExtra(EXTRA_DIRECT_ACCESS, EXTRA_DIRECT_ACCESS_ROOT)) { when (intent.getIntExtra(EXTRA_DIRECT_ACCESS, EXTRA_DIRECT_ACCESS_ROOT)) {
EXTRA_DIRECT_ACCESS_GENERAL -> EXTRA_DIRECT_ACCESS_GENERAL ->
replaceFragment(R.id.vector_settings_page, VectorSettingsGeneralFragment::class.java, null, FRAGMENT_TAG) replaceFragment(R.id.vector_settings_page, VectorSettingsGeneralFragment::class.java, null, FRAGMENT_TAG)
EXTRA_DIRECT_ACCESS_ADVANCED_SETTINGS -> EXTRA_DIRECT_ACCESS_ADVANCED_SETTINGS ->
replaceFragment(R.id.vector_settings_page, VectorSettingsAdvancedSettingsFragment::class.java, null, FRAGMENT_TAG) replaceFragment(R.id.vector_settings_page, VectorSettingsAdvancedSettingsFragment::class.java, null, FRAGMENT_TAG)

View File

@ -179,7 +179,7 @@ class GossipingEventsEpoxyController @Inject constructor(
} }
private fun buildOutgoing(data: KeyRequestListViewState?) { private fun buildOutgoing(data: KeyRequestListViewState?) {
data?.outgoingRoomKeyRequest?.let { async -> data?.outgoingRoomKeyRequests?.let { async ->
when (async) { when (async) {
is Uninitialized, is Uninitialized,
is Loading -> { is Loading -> {

View File

@ -107,7 +107,7 @@ class KeyRequestEpoxyController @Inject constructor(
} }
private fun buildOutgoing(data: KeyRequestListViewState?) { private fun buildOutgoing(data: KeyRequestListViewState?) {
data?.outgoingRoomKeyRequest?.let { async -> data?.outgoingRoomKeyRequests?.let { async ->
when (async) { when (async) {
is Uninitialized, is Uninitialized,
is Loading -> { is Loading -> {

View File

@ -36,7 +36,7 @@ import kotlinx.coroutines.launch
data class KeyRequestListViewState( data class KeyRequestListViewState(
val incomingRequests: Async<List<IncomingRoomKeyRequest>> = Uninitialized, val incomingRequests: Async<List<IncomingRoomKeyRequest>> = Uninitialized,
val outgoingRoomKeyRequest: Async<List<OutgoingRoomKeyRequest>> = Uninitialized val outgoingRoomKeyRequests: Async<List<OutgoingRoomKeyRequest>> = Uninitialized
) : MvRxState ) : MvRxState
class KeyRequestListViewModel @AssistedInject constructor(@Assisted initialState: KeyRequestListViewState, class KeyRequestListViewModel @AssistedInject constructor(@Assisted initialState: KeyRequestListViewState,
@ -49,14 +49,14 @@ class KeyRequestListViewModel @AssistedInject constructor(@Assisted initialState
fun refresh() { fun refresh() {
viewModelScope.launch { viewModelScope.launch {
session.cryptoService().getOutgoingRoomKeyRequest().let { session.cryptoService().getOutgoingRoomKeyRequests().let {
setState { setState {
copy( copy(
outgoingRoomKeyRequest = Success(it) outgoingRoomKeyRequests = Success(it)
) )
} }
} }
session.cryptoService().getIncomingRoomKeyRequest().let { session.cryptoService().getIncomingRoomKeyRequests().let {
setState { setState {
copy( copy(
incomingRequests = Success(it) incomingRequests = Success(it)

View File

@ -30,7 +30,7 @@ import im.vector.riotx.core.extensions.configureWith
import im.vector.riotx.core.extensions.exhaustive import im.vector.riotx.core.extensions.exhaustive
import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.core.platform.VectorBaseActivity
import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.platform.VectorBaseFragment
import im.vector.riotx.core.utils.openUrlInExternalBrowser import im.vector.riotx.core.utils.openUrlInChromeCustomTab
import kotlinx.android.synthetic.main.fragment_review_terms.* import kotlinx.android.synthetic.main.fragment_review_terms.*
import javax.inject.Inject import javax.inject.Inject
@ -106,6 +106,6 @@ class ReviewTermsFragment @Inject constructor(
} }
override fun review(term: Term) { override fun review(term: Term) {
openUrlInExternalBrowser(requireContext(), term.url) openUrlInChromeCustomTab(requireContext(), null, term.url)
} }
} }

View File

@ -7,6 +7,6 @@
android:width="1.2dp" android:width="1.2dp"
android:color="#E7E7E7" /> android:color="#E7E7E7" />
<solid android:color="@color/white" /> <solid android:color="?riotx_background" />
</shape> </shape>

View File

@ -7,6 +7,6 @@
android:width="1.2dp" android:width="1.2dp"
android:color="@color/riotx_accent" /> android:color="@color/riotx_accent" />
<solid android:color="@color/white" /> <solid android:color="?riotx_background" />
</shape> </shape>

View File

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="16dp"
android:viewportWidth="14"
android:viewportHeight="16">
<path
android:strokeWidth="1"
android:pathData="M13,11.1915V9.9086L8,5.6517C8,3.2856 8,1.8893 8,1.7728C8,1.2731 7.5522,0.6667 7,0.6667C6.4478,0.6667 6,1.2731 6,1.7728C6,1.9784 6,3.3376 6,5.6517L1,9.9086V11.1915L6,8.8416C6,10.3353 6,12.3168 6,13.0103L3.963,14.7439V15.3334L7,14.7508L10.037,15.3334V14.7439L8,13.0103C8,12.3168 8,10.3353 8,8.8416L13,11.1915Z"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="#2E2F32"
android:strokeLineCap="round"/>
</vector>

View File

@ -25,6 +25,7 @@
android:id="@+id/loginServerIcon" android:id="@+id/loginServerIcon"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:tint="?riotx_text_primary"
tools:src="@drawable/ic_logo_matrix_org" /> tools:src="@drawable/ic_logo_matrix_org" />
<TextView <TextView

View File

@ -63,6 +63,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:importantForAccessibility="no" android:importantForAccessibility="no"
android:src="@drawable/ic_logo_matrix_org" android:src="@drawable/ic_logo_matrix_org"
android:tint="?riotx_text_primary"
app:layout_constraintBottom_toTopOf="@+id/loginServerChoiceMatrixOrgText" app:layout_constraintBottom_toTopOf="@+id/loginServerChoiceMatrixOrgText"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
@ -103,6 +104,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:importantForAccessibility="no" android:importantForAccessibility="no"
android:src="@drawable/ic_logo_modular" android:src="@drawable/ic_logo_modular"
android:tint="?riotx_text_primary"
app:layout_constraintBottom_toTopOf="@+id/loginServerChoiceModularText" app:layout_constraintBottom_toTopOf="@+id/loginServerChoiceModularText"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"

View File

@ -26,7 +26,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:importantForAccessibility="no" android:importantForAccessibility="no"
android:src="@drawable/ic_logo_modular" /> android:src="@drawable/ic_logo_modular"
android:tint="?riotx_text_primary" />
<TextView <TextView
android:id="@+id/loginServerUrlFormTitle" android:id="@+id/loginServerUrlFormTitle"

View File

@ -23,6 +23,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:importantForAccessibility="no" android:importantForAccessibility="no"
android:tint="?riotx_text_primary"
android:visibility="gone" android:visibility="gone"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" <merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -36,16 +37,26 @@
tools:layout_marginTop="10dp" tools:layout_marginTop="10dp"
tools:visibility="visible" /> tools:visibility="visible" />
<TextView <FrameLayout
android:id="@+id/syncStateNoNetworkAirplane" android:id="@+id/syncStateNoNetworkAirplane"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/notification_accent_color" android:background="@color/notification_accent_color"
android:gravity="center"
android:text="@string/no_connectivity_to_the_server_indicator_airplane"
android:textColor="@color/white"
android:visibility="gone" android:visibility="gone"
tools:layout_marginTop="10dp" tools:layout_marginTop="10dp"
tools:visibility="visible" /> tools:visibility="visible">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawablePadding="4dp"
android:gravity="center"
android:text="@string/no_connectivity_to_the_server_indicator_airplane"
android:textColor="@color/white"
app:drawableStartCompat="@drawable/ic_airplane_16dp"
app:drawableTint="@color/white" />
</FrameLayout>
</merge> </merge>

View File

@ -862,6 +862,9 @@
<string name="settings_integration_allow">Allow integrations</string> <string name="settings_integration_allow">Allow integrations</string>
<string name="settings_integration_manager">Integration Manager</string> <string name="settings_integration_manager">Integration Manager</string>
<string name="disabled_integration_dialog_title">Integrations are disabled</string>
<string name="disabled_integration_dialog_content">"Enable 'Allow integrations' in Settings to do this."</string>
<string name="settings_user_interface">User interface</string> <string name="settings_user_interface">User interface</string>
<string name="settings_interface_language">Language</string> <string name="settings_interface_language">Language</string>
<string name="settings_select_language">Choose language</string> <string name="settings_select_language">Choose language</string>
@ -1162,8 +1165,6 @@
<string name="room_widget_webview_read_protected_media">Read DRM protected Media</string> <string name="room_widget_webview_read_protected_media">Read DRM protected Media</string>
<!-- Widget Integration Manager --> <!-- Widget Integration Manager -->
<string name="integration_manager_not_enabled_title">Integrations are disabled</string>
<string name="integration_manager_not_enabled_msg">Enable integrations in settings to allow this action.</string>
<string name="widget_integration_unable_to_create">Unable to create widget.</string> <string name="widget_integration_unable_to_create">Unable to create widget.</string>
<string name="widget_integration_failed_to_send_request">Failed to send request.</string> <string name="widget_integration_failed_to_send_request">Failed to send request.</string>

View File

@ -68,6 +68,26 @@
</im.vector.riotx.core.preference.VectorPreferenceCategory> </im.vector.riotx.core.preference.VectorPreferenceCategory>
<im.vector.riotx.core.preference.VectorPreferenceCategory android:title="@string/settings_integrations">
<im.vector.riotx.core.preference.VectorPreference
android:focusable="false"
android:persistent="false"
android:summary="@string/settings_integrations_summary" />
<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
android:dependency="SETTINGS_ALLOW_INTEGRATIONS_KEY"
android:key="SETTINGS_INTEGRATION_MANAGER_UI_URL_KEY"
android:persistent="false"
android:title="@string/settings_integration_manager" />
</im.vector.riotx.core.preference.VectorPreferenceCategory>
<im.vector.riotx.core.preference.VectorPreferenceCategory android:title="@string/settings_advanced"> <im.vector.riotx.core.preference.VectorPreferenceCategory android:title="@string/settings_advanced">
<im.vector.riotx.core.preference.VectorPreference <im.vector.riotx.core.preference.VectorPreference
@ -96,26 +116,6 @@
</im.vector.riotx.core.preference.VectorPreferenceCategory> </im.vector.riotx.core.preference.VectorPreferenceCategory>
<im.vector.riotx.core.preference.VectorPreferenceCategory android:title="@string/settings_integrations">
<im.vector.riotx.core.preference.VectorPreference
android:focusable="false"
android:persistent="false"
android:summary="@string/settings_integrations_summary" />
<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
android:dependency="SETTINGS_ALLOW_INTEGRATIONS_KEY"
android:key="SETTINGS_INTEGRATION_MANAGER_UI_URL_KEY"
android:persistent="false"
android:title="@string/settings_integration_manager" />
</im.vector.riotx.core.preference.VectorPreferenceCategory>
<im.vector.riotx.core.preference.VectorPreferenceCategory android:title="@string/action_sign_out"> <im.vector.riotx.core.preference.VectorPreferenceCategory android:title="@string/action_sign_out">
<im.vector.riotx.core.preference.VectorPreference <im.vector.riotx.core.preference.VectorPreference