Merge remote-tracking branch 'origin/develop' into feature/eric/audio-files-player

# Conflicts:
#	vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt
#	vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageViews.kt
#	vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt
#	vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt
This commit is contained in:
ericdecanini 2022-03-24 20:32:28 +01:00
commit 82cde166db
264 changed files with 3222 additions and 1442 deletions

View File

@ -26,7 +26,7 @@ jobs:
cancel-in-progress: true
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
@ -50,7 +50,7 @@ jobs:
# Only runs on main, no concurrency.
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches

View File

@ -34,7 +34,7 @@ jobs:
uses: actions/setup-python@v3
with:
python-version: 3.8
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
@ -43,7 +43,7 @@ jobs:
restore-keys: |
${{ runner.os }}-gradle-
- name: Start synapse server
uses: michaelkaye/setup-matrix-synapse@v0.3.0
uses: michaelkaye/setup-matrix-synapse@v0.4.0
with:
uploadLogs: true
httpPort: 8080
@ -221,7 +221,7 @@ jobs:
uses: actions/setup-python@v3
with:
python-version: 3.8
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
@ -230,7 +230,7 @@ jobs:
restore-keys: |
${{ runner.os }}-gradle-
- name: Start synapse server
uses: michaelkaye/setup-matrix-synapse@v0.3.0
uses: michaelkaye/setup-matrix-synapse@v0.4.0
with:
uploadLogs: true
httpPort: 8080
@ -273,7 +273,7 @@ jobs:
with:
distribution: 'adopt'
java-version: '11'
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
@ -302,7 +302,7 @@ jobs:
with:
distribution: 'adopt'
java-version: '11'
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches

View File

@ -97,7 +97,7 @@ jobs:
cancel-in-progress: true
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
@ -130,7 +130,7 @@ jobs:
cancel-in-progress: true
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches

View File

@ -25,7 +25,7 @@ jobs:
with:
distribution: 'adopt'
java-version: 11
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
@ -45,7 +45,7 @@ jobs:
cancel-in-progress: true
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches

View File

@ -1,3 +1,57 @@
Changes in Element v1.4.6 (2022-03-23)
======================================
Features ✨
----------
- Thread timeline is now live and much faster especially for large or old threads ([#5230](https://github.com/vector-im/element-android/issues/5230))
- View all threads per room screen is now live when the home server supports threads ([#5232](https://github.com/vector-im/element-android/issues/5232))
- Add a custom view to display a picker for share location options ([#5395](https://github.com/vector-im/element-android/issues/5395))
- Add ability to pin a location on map for sharing ([#5417](https://github.com/vector-im/element-android/issues/5417))
- Poll Integration Tests ([#5522](https://github.com/vector-im/element-android/issues/5522))
- Live location sharing: adding build config field and show permission dialog ([#5536](https://github.com/vector-im/element-android/issues/5536))
- Live location sharing: Adding indicator view when enabled ([#5571](https://github.com/vector-im/element-android/issues/5571))
Bugfixes 🐛
----------
- Poll system notifications on Android are not user friendly ([#4780](https://github.com/vector-im/element-android/issues/4780))
- Add colors for shield vector drawable ([#4860](https://github.com/vector-im/element-android/issues/4860))
- Support both stable and unstable prefixes for Events about Polls and Location ([#5340](https://github.com/vector-im/element-android/issues/5340))
- Fix missing messages when loading messages forwards ([#5448](https://github.com/vector-im/element-android/issues/5448))
- Fix presence indicator being aligned to the center of the room image ([#5489](https://github.com/vector-im/element-android/issues/5489))
- Read receipt in wrong order ([#5514](https://github.com/vector-im/element-android/issues/5514))
- Fix mentions using matrix.to rather than client defined permalink base url ([#5521](https://github.com/vector-im/element-android/issues/5521))
- Fixes crash when tapping the timeline verification surround box instead of the buttons ([#5540](https://github.com/vector-im/element-android/issues/5540))
- [Notification mode] Wrong mode is displayed when the mention only is selected on the web client ([#5547](https://github.com/vector-im/element-android/issues/5547))
- Fix local echos not being shown when re-opening rooms ([#5551](https://github.com/vector-im/element-android/issues/5551))
- Fix crash when closing a room while decrypting timeline events ([#5552](https://github.com/vector-im/element-android/issues/5552))
- Fix sometimes read marker not properly updating ([#5564](https://github.com/vector-im/element-android/issues/5564))
In development 🚧
----------------
- Dynamically showing/hiding onboarding personalisation screens based on the users homeserver capabilities ([#5375](https://github.com/vector-im/element-android/issues/5375))
- Introduces FTUE personalisation complete screen along with confetti celebration ([#5389](https://github.com/vector-im/element-android/issues/5389))
SDK API changes ⚠️
------------------
- Adds support for MSC3440, additional threads homeserver capabilities ([#5271](https://github.com/vector-im/element-android/issues/5271))
Other changes
-------------
- Improve headers UI in Rooms/Messages lists ([#4533](https://github.com/vector-im/element-android/issues/4533))
- Number of unread messages on space badge now include number of unread DMs ([#5260](https://github.com/vector-im/element-android/issues/5260))
- Amend spaces menu to be consistent with iOS version ([#5270](https://github.com/vector-im/element-android/issues/5270))
- Selected space highlight changed in left panel ([#5346](https://github.com/vector-im/element-android/issues/5346))
- [Rooms list] Do not suggest collapse the unique section ([#5347](https://github.com/vector-im/element-android/issues/5347))
- Add analytics support for threads ([#5378](https://github.com/vector-im/element-android/issues/5378))
- Add top margin before our first message ([#5384](https://github.com/vector-im/element-android/issues/5384))
- Improved onboarding registration unit test coverage ([#5408](https://github.com/vector-im/element-android/issues/5408))
- Adds stable room hierarchy endpoint with a fallback to the unstable one ([#5443](https://github.com/vector-im/element-android/issues/5443))
- Use ColorPrimary for attachmentGalleryButton tint ([#5501](https://github.com/vector-im/element-android/issues/5501))
- Added online presence indicator attribute online to match offline styling ([#5513](https://github.com/vector-im/element-android/issues/5513))
- Add a presence sync enabling build config ([#5563](https://github.com/vector-im/element-android/issues/5563))
- Show stickers on click ([#5572](https://github.com/vector-im/element-android/issues/5572))
Changes in Element v1.4.4 (2022-03-09)
======================================

View File

@ -1 +0,0 @@
Improve headers UI in Rooms/Messages lists

View File

@ -1 +0,0 @@
Poll system notifications on Android are not user friendly

View File

@ -1 +0,0 @@
Add colors for shield vector drawable

View File

@ -1 +0,0 @@
Thread timeline is now live and much faster especially for large or old threads

View File

@ -1 +0,0 @@
View all threads per room screen is now live when the home server supports threads

View File

@ -1 +0,0 @@
Number of unread messages on space badge now include number of unread DMs

View File

@ -1 +0,0 @@
Amend spaces menu to be consistent with iOS version

View File

@ -1 +0,0 @@
Adds support for MSC3440, additional threads homeserver capabilities

View File

@ -1 +0,0 @@
Support both stable and unstable prefixes for Events about Polls and Location

View File

@ -1 +0,0 @@
Selected space highlight changed in left panel

View File

@ -1 +0,0 @@
Dynamically showing/hiding onboarding personalisation screens based on the users homeserver capabilities

View File

@ -1 +0,0 @@
Add analytics support for threads

View File

@ -1 +0,0 @@
Add top margin before our first message

View File

@ -1 +0,0 @@
Introduces FTUE personalisation complete screen along with confetti celebration

View File

@ -1 +0,0 @@
Add a custom view to display a picker for share location options

View File

@ -1 +0,0 @@
Improved onboarding registration unit test coverage

View File

@ -1 +0,0 @@
Add ability to pin a location on map for sharing

1
changelog.d/5426.feature Normal file
View File

@ -0,0 +1 @@
Allow scrolling position of Voice Message playback

View File

@ -1 +0,0 @@
Adds stable room hierarchy endpoint with a fallback to the unstable one

View File

@ -1 +0,0 @@
Fix missing messages when loading messages forwards

View File

@ -1 +0,0 @@
Use ColorPrimary for attachmentGalleryButton tint

View File

@ -1 +0,0 @@
Added online presence indicator attribute online to match offline styling

View File

@ -1 +0,0 @@
Read receipt in wrong order

1
changelog.d/5517.misc Normal file
View File

@ -0,0 +1 @@
Flattening the asynchronous onboarding state and passing all errors through the same pipeline

View File

@ -1 +0,0 @@
Fix mentions using matrix.to rather than client defined permalink base url

View File

@ -1 +0,0 @@
Poll Integration Tests

View File

@ -1 +0,0 @@
Live location sharing: adding build config field and show permission dialog

View File

@ -1 +0,0 @@
Fixes crash when tapping the timeline verification surround box instead of the buttons

View File

@ -1 +0,0 @@
[Notification mode] Wrong mode is displayed when the mention only is selected on the web client

View File

@ -1 +0,0 @@
Fix local echos not being shown when re-opening rooms

View File

@ -1 +0,0 @@
Fix crash when closing a room while decrypting timeline events

View File

@ -1 +0,0 @@
Add a presence sync enabling build config

View File

@ -1 +0,0 @@
Live location sharing: Adding indicator view when enabled

View File

@ -1,2 +0,0 @@
Show stickers on click

View File

@ -9,13 +9,13 @@ ext.versions = [
def gradle = "7.0.4"
// Ref: https://kotlinlang.org/releases.html
def kotlin = "1.5.31"
def kotlinCoroutines = "1.5.2"
def kotlin = "1.6.0"
def kotlinCoroutines = "1.6.0"
def dagger = "2.40.5"
def retrofit = "2.9.0"
def arrow = "0.8.2"
def markwon = "4.6.2"
def moshi = "1.12.0"
def moshi = "1.13.0"
def lifecycle = "2.4.0"
def flowBinding = "1.2.0"
def epoxy = "4.6.2"

View File

@ -0,0 +1,2 @@
Main changes in this version: Thread timeline are now live and faster. Various bug fixes and stability improvements.
Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.4.6

View File

@ -0,0 +1,2 @@
Principales cambios de esta versión: primera implementación de los hilos de mensajes. Burbujas de mensajes.
Todos los cambios en: https://github.com/vector-im/element-android/releases/tag/v1.4.0

View File

@ -0,0 +1,2 @@
Principales cambios de esta versión: añadir @room, encuestas cerradas y muchos cambios menores más.
Todos los cambios en: https://github.com/vector-im/element-android/releases/tag/v1.4.2

View File

@ -0,0 +1,2 @@
تغییرات اصلی در این نگارش: پیاده سازی نخستین پیام‌های رشته‌ای. حباب‌های پیام.
گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases/tag/v1.4.0

View File

@ -0,0 +1,2 @@
تغییرات اصلی در این نگارش: افزودن پشتیبانی به @room و نظرسنجی‌های فاش نشده در کنار تغییرات کوچک دیگر.
گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases/tag/v1.4.2

View File

@ -8,12 +8,13 @@ Az Element egy biztonságos üzenetküldő, és egy csapatmunka app, amely távo
- Videochat, VoIP, és képernyőmegosztási lehetőséggel
- Egyszerű integráció a kedvenc online kollaborációs eszközeiddel, projektkezelési eszközökkel, VoIP szolgáltatásokkal, és más csoportos üzenetküldő alkalmazásokkal
Element is completely different from other messaging and collaboration apps. It operates on Matrix, an open network for secure messaging and decentralized communication. It allows self-hosting to give users maximum ownership and control of their data and messages.
Az Element teljesen más, mint az összes többi üzenetküldő és kollaborációs alkalmazás. A biztonságos üzenetküldést és decentralizált kommunikációt biztosító Matrix platformot használja. Akár egyénileg üzemeltetett szervereket is lehet használni az adatok teljes kontrollálása érdekében.
<b>Privacy and encrypted messaging</b>
Element protects you from unwanted ads, data mining and walled gardens. It also secures all your data, one-to-one video and voice communication through end-to-end encryption and cross-signed device verification.
<b>Magánszféra és titkosított csevegés</b>
Az Element megvéd a nemkívánatos hirdetésektől, adatbányászattól, és a zárt platformoktól. Ezeken felül biztonságban tartja az összes adatod és 1:1 hívásod a végponti titkosításnak és az eszközök-közti hitelesítésnek köszönhetően.
Az Element átadja neked az irányítást a magánszférád felett, miközben lehetővé teszi, hogy biztonságosan kommunikálj bárkivel a Matrix hálózatban, vagy a többi üzleti kommunikációs eszközt használókkal, az olyan appok integrálásának köszönhetően, mint például a Slack.
Element gives you control over your privacy while allowing you to communicate securely with anyone on the Matrix network, or other business collaboration tools by integrating with apps such as Slack.
<b>Element can be self-hosted</b>
To allow more control of your sensitive data and conversations, Element can be self-hosted or you can choose any Matrix-based host - the standard for open source, decentralized communication. Element gives you privacy, security compliance and integration flexibility.

View File

@ -0,0 +1,2 @@
Основные изменения в этой версии: Начальная реализация веток сообщений. Сообщения пузыри.
Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.4.0

View File

@ -0,0 +1,2 @@
Основные изменения в этой версии: добавлена поддержка @room и нераскрытых опросов, а также множество других мелких изменений.
Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.4.2

View File

@ -59,7 +59,7 @@ dependencies {
implementation libs.jetbrains.coroutinesCore
implementation libs.jetbrains.coroutinesAndroid
testImplementation 'org.json:json:20211205'
testImplementation 'org.json:json:20220320'
testImplementation libs.tests.junit
androidTestImplementation libs.androidx.junit
androidTestImplementation libs.androidx.espressoCore

View File

@ -20,13 +20,12 @@ import android.content.Context
import android.view.View
import com.airbnb.epoxy.TypedEpoxyController
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Success
import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence
import me.gujun.android.span.Span
import me.gujun.android.span.span
internal class JSonViewerEpoxyController(private val context: Context) :
TypedEpoxyController<JSonViewerState>() {
TypedEpoxyController<JSonViewerState>() {
private var styleProvider: JSonViewerStyleProvider = JSonViewerStyleProvider.default(context)
@ -44,10 +43,8 @@ internal class JSonViewerEpoxyController(private val context: Context) :
text(async.error.localizedMessage?.toEpoxyCharSequence())
}
}
is Success -> {
val model = data.root.invoke()
model?.let {
else -> {
async.invoke()?.let {
buildRec(it, 0, "")
}
}
@ -55,9 +52,9 @@ internal class JSonViewerEpoxyController(private val context: Context) :
}
private fun buildRec(
model: JSonViewerModel,
depth: Int,
idBase: String
model: JSonViewerModel,
depth: Int,
idBase: String
) {
val host = this
val id = "$idBase/${model.key ?: model.index}_${model.isExpanded}}"
@ -74,34 +71,34 @@ internal class JSonViewerEpoxyController(private val context: Context) :
id(id + "_sum")
depth(depth)
text(
span {
if (model.key != null) {
span("\"${model.key}\"") {
textColor = host.styleProvider.keyColor
}
span(" : ") {
textColor = host.styleProvider.baseColor
}
}
if (model.index != null) {
span("${model.index}") {
textColor = host.styleProvider.secondaryColor
}
span(" : ") {
textColor = host.styleProvider.baseColor
}
}
span {
+"{+${model.keys.size}}"
textColor = host.styleProvider.baseColor
}
}.toEpoxyCharSequence()
if (model.key != null) {
span("\"${model.key}\"") {
textColor = host.styleProvider.keyColor
}
span(" : ") {
textColor = host.styleProvider.baseColor
}
}
if (model.index != null) {
span("${model.index}") {
textColor = host.styleProvider.secondaryColor
}
span(" : ") {
textColor = host.styleProvider.baseColor
}
}
span {
+"{+${model.keys.size}}"
textColor = host.styleProvider.baseColor
}
}.toEpoxyCharSequence()
)
itemClickListener(View.OnClickListener { host.itemClicked(model) })
}
}
}
is JSonViewerArray -> {
is JSonViewerArray -> {
if (model.isExpanded) {
open(id, model.key, model.index, depth, false, model)
model.items.forEach {
@ -113,6 +110,38 @@ internal class JSonViewerEpoxyController(private val context: Context) :
id(id + "_sum")
depth(depth)
text(
span {
if (model.key != null) {
span("\"${model.key}\"") {
textColor = host.styleProvider.keyColor
}
span(" : ") {
textColor = host.styleProvider.baseColor
}
}
if (model.index != null) {
span("${model.index}") {
textColor = host.styleProvider.secondaryColor
}
span(" : ") {
textColor = host.styleProvider.baseColor
}
}
span {
+"[+${model.items.size}]"
textColor = host.styleProvider.baseColor
}
}.toEpoxyCharSequence()
)
itemClickListener(View.OnClickListener { host.itemClicked(model) })
}
}
}
is JSonViewerLeaf -> {
valueItem {
id(id)
depth(depth)
text(
span {
if (model.key != null) {
span("\"${model.key}\"") {
@ -122,6 +151,7 @@ internal class JSonViewerEpoxyController(private val context: Context) :
textColor = host.styleProvider.baseColor
}
}
if (model.index != null) {
span("${model.index}") {
textColor = host.styleProvider.secondaryColor
@ -130,41 +160,8 @@ internal class JSonViewerEpoxyController(private val context: Context) :
textColor = host.styleProvider.baseColor
}
}
span {
+"[+${model.items.size}]"
textColor = host.styleProvider.baseColor
}
append(host.valueToSpan(model))
}.toEpoxyCharSequence()
)
itemClickListener(View.OnClickListener { host.itemClicked(model) })
}
}
}
is JSonViewerLeaf -> {
valueItem {
id(id)
depth(depth)
text(
span {
if (model.key != null) {
span("\"${model.key}\"") {
textColor = host.styleProvider.keyColor
}
span(" : ") {
textColor = host.styleProvider.baseColor
}
}
if (model.index != null) {
span("${model.index}") {
textColor = host.styleProvider.secondaryColor
}
span(" : ") {
textColor = host.styleProvider.baseColor
}
}
append(host.valueToSpan(model))
}.toEpoxyCharSequence()
)
copyValue(model.stringRes)
}
@ -175,12 +172,12 @@ internal class JSonViewerEpoxyController(private val context: Context) :
private fun valueToSpan(leaf: JSonViewerLeaf): Span {
val host = this
return when (leaf.type) {
JSONType.STRING -> {
JSONType.STRING -> {
span("\"${leaf.stringRes}\"") {
textColor = host.styleProvider.stringColor
}
}
JSONType.NUMBER -> {
JSONType.NUMBER -> {
span(leaf.stringRes) {
textColor = host.styleProvider.numberColor
}
@ -190,7 +187,7 @@ internal class JSonViewerEpoxyController(private val context: Context) :
textColor = host.styleProvider.booleanColor
}
}
JSONType.NULL -> {
JSONType.NULL -> {
span("null") {
textColor = host.styleProvider.booleanColor
}
@ -199,42 +196,42 @@ internal class JSonViewerEpoxyController(private val context: Context) :
}
private fun open(
id: String,
key: String?,
index: Int?,
depth: Int,
isObject: Boolean = true,
composed: JSonViewerModel
id: String,
key: String?,
index: Int?,
depth: Int,
isObject: Boolean = true,
composed: JSonViewerModel
) {
val host = this
valueItem {
id("${id}_Open")
depth(depth)
text(
span {
if (key != null) {
span("\"$key\"") {
textColor = host.styleProvider.keyColor
span {
if (key != null) {
span("\"$key\"") {
textColor = host.styleProvider.keyColor
}
span(" : ") {
textColor = host.styleProvider.baseColor
}
}
span(" : ") {
textColor = host.styleProvider.baseColor
if (index != null) {
span("$index") {
textColor = host.styleProvider.secondaryColor
}
span(" : ") {
textColor = host.styleProvider.baseColor
}
}
}
if (index != null) {
span("$index") {
span("- ") {
textColor = host.styleProvider.secondaryColor
}
span(" : ") {
span("{".takeIf { isObject } ?: "[") {
textColor = host.styleProvider.baseColor
}
}
span("- ") {
textColor = host.styleProvider.secondaryColor
}
span("{".takeIf { isObject } ?: "[") {
textColor = host.styleProvider.baseColor
}
}.toEpoxyCharSequence()
}.toEpoxyCharSequence()
)
itemClickListener(View.OnClickListener { host.itemClicked(composed) })
}
@ -251,10 +248,10 @@ internal class JSonViewerEpoxyController(private val context: Context) :
id("${id}_Close")
depth(depth)
text(
span {
text = "}".takeIf { isObject } ?: "]"
textColor = host.styleProvider.baseColor
}.toEpoxyCharSequence()
span {
text = "}".takeIf { isObject } ?: "]"
textColor = host.styleProvider.baseColor
}.toEpoxyCharSequence()
)
}
}

View File

@ -60,6 +60,4 @@ dependencies {
implementation 'com.github.vector-im:PFLockScreen-Android:1.0.0-beta12'
// dialpad dimen
implementation 'im.dlg:android-dialer:1.2.5'
// AudioRecordView attr
implementation 'com.github.Armen101:AudioRecordView:1.0.5'
}

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="AudioWaveformView">
<attr name="alignment" format="enum">
<enum name="center" value="0" />
<enum name="bottom" value="1" />
<enum name="top" value="2" />
</attr>
<attr name="flow" format="enum">
<enum name="leftToRight" value="0" />
<enum name="rightToLeft" value="1" />
</attr>
<attr name="verticalPadding" format="dimension" />
<attr name="horizontalPadding" format="dimension" />
<attr name="barWidth" format="dimension" />
<attr name="barSpace" format="dimension" />
<attr name="barMinHeight" format="dimension" />
<attr name="isBarRounded" format="boolean" />
</declare-styleable>
</resources>

View File

@ -2,14 +2,14 @@
<resources>
<style name="VoicePlaybackWaveform">
<item name="chunkColor">?vctr_content_secondary</item>
<item name="chunkAlignTo">center</item>
<item name="chunkMinHeight">1dp</item>
<item name="chunkRoundedCorners">true</item>
<item name="chunkSoftTransition">true</item>
<item name="chunkSpace">2dp</item>
<item name="chunkWidth">2dp</item>
<item name="direction">rightToLeft</item>
<item name="alignment">center</item>
<item name="flow">leftToRight</item>
<item name="verticalPadding">4dp</item>
<item name="horizontalPadding">4dp</item>
<item name="barWidth">2dp</item>
<item name="barSpace">2dp</item>
<item name="barMinHeight">1dp</item>
<item name="isBarRounded">true</item>
</style>
</resources>

View File

@ -31,7 +31,7 @@ android {
// that the app's state is completely cleared between tests.
testInstrumentationRunnerArguments clearPackageData: 'true'
buildConfigField "String", "SDK_VERSION", "\"1.4.6\""
buildConfigField "String", "SDK_VERSION", "\"1.4.8\""
buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\""
buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\""

View File

@ -64,7 +64,11 @@ data class MatrixConfiguration(
/**
* True to enable presence information sync (if available). False to disable regardless of server setting.
*/
val presenceSyncEnabled: Boolean = true
val presenceSyncEnabled: Boolean = true,
/**
* Thread messages default enable/disabled value
*/
val threadMessagesEnabledDefault: Boolean = false,
) {
/**

View File

@ -58,12 +58,36 @@ fun Throwable.getRetryDelay(defaultValue: Long): Long {
?: defaultValue
}
fun Throwable.isUsernameInUse(): Boolean {
return this is Failure.ServerError && error.code == MatrixError.M_USER_IN_USE
}
fun Throwable.isInvalidUsername(): Boolean {
return this is Failure.ServerError &&
error.code == MatrixError.M_INVALID_USERNAME
}
fun Throwable.isInvalidPassword(): Boolean {
return this is Failure.ServerError &&
error.code == MatrixError.M_FORBIDDEN &&
error.message == "Invalid password"
}
fun Throwable.isRegistrationDisabled(): Boolean {
return this is Failure.ServerError && error.code == MatrixError.M_FORBIDDEN &&
httpCode == HttpsURLConnection.HTTP_FORBIDDEN
}
fun Throwable.isWeakPassword(): Boolean {
return this is Failure.ServerError && error.code == MatrixError.M_WEAK_PASSWORD
}
fun Throwable.isLoginEmailUnknown(): Boolean {
return this is Failure.ServerError &&
error.code == MatrixError.M_FORBIDDEN &&
error.message.isEmpty()
}
fun Throwable.isInvalidUIAAuth(): Boolean {
return this is Failure.ServerError &&
error.code == MatrixError.M_FORBIDDEN &&
@ -104,8 +128,8 @@ fun Throwable.isRegistrationAvailabilityError(): Boolean {
return this is Failure.ServerError &&
httpCode == HttpsURLConnection.HTTP_BAD_REQUEST && /* 400 */
(error.code == MatrixError.M_USER_IN_USE ||
error.code == MatrixError.M_INVALID_USERNAME ||
error.code == MatrixError.M_EXCLUSIVE)
error.code == MatrixError.M_INVALID_USERNAME ||
error.code == MatrixError.M_EXCLUSIVE)
}
/**

View File

@ -29,7 +29,6 @@ import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64Safe
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationTransaction
import org.matrix.android.sdk.internal.crypto.verification.ValidVerificationInfoStart
import org.matrix.android.sdk.internal.util.exhaustive
import timber.log.Timber
internal class DefaultQrCodeVerificationTransaction(
@ -129,7 +128,7 @@ internal class DefaultQrCodeVerificationTransaction(
// Nothing special here, we will send a reciprocate start event, and then the other session will trust it's view of the MSK
}
}
}.exhaustive
}
val toVerifyDeviceIds = mutableListOf<String>()
@ -174,7 +173,7 @@ internal class DefaultQrCodeVerificationTransaction(
Unit
}
}
}.exhaustive
}
if (!canTrustOtherUserMasterKey && toVerifyDeviceIds.isEmpty()) {
// Nothing to verify
@ -272,6 +271,7 @@ internal class DefaultQrCodeVerificationTransaction(
// I now know that i can trust my MSK
trust(true, emptyList(), true)
}
null -> Unit
}
}

View File

@ -19,15 +19,19 @@ package org.matrix.android.sdk.internal.database.lightweight
import android.content.Context
import androidx.core.content.edit
import androidx.preference.PreferenceManager
import org.matrix.android.sdk.api.MatrixConfiguration
import javax.inject.Inject
/**
* The purpose of this class is to provide an alternative and lightweight way to store settings/data
* on the sdi without using the database. This should be used just for sdk/user preferences and
* on the sdk without using the database. This should be used just for sdk/user preferences and
* not for large data sets
*/
class LightweightSettingsStorage @Inject constructor(context: Context) {
class LightweightSettingsStorage @Inject constructor(
context: Context,
private val matrixConfiguration: MatrixConfiguration
) {
private val sdkDefaultPrefs = PreferenceManager.getDefaultSharedPreferences(context.applicationContext)
@ -38,7 +42,7 @@ class LightweightSettingsStorage @Inject constructor(context: Context) {
}
fun areThreadMessagesEnabled(): Boolean {
return sdkDefaultPrefs.getBoolean(MATRIX_SDK_SETTINGS_THREAD_MESSAGES_ENABLED, false)
return sdkDefaultPrefs.getBoolean(MATRIX_SDK_SETTINGS_THREAD_MESSAGES_ENABLED, matrixConfiguration.threadMessagesEnabledDefault)
}
companion object {

View File

@ -80,8 +80,8 @@ internal class WorkManagerProvider @Inject constructor(
workManager.enqueue(checkWorkerRequest)
val checkWorkerLiveState = workManager.getWorkInfoByIdLiveData(checkWorkerRequest.id)
val observer = object : Observer<WorkInfo> {
override fun onChanged(workInfo: WorkInfo) {
if (workInfo.state.isFinished) {
override fun onChanged(workInfo: WorkInfo?) {
if (workInfo?.state?.isFinished == true) {
checkWorkerLiveState.removeObserver(this)
if (workInfo.state == WorkInfo.State.FAILED) {
throw RuntimeException("MatrixWorkerFactory is not being set on your worker configuration.\n" +

View File

@ -44,7 +44,7 @@ internal interface FetchThreadSummariesTask : Task<FetchThreadSummariesTask.Para
data class Params(
val roomId: String,
val from: String = "",
val limit: Int = 100,
val limit: Int = 500,
val isUserParticipating: Boolean = true
)
}

View File

@ -314,6 +314,7 @@ internal class RoomSummaryDataSource @Inject constructor(
RoomCategoryFilter.ONLY_ROOMS -> query.equalTo(RoomSummaryEntityFields.IS_DIRECT, false)
RoomCategoryFilter.ONLY_WITH_NOTIFICATIONS -> query.greaterThan(RoomSummaryEntityFields.NOTIFICATION_COUNT, 0)
RoomCategoryFilter.ALL -> Unit // nop
null -> Unit
}
// Timber.w("VAL: activeSpaceId : ${queryParams.activeSpaceId}")

View File

@ -83,11 +83,15 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity,
isLastBackward.set(chunkEntity.isLastBackward)
}
if (changeSet.isFieldChanged(ChunkEntityFields.NEXT_CHUNK.`$`)) {
nextChunk = createTimelineChunk(chunkEntity.nextChunk)
nextChunk = createTimelineChunk(chunkEntity.nextChunk).also {
it?.prevChunk = this
}
nextChunkLatch?.complete(Unit)
}
if (changeSet.isFieldChanged(ChunkEntityFields.PREV_CHUNK.`$`)) {
prevChunk = createTimelineChunk(chunkEntity.prevChunk)
prevChunk = createTimelineChunk(chunkEntity.prevChunk).also {
it?.nextChunk = this
}
prevChunkLatch?.complete(Unit)
}
}
@ -194,7 +198,9 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity,
when {
nextChunkEntity != null -> {
if (nextChunk == null) {
nextChunk = createTimelineChunk(nextChunkEntity)
nextChunk = createTimelineChunk(nextChunkEntity).also {
it?.prevChunk = this
}
}
nextChunk?.loadMore(offsetCount, direction, fetchFromServerIfNeeded) ?: LoadMoreResult.FAILURE
}
@ -210,7 +216,9 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity,
when {
prevChunkEntity != null -> {
if (prevChunk == null) {
prevChunk = createTimelineChunk(prevChunkEntity)
prevChunk = createTimelineChunk(prevChunkEntity).also {
it?.nextChunk = this
}
}
prevChunk?.loadMore(offsetCount, direction, fetchFromServerIfNeeded) ?: LoadMoreResult.FAILURE
}

View File

@ -1,20 +0,0 @@
/*
* Copyright 2020 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.internal.util
// Trick to ensure that when block is exhaustive
internal val <T> T.exhaustive: T get() = this

View File

@ -16,7 +16,8 @@
package org.matrix.android.sdk.internal.session.pushers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.amshove.kluent.internal.assertFailsWith
import org.amshove.kluent.shouldBeEqualTo
import org.junit.Test
@ -39,6 +40,7 @@ private val A_JSON_PUSHER = JsonPusher(
data = JsonPusherData(brand = "Element")
)
@ExperimentalCoroutinesApi
class DefaultAddPusherTaskTest {
private val pushersAPI = FakePushersAPI()
@ -55,7 +57,7 @@ class DefaultAddPusherTaskTest {
fun `given no persisted pusher when adding Pusher then updates api and inserts result with Registered state`() {
monarchy.givenWhereReturns<PusherEntity>(result = null)
runBlocking { addPusherTask.execute(AddPusherTask.Params(A_JSON_PUSHER)) }
runTest { addPusherTask.execute(AddPusherTask.Params(A_JSON_PUSHER)) }
pushersAPI.verifySetPusher(A_JSON_PUSHER)
monarchy.verifyInsertOrUpdate<PusherEntity> {
@ -70,7 +72,7 @@ class DefaultAddPusherTaskTest {
val realmResult = PusherEntity(appDisplayName = null)
monarchy.givenWhereReturns(result = realmResult)
runBlocking { addPusherTask.execute(AddPusherTask.Params(A_JSON_PUSHER)) }
runTest { addPusherTask.execute(AddPusherTask.Params(A_JSON_PUSHER)) }
pushersAPI.verifySetPusher(A_JSON_PUSHER)
@ -85,7 +87,7 @@ class DefaultAddPusherTaskTest {
pushersAPI.givenSetPusherErrors(SocketException())
assertFailsWith<SocketException> {
runBlocking { addPusherTask.execute(AddPusherTask.Params(A_JSON_PUSHER)) }
runTest { addPusherTask.execute(AddPusherTask.Params(A_JSON_PUSHER)) }
}
realmResult.state shouldBeEqualTo PusherState.FAILED_TO_REGISTER
@ -97,7 +99,7 @@ class DefaultAddPusherTaskTest {
pushersAPI.givenSetPusherErrors(SocketException())
assertFailsWith<SocketException> {
runBlocking { addPusherTask.execute(AddPusherTask.Params(A_JSON_PUSHER)) }
runTest { addPusherTask.execute(AddPusherTask.Params(A_JSON_PUSHER)) }
}
}
}

View File

@ -17,7 +17,7 @@
package org.matrix.android.sdk.internal.session.space
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runBlockingTest
import kotlinx.coroutines.test.runTest
import okhttp3.ResponseBody.Companion.toResponseBody
import org.amshove.kluent.shouldBeEqualTo
import org.junit.Test
@ -35,7 +35,7 @@ internal class DefaultResolveSpaceInfoTaskTest {
private val resolveSpaceInfoTask = DefaultResolveSpaceInfoTask(spaceApi.instance, globalErrorReceiver)
@Test
fun `given stable endpoint works, when execute, then return stable api data`() = runBlockingTest {
fun `given stable endpoint works, when execute, then return stable api data`() = runTest {
spaceApi.givenStableEndpointReturns(response)
val result = resolveSpaceInfoTask.execute(spaceApi.params)
@ -44,7 +44,7 @@ internal class DefaultResolveSpaceInfoTaskTest {
}
@Test
fun `given stable endpoint fails, when execute, then fallback to unstable endpoint`() = runBlockingTest {
fun `given stable endpoint fails, when execute, then fallback to unstable endpoint`() = runTest {
spaceApi.givenStableEndpointThrows(httpException)
spaceApi.givenUnstableEndpointReturns(response)

View File

@ -21,7 +21,7 @@ import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.delay
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertEquals
import org.junit.Test
import org.matrix.android.sdk.MatrixTest
@ -51,7 +51,7 @@ class CoroutineSequencersTest : MatrixTest {
.also { results.add(it) }
}
)
runBlocking {
runTest {
jobs.joinAll()
}
assertEquals(3, results.size)
@ -81,7 +81,7 @@ class CoroutineSequencersTest : MatrixTest {
.also { results.add(it) }
}
)
runBlocking {
runTest {
jobs.joinAll()
}
assertEquals(3, results.size)
@ -109,7 +109,7 @@ class CoroutineSequencersTest : MatrixTest {
)
// We are canceling the second job
jobs[1].cancel()
runBlocking {
runTest {
jobs.joinAll()
}
assertEquals(2, results.size)

View File

@ -7,7 +7,6 @@ import com.airbnb.mvrx.ViewModelContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dagger.assisted.AssistedFactory
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
<#if createViewEvents>
@ -42,6 +41,6 @@ class ${viewModelClass} @AssistedInject constructor(@Assisted initialState: ${vi
override fun handle(action: ${actionClass}) {
when (action) {
}.exhaustive
}
}
}

View File

@ -36,8 +36,9 @@
<!-- Level 1: Security and Privacy -->
<!-- Level 1: Labs -->
<bool name="settings_labs_thread_messages_default">false</bool>
<!-- Level 1: Advcanced settings -->
<!-- Level 1: Advanced settings -->
<!-- Level 1: Help and about -->

View File

@ -18,7 +18,7 @@ ext.versionMinor = 4
// Note: even values are reserved for regular release, odd values for hotfix release.
// When creating a hotfix, you should decrease the value, since the current value
// is the value for the next regular release.
ext.versionPatch = 6
ext.versionPatch = 8
static def getGitTimestamp() {
def cmd = 'git show -s --format=%ct'
@ -411,7 +411,6 @@ dependencies {
implementation 'jp.wasabeef:glide-transformations:4.3.0'
implementation 'com.github.vector-im:PFLockScreen-Android:1.0.0-beta12'
implementation 'com.github.hyuwah:DraggableView:1.0.0'
implementation 'com.github.Armen101:AudioRecordView:1.0.5'
// Custom Tab
implementation 'androidx.browser:browser:1.4.0'

View File

@ -21,6 +21,7 @@ import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.Espresso.pressBack
import androidx.test.espresso.matcher.ViewMatchers.isRoot
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import com.adevinta.android.barista.assertion.BaristaEnabledAssertions.assertDisabled
import com.adevinta.android.barista.assertion.BaristaEnabledAssertions.assertEnabled
import com.adevinta.android.barista.assertion.BaristaVisibilityAssertions.assertDisplayed
@ -55,6 +56,8 @@ class OnboardingRobot {
fun createAccount(userId: String, password: String = "password", homeServerUrl: String = "http://10.0.2.2:8080") {
initSession(true, userId, password, homeServerUrl)
waitUntilViewVisible(withText(R.string.ftue_account_created_congratulations_title))
clickOn(R.string.ftue_account_created_take_me_home)
}
fun login(userId: String, password: String = "password", homeServerUrl: String = "http://10.0.2.2:8080") {

View File

@ -22,7 +22,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.analytics.store.AnalyticsStore
@ -53,7 +52,7 @@ class DebugAnalyticsViewModel @AssistedInject constructor(
override fun handle(action: DebugAnalyticsViewActions) {
when (action) {
DebugAnalyticsViewActions.ResetAnalyticsOptInDisplayed -> handleResetAnalyticsOptInDisplayed()
}.exhaustive
}
}
private fun handleResetAnalyticsOptInDisplayed() {

View File

@ -22,7 +22,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.debug.features.DebugVectorOverrides
@ -71,7 +70,7 @@ class DebugPrivateSettingsViewModel @AssistedInject constructor(
is DebugPrivateSettingsViewActions.SetForceLoginFallbackEnabled -> handleSetForceLoginFallbackEnabled(action)
is SetDisplayNameCapabilityOverride -> handSetDisplayNameCapabilityOverride(action)
is SetAvatarCapabilityOverride -> handSetAvatarCapabilityOverride(action)
}.exhaustive
}
}
private fun handleSetDialPadVisibility(action: DebugPrivateSettingsViewActions.SetDialPadVisibility) {

View File

@ -437,11 +437,6 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<br/>
Copyright (c) 2017-present, dialog LLC &lt;info@dlg.im&gt;
</li>
<li>
<b>Armen101 / AudioRecordView</b>
<br/>
Copyright 2019 Armen Gevorgyan
</li>
</ul>
<pre>
Apache License

View File

@ -46,6 +46,7 @@ import im.vector.app.features.navigation.Navigator
import im.vector.app.features.pin.PinCodeStore
import im.vector.app.features.pin.SharedPrefPinCodeStore
import im.vector.app.features.room.VectorRoomDisplayNameFallbackProvider
import im.vector.app.features.settings.VectorPreferences
import im.vector.app.features.ui.SharedPreferencesUiStateRepository
import im.vector.app.features.ui.UiStateRepository
import kotlinx.coroutines.CoroutineScope
@ -113,10 +114,13 @@ object VectorStaticModule {
}
@Provides
fun providesMatrixConfiguration(vectorRoomDisplayNameFallbackProvider: VectorRoomDisplayNameFallbackProvider): MatrixConfiguration {
fun providesMatrixConfiguration(
vectorPreferences: VectorPreferences,
vectorRoomDisplayNameFallbackProvider: VectorRoomDisplayNameFallbackProvider): MatrixConfiguration {
return MatrixConfiguration(
applicationFlavor = BuildConfig.FLAVOR_DESCRIPTION,
roomDisplayNameFallbackProvider = vectorRoomDisplayNameFallbackProvider,
threadMessagesEnabledDefault = vectorPreferences.areThreadMessagesEnabled(),
presenceSyncEnabled = BuildConfig.PRESENCE_SYNC_ENABLED
)
}

View File

@ -1,20 +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.app.core.extensions
// Trick to ensure that when block is exhaustive
val <T> T.exhaustive: T get() = this

View File

@ -54,7 +54,6 @@ import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.di.ActivityEntryPoint
import im.vector.app.core.dialogs.DialogLocker
import im.vector.app.core.dialogs.UnrecognizedCertificateDialog
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.observeEvent
import im.vector.app.core.extensions.observeNotNull
import im.vector.app.core.extensions.registerStartForActivityResult
@ -267,7 +266,7 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
is GlobalError.CertificateError ->
handleCertificateError(globalError)
GlobalError.ExpiredAccount -> Unit // TODO Handle account expiration
}.exhaustive
}
}
private fun handleCertificateError(certificateError: GlobalError.CertificateError) {

View File

@ -83,6 +83,7 @@ class PushRulePreference : VectorPreference {
NotificationIndex.NOISY -> {
radioGroup?.check(R.id.bingPreferenceRadioBingRuleNoisy)
}
null -> Unit
}
radioGroup?.setOnCheckedChangeListener { _, checkedId ->

View File

@ -77,13 +77,10 @@ class KeysBackupBanner @JvmOverloads constructor(
override fun onClick(v: View?) {
when (state) {
is State.Setup -> {
delegate?.setupKeysBackup()
}
is State.Setup -> delegate?.setupKeysBackup()
is State.Update,
is State.Recover -> {
delegate?.recoverKeysBackup()
}
is State.Recover -> delegate?.recoverKeysBackup()
else -> Unit
}
}

View File

@ -27,7 +27,6 @@ import androidx.core.text.italic
import im.vector.app.R
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.error.ResourceLimitErrorFormatter
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.utils.DimensionConverter
import im.vector.app.databinding.ViewNotificationAreaBinding
import im.vector.app.features.themes.ThemeUtils
@ -77,7 +76,7 @@ class NotificationAreaView @JvmOverloads constructor(
is State.UnsupportedAlgorithm -> renderUnsupportedAlgorithm(newState)
is State.Tombstone -> renderTombstone()
is State.ResourceLimitExceededError -> renderResourceLimitExceededError(newState)
}.exhaustive
}
}
// PRIVATE METHODS ****************************************************************************************************************************************

View File

@ -49,6 +49,7 @@ class PresenceStateImageView @JvmOverloads constructor(
setImageResource(R.drawable.ic_presence_offline)
contentDescription = context.getString(R.string.a11y_presence_offline)
}
null -> Unit
}
}
}

View File

@ -40,21 +40,21 @@ class ShieldImageView @JvmOverloads constructor(
isVisible = roomEncryptionTrustLevel != null
when (roomEncryptionTrustLevel) {
RoomEncryptionTrustLevel.Default -> {
RoomEncryptionTrustLevel.Default -> {
contentDescription = context.getString(R.string.a11y_trust_level_default)
setImageResource(
if (borderLess) R.drawable.ic_shield_black_no_border
else R.drawable.ic_shield_black
)
}
RoomEncryptionTrustLevel.Warning -> {
RoomEncryptionTrustLevel.Warning -> {
contentDescription = context.getString(R.string.a11y_trust_level_warning)
setImageResource(
if (borderLess) R.drawable.ic_shield_warning_no_border
else R.drawable.ic_shield_warning
)
}
RoomEncryptionTrustLevel.Trusted -> {
RoomEncryptionTrustLevel.Trusted -> {
contentDescription = context.getString(R.string.a11y_trust_level_trusted)
setImageResource(
if (borderLess) R.drawable.ic_shield_trusted_no_border
@ -65,6 +65,7 @@ class ShieldImageView @JvmOverloads constructor(
contentDescription = context.getString(R.string.a11y_trust_level_trusted)
setImageResource(R.drawable.ic_warning_badge)
}
null -> Unit
}
}
}
@ -72,9 +73,9 @@ class ShieldImageView @JvmOverloads constructor(
@DrawableRes
fun RoomEncryptionTrustLevel.toDrawableRes(): Int {
return when (this) {
RoomEncryptionTrustLevel.Default -> R.drawable.ic_shield_black
RoomEncryptionTrustLevel.Warning -> R.drawable.ic_shield_warning
RoomEncryptionTrustLevel.Trusted -> R.drawable.ic_shield_trusted
RoomEncryptionTrustLevel.Default -> R.drawable.ic_shield_black
RoomEncryptionTrustLevel.Warning -> R.drawable.ic_shield_warning
RoomEncryptionTrustLevel.Trusted -> R.drawable.ic_shield_trusted
RoomEncryptionTrustLevel.E2EWithUnsupportedAlgorithm -> R.drawable.ic_warning_badge
}
}

View File

@ -241,7 +241,7 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
// We have a session.
// Check it can be opened
if (sessionHolder.getActiveSession().isOpenable) {
HomeActivity.newIntent(this)
HomeActivity.newIntent(this, existingSession = true)
} else {
// The token is still invalid
navigator.softLogout(this)

View File

@ -22,7 +22,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.analytics.VectorAnalytics
import kotlinx.coroutines.launch
@ -55,7 +54,7 @@ class AnalyticsConsentViewModel @AssistedInject constructor(
override fun handle(action: AnalyticsConsentViewActions) {
when (action) {
is AnalyticsConsentViewActions.SetUserConsent -> handleSetUserConsent(action)
}.exhaustive
}
}
private fun handleSetUserConsent(action: AnalyticsConsentViewActions.SetUserConsent) {

View File

@ -19,7 +19,6 @@ package im.vector.app.features.analytics.ui.consent
import com.airbnb.mvrx.viewModel
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.ScreenOrientationLocker
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivitySimpleBinding
@ -48,7 +47,7 @@ class AnalyticsOptInActivity : VectorBaseActivity<ActivitySimpleBinding>() {
viewModel.observeViewEvents {
when (it) {
AnalyticsOptInViewEvents.OnDataSaved -> finish()
}.exhaustive
}
}
}
}

View File

@ -17,7 +17,6 @@
package im.vector.app.features.attachments.preview
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
class AttachmentsPreviewViewModel(initialState: AttachmentsPreviewViewState) :
@ -28,7 +27,7 @@ class AttachmentsPreviewViewModel(initialState: AttachmentsPreviewViewState) :
is AttachmentsPreviewAction.SetCurrentAttachment -> handleSetCurrentAttachment(action)
is AttachmentsPreviewAction.UpdatePathOfCurrentAttachment -> handleUpdatePathOfCurrentAttachment(action)
AttachmentsPreviewAction.RemoveCurrentAttachment -> handleRemoveCurrentAttachment()
}.exhaustive
}
}
private fun handleRemoveCurrentAttachment() = withState {

View File

@ -111,6 +111,7 @@ class CallControlsView @JvmOverloads constructor(
views.ringingControls.isVisible = false
views.connectedControls.isVisible = false
}
null -> Unit
}
}

View File

@ -525,8 +525,7 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
navigator.openCallTransfer(this, callTransferActivityResultLauncher, callId)
}
is VectorCallViewEvents.FailToTransfer -> showSnackbar(getString(R.string.call_transfer_failure))
null -> {
}
else -> Unit
}
}

View File

@ -26,7 +26,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.call.audio.CallAudioManager
import im.vector.app.features.call.dialpad.DialPadLookup
@ -343,7 +342,7 @@ class VectorCallViewModel @AssistedInject constructor(
setState { VectorCallViewState(action.callArgs) }
setupCallWithCurrentState()
}
}.exhaustive
}
}
private fun handleCallTransfer() {
@ -358,7 +357,7 @@ class VectorCallViewModel @AssistedInject constructor(
when (result) {
is CallTransferResult.ConnectWithUserId -> connectWithUserId(result)
is CallTransferResult.ConnectWithPhoneNumber -> connectWithPhoneNumber(result)
}.exhaustive
}
}
private fun connectWithUserId(result: CallTransferResult.ConnectWithUserId) {

View File

@ -27,7 +27,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
@ -103,7 +102,7 @@ class JitsiCallViewModel @AssistedInject constructor(
when (action) {
is JitsiCallViewActions.SwitchTo -> handleSwitchTo(action)
JitsiCallViewActions.OnConferenceLeft -> handleOnConferenceLeft()
}.exhaustive
}
}
private fun handleSwitchTo(action: JitsiCallViewActions.SwitchTo) = withState { state ->

View File

@ -35,7 +35,6 @@ import com.facebook.react.modules.core.PermissionListener
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivityJitsiBinding
import kotlinx.parcelize.Parcelize
@ -79,7 +78,7 @@ class VectorJitsiActivity : VectorBaseActivity<ActivityJitsiBinding>(), JitsiMee
JitsiCallViewEvents.FailJoiningConference -> handleFailJoining()
JitsiCallViewEvents.Finish -> finish()
JitsiCallViewEvents.LeaveConference -> handleLeaveConference()
}.exhaustive
}
}
lifecycle.addObserver(ConferenceEventObserver(this, this::onBroadcastEvent))
}

View File

@ -26,7 +26,6 @@ import com.google.android.material.tabs.TabLayoutMediator
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivityCallTransferBinding
import kotlinx.parcelize.Parcelize
@ -57,7 +56,7 @@ class CallTransferActivity : VectorBaseActivity<ActivityCallTransferBinding>() {
callTransferViewModel.observeViewEvents {
when (it) {
is CallTransferViewEvents.Complete -> handleComplete()
}.exhaustive
}
}
sectionsPagerAdapter = CallTransferPagerAdapter(this)

View File

@ -26,7 +26,6 @@ import com.airbnb.mvrx.activityViewModel
import com.airbnb.mvrx.withState
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.hideKeyboard
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.showIdentityServerConsentDialog
@ -73,7 +72,7 @@ class ContactsBookFragment @Inject constructor(
when (it) {
is ContactsBookViewEvents.Failure -> showFailure(it.throwable)
is ContactsBookViewEvents.OnPoliciesRetrieved -> showConsentDialog(it)
}.exhaustive
}
}
}

View File

@ -27,7 +27,6 @@ import im.vector.app.core.contacts.ContactsDataSource
import im.vector.app.core.contacts.MappedContact
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.discovery.fetchIdentityServerWithTerms
@ -165,7 +164,7 @@ class ContactsBookViewModel @AssistedInject constructor(
is ContactsBookAction.OnlyBoundContacts -> handleOnlyBoundContacts(action)
ContactsBookAction.UserConsentGranted -> handleUserConsentGranted()
ContactsBookAction.UserConsentRequest -> handleUserConsentRequest()
}.exhaustive
}
}
private fun handleUserConsentRequest() {

View File

@ -28,6 +28,7 @@ import com.airbnb.mvrx.Async
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.Uninitialized
import com.airbnb.mvrx.viewModel
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
@ -35,7 +36,6 @@ import im.vector.app.R
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.extensions.addFragmentToBackstack
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.SimpleFragmentActivity
import im.vector.app.core.platform.WaitingViewData
import im.vector.app.core.utils.PERMISSIONS_FOR_MEMBERS_SEARCH
@ -84,7 +84,7 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
is UserListSharedAction.OnMenuItemSelected -> onMenuItemSelected(action)
UserListSharedAction.OpenPhoneBook -> openPhoneBook()
UserListSharedAction.AddByQrCode -> openAddByQrCode()
}.exhaustive
}
}
.launchIn(lifecycleScope)
if (isFirstCreation()) {
@ -111,7 +111,7 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
Toast.makeText(this, R.string.cannot_dm_self, Toast.LENGTH_SHORT).show()
finish()
}
}.exhaustive
}
}
qrViewModel.observeViewEvents {
@ -124,7 +124,7 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
finish()
}
else -> Unit
}.exhaustive
}
}
}
@ -167,6 +167,7 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
private fun renderCreateAndInviteState(state: Async<String>) {
when (state) {
Uninitialized,
is Loading -> renderCreationLoading()
is Success -> renderCreationSuccess(state())
is Fail -> renderCreationFailure(state.error)

View File

@ -24,7 +24,6 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.mvrx.runCatchingToAsync
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.raw.wellknown.getElementWellknown
@ -56,7 +55,7 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted
when (action) {
is CreateDirectRoomAction.CreateRoomAndInviteSelectedUsers -> onSubmitInvitees(action.selections)
is CreateDirectRoomAction.QrScannedAction -> onCodeParsed(action)
}.exhaustive
}
}
private fun onCodeParsed(action: CreateDirectRoomAction.QrScannedAction) {
@ -108,7 +107,7 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted
when (it) {
is PendingSelection.UserPendingSelection -> invitedUserIds.add(it.user.userId)
is PendingSelection.ThreePidPendingSelection -> invite3pids.add(it.threePid)
}.exhaustive
}
}
setDirectMessage()
enableEncryptionIfInvitedUsersSupportIt = adminE2EByDefault

View File

@ -140,6 +140,7 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(
isBackupAlreadySetup = true
}
null -> Unit
}
if (isBackupAlreadySetup) {

View File

@ -116,12 +116,13 @@ class SharedSecureStorageActivity :
is SharedSecureStorageViewEvent.FinishSuccess -> {
val dataResult = Intent()
dataResult.putExtra(EXTRA_DATA_RESULT, it.cypherResult)
setResult(Activity.RESULT_OK, dataResult)
setResult(RESULT_OK, dataResult)
finish()
}
is SharedSecureStorageViewEvent.ShowResetBottomSheet -> {
navigator.open4SSetup(this, SetupMode.HARD_RESET)
}
else -> Unit
}
}

View File

@ -29,7 +29,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.R
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.platform.WaitingViewData
import im.vector.app.core.resources.StringProvider
@ -142,7 +141,7 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
SharedSecureStorageAction.Back -> handleBack()
SharedSecureStorageAction.ForgotResetAll -> handleResetAll()
SharedSecureStorageAction.DoResetAll -> handleDoResetAll()
}.exhaustive
}
}
private fun handleDoResetAll() {

View File

@ -77,6 +77,7 @@ class SharedSecuredStorageKeyFragment @Inject constructor() : VectorBaseFragment
is SharedSecureStorageViewEvent.KeyInlineError -> {
views.ssssKeyEnterTil.error = it.message
}
else -> Unit
}
}

View File

@ -86,6 +86,7 @@ class SharedSecuredStoragePassphraseFragment @Inject constructor(
is SharedSecureStorageViewEvent.InlineError -> {
views.ssssPassphraseEnterTil.error = it.message
}
else -> Unit
}
}

Some files were not shown because too many files have changed in this diff Show More