Merge branch 'develop' into feature/space_in_passwords

This commit is contained in:
Benoit Marty 2020-03-04 14:12:12 +01:00 committed by GitHub
commit 277ad9e042
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
68 changed files with 254 additions and 199 deletions

View File

@ -81,7 +81,7 @@ steps:
- label: "ktlint"
command:
- "curl -sSLO https://github.com/pinterest/ktlint/releases/download/0.34.2/ktlint && chmod a+x ktlint"
- "curl -sSLO https://github.com/pinterest/ktlint/releases/download/0.36.0/ktlint && chmod a+x ktlint"
- "./ktlint --android --experimental -v"
plugins:
- docker#v3.1.0:

View File

@ -1,9 +1,6 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="RIGHT_MARGIN" value="160" />
<AndroidXmlCodeStyleSettings>
<option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
</AndroidXmlCodeStyleSettings>
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>

View File

@ -7,6 +7,7 @@ Features ✨:
Improvements 🙌:
- Add support for `/plain` command (#12)
- Detect spaces in password if user fail to login (#1038)
- FTUE: do not display a different color when encrypting message when not in developer mode.
Bugfix 🐛:
- Fix crash on attachment preview screen (#1088)
@ -18,9 +19,10 @@ SDK API changes ⚠️:
-
Build 🧱:
-
- Upgrade ktlint to version 0.36.0
Other changes:
- Restore availability to Chromebooks (#932)
- Add a [documentation](./docs/integration_tests.md) to run integration tests
Changes in RiotX 0.17.0 (2020-02-27)

View File

@ -6,6 +6,11 @@
<issue id="MissingTranslation" severity="warning" />
<issue id="TypographyEllipsis" severity="error" />
<issue id="ImpliedQuantity" severity="warning" />
<issue id="IconXmlAndPng" severity="error" />
<issue id="IconDipSize" severity="error" />
<issue id="IconDuplicatesConfig" severity="error" />
<issue id="IconDuplicates" severity="error" />
<issue id="IconExpectedSize" severity="error" />
<!-- UX -->
<issue id="ButtonOrder" severity="error" />
@ -19,6 +24,7 @@
<issue id="InefficientWeight" severity="error" />
<issue id="DisableBaselineAlignment" severity="error" />
<issue id="ScrollViewSize" severity="error" />
<issue id="NegativeMargin" severity="error" />
<!-- RTL -->
<issue id="RtlEnabled" severity="error" />
@ -30,9 +36,14 @@
<issue id="SetTextI18n" severity="error" />
<issue id="ViewConstructor" severity="error" />
<issue id="UseValueOf" severity="error" />
<issue id="Recycle" severity="error" />
<issue id="KotlinPropertyAccess" severity="error" />
<!-- Ignore error from HtmlCompressor lib -->
<issue id="InvalidPackage">
<ignore path="**/htmlcompressor-1.4.jar" />
</issue>
<!-- Manifest -->
<issue id="PermissionImpliesUnsupportedChromeOsHardware" severity="error" />
</lint>

View File

@ -9,6 +9,15 @@
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CAMERA" />
<!-- Adding CAMERA permission prevents Chromebooks to see the application on the PlayStore -->
<!-- Tell that the Camera is not mandatory to install the application -->
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<application
android:name=".VectorApplication"
android:allowBackup="false"

View File

@ -0,0 +1,46 @@
/*
* 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.
*/
@file:Suppress("DEPRECATION")
package im.vector.riotx.core.hardware
import android.content.Context
import android.hardware.Camera
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager
import android.os.Build
import javax.inject.Inject
class HardwareInfo @Inject constructor(
private val context: Context
) {
/**
* Tell if the device has a back (or external) camera
*/
fun hasBackCamera(): Boolean {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return Camera.getNumberOfCameras() > 0
}
val manager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager? ?: return Camera.getNumberOfCameras() > 0
return manager.cameraIdList.any {
val lensFacing = manager.getCameraCharacteristics(it).get(CameraCharacteristics.LENS_FACING)
lensFacing == CameraCharacteristics.LENS_FACING_BACK || lensFacing == CameraCharacteristics.LENS_FACING_EXTERNAL
}
}
}

View File

@ -129,7 +129,7 @@ class BadgeFloatingActionButton @JvmOverloads constructor(
attrs?.let { initAttrs(attrs) }
}
@SuppressWarnings("ResourceType", "Recycle")
@SuppressWarnings("Recycle")
private fun initAttrs(attrs: AttributeSet) {
context.obtainStyledAttributes(attrs, R.styleable.BadgeFloatingActionButton).use {
counterBackgroundColor = it.getColor(R.styleable.BadgeFloatingActionButton_badgeBackgroundColor, 0)

View File

@ -1,29 +0,0 @@
/*
* Copyright 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.riotx.features.crypto.verification
import im.vector.matrix.android.api.session.crypto.verification.VerificationMethod
val supportedVerificationMethods =
listOf(
// RiotX supports SAS verification
VerificationMethod.SAS,
// RiotX is able to show QR codes
VerificationMethod.QR_CODE_SHOW,
// RiotX is able to scan QR codes
VerificationMethod.QR_CODE_SCAN
)

View File

@ -0,0 +1,47 @@
/*
* Copyright 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.riotx.features.crypto.verification
import im.vector.matrix.android.api.session.crypto.verification.VerificationMethod
import im.vector.riotx.core.hardware.HardwareInfo
import timber.log.Timber
import javax.inject.Inject
class SupportedVerificationMethodsProvider @Inject constructor(
private val hardwareInfo: HardwareInfo
) {
/**
* Provide the list of supported method by RiotX, with or without the QR_CODE_SCAN, depending if a back camera
* is available
*/
fun provide(): List<VerificationMethod> {
return mutableListOf(
// RiotX supports SAS verification
VerificationMethod.SAS,
// RiotX is able to show QR codes
VerificationMethod.QR_CODE_SHOW)
.apply {
if (hardwareInfo.hasBackCamera()) {
// RiotX is able to scan QR codes, and a Camera is available
add(VerificationMethod.QR_CODE_SCAN)
} else {
// This quite uncommon
Timber.w("No back Camera detected")
}
}
}
}

View File

@ -63,9 +63,11 @@ data class VerificationBottomSheetViewState(
val isMe: Boolean = false
) : MvRxState
class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted initialState: VerificationBottomSheetViewState,
class VerificationBottomSheetViewModel @AssistedInject constructor(
@Assisted initialState: VerificationBottomSheetViewState,
@Assisted args: VerificationBottomSheet.VerificationArgs,
private val session: Session)
private val session: Session,
private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider)
: VectorViewModel<VerificationBottomSheetViewState, VerificationAction, VerificationBottomSheetViewEvents>(initialState),
VerificationService.Listener {
@ -116,9 +118,11 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
if (autoReady) {
// TODO, can I be here in DM mode? in this case should test if roomID is null?
session.cryptoService().verificationService()
.readyPendingVerification(supportedVerificationMethods,
.readyPendingVerification(
supportedVerificationMethodsProvider.provide(),
pr!!.otherUserId,
pr.transactionId ?: "")
pr.transactionId ?: ""
)
}
}
@ -173,7 +177,12 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
session
.cryptoService()
.verificationService()
.requestKeyVerificationInDMs(supportedVerificationMethods, otherUserId, data, pendingLocalId)
.requestKeyVerificationInDMs(
supportedVerificationMethodsProvider.provide(),
otherUserId,
data,
pendingLocalId
)
)
)
}
@ -191,7 +200,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
pendingRequest = Success(session
.cryptoService()
.verificationService()
.requestKeyVerificationInDMs(supportedVerificationMethods, otherUserId, roomId)
.requestKeyVerificationInDMs(supportedVerificationMethodsProvider.provide(), otherUserId, roomId)
)
)
}
@ -294,8 +303,6 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
} catch (failure: Throwable) {
_viewEvents.post(VerificationBottomSheetViewEvents.ModalError(failure.localizedMessage))
}
Unit
}
}.exhaustive
}
@ -362,9 +369,11 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
// auto ready in this case, as we are waiting
// TODO, can I be here in DM mode? in this case should test if roomID is null?
session.cryptoService().verificationService()
.readyPendingVerification(supportedVerificationMethods,
.readyPendingVerification(
supportedVerificationMethodsProvider.provide(),
pr.otherUserId,
pr.transactionId ?: "")
pr.transactionId ?: ""
)
}
// Use this one!

View File

@ -65,7 +65,7 @@ import im.vector.riotx.core.resources.UserPreferencesProvider
import im.vector.riotx.core.utils.subscribeLogError
import im.vector.riotx.features.command.CommandParser
import im.vector.riotx.features.command.ParsedCommand
import im.vector.riotx.features.crypto.verification.supportedVerificationMethods
import im.vector.riotx.features.crypto.verification.SupportedVerificationMethodsProvider
import im.vector.riotx.features.home.room.detail.composer.rainbow.RainbowGenerator
import im.vector.riotx.features.home.room.detail.timeline.helper.TimelineDisplayableEvents
import im.vector.riotx.features.home.room.typing.TypingHelper
@ -81,13 +81,15 @@ import java.io.File
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean
class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: RoomDetailViewState,
class RoomDetailViewModel @AssistedInject constructor(
@Assisted initialState: RoomDetailViewState,
userPreferencesProvider: UserPreferencesProvider,
private val vectorPreferences: VectorPreferences,
private val stringProvider: StringProvider,
private val typingHelper: TypingHelper,
private val rainbowGenerator: RainbowGenerator,
private val session: Session
private val session: Session,
private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider
) : VectorViewModel<RoomDetailViewState, RoomDetailAction, RoomDetailViewEvents>(initialState), Timeline.Listener {
private val room = session.getRoom(initialState.roomId)!!
@ -427,7 +429,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
session
.cryptoService()
.verificationService()
.requestKeyVerificationInDMs(supportedVerificationMethods, slashCommandResult.userId, room.roomId)
.requestKeyVerificationInDMs(supportedVerificationMethodsProvider.provide(), slashCommandResult.userId, room.roomId)
_viewEvents.post(RoomDetailViewEvents.SlashCommandHandled())
popDraft()
}
@ -834,7 +836,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
private fun handleAcceptVerification(action: RoomDetailAction.AcceptVerificationRequest) {
Timber.v("## SAS handleAcceptVerification ${action.otherUserId}, roomId:${room.roomId}, txId:${action.transactionId}")
if (session.cryptoService().verificationService().readyPendingVerificationInDMs(
supportedVerificationMethods,
supportedVerificationMethodsProvider.provide(),
action.otherUserId,
room.roomId,
action.transactionId)) {

View File

@ -0,0 +1,58 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.riotx.features.home.room.detail.timeline
import androidx.annotation.ColorInt
import im.vector.matrix.android.api.session.room.send.SendState
import im.vector.riotx.R
import im.vector.riotx.core.resources.ColorProvider
import im.vector.riotx.features.settings.VectorPreferences
import javax.inject.Inject
class MessageColorProvider @Inject constructor(
private val colorProvider: ColorProvider,
private val vectorPreferences: VectorPreferences) {
@ColorInt
fun getMessageTextColor(sendState: SendState): Int {
return if (vectorPreferences.developerMode()) {
when (sendState) {
// SendStates, in the classical order they will occur
SendState.UNKNOWN,
SendState.UNSENT -> colorProvider.getColorFromAttribute(R.attr.vctr_sending_message_text_color)
SendState.ENCRYPTING -> colorProvider.getColorFromAttribute(R.attr.vctr_encrypting_message_text_color)
SendState.SENDING -> colorProvider.getColorFromAttribute(R.attr.vctr_sending_message_text_color)
SendState.SENT,
SendState.SYNCED -> colorProvider.getColorFromAttribute(R.attr.vctr_message_text_color)
SendState.UNDELIVERED,
SendState.FAILED_UNKNOWN_DEVICES -> colorProvider.getColorFromAttribute(R.attr.vctr_unsent_message_text_color)
}
} else {
// When not in developer mode, we do not use special color for the encrypting state
when (sendState) {
SendState.UNKNOWN,
SendState.UNSENT,
SendState.ENCRYPTING,
SendState.SENDING -> colorProvider.getColorFromAttribute(R.attr.vctr_sending_message_text_color)
SendState.SENT,
SendState.SYNCED -> colorProvider.getColorFromAttribute(R.attr.vctr_message_text_color)
SendState.UNDELIVERED,
SendState.FAILED_UNKNOWN_DEVICES -> colorProvider.getColorFromAttribute(R.attr.vctr_unsent_message_text_color)
}
}
}
}

View File

@ -222,7 +222,7 @@ class MessageItemFactory @Inject constructor(
referenceId = informationData.eventId,
informationData = informationData,
avatarRenderer = attributes.avatarRenderer,
colorProvider = attributes.colorProvider,
messageColorProvider = attributes.messageColorProvider,
itemLongClickListener = attributes.itemLongClickListener,
itemClickListener = attributes.itemClickListener,
reactionPillCallback = attributes.reactionPillCallback,

View File

@ -27,8 +27,8 @@ import im.vector.matrix.android.api.session.room.model.message.MessageVerificati
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.internal.session.room.VerificationState
import im.vector.riotx.core.epoxy.VectorEpoxyModel
import im.vector.riotx.core.resources.ColorProvider
import im.vector.riotx.core.resources.UserPreferencesProvider
import im.vector.riotx.features.home.room.detail.timeline.MessageColorProvider
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
import im.vector.riotx.features.home.room.detail.timeline.helper.AvatarSizeProvider
import im.vector.riotx.features.home.room.detail.timeline.helper.MessageInformationDataFactory
@ -43,7 +43,7 @@ import javax.inject.Inject
* several checks are made to see if this conclusion is attached to a known request
*/
class VerificationItemFactory @Inject constructor(
private val colorProvider: ColorProvider,
private val messageColorProvider: MessageColorProvider,
private val messageInformationDataFactory: MessageInformationDataFactory,
private val messageItemAttributesFactory: MessageItemAttributesFactory,
private val avatarSizeProvider: AvatarSizeProvider,
@ -97,7 +97,7 @@ class VerificationItemFactory @Inject constructor(
isPositive = false,
informationData = informationData,
avatarRenderer = attributes.avatarRenderer,
colorProvider = colorProvider,
messageColorProvider = messageColorProvider,
emojiTypeFace = attributes.emojiTypeFace,
itemClickListener = attributes.itemClickListener,
itemLongClickListener = attributes.itemLongClickListener,
@ -130,7 +130,7 @@ class VerificationItemFactory @Inject constructor(
isPositive = true,
informationData = informationData,
avatarRenderer = attributes.avatarRenderer,
colorProvider = colorProvider,
messageColorProvider = messageColorProvider,
emojiTypeFace = attributes.emojiTypeFace,
itemClickListener = attributes.itemClickListener,
itemLongClickListener = attributes.itemLongClickListener,

View File

@ -27,14 +27,13 @@ import im.vector.riotx.R
import im.vector.riotx.core.di.ActiveSessionHolder
import im.vector.riotx.core.di.ScreenScope
import im.vector.riotx.core.error.ErrorFormatter
import im.vector.riotx.core.resources.ColorProvider
import im.vector.riotx.core.utils.TextUtils
import im.vector.riotx.features.ui.getMessageTextColor
import im.vector.riotx.features.home.room.detail.timeline.MessageColorProvider
import javax.inject.Inject
@ScreenScope
class ContentUploadStateTrackerBinder @Inject constructor(private val activeSessionHolder: ActiveSessionHolder,
private val colorProvider: ColorProvider,
private val messageColorProvider: MessageColorProvider,
private val errorFormatter: ErrorFormatter) {
private val updateListeners = mutableMapOf<String, ContentUploadStateTracker.UpdateListener>()
@ -44,7 +43,7 @@ class ContentUploadStateTrackerBinder @Inject constructor(private val activeSess
progressLayout: ViewGroup) {
activeSessionHolder.getSafeActiveSession()?.also { session ->
val uploadStateTracker = session.contentUploadProgressTracker()
val updateListener = ContentMediaProgressUpdater(progressLayout, isLocalFile, colorProvider, errorFormatter)
val updateListener = ContentMediaProgressUpdater(progressLayout, isLocalFile, messageColorProvider, errorFormatter)
updateListeners[eventId] = updateListener
uploadStateTracker.track(eventId, updateListener)
}
@ -68,7 +67,7 @@ class ContentUploadStateTrackerBinder @Inject constructor(private val activeSess
private class ContentMediaProgressUpdater(private val progressLayout: ViewGroup,
private val isLocalFile: Boolean,
private val colorProvider: ColorProvider,
private val messageColorProvider: MessageColorProvider,
private val errorFormatter: ErrorFormatter) : ContentUploadStateTracker.UpdateListener {
override fun onUpdate(state: ContentUploadStateTracker.State) {
@ -92,7 +91,7 @@ private class ContentMediaProgressUpdater(private val progressLayout: ViewGroup,
progressBar?.isIndeterminate = true
progressBar?.progress = 0
progressTextView?.text = progressLayout.context.getString(R.string.send_file_step_idle)
progressTextView?.setTextColor(colorProvider.getMessageTextColor(SendState.UNSENT))
progressTextView?.setTextColor(messageColorProvider.getMessageTextColor(SendState.UNSENT))
} else {
progressLayout.isVisible = false
}
@ -120,7 +119,7 @@ private class ContentMediaProgressUpdater(private val progressLayout: ViewGroup,
val progressTextView = progressLayout.findViewById<TextView>(R.id.mediaProgressTextView)
progressBar?.isIndeterminate = true
progressTextView?.text = progressLayout.context.getString(resId)
progressTextView?.setTextColor(colorProvider.getMessageTextColor(SendState.ENCRYPTING))
progressTextView?.setTextColor(messageColorProvider.getMessageTextColor(SendState.ENCRYPTING))
}
private fun doHandleProgress(resId: Int, current: Long, total: Long) {
@ -134,7 +133,7 @@ private class ContentMediaProgressUpdater(private val progressLayout: ViewGroup,
progressTextView?.text = progressLayout.context.getString(resId,
TextUtils.formatFileSize(progressLayout.context, current, true),
TextUtils.formatFileSize(progressLayout.context, total, true))
progressTextView?.setTextColor(colorProvider.getMessageTextColor(SendState.SENDING))
progressTextView?.setTextColor(messageColorProvider.getMessageTextColor(SendState.SENDING))
}
private fun handleFailure(state: ContentUploadStateTracker.State.Failure) {
@ -143,7 +142,7 @@ private class ContentMediaProgressUpdater(private val progressLayout: ViewGroup,
val progressTextView = progressLayout.findViewById<TextView>(R.id.mediaProgressTextView)
progressBar?.isVisible = false
progressTextView?.text = errorFormatter.toHumanReadable(state.throwable)
progressTextView?.setTextColor(colorProvider.getMessageTextColor(SendState.UNDELIVERED))
progressTextView?.setTextColor(messageColorProvider.getMessageTextColor(SendState.UNDELIVERED))
}
private fun handleSuccess() {

View File

@ -20,9 +20,9 @@ package im.vector.riotx.features.home.room.detail.timeline.helper
import android.view.View
import im.vector.matrix.android.api.session.room.model.message.MessageContent
import im.vector.riotx.EmojiCompatFontProvider
import im.vector.riotx.core.resources.ColorProvider
import im.vector.riotx.core.utils.DebouncedClickListener
import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.home.room.detail.timeline.MessageColorProvider
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
import im.vector.riotx.features.home.room.detail.timeline.item.AbsMessageItem
import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData
@ -30,7 +30,7 @@ import javax.inject.Inject
class MessageItemAttributesFactory @Inject constructor(
private val avatarRenderer: AvatarRenderer,
private val colorProvider: ColorProvider,
private val messageColorProvider: MessageColorProvider,
private val avatarSizeProvider: AvatarSizeProvider,
private val emojiCompatFontProvider: EmojiCompatFontProvider) {
@ -41,7 +41,7 @@ class MessageItemAttributesFactory @Inject constructor(
avatarSize = avatarSizeProvider.avatarSize,
informationData = informationData,
avatarRenderer = avatarRenderer,
colorProvider = colorProvider,
messageColorProvider = messageColorProvider,
itemLongClickListener = View.OnLongClickListener { view ->
callback?.onEventLongClicked(informationData, messageContent, view) ?: false
},

View File

@ -24,12 +24,11 @@ import androidx.annotation.IdRes
import androidx.core.view.isVisible
import im.vector.matrix.android.api.session.room.send.SendState
import im.vector.riotx.R
import im.vector.riotx.core.resources.ColorProvider
import im.vector.riotx.core.utils.DebouncedClickListener
import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.home.room.detail.timeline.MessageColorProvider
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
import im.vector.riotx.features.reactions.widget.ReactionButton
import im.vector.riotx.features.ui.getMessageTextColor
/**
* Base timeline item with reactions and read receipts.
@ -105,7 +104,7 @@ abstract class AbsBaseMessageItem<H : AbsBaseMessageItem.Holder> : BaseEventItem
protected open fun renderSendState(root: View, textView: TextView?, failureIndicator: ImageView? = null) {
root.isClickable = baseAttributes.informationData.sendState.isSent()
val state = if (baseAttributes.informationData.hasPendingEdits) SendState.UNSENT else baseAttributes.informationData.sendState
textView?.setTextColor(baseAttributes.colorProvider.getMessageTextColor(state))
textView?.setTextColor(baseAttributes.messageColorProvider.getMessageTextColor(state))
failureIndicator?.isVisible = baseAttributes.informationData.sendState.hasFailed()
}
@ -120,7 +119,7 @@ abstract class AbsBaseMessageItem<H : AbsBaseMessageItem.Holder> : BaseEventItem
// val avatarSize: Int,
val informationData: MessageInformationData
val avatarRenderer: AvatarRenderer
val colorProvider: ColorProvider
val messageColorProvider: MessageColorProvider
val itemLongClickListener: View.OnLongClickListener?
val itemClickListener: View.OnClickListener?
// val memberClickListener: View.OnClickListener?

View File

@ -23,9 +23,9 @@ import android.widget.TextView
import androidx.annotation.IdRes
import com.airbnb.epoxy.EpoxyAttribute
import im.vector.riotx.R
import im.vector.riotx.core.resources.ColorProvider
import im.vector.riotx.core.utils.DebouncedClickListener
import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.home.room.detail.timeline.MessageColorProvider
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
/**
@ -88,7 +88,7 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : AbsBaseMessageItem<H>
val avatarSize: Int,
override val informationData: MessageInformationData,
override val avatarRenderer: AvatarRenderer,
override val colorProvider: ColorProvider,
override val messageColorProvider: MessageColorProvider,
override val itemLongClickListener: View.OnLongClickListener? = null,
override val itemClickListener: View.OnClickListener? = null,
val memberClickListener: View.OnClickListener? = null,

View File

@ -73,11 +73,11 @@ class PollResultLineView @JvmOverloads constructor(
orientation = HORIZONTAL
ButterKnife.bind(this)
val typedArray = context.obtainStyledAttributes(attrs,
R.styleable.PollResultLineView, 0, 0)
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.PollResultLineView, 0, 0)
label = typedArray.getString(R.styleable.PollResultLineView_optionName) ?: ""
percent = typedArray.getString(R.styleable.PollResultLineView_optionCount) ?: ""
optionSelected = typedArray.getBoolean(R.styleable.PollResultLineView_optionSelected, false)
isWinner = typedArray.getBoolean(R.styleable.PollResultLineView_optionIsWinner, false)
typedArray.recycle()
}
}

View File

@ -26,8 +26,8 @@ import androidx.core.view.updateLayoutParams
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
import im.vector.riotx.R
import im.vector.riotx.core.resources.ColorProvider
import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.home.room.detail.timeline.MessageColorProvider
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
@EpoxyModelClass(layout = R.layout.item_timeline_event_base_state)
@ -80,7 +80,7 @@ abstract class VerificationRequestConclusionItem : AbsBaseMessageItem<Verificati
val isPositive: Boolean,
override val informationData: MessageInformationData,
override val avatarRenderer: AvatarRenderer,
override val colorProvider: ColorProvider,
override val messageColorProvider: MessageColorProvider,
override val itemLongClickListener: View.OnLongClickListener? = null,
override val itemClickListener: View.OnClickListener? = null,
override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null,

View File

@ -32,10 +32,10 @@ import im.vector.matrix.android.api.session.crypto.verification.VerificationServ
import im.vector.matrix.android.internal.session.room.VerificationState
import im.vector.riotx.R
import im.vector.riotx.core.extensions.exhaustive
import im.vector.riotx.core.resources.ColorProvider
import im.vector.riotx.core.utils.DebouncedClickListener
import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.home.room.detail.RoomDetailAction
import im.vector.riotx.features.home.room.detail.timeline.MessageColorProvider
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
@EpoxyModelClass(layout = R.layout.item_timeline_event_base_state)
@ -166,7 +166,7 @@ abstract class VerificationRequestItem : AbsBaseMessageItem<VerificationRequestI
// val avatarSize: Int,
override val informationData: MessageInformationData,
override val avatarRenderer: AvatarRenderer,
override val colorProvider: ColorProvider,
override val messageColorProvider: MessageColorProvider,
override val itemLongClickListener: View.OnLongClickListener? = null,
override val itemClickListener: View.OnClickListener? = null,
// val memberClickListener: View.OnClickListener? = null,

View File

@ -24,7 +24,6 @@ import androidx.core.app.ActivityOptionsCompat
import androidx.core.app.TaskStackBuilder
import androidx.core.view.ViewCompat
import im.vector.matrix.android.api.session.crypto.verification.IncomingSasVerificationTransaction
import im.vector.matrix.android.api.session.crypto.verification.VerificationMethod
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom
import im.vector.matrix.android.api.util.MatrixItem
import im.vector.riotx.R
@ -35,6 +34,7 @@ import im.vector.riotx.core.utils.toast
import im.vector.riotx.features.createdirect.CreateDirectRoomActivity
import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupManageActivity
import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupActivity
import im.vector.riotx.features.crypto.verification.SupportedVerificationMethodsProvider
import im.vector.riotx.features.crypto.verification.VerificationBottomSheet
import im.vector.riotx.features.debug.DebugMenuActivity
import im.vector.riotx.features.home.room.detail.RoomDetailActivity
@ -56,7 +56,8 @@ import javax.inject.Singleton
@Singleton
class DefaultNavigator @Inject constructor(
private val sessionHolder: ActiveSessionHolder,
private val vectorPreferences: VectorPreferences
private val vectorPreferences: VectorPreferences,
private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider
) : Navigator {
override fun openRoom(context: Context, roomId: String, eventId: String?, buildTask: Boolean) {
@ -85,9 +86,10 @@ class DefaultNavigator @Inject constructor(
override fun requestSessionVerification(context: Context) {
val session = sessionHolder.getSafeActiveSession() ?: return
val pr = session.cryptoService().verificationService().requestKeyVerification(
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW),
supportedVerificationMethodsProvider.provide(),
session.myUserId,
session.cryptoService().getUserDevices(session.myUserId).map { it.deviceId })
session.cryptoService().getUserDevices(session.myUserId).map { it.deviceId }
)
if (context is VectorBaseActivity) {
VerificationBottomSheet.withArgs(
roomId = null,

View File

@ -40,7 +40,7 @@ import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse
import im.vector.matrix.rx.rx
import im.vector.riotx.core.platform.VectorViewModel
import im.vector.riotx.features.crypto.verification.supportedVerificationMethods
import im.vector.riotx.features.crypto.verification.SupportedVerificationMethodsProvider
data class DevicesViewState(
val myDeviceId: String = "",
@ -50,8 +50,10 @@ data class DevicesViewState(
val request: Async<Unit> = Uninitialized
) : MvRxState
class DevicesViewModel @AssistedInject constructor(@Assisted initialState: DevicesViewState,
private val session: Session)
class DevicesViewModel @AssistedInject constructor(
@Assisted initialState: DevicesViewState,
private val session: Session,
private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider)
: VectorViewModel<DevicesViewState, DevicesAction, DevicesViewEvents>(initialState), VerificationService.Listener {
@AssistedInject.Factory
@ -172,7 +174,9 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic
}
private fun handleVerify(action: DevicesAction.VerifyMyDevice) {
val txID = session.cryptoService().verificationService().requestKeyVerification(supportedVerificationMethods, session.myUserId, listOf(action.deviceId))
val txID = session.cryptoService()
.verificationService()
.requestKeyVerification(supportedVerificationMethodsProvider.provide(), session.myUserId, listOf(action.deviceId))
_viewEvents.post(DevicesViewEvents.ShowVerifyDevice(
session.myUserId,
txID.transactionId

View File

@ -1,37 +0,0 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.riotx.features.ui
import androidx.annotation.ColorInt
import im.vector.matrix.android.api.session.room.send.SendState
import im.vector.riotx.R
import im.vector.riotx.core.resources.ColorProvider
@ColorInt
fun ColorProvider.getMessageTextColor(sendState: SendState): Int {
return when (sendState) {
// SendStates, in the classical order they will occur
SendState.UNKNOWN,
SendState.UNSENT -> getColorFromAttribute(R.attr.vctr_sending_message_text_color)
SendState.ENCRYPTING -> getColorFromAttribute(R.attr.vctr_encrypting_message_text_color)
SendState.SENDING -> getColorFromAttribute(R.attr.vctr_sending_message_text_color)
SendState.SENT,
SendState.SYNCED -> getColorFromAttribute(R.attr.vctr_message_text_color)
SendState.UNDELIVERED,
SendState.FAILED_UNKNOWN_DEVICES -> getColorFromAttribute(R.attr.vctr_unsent_message_text_color)
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 684 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 712 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 684 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 565 B

View File

@ -21,6 +21,7 @@
android:layout_marginLeft="-5dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
tools:ignore="NegativeMargin"
tools:src="@tools:sample/avatars" />
<ImageView
@ -31,6 +32,7 @@
android:layout_marginLeft="-5dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
tools:ignore="NegativeMargin"
tools:src="@tools:sample/avatars" />
<ImageView
@ -41,6 +43,7 @@
android:layout_marginLeft="-5dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
tools:ignore="NegativeMargin"
tools:src="@tools:sample/avatars" />
<ImageView
@ -51,6 +54,7 @@
android:layout_marginLeft="-5dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
tools:ignore="NegativeMargin"
tools:src="@tools:sample/avatars" />
</LinearLayout>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/ic_action_select_remove_group"
android:icon="@drawable/vector_leave_room_black"
android:title="@string/leave" />
</menu>

View File

@ -1,43 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu 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"
tools:context="org.matrix.vector.activity.RoomActivity">
<item
android:id="@+id/ic_action_search_in_room"
android:icon="@drawable/ic_material_search_white"
android:title="@string/room_menu_search"
app:showAsAction="always" />
<item
android:id="@+id/ic_action_matrix_apps"
android:icon="@drawable/apps_icon"
android:title="@string/room_add_matrix_apps"
app:showAsAction="collapseActionView" />
<item
android:id="@+id/ic_action_room_resend_unsent"
android:icon="@drawable/ic_material_send_black"
android:title="@string/room_resend_unsent_messages"
app:showAsAction="collapseActionView" />
<item
android:id="@+id/ic_action_room_delete_unsent"
android:icon="@drawable/ic_material_delete"
android:title="@string/room_delete_unsent_messages"
app:showAsAction="collapseActionView" />
<item
android:id="@+id/ic_action_room_settings"
android:icon="@drawable/ic_material_settings_small"
android:title="@string/room_details_title"
app:showAsAction="collapseActionView" />
<item
android:id="@+id/ic_action_room_leave"
android:icon="@drawable/vector_leave_room_black"
android:title="@string/leave"
app:showAsAction="collapseActionView" />
</menu>

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu 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"
tools:context="org.matrix.vector.activity.RoomActivity">
<item
android:id="@+id/ic_action_speak_to_search"
android:icon="@drawable/vector_micro_green"
android:title="@string/speak"
app:showAsAction="always" />
<item
android:id="@+id/ic_action_clear_search"
android:icon="@drawable/vector_clear_edittext_green"
android:title="@string/clear"
app:showAsAction="always" />
</menu>