From 87f506f23bbd83be51ad4b3e374981de757786ec Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 16 Jul 2020 19:10:52 +0200 Subject: [PATCH 01/21] Update Readme file after the release of Element --- README.md | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 251ee3e236..3d5c88ada3 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,32 @@ [![Buildkite](https://badge.buildkite.com/657d3db27364448d69d54f66c690f7788bc6aa80a7628e37f3.svg?branch=develop)](https://buildkite.com/matrix-dot-org/riotx-android/builds?branch=develop) [![Weblate](https://translate.riot.im/widgets/riot-android/-/svg-badge.svg)](https://translate.riot.im/engage/riot-android/?utm_source=widget) -[![RiotX Android Matrix room #riot-android:matrix.org](https://img.shields.io/matrix/riotx:matrix.org.svg?label=%23RiotX:matrix.org&logo=matrix&server_fqdn=matrix.org)](https://matrix.to/#/#riotx:matrix.org) +[![Element Android Matrix room #element-android:matrix.org](https://img.shields.io/matrix/element-android:matrix.org.svg?label=%23element-android:matrix.org&logo=matrix&server_fqdn=matrix.org)](https://matrix.to/#/#element-android:matrix.org) [![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=vector.android.riotx&metric=alert_status)](https://sonarcloud.io/dashboard?id=vector.android.riotx) [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=vector.android.riotx&metric=vulnerabilities)](https://sonarcloud.io/dashboard?id=vector.android.riotx) [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=vector.android.riotx&metric=bugs)](https://sonarcloud.io/dashboard?id=vector.android.riotx) -# RiotX Android +# Element Android -RiotX is an Android Matrix Client currently in beta but in active development. +Element Android is an Android Matrix Client provided by [Element](https://element.io/). -It is a total rewrite of [Riot-Android](https://github.com/vector-im/riot-android) with a new user experience. RiotX will become the official replacement as soon as all features are implemented. +It is a total rewrite of [Riot-Android](https://github.com/vector-im/riot-android) with a new user experience. -[Get it on Google Play](https://play.google.com/store/apps/details?id=im.vector.riotx) -[Get it on F-Droid](https://f-droid.org/app/im.vector.riotx) +[Get it on Google Play](https://play.google.com/store/apps/details?id=im.vector.app) +[Get it on F-Droid](https://f-droid.org/app/im.vector.app) Nightly build: [![Buildkite](https://badge.buildkite.com/657d3db27364448d69d54f66c690f7788bc6aa80a7628e37f3.svg?branch=develop)](https://buildkite.com/matrix-dot-org/riotx-android/builds?branch=develop) # New Android SDK -RiotX is based on a new Android SDK fully written in Kotlin (like RiotX). In order to make the early development as fast as possible, RiotX and the new SDK currently share the same git repository. We will make separate repos once the SDK is stable enough. - +Element is based on a new Android SDK fully written in Kotlin (like Element). In order to make the early development as fast as possible, Element and the new SDK currently share the same git repository. We will make separate repos once the SDK is stable enough. # Roadmap -The current target is to release an application out of beta with the same level of features (and even more) as Riot. -The roadmap has 3 phases: - -- [phase 0](https://github.com/vector-im/riotX-android/labels/phase0): Prototyping / Project setup -- [phase 1](https://github.com/vector-im/riotX-android/labels/phase1): Beta release to the Play Store -- [phase 2](https://github.com/vector-im/riotX-android/labels/phase2): Out of beta - +The version 1.0.0 of Element still misses some features which was previously included in Riot-Android. +The team will work to add them on a regular basis. ## Contributing Please refer to [CONTRIBUTING.md](https://github.com/vector-im/riotX-android/blob/develop/CONTRIBUTING.md) if you want to contribute on Matrix Android projects! -Come chat with the community in the dedicated Matrix [room](https://matrix.to/#/#riotx:matrix.org). +Come chat with the community in the dedicated Matrix [room](https://matrix.to/#/#element-android:matrix.org). From 993c340c4f5367461ec7aba7d0113f530026e2e7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 16 Jul 2020 19:11:33 +0200 Subject: [PATCH 02/21] Update Authors file after the release of Element --- AUTHORS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AUTHORS.md b/AUTHORS.md index d1898a3cf6..3d9dffbef5 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -28,8 +28,8 @@ Even if we try to be able to work on all the functionalities, we have more knowl # Other contributors -First of all, we thank all contributors who use RiotX and report problems on this GitHub project or via the integrated rageshake function. +First of all, we thank all contributors who use Element and report problems on this GitHub project or via the integrated rageshake function. -We do not forget all translators, for their work of translating RiotX into many languages. They are also the authors of RiotX. +We do not forget all translators, for their work of translating Element into many languages. They are also the authors of Element. Feel free to add your name below, when you contribute to the project! From a600e896a05462f4b40c89424d797e7d01acc6b1 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 16 Jul 2020 19:14:20 +0200 Subject: [PATCH 03/21] Update Contributing file after the release of Element --- CONTRIBUTING.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a2126f25d4..e57b5d92fb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,9 +2,7 @@ Please read https://github.com/matrix-org/synapse/blob/master/CONTRIBUTING.md -Android support can be found in this [![Riot Android Matrix room #riot-android:matrix.org](https://img.shields.io/matrix/riot-android:matrix.org.svg?label=%23riot-android:matrix.org&logo=matrix&server_fqdn=matrix.org)](https://matrix.to/#/#riot-android:matrix.org) room. - -Dedicated room for RiotX: [![RiotX Android Matrix room #riot-android:matrix.org](https://img.shields.io/matrix/riotx:matrix.org.svg?label=%23RiotX:matrix.org&logo=matrix&server_fqdn=matrix.org)](https://matrix.to/#/#riotx:matrix.org) +Android support can be found in this [![Element Android Matrix room #element-android:matrix.org](https://img.shields.io/matrix/element-android:matrix.org.svg?label=%23element-android:matrix.org&logo=matrix&server_fqdn=matrix.org)](https://matrix.to/#/#element-android:matrix.org) room. # Specific rules for Matrix Android projects @@ -37,15 +35,13 @@ Note that if the templates are modified, the only things to do is to restart And ## Compilation -For now, the Matrix SDK and the RiotX application are in the same project. So there is no specific thing to do, this project should compile without any special action. +For now, the Matrix SDK and the Element application are in the same project. So there is no specific thing to do, this project should compile without any special action. -## I want to help translating RiotX +## I want to help translating Element If you want to fix an issue with an English string, please submit a PR. If you want to fix an issue in other languages, or add a missing translation, or even add a new language, please use [Weblate](https://translate.riot.im/projects/riot-android/). -For the moment, Strings from Riot will be used, there is no dedicated project in Weblate for RiotX. - ## I want to submit a PR to fix an issue Please check if a corresponding issue exists. If yes, please let us know in a comment that you're working on it. @@ -101,7 +97,7 @@ Make sure the following commands execute without any error: ### Tests -RiotX is currently supported on Android KitKat (API 19+): please test your change on an Android device (or Android emulator) running with API 19. Many issues can happen (including crashes) on older devices. +Element is currently supported on Android Lollipop (API 21+): please test your change on an Android device (or Android emulator) running with API 21. Many issues can happen (including crashes) on older devices. Also, if possible, please test your change on a real device. Testing on Android emulator may not be sufficient. You should consider adding Unit tests with your PR, and also integration tests (AndroidTest). Please refer to [this document](./docs/integration_tests.md) to install and run the integration test environment. @@ -120,7 +116,7 @@ Please consider accessibility as an important point. As a minimum requirement, i When adding or editing layouts, make sure the layout will render correctly if device uses a RTL (Right To Left) language. You can check this in the layout editor preview by selecting any RTL language (ex: Arabic). -Also please check that the colors are ok for all the current themes of RiotX. Please use `?attr` instead of `@color` to reference colors in the layout. You can check this in the layout editor preview by selecting all the main themes (`AppTheme.Status`, `AppTheme.Dark`, etc.). +Also please check that the colors are ok for all the current themes of Element. Please use `?attr` instead of `@color` to reference colors in the layout. You can check this in the layout editor preview by selecting all the main themes (`AppTheme.Status`, `AppTheme.Dark`, etc.). ### Authors From ef93ef57f99c137dcbdadb1edb582187e9cccab8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 16 Jul 2020 19:19:31 +0200 Subject: [PATCH 04/21] Replace Riot -> Element in documentation --- docs/identity_server.md | 6 ++--- docs/notifications.md | 54 ++++++++++++++++++++--------------------- docs/voip_signaling.md | 12 ++++----- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/docs/identity_server.md b/docs/identity_server.md index 04127c9ab0..0d75108dd3 100644 --- a/docs/identity_server.md +++ b/docs/identity_server.md @@ -14,7 +14,7 @@ Difference though (list not exhaustive): - Only API v2 is supported (see https://matrix.org/docs/spec/identity_service/latest) - Homeserver has to be up to date to support binding (Versions.isLoginAndRegistrationSupportedBySdk() has to return true) - The SDK managed the session and client secret when binding ThreePid. Those data are not exposed to the client. -- The SDK supports incremental sendAttempt (this is not used by RiotX) +- The SDK supports incremental sendAttempt (this is not used by Element) - The "Continue" button is now under the information, and not as the same place that the checkbox - The app can cancel a binding. Current data are erased from DB. - The API (IdentityService) is improved. @@ -22,7 +22,7 @@ Difference though (list not exhaustive): Missing features (list not exhaustive): - Invite by 3Pid (will be in a dedicated PR) -- Add email or phone to account (not P1, can be done on Riot-Web) +- Add email or phone to account (not P1, can be done on Element-Web) - List email and phone of the account (could be done in a dedicated PR) - Search contact (not P1) - Logout from identity server when user sign out or deactivate his account. @@ -55,7 +55,7 @@ The list can be found here: https://matrix.org/blog/2019/09/27/privacy-improveme - Default identity server URL, from Wellknown data is proposed to the user. - Identity server can be set -- Identity server can be changed on another user's device, so when the change is detected (thanks to account data sync) RiotX should properly disconnect from a previous identity server (I think it was not the case in Riot-Android, where we keep the token forever) +- Identity server can be changed on another user's device, so when the change is detected (thanks to account data sync) Element should properly disconnect from a previous identity server (I think it was not the case in Riot-Android, where we keep the token forever) - Registration to the identity server is managed with an openId token - Terms of service can be accepted when configuring the identity server. - Terms of service can be accepted after, if they change. diff --git a/docs/notifications.md b/docs/notifications.md index 8efcb87bf3..63bf593d0d 100644 --- a/docs/notifications.md +++ b/docs/notifications.md @@ -1,4 +1,4 @@ -This document aims to describe how RiotX android displays notifications to the end user. It also clarifies notifications and background settings in the app. +This document aims to describe how Element android displays notifications to the end user. It also clarifies notifications and background settings in the app. # Table of Contents 1. [Prerequisites Knowledge](#prerequisites-knowledge) @@ -9,7 +9,7 @@ This document aims to describe how RiotX android displays notifications to the e * [How does the Home Server knows when to notify a client?](#how-does-the-home-server-knows-when-to-notify-a-client) * [Push vs privacy, and mitigation](#push-vs-privacy-and-mitigation) * [Background processing limitations](#background-processing-limitations) -2. [RiotX Notification implementations](#riotx-notification-implementations) +2. [Element Notification implementations](#element-notification-implementations) * [Requirements](#requirements) * [Foreground sync mode (Gplay & F-Droid)](#foreground-sync-mode-gplay-f-droid) * [Push (FCM) received in background](#push-fcm-received-in-background) @@ -50,7 +50,7 @@ By default, this is 0, so the server will return immediately even if the respons **delay** is a client preference. When the server responds to a sync request, the client waits for `delay`before calling a new sync. -When the RiotX Android app is open (i.e in foreground state), the default timeout is 30 seconds, and delay is 0. +When the Element Android app is open (i.e in foreground state), the default timeout is 30 seconds, and delay is 0. ## How does a mobile app receives push notification @@ -86,7 +86,7 @@ This need some disambiguation, because it is the source of common confusion: In order to send a push to a mobile, App developers need to have a server that will use the FCM APIs, and these APIs requires authentication! This server is called a **Push Gateway** in the matrix world -That means that RiotX Android, a matrix client created by New Vector, is using a **Push Gateway** with the needed credentials (FCM API secret Key) in order to send push to the New Vector client. +That means that Element Android, a matrix client created by New Vector, is using a **Push Gateway** with the needed credentials (FCM API secret Key) in order to send push to the New Vector client. If you create your own matrix client, you will also need to deploy an instance of a **Push Gateway** with the credentials needed to use FCM for your app. @@ -132,7 +132,7 @@ A Home Server can be configured with default rules (for Direct messages, group m There are different kind of push rules, it can be per room (each new message on this room should be notified), it can also define a pattern that a message should match (when you are mentioned, or key word based). -Notifications have 2 'levels' (`highlighted = true/false sound = default/custom`). In RiotX these notifications level are reflected as Noisy/Silent. +Notifications have 2 'levels' (`highlighted = true/false sound = default/custom`). In Element these notifications level are reflected as Noisy/Silent. **What about encrypted messages?** @@ -158,7 +158,7 @@ In a nutshell, apps can't do much in background now. If the devices is not plugged and stays IDLE for a certain amount of time, radio (mobile connectivity) and CPU can/will be turned off. -For an application like RiotX, where users can receive important information at anytime, the best option is to rely on a push system (Google's Firebase Message a.k.a FCM). FCM high priority push can wake up the device and whitelist an application to perform background task (for a limited but unspecified amount of time). +For an application like Element, where users can receive important information at anytime, the best option is to rely on a push system (Google's Firebase Message a.k.a FCM). FCM high priority push can wake up the device and whitelist an application to perform background task (for a limited but unspecified amount of time). Notice that this is still evolving, and in future versions application that has been 'background restricted' by users won't be able to wake up even when a high priority push is received. Also high priority notifications could be rate limited (not defined anywhere) @@ -167,41 +167,41 @@ The documentation on this subject is vague, and as per our experiments not alway It is getting more and more complex to have reliable notifications when FCM is not used. -# RiotX Notification implementations +# Element Notification implementations ## Requirements -RiotX Android must work with and without FCM. -* The RiotX android app published on F-Droid do not rely on FCM (all related dependencies are not present) -* The RiotX android app published on google play rely on FCM, with a fallback mode when FCM registration has failed (e.g outdated or missing Google Play Services) +Element Android must work with and without FCM. +* The Element android app published on F-Droid do not rely on FCM (all related dependencies are not present) +* The Element android app published on google play rely on FCM, with a fallback mode when FCM registration has failed (e.g outdated or missing Google Play Services) ## Foreground sync mode (Gplay & F-Droid) -When in foreground, RiotX performs sync continuously with a timeout value set to 10 seconds (see HttpPooling). +When in foreground, Element performs sync continuously with a timeout value set to 10 seconds (see HttpPooling). -As this mode does not need to live beyond the scope of the application, and as per Google recommendation, RiotX uses the internal app resources (Thread and Timers) to perform the syncs. +As this mode does not need to live beyond the scope of the application, and as per Google recommendation, Element uses the internal app resources (Thread and Timers) to perform the syncs. This mode is turned on when the app enters foreground, and off when enters background. -In background, and depending on wether push is available or not, RiotX will use different methods to perform the syncs (Workers / Alarms / Service) +In background, and depending on wether push is available or not, Element will use different methods to perform the syncs (Workers / Alarms / Service) ## Push (FCM) received in background -In order to enable Push, RiotX must first get a push token from the firebase SDK, then register a pusher with this token on the HomeServer. +In order to enable Push, Element must first get a push token from the firebase SDK, then register a pusher with this token on the HomeServer. -When a message should be notified to a user, the user's homeserver notifies the registered `push gateway` for RiotX, that is [sygnal](https://github.com/matrix-org/sygnal) _- The reference implementation for push gateways -_ hosted by matrix.org. +When a message should be notified to a user, the user's homeserver notifies the registered `push gateway` for Element, that is [sygnal](https://github.com/matrix-org/sygnal) _- The reference implementation for push gateways -_ hosted by matrix.org. -This sygnal instance is configured with the required FCM API authentication token, and will then use the FCM API in order to notify the user's device running riotX. +This sygnal instance is configured with the required FCM API authentication token, and will then use the FCM API in order to notify the user's device running Element. ``` -Homeserver ----> Sygnal (configured for RiotX) ----> FCM ----> RiotX +Homeserver ----> Sygnal (configured for Element) ----> FCM ----> Element ``` The push gateway is configured to only send `(eventId,roomId)` in the push payload (for better [privacy](#push-vs-privacy-and-mitigation)). -RiotX needs then to synchronise with the user's HomeServer, in order to resolve the event and create a notification. +Element needs then to synchronise with the user's HomeServer, in order to resolve the event and create a notification. -As per [Google recommendation](https://android-developers.googleblog.com/2018/09/notifying-your-users-with-fcm.html), RiotX will then use the WorkManager API in order to trigger a background sync. +As per [Google recommendation](https://android-developers.googleblog.com/2018/09/notifying-your-users-with-fcm.html), Element will then use the WorkManager API in order to trigger a background sync. **Google recommendations:** > We recommend using FCM messages in combination with the WorkManager 1 or JobScheduler API @@ -209,7 +209,7 @@ As per [Google recommendation](https://android-developers.googleblog.com/2018/09 > Avoid background services. One common pitfall is using a background service to fetch data in the FCM message handler, since background service will be stopped by the system per recent changes to Google Play Policy ``` -Homeserver ----> Sygnal ----> FCM ----> RiotX +Homeserver ----> Sygnal ----> FCM ----> Element (Sync) ----> Homeserver <---- Display notification @@ -217,24 +217,24 @@ Homeserver ----> Sygnal ----> FCM ----> RiotX **Possible outcomes** -Upon reception of the FCM push, RiotX will perform a sync call to the Home Server, during this process it is possible that: +Upon reception of the FCM push, Element will perform a sync call to the Home Server, during this process it is possible that: * Happy path, the sync is performed, the message resolved and displayed in the notification drawer * The notified message is not in the sync. Can happen if a lot of things did happen since the push (`gappy sync`) * The sync generates additional notifications (e.g an encrypted message where the user is mentioned detected locally) * The sync takes too long and the process is killed before completion, or network is not reliable and the sync fails. -RiotX implements several strategies in these cases (TODO document) +Element implements several strategies in these cases (TODO document) ## FCM Fallback mode -It is possible that RiotX is not able to get a FCM push token. +It is possible that Element is not able to get a FCM push token. Common errors (amoung several others) that can cause that: * Google Play Services is outdated * Google Play Service fails in someways with FCM servers (infamous `SERVICE_NOT_AVAILABLE`) -If RiotX is able to detect one of this cases, it will notifies it to the users and when possible help him fix it via a dedicated troubleshoot screen. +If Element is able to detect one of this cases, it will notifies it to the users and when possible help him fix it via a dedicated troubleshoot screen. -Meanwhile, in order to offer a minimal service, and as per Google's recommendation for background activities, RiotX will launch periodic background sync in order to stays in sync with servers. +Meanwhile, in order to offer a minimal service, and as per Google's recommendation for background activities, Element will launch periodic background sync in order to stays in sync with servers. The fallback mode is impacted by all the battery life saving mechanism implemented by android. Meaning that if the app is not used for a certain amount of time (`App-Standby`), or the device stays still and unplugged (`Light Doze`) , the sync will become less frequent. @@ -248,7 +248,7 @@ The fallback mode is supposed to be a temporary state waiting for the user to fi ## F-Droid background Mode -The F-Droid RiotX flavor has no dependencies to FCM, therefore cannot relies on Push. +The F-Droid Element flavor has no dependencies to FCM, therefore cannot relies on Push. Also Google's recommended background processing method cannot be applied. This is because all of these methods are affected by IDLE modes, and will result on the user not being notified at all when the app is in a Doze mode (only in maintenance windows that could happens only after hours). @@ -262,7 +262,7 @@ F-Droid version will schedule alarms that will then trigger a Broadcast Receiver Depending on the system status (or device make), it is still possible that the app is not given enough time to launch the service, or that the radio is still turned off thus preventing the sync to success (that's why Alarms are not recommended for network related tasks). -That is why on RiotX F-Droid, the broadcast receiver will acquire a temporary WAKE_LOCK for several seconds (thus securing cpu/network), and launch the service in foreground. The service performs the sync. +That is why on Element F-Droid, the broadcast receiver will acquire a temporary WAKE_LOCK for several seconds (thus securing cpu/network), and launch the service in foreground. The service performs the sync. Note that foreground services require to put a notification informing the user that the app is doing something even if not launched). diff --git a/docs/voip_signaling.md b/docs/voip_signaling.md index e055b4cd35..c6e5b97177 100644 --- a/docs/voip_signaling.md +++ b/docs/voip_signaling.md @@ -26,7 +26,7 @@ Useful links: │ │ │ │ │ mx event │ │ │ │ │ │ │ └────────────────────┘ │ │ │ │ │ │ │ │ │ │ │ - │ Riot.im │ │ │ │ │ Riot.im │ + │ Element │ │ │ │ │ Element │ ┌──│ App │ │ │ │ │ App │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ @@ -103,7 +103,7 @@ Useful links: │ │ ┌────┐ │ │ └────────────────────┘ │ │ │ │ │ │ 3 │ │ ┌────────────────────┐ │ │ │ │ │ │──────┴────┴───────┼──────────────────┼─▶│ m.call.candidates │ │ │ │ - │ Riot.im │ │ │ mx event │ │ │ │ Riot.im │ + │ Element │ │ │ mx event │ │ │ │ Element │ │ App │ │ │ └────────────────────┘ │ │ App │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ @@ -195,9 +195,9 @@ Useful links: │ │ │ m.call.invite │───┼────────────────────────────┬────┬───▶│ │ ┌─────────────────┐ │ │ mx event │ │ │ │ 1 │ │ │ │ │ │ │ └────────────────────┘ │ └────┘ │ │ - │ │ │ ┌────────────────────┐ │ │ │ Riot.im │ + │ │ │ ┌────────────────────┐ │ │ │ Element │ │ │ │ │ │ m.call.candidates │ │ │ App │ - │ Riot.im │ │ │ mx event │ │ │ │ │ + │ Element │ │ │ mx event │ │ │ │ │ │ App │ │ │ └────────────────────┘ │ │ │ │ │ │ ┌────────────────────┐◀──┼─────────────────┼───┬────┬───────────┤ │ │ │◀──────────────────┼──────────────────┼──│ m.call.answer │ │ │ 4 │ └──┬──────────────┘ @@ -275,7 +275,7 @@ Useful links: │ │ │ │ └────────────────────┘ │ │ │ │ │ │ ┌────────────────────┐ │ │ │ │ │ │ │ │ │ m.call.candidates │ │ │ │ - │ Riot.im │ │ │ mx event │ │ │ │ Riot.im │ + │ Element │ │ │ mx event │ │ │ │ Element │ │ App │ │ │ └────────────────────┘ │ ┌────┐ │ App │ │ │ │ ┌────────────────────┐ │ │ │ 3 │ │ │ │ │◀──────────────────┼┐ │ │ m.call.answer │ │ ┌───────┴────┴────────│ │ @@ -370,7 +370,7 @@ Useful links: │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ - │ Riot.im │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ Riot.im │ + │ Element │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ Element │ │ App │ │ App │ │ │ │ │ │ │ │ │ From d78cd81c6fb2cf93d5b51c7b748eaf0898e4f2fe Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 16 Jul 2020 19:21:02 +0200 Subject: [PATCH 05/21] Cleanup strings.xml --- vector/src/main/res/values/strings.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index a3c69a772c..ea737e5e30 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1599,7 +1599,6 @@ Why choose Element? It looks like you’re trying to connect to another homeserver. Do you want to sign out? - Edit Reply @@ -1703,7 +1702,6 @@ Why choose Element? Show hidden events in timeline - Element - Next Generation Matrix Client A faster and lighter client for Matrix using the latest Android frameworks "Element is a new client for the Matrix protocol (Matrix.org): an open network for secure, decentralised communication. Element is a full rewrite of the Riot Android client, based on a full rewrite of the Matrix Android SDK. @@ -2417,7 +2415,7 @@ Not all features in Riot are implemented in Element yet. Main missing (and comin Generating SSSS key from passphrase (%s) Generating SSSS key from recovery key Storing keybackup secret in SSSS - + %1$s (%2$s) Enter your Key Backup Passphrase to continue. From 6e0095edb080f0b5a6c382c6ce9f5d369e84b6b1 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 17 Jul 2020 13:31:36 +0200 Subject: [PATCH 06/21] Feature/fix notification clearing (#1707) Updating notification when entering a room --- CHANGES.md | 1 + .../features/notifications/NotificationDrawerManager.kt | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index b45ad9dff8..0099412196 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ Improvements 🙌: Bugfix 🐛: - Fix theme issue on Room directory screen (#1613) + - Fix notification not dismissing when entering a room Translations 🗣: - diff --git a/vector/src/main/java/im/vector/riotx/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/riotx/features/notifications/NotificationDrawerManager.kt index d0839795dd..f7085a000e 100644 --- a/vector/src/main/java/im/vector/riotx/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/riotx/features/notifications/NotificationDrawerManager.kt @@ -155,14 +155,17 @@ class NotificationDrawerManager @Inject constructor(private val context: Context /** Clear all known message events for this room */ fun clearMessageEventOfRoom(roomId: String?) { Timber.v("clearMessageEventOfRoom $roomId") - if (roomId != null) { + var shouldUpdate = false synchronized(eventList) { - eventList.removeAll { e -> + shouldUpdate = eventList.removeAll { e -> e is NotifiableMessageEvent && e.roomId == roomId } } - refreshNotificationDrawer() + if (shouldUpdate) { + notificationUtils.cancelNotificationMessage(roomId, ROOM_MESSAGES_NOTIFICATION_ID) + refreshNotificationDrawer() + } } } From 5082defddf96d719ac4677852c5f7d863faae376 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 17 Jul 2020 17:23:48 +0200 Subject: [PATCH 07/21] i18n deactivated account error --- CHANGES.md | 2 +- .../main/java/im/vector/riotx/core/error/ErrorFormatter.kt | 5 ++++- vector/src/main/res/values/strings.xml | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 0099412196..b2ef53ff57 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,7 +21,7 @@ Build 🧱: - Other changes: - - + - i18n deactivated account error Changes in Element 1.0.0 (2020-07-15) =================================================== diff --git a/vector/src/main/java/im/vector/riotx/core/error/ErrorFormatter.kt b/vector/src/main/java/im/vector/riotx/core/error/ErrorFormatter.kt index 907107c90b..e33f19a59c 100644 --- a/vector/src/main/java/im/vector/riotx/core/error/ErrorFormatter.kt +++ b/vector/src/main/java/im/vector/riotx/core/error/ErrorFormatter.kt @@ -51,7 +51,7 @@ class DefaultErrorFormatter @Inject constructor( stringProvider.getString(R.string.login_error_unknown_host) is SSLPeerUnverifiedException -> stringProvider.getString(R.string.login_error_ssl_peer_unverified) - is SSLException -> + is SSLException -> stringProvider.getString(R.string.login_error_ssl_other) else -> stringProvider.getString(R.string.error_no_network) @@ -84,6 +84,9 @@ class DefaultErrorFormatter @Inject constructor( throwable.error.code == MatrixError.M_THREEPID_NOT_FOUND -> { stringProvider.getString(R.string.login_reset_password_error_not_found) } + throwable.error.code == MatrixError.M_USER_DEACTIVATED -> { + stringProvider.getString(R.string.auth_invalid_login_deactivated_account) + } else -> { throwable.error.message.takeIf { it.isNotEmpty() } ?: throwable.error.code.takeIf { it.isNotEmpty() } diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index a3c69a772c..0f9941e64c 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2392,6 +2392,7 @@ Not all features in Riot are implemented in Element yet. Main missing (and comin Sends a message as plain text, without interpreting it as markdown Incorrect username and/or password. The entered password starts or ends with spaces, please check it. + This account has been deactivated. Message… From 27207a27aee187e036003ca29eba1bb4c90c3444 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 17 Jul 2020 20:16:27 +0200 Subject: [PATCH 08/21] Fix "uploads don't work with Room v6" #1558 --- CHANGES.md | 1 + matrix-sdk-android/build.gradle | 6 ++- .../internal/network/RetrofitFactory.kt | 2 + .../android/internal/session/room/RoomAPI.kt | 15 ++++++ .../session/room/send/DefaultSendService.kt | 6 --- .../session/room/send/SendEventWorker.kt | 47 ++++++++++++------- 6 files changed, 52 insertions(+), 25 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 0099412196..004c999246 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ Improvements 🙌: Bugfix 🐛: - Fix theme issue on Room directory screen (#1613) - Fix notification not dismissing when entering a room + - Fix uploads don't work with Room v6 (#1558) Translations 🗣: - diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 71b763545c..a96e0690dc 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -116,6 +116,7 @@ dependencies { def markwon_version = '3.1.0' def daggerVersion = '2.25.4' def work_version = '2.3.3' + def retrofit_version = '2.6.2' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" @@ -128,8 +129,9 @@ dependencies { implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" // Network - implementation 'com.squareup.retrofit2:retrofit:2.6.2' - implementation 'com.squareup.retrofit2:converter-moshi:2.6.2' + implementation "com.squareup.retrofit2:retrofit:$retrofit_version" + implementation "com.squareup.retrofit2:converter-moshi:$retrofit_version" + implementation "com.squareup.retrofit2:converter-scalars:$retrofit_version" implementation 'com.squareup.okhttp3:okhttp:4.2.2' implementation 'com.squareup.okhttp3:logging-interceptor:4.2.2' implementation "com.squareup.moshi:moshi-adapters:$moshi_version" diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/RetrofitFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/RetrofitFactory.kt index 0b087d7a1a..9da7b1f488 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/RetrofitFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/RetrofitFactory.kt @@ -24,6 +24,7 @@ import okhttp3.OkHttpClient import okhttp3.Request import retrofit2.Retrofit import retrofit2.converter.moshi.MoshiConverterFactory +import retrofit2.converter.scalars.ScalarsConverterFactory import javax.inject.Inject internal class RetrofitFactory @Inject constructor(private val moshi: Moshi) { @@ -48,6 +49,7 @@ internal class RetrofitFactory @Inject constructor(private val moshi: Moshi) { return okHttpClient.get().newCall(request) } }) + .addConverterFactory(ScalarsConverterFactory.create()) .addConverterFactory(UnitConverterFactory) .addConverterFactory(MoshiConverterFactory.create(moshi)) .build() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAPI.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAPI.kt index fd16b1891e..14090ab62f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAPI.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAPI.kt @@ -129,6 +129,21 @@ internal interface RoomAPI { @Body content: Content? ): Call + /** + * Send an event to a room. + * + * @param txId the transaction Id + * @param roomId the room id + * @param eventType the event type + * @param content the event content as string + */ + @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/send/{eventType}/{txId}") + fun send(@Path("txId") txId: String, + @Path("roomId") roomId: String, + @Path("eventType") eventType: String, + @Body content: String? + ): Call + /** * Get the context surrounding an event. * diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt index b4593bc71b..6db44314e5 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt @@ -282,12 +282,6 @@ internal class DefaultSendService @AssistedInject constructor( } } - private fun createSendEventWork(event: Event, startChain: Boolean): OneTimeWorkRequest { - return SendEventWorker.Params(sessionId, event) - .let { WorkerParamsFactory.toData(it) } - .let { timelineSendEventWorkCommon.createWork(it, startChain) } - } - private fun createRedactEventWork(event: Event, reason: String?): OneTimeWorkRequest { return localEchoEventFactory.createRedactEvent(roomId, event.eventId!!, reason) .also { createLocalEcho(it) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt index d55b9665f6..2cfdc22aae 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt @@ -23,6 +23,7 @@ import com.squareup.moshi.JsonClass import im.vector.matrix.android.api.failure.shouldBeRetried import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.room.send.SendState +import im.vector.matrix.android.internal.database.mapper.ContentMapper import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.session.room.RoomAPI import im.vector.matrix.android.internal.worker.SessionWorkerParams @@ -43,9 +44,24 @@ internal class SendEventWorker(context: Context, @JsonClass(generateAdapter = true) internal data class Params( override val sessionId: String, - val event: Event, + //TODO remove after some time, it's used for compat + val event: Event? = null, + val eventId: String? = null, + val roomId: String? = null, + val type: String? = null, + val contentStr: String? = null, override val lastFailureMessage: String? = null - ) : SessionWorkerParams + ) : SessionWorkerParams { + + constructor(sessionId: String, event: Event, lastFailureMessage: String? = null) : this( + sessionId = sessionId, + eventId = event.eventId, + roomId = event.roomId, + type = event.type, + contentStr = ContentMapper.map(event.content), + lastFailureMessage = lastFailureMessage + ) + } @Inject lateinit var localEchoUpdater: LocalEchoUpdater @Inject lateinit var roomAPI: RoomAPI @@ -59,41 +75,38 @@ internal class SendEventWorker(context: Context, val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success() sessionComponent.inject(this) - val event = params.event - if (event.eventId == null) { + if (params.eventId == null || params.roomId == null || params.type == null) { + // compat with old params, make it fail if any + if (params.event?.eventId != null) { + localEchoUpdater.updateSendState(params.event.eventId, SendState.UNDELIVERED) + } return Result.success() } - if (params.lastFailureMessage != null) { - localEchoUpdater.updateSendState(event.eventId, SendState.UNDELIVERED) + localEchoUpdater.updateSendState(params.eventId, SendState.UNDELIVERED) // Transmit the error return Result.success(inputData) .also { Timber.e("Work cancelled due to input error from parent") } } return try { - sendEvent(event) + sendEvent(params.eventId, params.roomId, params.type, params.contentStr) Result.success() } catch (exception: Throwable) { if (exception.shouldBeRetried()) { Result.retry() } else { - localEchoUpdater.updateSendState(event.eventId, SendState.UNDELIVERED) + localEchoUpdater.updateSendState(params.eventId, SendState.UNDELIVERED) // always return success, or the chain will be stuck for ever! Result.success() } } } - private suspend fun sendEvent(event: Event) { - localEchoUpdater.updateSendState(event.eventId!!, SendState.SENDING) + private suspend fun sendEvent(eventId: String, roomId: String, type: String, contentStr: String?) { + localEchoUpdater.updateSendState(eventId, SendState.SENDING) executeRequest(eventBus) { - apiCall = roomAPI.send( - event.eventId, - event.roomId!!, - event.type, - event.content - ) + apiCall = roomAPI.send(eventId, roomId, type, contentStr) } - localEchoUpdater.updateSendState(event.eventId, SendState.SENT) + localEchoUpdater.updateSendState(eventId, SendState.SENT) } } From 0d51c160ebb7e918745b9704be0160fdcba57102 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 20 Jul 2020 16:42:56 +0200 Subject: [PATCH 09/21] Should fix realm crash loop --- .../database/EventInsertLiveObserver.kt | 24 ++++++++++++++----- .../database/RealmLiveEntityObserver.kt | 3 ++- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/EventInsertLiveObserver.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/EventInsertLiveObserver.kt index 98d8806288..8913aa784a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/EventInsertLiveObserver.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/EventInsertLiveObserver.kt @@ -24,6 +24,7 @@ import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResu import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventInsertEntity +import im.vector.matrix.android.internal.database.model.EventInsertEntityFields import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.di.SessionDatabase import im.vector.matrix.android.internal.session.EventInsertLiveProcessor @@ -46,17 +47,25 @@ internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase real if (!results.isLoaded || results.isEmpty()) { return } + val idsToDeleteAfterProcess = ArrayList() + val filteredEvents = ArrayList(results.size) Timber.v("EventInsertEntity updated with ${results.size} results in db") - val filteredEvents = results.mapNotNull { + results.forEach { if (shouldProcess(it)) { - results.realm.copyFromRealm(it) - } else { - null + // don't use copy from realm over there + val copiedEvent = EventInsertEntity( + eventId = it.eventId, + eventType = it.eventType + ).apply { + insertType = it.insertType + } + filteredEvents.add(copiedEvent) } + idsToDeleteAfterProcess.add(it.eventId) } - Timber.v("There are ${filteredEvents.size} events to process") observerScope.launch { awaitTransaction(realmConfiguration) { realm -> + Timber.v("##Transaction: There are ${filteredEvents.size} events to process ") filteredEvents.forEach { eventInsert -> val eventId = eventInsert.eventId val event = EventEntity.where(realm, eventId).findFirst() @@ -72,7 +81,10 @@ internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase real it.process(realm, domainEvent) } } - realm.delete(EventInsertEntity::class.java) + realm.where(EventInsertEntity::class.java) + .`in`(EventInsertEntityFields.EVENT_ID, idsToDeleteAfterProcess.toTypedArray()) + .findAll() + .deleteAllFromRealm() } } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/RealmLiveEntityObserver.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/RealmLiveEntityObserver.kt index 3f0dc4cddd..fe79833708 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/RealmLiveEntityObserver.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/RealmLiveEntityObserver.kt @@ -26,6 +26,7 @@ import io.realm.RealmObject import io.realm.RealmResults import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.android.asCoroutineDispatcher import kotlinx.coroutines.cancelChildren import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicReference @@ -39,7 +40,7 @@ internal abstract class RealmLiveEntityObserver(protected val r val BACKGROUND_HANDLER = createBackgroundHandler("LIVE_ENTITY_BACKGROUND") } - protected val observerScope = CoroutineScope(SupervisorJob()) + protected val observerScope = CoroutineScope(SupervisorJob() + BACKGROUND_HANDLER.asCoroutineDispatcher()) protected abstract val query: Monarchy.Query private val isStarted = AtomicBoolean(false) private val backgroundRealm = AtomicReference() From a488e88f9363b12a6c13b6006771d26281ec26b2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 20 Jul 2020 16:49:05 +0200 Subject: [PATCH 10/21] Add reaction to RoomSummary latest previewable event --- .../session/room/summary/RoomSummaryUpdater.kt | 1 + .../timeline/format/DisplayableEventFormatter.kt | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/summary/RoomSummaryUpdater.kt index ea2948c11f..d61ebc4fc1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/summary/RoomSummaryUpdater.kt @@ -75,6 +75,7 @@ internal class RoomSummaryUpdater @Inject constructor( EventType.STATE_ROOM_ENCRYPTION, EventType.STATE_ROOM_THIRD_PARTY_INVITE, EventType.STICKER, + EventType.REACTION, EventType.STATE_ROOM_CREATE ) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt index c931c155b1..0043cc10c5 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt @@ -17,11 +17,14 @@ package im.vector.riotx.features.home.room.detail.timeline.format import im.vector.matrix.android.api.session.events.model.EventType +import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.message.MessageType import im.vector.matrix.android.api.session.room.model.message.isReply +import im.vector.matrix.android.api.session.room.model.relation.ReactionContent import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent import im.vector.matrix.android.api.session.room.timeline.getTextEditableContent +import im.vector.riotx.EmojiCompatWrapper import im.vector.riotx.R import im.vector.riotx.core.resources.ColorProvider import im.vector.riotx.core.resources.StringProvider @@ -31,6 +34,7 @@ import javax.inject.Inject class DisplayableEventFormatter @Inject constructor( private val stringProvider: StringProvider, private val colorProvider: ColorProvider, + private val emojiCompatWrapper: EmojiCompatWrapper, private val noticeEventFormatter: NoticeEventFormatter ) { @@ -47,10 +51,16 @@ class DisplayableEventFormatter @Inject constructor( val senderName = timelineEvent.senderInfo.disambiguatedDisplayName when (timelineEvent.root.getClearType()) { - EventType.STICKER -> { + EventType.STICKER -> { return simpleFormat(senderName, stringProvider.getString(R.string.send_a_sticker), appendAuthor) } - EventType.MESSAGE -> { + EventType.REACTION -> { + timelineEvent.root.getClearContent().toModel()?.relatesTo?.let { + val emojiSpanned = emojiCompatWrapper.safeEmojiSpanify(it.key) + return simpleFormat(senderName, emojiSpanned, appendAuthor) + } + } + EventType.MESSAGE -> { timelineEvent.getLastMessageContent()?.let { messageContent -> when (messageContent.msgType) { MessageType.MSGTYPE_VERIFICATION_REQUEST -> { @@ -84,7 +94,7 @@ class DisplayableEventFormatter @Inject constructor( } } } - else -> { + else -> { return span { text = noticeEventFormatter.format(timelineEvent) ?: "" textStyle = "italic" From 35fe4f72684969f3ad9ec3c2ce49aab0daa6fb2a Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 20 Jul 2020 18:47:41 +0200 Subject: [PATCH 11/21] Fix modular link to EMS --- .../im/vector/riotx/features/login/Config.kt | 6 +++--- .../riotx/features/login/LoginActivity.kt | 2 +- .../riotx/features/login/LoginFragment.kt | 2 +- .../login/LoginServerSelectionFragment.kt | 12 +++++------ .../login/LoginServerUrlFormFragment.kt | 6 +++--- .../LoginSignUpSignInSelectionFragment.kt | 2 +- .../riotx/features/login/LoginViewModel.kt | 2 +- .../vector/riotx/features/login/ServerType.kt | 2 +- .../fragment_login_server_selection.xml | 20 +++++++++---------- 9 files changed, 27 insertions(+), 27 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/login/Config.kt b/vector/src/main/java/im/vector/riotx/features/login/Config.kt index 66db981b1c..0f12947dcb 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/Config.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/Config.kt @@ -16,7 +16,7 @@ package im.vector.riotx.features.login -const val MODULAR_LINK = "https://modular.im/services/matrix-hosting-riot" + - "?utm_source=riot-x-android" + +const val EMS_LINK = "https://element.io/matrix-services" + + "?utm_source=element-android" + "&utm_medium=native" + - "&utm_campaign=riot-x-android-authentication" + "&utm_campaign=element-android-authentication" diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginActivity.kt index f71b0ecba4..845e628bc6 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginActivity.kt @@ -231,7 +231,7 @@ open class LoginActivity : VectorBaseActivity(), ToolbarConfigurable { private fun onServerSelectionDone(loginViewEvents: LoginViewEvents.OnServerSelectionDone) { when (loginViewEvents.serverType) { ServerType.MatrixOrg -> Unit // In this case, we wait for the login flow - ServerType.Modular, + ServerType.EMS, ServerType.Other -> addFragmentToBackstack(R.id.loginFragmentContainer, LoginServerUrlFormFragment::class.java, option = commonOption) diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt index b7de44aa24..6f032120b7 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt @@ -155,7 +155,7 @@ class LoginFragment @Inject constructor() : AbstractLoginFragment() { loginTitle.text = getString(resId, state.homeServerUrl.toReducedUrl()) loginNotice.text = getString(R.string.login_server_matrix_org_text) } - ServerType.Modular -> { + ServerType.EMS -> { loginServerIcon.isVisible = true loginServerIcon.setImageResource(R.drawable.ic_logo_element_matrix_services) loginTitle.text = getString(resId, "Element Matrix Services") diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginServerSelectionFragment.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginServerSelectionFragment.kt index 3a1bba7f11..5eef820e39 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginServerSelectionFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginServerSelectionFragment.kt @@ -43,15 +43,15 @@ class LoginServerSelectionFragment @Inject constructor() : AbstractLoginFragment } private fun initTextViews() { - loginServerChoiceModularLearnMore.text = span { + loginServerChoiceEMSLearnMore.text = span { text = getString(R.string.login_server_modular_learn_more) textDecorationLine = "underline" } } - @OnClick(R.id.loginServerChoiceModularLearnMore) + @OnClick(R.id.loginServerChoiceEMSLearnMore) fun learnMore() { - openUrlInChromeCustomTab(requireActivity(), null, MODULAR_LINK) + openUrlInChromeCustomTab(requireActivity(), null, EMS_LINK) } @OnClick(R.id.loginServerChoiceMatrixOrg) @@ -59,9 +59,9 @@ class LoginServerSelectionFragment @Inject constructor() : AbstractLoginFragment loginViewModel.handle(LoginAction.UpdateServerType(ServerType.MatrixOrg)) } - @OnClick(R.id.loginServerChoiceModular) - fun selectModular() { - loginViewModel.handle(LoginAction.UpdateServerType(ServerType.Modular)) + @OnClick(R.id.loginServerChoiceEMS) + fun selectEMS() { + loginViewModel.handle(LoginAction.UpdateServerType(ServerType.EMS)) } @OnClick(R.id.loginServerChoiceOther) diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginServerUrlFormFragment.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginServerUrlFormFragment.kt index 980525363a..b5c19d779a 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginServerUrlFormFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginServerUrlFormFragment.kt @@ -62,7 +62,7 @@ class LoginServerUrlFormFragment @Inject constructor() : AbstractLoginFragment() private fun setupUi(state: LoginViewState) { when (state.serverType) { - ServerType.Modular -> { + ServerType.EMS -> { loginServerUrlFormIcon.isVisible = true loginServerUrlFormTitle.text = getString(R.string.login_connect_to_modular) loginServerUrlFormText.text = getString(R.string.login_server_url_form_modular_text) @@ -70,7 +70,7 @@ class LoginServerUrlFormFragment @Inject constructor() : AbstractLoginFragment() loginServerUrlFormHomeServerUrlTil.hint = getText(R.string.login_server_url_form_modular_hint) loginServerUrlFormNotice.text = getString(R.string.login_server_url_form_common_notice) } - else -> { + else -> { loginServerUrlFormIcon.isVisible = false loginServerUrlFormTitle.text = getString(R.string.login_server_other_title) loginServerUrlFormText.text = getString(R.string.login_connect_to_a_custom_server) @@ -83,7 +83,7 @@ class LoginServerUrlFormFragment @Inject constructor() : AbstractLoginFragment() @OnClick(R.id.loginServerUrlFormLearnMore) fun learnMore() { - openUrlInChromeCustomTab(requireActivity(), null, MODULAR_LINK) + openUrlInChromeCustomTab(requireActivity(), null, EMS_LINK) } override fun resetViewModel() { diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginSignUpSignInSelectionFragment.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginSignUpSignInSelectionFragment.kt index d0b814b6d5..7b0ba7b1f9 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginSignUpSignInSelectionFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginSignUpSignInSelectionFragment.kt @@ -38,7 +38,7 @@ open class LoginSignUpSignInSelectionFragment @Inject constructor() : AbstractLo loginSignupSigninTitle.text = getString(R.string.login_connect_to, state.homeServerUrl.toReducedUrl()) loginSignupSigninText.text = getString(R.string.login_server_matrix_org_text) } - ServerType.Modular -> { + ServerType.EMS -> { loginSignupSigninServerIcon.setImageResource(R.drawable.ic_logo_element_matrix_services) loginSignupSigninServerIcon.isVisible = true loginSignupSigninTitle.text = getString(R.string.login_connect_to_modular) diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt index 071e23c252..bb04fef685 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt @@ -410,7 +410,7 @@ class LoginViewModel @AssistedInject constructor( ServerType.MatrixOrg -> // Request login flow here handle(LoginAction.UpdateHomeServer(matrixOrgUrl)) - ServerType.Modular, + ServerType.EMS, ServerType.Other -> _viewEvents.post(LoginViewEvents.OnServerSelectionDone(action.serverType)) }.exhaustive } diff --git a/vector/src/main/java/im/vector/riotx/features/login/ServerType.kt b/vector/src/main/java/im/vector/riotx/features/login/ServerType.kt index 50dfee19f0..058a052059 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/ServerType.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/ServerType.kt @@ -19,6 +19,6 @@ package im.vector.riotx.features.login enum class ServerType { Unknown, MatrixOrg, - Modular, + EMS, Other } diff --git a/vector/src/main/res/layout/fragment_login_server_selection.xml b/vector/src/main/res/layout/fragment_login_server_selection.xml index fe38f46828..4eea427bfc 100644 --- a/vector/src/main/res/layout/fragment_login_server_selection.xml +++ b/vector/src/main/res/layout/fragment_login_server_selection.xml @@ -86,7 +86,7 @@ + app:layout_constraintTop_toBottomOf="@+id/loginServerChoiceEMSIcon" /> + app:layout_constraintTop_toTopOf="@+id/loginServerChoiceEMSText" /> @@ -150,7 +150,7 @@ android:paddingEnd="@dimen/layout_horizontal_margin" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/loginServerChoiceModular"> + app:layout_constraintTop_toBottomOf="@+id/loginServerChoiceEMS"> Date: Mon, 20 Jul 2020 19:52:24 +0200 Subject: [PATCH 12/21] Rework a bit user account data (and avoid blocking syncs) --- .../java/im/vector/matrix/rx/RxSession.kt | 5 +- .../internal/crypto/ssss/QuadSTests.kt | 2 +- .../session/accountdata/AccountDataService.kt | 1 - .../accountdata/UserAccountDataEvent.kt} | 16 +++--- .../accountdata/UserAccountDataTypes.kt | 32 +++++++++++ .../database/mapper/AccountDataMapper.kt | 2 +- .../android/internal/di/MoshiProvider.kt | 12 ----- .../identity/DefaultIdentityService.kt | 4 +- .../integrationmanager/IntegrationManager.kt | 20 +++---- .../sync/UserAccountDataSyncHandler.kt | 54 +++++++++---------- ...ceptedTerms.kt => AcceptedTermsContent.kt} | 6 --- ...taBreadcrumbs.kt => BreadcrumbsContent.kt} | 6 --- ...tDataEvent.kt => DirectMessagesContent.kt} | 10 +--- ...tityServer.kt => IdentityServerContent.kt} | 6 --- .../sync/model/accountdata/UserAccountData.kt | 38 ------------- .../UserAccountDataDirectMessages.kt | 26 --------- .../UserAccountDataIgnoredUsers.kt | 26 --------- .../UserAccountDataIntegrationProvisioning.kt | 27 ---------- .../accountdata/UserAccountDataPushRules.kt | 27 ---------- .../model/accountdata/UserAccountDataSync.kt | 4 +- .../accountdata/UserAccountDataWidgets.kt | 50 ----------------- .../session/terms/DefaultTermsService.kt | 4 +- .../user/accountdata/AccountDataDataSource.kt | 2 +- .../accountdata/DefaultAccountDataService.kt | 2 +- .../accountdata/UpdateIgnoredUserIdsTask.kt | 4 +- .../accountdata/UpdateUserAccountDataTask.kt | 14 ++--- .../internal/session/widgets/WidgetManager.kt | 10 ++-- .../widgets/helper/UserAccountWidgets.kt | 2 +- .../devtools/AccountDataEpoxyController.kt | 5 +- .../settings/devtools/AccountDataFragment.kt | 9 ++-- .../settings/devtools/AccountDataViewModel.kt | 4 +- .../features/widgets/WidgetPostAPIHandler.kt | 4 +- .../signout/ServerBackupStatusViewModel.kt | 4 +- 33 files changed, 117 insertions(+), 321 deletions(-) rename matrix-sdk-android/src/main/java/im/vector/matrix/android/{internal/session/sync/model/accountdata/UserAccountDataAllowedWidgets.kt => api/session/accountdata/UserAccountDataEvent.kt} (64%) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/UserAccountDataTypes.kt rename matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/{UserAccountDataAcceptedTerms.kt => AcceptedTermsContent.kt} (78%) rename matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/{UserAccountDataBreadcrumbs.kt => BreadcrumbsContent.kt} (78%) rename matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/{UserAccountDataEvent.kt => DirectMessagesContent.kt} (67%) rename matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/{UserAccountDataIdentityServer.kt => IdentityServerContent.kt} (77%) delete mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountData.kt delete mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataDirectMessages.kt delete mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIgnoredUsers.kt delete mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIntegrationProvisioning.kt delete mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataPushRules.kt delete mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataWidgets.kt diff --git a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt index ca0bb46f4b..f09015e80d 100644 --- a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt +++ b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt @@ -42,8 +42,7 @@ import im.vector.matrix.android.api.util.toOptional import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo import im.vector.matrix.android.internal.crypto.store.PrivateKeysInfo -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent +import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent import io.reactivex.Observable import io.reactivex.Single import io.reactivex.functions.Function3 @@ -179,7 +178,7 @@ class RxSession(private val session: Session) { } fun liveSecretSynchronisationInfo(): Observable { - return Observable.combineLatest, Optional, Optional, SecretsSynchronisationInfo>( + return Observable.combineLatest, Optional, Optional, SecretsSynchronisationInfo>( liveAccountData(setOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME, KEYBACKUP_SECRET_SSSS_NAME)), liveCrossSigningInfo(session.myUserId), liveCrossSigningPrivateKeys(), diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ssss/QuadSTests.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ssss/QuadSTests.kt index d93b151ded..8bbc74011a 100644 --- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ssss/QuadSTests.kt +++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ssss/QuadSTests.kt @@ -35,7 +35,7 @@ import im.vector.matrix.android.common.TestMatrixCallback import im.vector.matrix.android.internal.crypto.SSSS_ALGORITHM_AES_HMAC_SHA2 import im.vector.matrix.android.internal.crypto.crosssigning.toBase64NoPadding import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorageService -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent +import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/AccountDataService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/AccountDataService.kt index ee13d1f097..3d5637caa1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/AccountDataService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/AccountDataService.kt @@ -21,7 +21,6 @@ import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.session.events.model.Content import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Optional -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent interface AccountDataService { /** diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataAllowedWidgets.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/UserAccountDataEvent.kt similarity index 64% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataAllowedWidgets.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/UserAccountDataEvent.kt index 43f3b3b32a..4ff0975de9 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataAllowedWidgets.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/UserAccountDataEvent.kt @@ -14,14 +14,18 @@ * limitations under the License. */ -package im.vector.matrix.android.internal.session.sync.model.accountdata +package im.vector.matrix.android.api.session.accountdata import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import im.vector.matrix.android.internal.session.integrationmanager.AllowedWidgetsContent +import im.vector.matrix.android.api.session.events.model.Content +/** + * This is a simplified Event with just a type and a content. + * Currently used types are defined in [UserAccountDataTypes]. + */ @JsonClass(generateAdapter = true) -internal data class UserAccountDataAllowedWidgets( - @Json(name = "type") override val type: String = TYPE_ALLOWED_WIDGETS, - @Json(name = "content") val content: AllowedWidgetsContent -) : UserAccountData() +data class UserAccountDataEvent( + @Json(name = "type") val type: String, + @Json(name = "content") val content: Content +) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/UserAccountDataTypes.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/UserAccountDataTypes.kt new file mode 100644 index 0000000000..49b0c56726 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/UserAccountDataTypes.kt @@ -0,0 +1,32 @@ +/* + * 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.matrix.android.api.session.accountdata + +object UserAccountDataTypes { + + const val TYPE_IGNORED_USER_LIST = "m.ignored_user_list" + const val TYPE_DIRECT_MESSAGES = "m.direct" + const val TYPE_BREADCRUMBS = "im.vector.setting.breadcrumbs" // Was previously "im.vector.riot.breadcrumb_rooms" + const val TYPE_PREVIEW_URLS = "org.matrix.preview_urls" + const val TYPE_WIDGETS = "m.widgets" + const val TYPE_PUSH_RULES = "m.push_rules" + const val TYPE_INTEGRATION_PROVISIONING = "im.vector.setting.integration_provisioning" + const val TYPE_ALLOWED_WIDGETS = "im.vector.setting.allowed_widgets" + const val TYPE_IDENTITY_SERVER = "m.identity_server" + const val TYPE_ACCEPTED_TERMS = "m.accepted_terms" + +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/AccountDataMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/AccountDataMapper.kt index 528712b731..621267ca40 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/AccountDataMapper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/AccountDataMapper.kt @@ -19,7 +19,7 @@ package im.vector.matrix.android.internal.database.mapper import com.squareup.moshi.Moshi import im.vector.matrix.android.api.util.JSON_DICT_PARAMETERIZED_TYPE import im.vector.matrix.android.internal.database.model.UserAccountDataEntity -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent +import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent import javax.inject.Inject internal class AccountDataMapper @Inject constructor(moshi: Moshi) { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MoshiProvider.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MoshiProvider.kt index 3164bf75c0..8a2cc50456 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MoshiProvider.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MoshiProvider.kt @@ -34,24 +34,12 @@ import im.vector.matrix.android.api.session.room.model.message.MessageVideoConte import im.vector.matrix.android.internal.network.parsing.ForceToBooleanJsonAdapter import im.vector.matrix.android.internal.network.parsing.RuntimeJsonAdapterFactory import im.vector.matrix.android.internal.network.parsing.UriMoshiAdapter -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataBreadcrumbs -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataDirectMessages -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIgnoredUsers -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataPushRules object MoshiProvider { private val moshi: Moshi = Moshi.Builder() .add(UriMoshiAdapter()) .add(ForceToBooleanJsonAdapter()) - .add(RuntimeJsonAdapterFactory.of(UserAccountData::class.java, "type", UserAccountDataEvent::class.java) - .registerSubtype(UserAccountDataDirectMessages::class.java, UserAccountData.TYPE_DIRECT_MESSAGES) - .registerSubtype(UserAccountDataIgnoredUsers::class.java, UserAccountData.TYPE_IGNORED_USER_LIST) - .registerSubtype(UserAccountDataPushRules::class.java, UserAccountData.TYPE_PUSH_RULES) - .registerSubtype(UserAccountDataBreadcrumbs::class.java, UserAccountData.TYPE_BREADCRUMBS) - ) .add(RuntimeJsonAdapterFactory.of(MessageContent::class.java, "msgtype", MessageDefaultContent::class.java) .registerSubtype(MessageTextContent::class.java, MessageType.MSGTYPE_TEXT) .registerSubtype(MessageNoticeContent::class.java, MessageType.MSGTYPE_NOTICE) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt index 13c97599f7..c0462d7af6 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt @@ -46,7 +46,7 @@ import im.vector.matrix.android.internal.session.openid.GetOpenIdTokenTask import im.vector.matrix.android.internal.session.profile.BindThreePidsTask import im.vector.matrix.android.internal.session.profile.UnbindThreePidsTask import im.vector.matrix.android.internal.session.sync.model.accountdata.IdentityServerContent -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData +import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes import im.vector.matrix.android.internal.session.user.accountdata.AccountDataDataSource import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask import im.vector.matrix.android.internal.task.TaskExecutor @@ -95,7 +95,7 @@ internal class DefaultIdentityService @Inject constructor( lifecycleRegistry.currentState = Lifecycle.State.STARTED // Observe the account data change accountDataDataSource - .getLiveAccountDataEvent(UserAccountData.TYPE_IDENTITY_SERVER) + .getLiveAccountDataEvent(UserAccountDataTypes.TYPE_IDENTITY_SERVER) .observeNotNull(lifecycleOwner) { notifyIdentityServerUrlChange(it.getOrNull()?.content?.toModel()?.baseUrl) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/integrationmanager/IntegrationManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/integrationmanager/IntegrationManager.kt index ac50f2118a..27e035e093 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/integrationmanager/IntegrationManager.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/integrationmanager/IntegrationManager.kt @@ -34,8 +34,8 @@ import im.vector.matrix.android.internal.di.SessionDatabase import im.vector.matrix.android.internal.extensions.observeNotNull import im.vector.matrix.android.internal.session.SessionLifecycleObserver import im.vector.matrix.android.internal.session.SessionScope -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent +import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes +import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent import im.vector.matrix.android.internal.session.user.accountdata.AccountDataDataSource import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask import im.vector.matrix.android.internal.session.widgets.helper.WidgetFactory @@ -87,7 +87,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri lifecycleRegistry.currentState = Lifecycle.State.STARTED observeWellknownConfig() accountDataDataSource - .getLiveAccountDataEvent(UserAccountData.TYPE_ALLOWED_WIDGETS) + .getLiveAccountDataEvent(UserAccountDataTypes.TYPE_ALLOWED_WIDGETS) .observeNotNull(lifecycleOwner) { val allowedWidgetsContent = it.getOrNull()?.content?.toModel() if (allowedWidgetsContent != null) { @@ -95,7 +95,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri } } accountDataDataSource - .getLiveAccountDataEvent(UserAccountData.TYPE_INTEGRATION_PROVISIONING) + .getLiveAccountDataEvent(UserAccountDataTypes.TYPE_INTEGRATION_PROVISIONING) .observeNotNull(lifecycleOwner) { val integrationProvisioningContent = it.getOrNull()?.content?.toModel() if (integrationProvisioningContent != null) { @@ -103,7 +103,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri } } accountDataDataSource - .getLiveAccountDataEvent(UserAccountData.TYPE_WIDGETS) + .getLiveAccountDataEvent(UserAccountDataTypes.TYPE_WIDGETS) .observeNotNull(lifecycleOwner) { val integrationManagerContent = it.getOrNull()?.asIntegrationManagerWidgetContent() val config = integrationManagerContent?.extractIntegrationManagerConfig() @@ -132,7 +132,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri * Returns false if the user as disabled integration manager feature */ fun isIntegrationEnabled(): Boolean { - val integrationProvisioningData = accountDataDataSource.getAccountDataEvent(UserAccountData.TYPE_INTEGRATION_PROVISIONING) + val integrationProvisioningData = accountDataDataSource.getAccountDataEvent(UserAccountDataTypes.TYPE_INTEGRATION_PROVISIONING) val integrationProvisioningContent = integrationProvisioningData?.content?.toModel() return integrationProvisioningContent?.enabled ?: false } @@ -153,7 +153,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri } fun setWidgetAllowed(stateEventId: String, allowed: Boolean, callback: MatrixCallback): Cancelable { - val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountData.TYPE_ALLOWED_WIDGETS) + val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountDataTypes.TYPE_ALLOWED_WIDGETS) val currentContent = currentAllowedWidgets?.content?.toModel() val newContent = if (currentContent == null) { val allowedWidget = mapOf(stateEventId to allowed) @@ -173,13 +173,13 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri } fun isWidgetAllowed(stateEventId: String): Boolean { - val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountData.TYPE_ALLOWED_WIDGETS) + val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountDataTypes.TYPE_ALLOWED_WIDGETS) val currentContent = currentAllowedWidgets?.content?.toModel() return currentContent?.widgets?.get(stateEventId) ?: false } fun setNativeWidgetDomainAllowed(widgetType: String, domain: String, allowed: Boolean, callback: MatrixCallback): Cancelable { - val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountData.TYPE_ALLOWED_WIDGETS) + val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountDataTypes.TYPE_ALLOWED_WIDGETS) val currentContent = currentAllowedWidgets?.content?.toModel() val newContent = if (currentContent == null) { val nativeAllowedWidgets = mapOf(widgetType to mapOf(domain to allowed)) @@ -203,7 +203,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri } fun isNativeWidgetDomainAllowed(widgetType: String, domain: String?): Boolean { - val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountData.TYPE_ALLOWED_WIDGETS) + val currentAllowedWidgets = accountDataDataSource.getAccountDataEvent(UserAccountDataTypes.TYPE_ALLOWED_WIDGETS) val currentContent = currentAllowedWidgets?.content?.toModel() return currentContent?.native?.get(widgetType)?.get(domain) ?: false } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt index 4d7d056a2b..afa4fb680e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt @@ -16,11 +16,14 @@ package im.vector.matrix.android.internal.session.sync +import com.squareup.moshi.Moshi import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.pushrules.RuleScope import im.vector.matrix.android.api.pushrules.RuleSetKey +import im.vector.matrix.android.api.pushrules.rest.GetPushRulesResponse +import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent +import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes import im.vector.matrix.android.api.session.events.model.Content -import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.RoomMemberContent import im.vector.matrix.android.api.session.room.model.RoomSummary @@ -37,16 +40,13 @@ import im.vector.matrix.android.internal.database.model.UserAccountDataEntityFie import im.vector.matrix.android.internal.database.query.getDirectRooms import im.vector.matrix.android.internal.database.query.getOrCreate import im.vector.matrix.android.internal.database.query.where -import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.matrix.android.internal.di.SessionDatabase import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataBreadcrumbs -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataDirectMessages -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIgnoredUsers -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataPushRules +import im.vector.matrix.android.internal.session.sync.model.accountdata.BreadcrumbsContent +import im.vector.matrix.android.internal.session.sync.model.accountdata.DirectMessagesContent +import im.vector.matrix.android.internal.session.sync.model.accountdata.IgnoredUsersContent import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataSync import im.vector.matrix.android.internal.session.user.accountdata.DirectChatsHelper import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask @@ -60,25 +60,18 @@ internal class UserAccountDataSyncHandler @Inject constructor( @SessionDatabase private val monarchy: Monarchy, @UserId private val userId: String, private val directChatsHelper: DirectChatsHelper, + private val moshi: Moshi, private val updateUserAccountDataTask: UpdateUserAccountDataTask) { fun handle(realm: Realm, accountData: UserAccountDataSync?) { - accountData?.list?.forEach { + accountData?.list?.forEach { event -> // Generic handling, just save in base - handleGenericAccountData(realm, it.type, it.content) - - // Didn't want to break too much thing, so i re-serialize to jsonString before reparsing - // TODO would be better to have a mapper? - val toJson = MoshiProvider.providesMoshi().adapter(Event::class.java).toJson(it) - val model = toJson?.let { json -> - MoshiProvider.providesMoshi().adapter(UserAccountData::class.java).fromJson(json) - } - // Specific parsing - when (model) { - is UserAccountDataDirectMessages -> handleDirectChatRooms(realm, model) - is UserAccountDataPushRules -> handlePushRules(realm, model) - is UserAccountDataIgnoredUsers -> handleIgnoredUsers(realm, model) - is UserAccountDataBreadcrumbs -> handleBreadcrumbs(realm, model) + handleGenericAccountData(realm, event.type, event.content) + when (event.type) { + UserAccountDataTypes.TYPE_DIRECT_MESSAGES -> handleDirectChatRooms(realm, event) + UserAccountDataTypes.TYPE_PUSH_RULES -> handlePushRules(realm, event) + UserAccountDataTypes.TYPE_IGNORED_USER_LIST -> handleIgnoredUsers(realm, event) + UserAccountDataTypes.TYPE_BREADCRUMBS -> handleBreadcrumbs(realm, event) } } } @@ -116,8 +109,8 @@ internal class UserAccountDataSyncHandler @Inject constructor( } } - private fun handlePushRules(realm: Realm, userAccountDataPushRules: UserAccountDataPushRules) { - val pushRules = userAccountDataPushRules.content + private fun handlePushRules(realm: Realm, event: UserAccountDataEvent) { + val pushRules = event.content.toModel() ?: return realm.where(PushRulesEntity::class.java) .findAll() .deleteAllFromRealm() @@ -158,13 +151,14 @@ internal class UserAccountDataSyncHandler @Inject constructor( realm.insertOrUpdate(underrides) } - private fun handleDirectChatRooms(realm: Realm, directMessages: UserAccountDataDirectMessages) { + private fun handleDirectChatRooms(realm: Realm, event: UserAccountDataEvent) { val oldDirectRooms = RoomSummaryEntity.getDirectRooms(realm) oldDirectRooms.forEach { it.isDirect = false it.directUserId = null } - directMessages.content.forEach { + val content = event.content.toModel() ?: return + content.forEach { val userId = it.key it.value.forEach { roomId -> val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst() @@ -177,8 +171,8 @@ internal class UserAccountDataSyncHandler @Inject constructor( } } - private fun handleIgnoredUsers(realm: Realm, userAccountDataIgnoredUsers: UserAccountDataIgnoredUsers) { - val userIds = userAccountDataIgnoredUsers.content.ignoredUsers.keys + private fun handleIgnoredUsers(realm: Realm, event: UserAccountDataEvent) { + val userIds = event.content.toModel()?.ignoredUsers?.keys ?: return realm.where(IgnoredUserEntity::class.java) .findAll() .deleteAllFromRealm() @@ -187,8 +181,8 @@ internal class UserAccountDataSyncHandler @Inject constructor( // TODO If not initial sync, we should execute a init sync } - private fun handleBreadcrumbs(realm: Realm, userAccountDataBreadcrumbs: UserAccountDataBreadcrumbs) { - val recentRoomIds = userAccountDataBreadcrumbs.content.recentRoomIds + private fun handleBreadcrumbs(realm: Realm, event: UserAccountDataEvent) { + val recentRoomIds = event.content.toModel()?.recentRoomIds ?: return val entity = BreadcrumbsEntity.getOrCreate(realm) // And save the new received list diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataAcceptedTerms.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/AcceptedTermsContent.kt similarity index 78% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataAcceptedTerms.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/AcceptedTermsContent.kt index ef34503463..c62a9a9502 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataAcceptedTerms.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/AcceptedTermsContent.kt @@ -19,12 +19,6 @@ package im.vector.matrix.android.internal.session.sync.model.accountdata import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -@JsonClass(generateAdapter = true) -internal data class UserAccountDataAcceptedTerms( - @Json(name = "type") override val type: String = TYPE_ACCEPTED_TERMS, - @Json(name = "content") val content: AcceptedTermsContent -) : UserAccountData() - @JsonClass(generateAdapter = true) internal data class AcceptedTermsContent( @Json(name = "accepted") val acceptedTerms: List = emptyList() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataBreadcrumbs.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/BreadcrumbsContent.kt similarity index 78% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataBreadcrumbs.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/BreadcrumbsContent.kt index cf5ee9c5e1..143093b1fd 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataBreadcrumbs.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/BreadcrumbsContent.kt @@ -19,12 +19,6 @@ package im.vector.matrix.android.internal.session.sync.model.accountdata import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -@JsonClass(generateAdapter = true) -internal data class UserAccountDataBreadcrumbs( - @Json(name = "type") override val type: String = TYPE_BREADCRUMBS, - @Json(name = "content") val content: BreadcrumbsContent -) : UserAccountData() - @JsonClass(generateAdapter = true) internal data class BreadcrumbsContent( @Json(name = "recent_rooms") val recentRoomIds: List = emptyList() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataEvent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/DirectMessagesContent.kt similarity index 67% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataEvent.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/DirectMessagesContent.kt index 65d3ce1ce7..875badc736 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataEvent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/DirectMessagesContent.kt @@ -16,12 +16,4 @@ package im.vector.matrix.android.internal.session.sync.model.accountdata -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass -import im.vector.matrix.android.api.util.JsonDict - -@JsonClass(generateAdapter = true) -data class UserAccountDataEvent( - @Json(name = "type") override val type: String, - @Json(name = "content") val content: JsonDict -) : UserAccountData() +typealias DirectMessagesContent = Map> diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIdentityServer.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/IdentityServerContent.kt similarity index 77% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIdentityServer.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/IdentityServerContent.kt index 4af2034d64..bf373aaef5 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIdentityServer.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/IdentityServerContent.kt @@ -19,12 +19,6 @@ package im.vector.matrix.android.internal.session.sync.model.accountdata import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -@JsonClass(generateAdapter = true) -internal data class UserAccountDataIdentityServer( - @Json(name = "type") override val type: String = TYPE_IDENTITY_SERVER, - @Json(name = "content") val content: IdentityServerContent? = null -) : UserAccountData() - @JsonClass(generateAdapter = true) internal data class IdentityServerContent( @Json(name = "base_url") val baseUrl: String? = null diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountData.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountData.kt deleted file mode 100644 index d758110e09..0000000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountData.kt +++ /dev/null @@ -1,38 +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.matrix.android.internal.session.sync.model.accountdata - -import com.squareup.moshi.Json -import im.vector.matrix.android.internal.session.user.accountdata.AccountDataContent - -abstract class UserAccountData : AccountDataContent { - - @Json(name = "type") abstract val type: String - - companion object { - const val TYPE_IGNORED_USER_LIST = "m.ignored_user_list" - const val TYPE_DIRECT_MESSAGES = "m.direct" - const val TYPE_BREADCRUMBS = "im.vector.setting.breadcrumbs" // Was previously "im.vector.riot.breadcrumb_rooms" - const val TYPE_PREVIEW_URLS = "org.matrix.preview_urls" - const val TYPE_WIDGETS = "m.widgets" - const val TYPE_PUSH_RULES = "m.push_rules" - const val TYPE_INTEGRATION_PROVISIONING = "im.vector.setting.integration_provisioning" - const val TYPE_ALLOWED_WIDGETS = "im.vector.setting.allowed_widgets" - const val TYPE_IDENTITY_SERVER = "m.identity_server" - const val TYPE_ACCEPTED_TERMS = "m.accepted_terms" - } -} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataDirectMessages.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataDirectMessages.kt deleted file mode 100644 index e5c6135bd1..0000000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataDirectMessages.kt +++ /dev/null @@ -1,26 +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.matrix.android.internal.session.sync.model.accountdata - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -@JsonClass(generateAdapter = true) -internal data class UserAccountDataDirectMessages( - @Json(name = "type") override val type: String = TYPE_DIRECT_MESSAGES, - @Json(name = "content") val content: Map> -) : UserAccountData() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIgnoredUsers.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIgnoredUsers.kt deleted file mode 100644 index 63a7604305..0000000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIgnoredUsers.kt +++ /dev/null @@ -1,26 +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.matrix.android.internal.session.sync.model.accountdata - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -@JsonClass(generateAdapter = true) -internal data class UserAccountDataIgnoredUsers( - @Json(name = "type") override val type: String = TYPE_IGNORED_USER_LIST, - @Json(name = "content") val content: IgnoredUsersContent -) : UserAccountData() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIntegrationProvisioning.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIntegrationProvisioning.kt deleted file mode 100644 index a47bb761cd..0000000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIntegrationProvisioning.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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. - */ - -package im.vector.matrix.android.internal.session.sync.model.accountdata - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass -import im.vector.matrix.android.internal.session.integrationmanager.IntegrationProvisioningContent - -@JsonClass(generateAdapter = true) -internal data class UserAccountDataIntegrationProvisioning( - @Json(name = "type") override val type: String = TYPE_INTEGRATION_PROVISIONING, - @Json(name = "content") val content: IntegrationProvisioningContent -) : UserAccountData() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataPushRules.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataPushRules.kt deleted file mode 100644 index 0d549d1667..0000000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataPushRules.kt +++ /dev/null @@ -1,27 +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.matrix.android.internal.session.sync.model.accountdata - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass -import im.vector.matrix.android.api.pushrules.rest.GetPushRulesResponse - -@JsonClass(generateAdapter = true) -internal data class UserAccountDataPushRules( - @Json(name = "type") override val type: String = TYPE_PUSH_RULES, - @Json(name = "content") val content: GetPushRulesResponse -) : UserAccountData() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataSync.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataSync.kt index 8acac86e1a..ff018a5181 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataSync.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataSync.kt @@ -18,9 +18,9 @@ package im.vector.matrix.android.internal.session.sync.model.accountdata import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import im.vector.matrix.android.api.session.events.model.Event +import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent @JsonClass(generateAdapter = true) internal data class UserAccountDataSync( - @Json(name = "events") val list: List = emptyList() + @Json(name = "events") val list: List = emptyList() ) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataWidgets.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataWidgets.kt deleted file mode 100644 index 5c13b4d5fe..0000000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataWidgets.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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. - */ - -package im.vector.matrix.android.internal.session.sync.model.accountdata - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass -import im.vector.matrix.android.api.session.events.model.Event - -/* -"m.widgets":{ - "stickerpicker_@rxl881:matrix.org_1514573757015":{ - "content":{ - "creatorUserId":"@rxl881:matrix.org", - "data":{ - "..." - }, - "id":"stickerpicker_@rxl881:matrix.org_1514573757015", - "name":"Stickerpicker", - "type":"m.stickerpicker", - "url":"https://...", - "waitForIframeLoad":true - }, - "sender":"@rxl881:matrix.org" - "state_key":"stickerpicker_@rxl881:matrix.org_1514573757015", - "type":"m.widget" - }, -{ - "..." - } -} - */ -@JsonClass(generateAdapter = true) -internal data class UserAccountDataWidgets( - @Json(name = "type") override val type: String = TYPE_WIDGETS, - @Json(name = "content") val content: Map -) : UserAccountData() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/terms/DefaultTermsService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/terms/DefaultTermsService.kt index 1781fcc3dc..c70fb11d0c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/terms/DefaultTermsService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/terms/DefaultTermsService.kt @@ -30,7 +30,7 @@ import im.vector.matrix.android.internal.session.identity.IdentityAuthAPI import im.vector.matrix.android.internal.session.identity.IdentityRegisterTask import im.vector.matrix.android.internal.session.openid.GetOpenIdTokenTask import im.vector.matrix.android.internal.session.sync.model.accountdata.AcceptedTermsContent -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData +import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes import im.vector.matrix.android.internal.session.user.accountdata.AccountDataDataSource import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask import im.vector.matrix.android.internal.task.TaskExecutor @@ -109,7 +109,7 @@ internal class DefaultTermsService @Inject constructor( } private fun getAlreadyAcceptedTermUrlsFromAccountData(): Set { - return accountDataDataSource.getAccountDataEvent(UserAccountData.TYPE_ACCEPTED_TERMS) + return accountDataDataSource.getAccountDataEvent(UserAccountDataTypes.TYPE_ACCEPTED_TERMS) ?.content ?.toModel() ?.acceptedTerms diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/AccountDataDataSource.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/AccountDataDataSource.kt index 964ce3509b..ed5f26ab18 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/AccountDataDataSource.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/AccountDataDataSource.kt @@ -25,7 +25,7 @@ import im.vector.matrix.android.internal.database.mapper.AccountDataMapper import im.vector.matrix.android.internal.database.model.UserAccountDataEntity import im.vector.matrix.android.internal.database.model.UserAccountDataEntityFields import im.vector.matrix.android.internal.di.SessionDatabase -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent +import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent import io.realm.Realm import io.realm.RealmQuery import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/DefaultAccountDataService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/DefaultAccountDataService.kt index 82864bb9fb..c8dafcc33e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/DefaultAccountDataService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/DefaultAccountDataService.kt @@ -25,7 +25,7 @@ import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Optional import im.vector.matrix.android.internal.di.SessionDatabase import im.vector.matrix.android.internal.session.sync.UserAccountDataSyncHandler -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent +import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.configureWith import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt index bd5af7817a..3a224b273a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt @@ -22,7 +22,7 @@ import im.vector.matrix.android.internal.di.SessionDatabase import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.session.sync.model.accountdata.IgnoredUsersContent -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData +import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes import im.vector.matrix.android.internal.task.Task import org.greenrobot.eventbus.EventBus import javax.inject.Inject @@ -64,7 +64,7 @@ internal class DefaultUpdateIgnoredUserIdsTask @Inject constructor( val body = IgnoredUsersContent.createWithUserIds(list) executeRequest(eventBus) { - apiCall = accountDataApi.setAccountData(userId, UserAccountData.TYPE_IGNORED_USER_LIST, body) + apiCall = accountDataApi.setAccountData(userId, UserAccountDataTypes.TYPE_IGNORED_USER_LIST, body) } // Update the DB right now (do not wait for the sync to come back with updated data, for a faster UI update) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt index 8db2ad9781..f456bbebd3 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt @@ -23,7 +23,7 @@ import im.vector.matrix.android.internal.session.integrationmanager.IntegrationP import im.vector.matrix.android.internal.session.sync.model.accountdata.AcceptedTermsContent import im.vector.matrix.android.internal.session.sync.model.accountdata.BreadcrumbsContent import im.vector.matrix.android.internal.session.sync.model.accountdata.IdentityServerContent -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData +import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes import im.vector.matrix.android.internal.task.Task import org.greenrobot.eventbus.EventBus import javax.inject.Inject @@ -35,7 +35,7 @@ internal interface UpdateUserAccountDataTask : Task> ) : Params { @@ -63,7 +63,7 @@ internal interface UpdateUserAccountDataTask : Task? = null, excludedTypes: Set? = null ): LiveData> { - val widgetsAccountData = accountDataDataSource.getLiveAccountDataEvent(UserAccountData.TYPE_WIDGETS) + val widgetsAccountData = accountDataDataSource.getLiveAccountDataEvent(UserAccountDataTypes.TYPE_WIDGETS) return Transformations.map(widgetsAccountData) { it.getOrNull()?.mapToWidgets(widgetTypes, excludedTypes) ?: emptyList() } @@ -146,12 +146,12 @@ internal class WidgetManager @Inject constructor(private val integrationManager: widgetTypes: Set? = null, excludedTypes: Set? = null ): List { - val widgetsAccountData = accountDataDataSource.getAccountDataEvent(UserAccountData.TYPE_WIDGETS) ?: return emptyList() + val widgetsAccountData = accountDataDataSource.getAccountDataEvent(UserAccountDataTypes.TYPE_WIDGETS) ?: return emptyList() return widgetsAccountData.mapToWidgets(widgetTypes, excludedTypes) } private fun UserAccountDataEvent.mapToWidgets(widgetTypes: Set? = null, - excludedTypes: Set? = null): List { + excludedTypes: Set? = null): List { return extractWidgetSequence(widgetFactory) .filter { val widgetType = it.widgetContent.type ?: return@filter false diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/helper/UserAccountWidgets.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/helper/UserAccountWidgets.kt index 113047246e..7f64c8a81e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/helper/UserAccountWidgets.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/helper/UserAccountWidgets.kt @@ -19,7 +19,7 @@ package im.vector.matrix.android.internal.session.widgets.helper import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.util.JsonDict -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent +import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent import im.vector.matrix.android.api.session.widgets.model.Widget internal fun UserAccountDataEvent.extractWidgetSequence(widgetFactory: WidgetFactory): Sequence { diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataEpoxyController.kt index c8a09bfb64..821a654342 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataEpoxyController.kt @@ -21,7 +21,8 @@ import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Loading import com.airbnb.mvrx.Success -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData +import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent +import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes import im.vector.riotx.R import im.vector.riotx.core.epoxy.loadingItem import im.vector.riotx.core.resources.StringProvider @@ -35,7 +36,7 @@ class AccountDataEpoxyController @Inject constructor( ) : TypedEpoxyController() { interface InteractionListener { - fun didTap(data: UserAccountData) + fun didTap(data: UserAccountDataEvent) } var interactionListener: InteractionListener? = null diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataFragment.kt index ad8831124a..c873805d7c 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataFragment.kt @@ -21,8 +21,8 @@ import android.view.View import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.matrix.android.internal.di.MoshiProvider -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent +import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes +import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent import im.vector.riotx.R import im.vector.riotx.core.extensions.cleanup import im.vector.riotx.core.extensions.configureWith @@ -65,11 +65,10 @@ class AccountDataFragment @Inject constructor( epoxyController.interactionListener = null } - override fun didTap(data: UserAccountData) { - val fb = data as? UserAccountDataEvent ?: return + override fun didTap(data: UserAccountDataEvent) { val jsonString = MoshiProvider.providesMoshi() .adapter(UserAccountDataEvent::class.java) - .toJson(fb) + .toJson(data) JSonViewerDialog.newInstance( jsonString, -1, // open All diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataViewModel.kt b/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataViewModel.kt index 32ce17c660..825af6e397 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataViewModel.kt @@ -25,14 +25,14 @@ import com.airbnb.mvrx.ViewModelContext import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.session.Session -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData +import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent import im.vector.matrix.rx.rx import im.vector.riotx.core.platform.EmptyAction import im.vector.riotx.core.platform.EmptyViewEvents import im.vector.riotx.core.platform.VectorViewModel data class AccountDataViewState( - val accountData: Async> = Uninitialized + val accountData: Async> = Uninitialized ) : MvRxState class AccountDataViewModel @AssistedInject constructor(@Assisted initialState: AccountDataViewState, diff --git a/vector/src/main/java/im/vector/riotx/features/widgets/WidgetPostAPIHandler.kt b/vector/src/main/java/im/vector/riotx/features/widgets/WidgetPostAPIHandler.kt index 7115a2ea62..ce3ad466e2 100644 --- a/vector/src/main/java/im/vector/riotx/features/widgets/WidgetPostAPIHandler.kt +++ b/vector/src/main/java/im/vector/riotx/features/widgets/WidgetPostAPIHandler.kt @@ -31,7 +31,7 @@ import im.vector.matrix.android.api.session.room.model.PowerLevelsContent import im.vector.matrix.android.api.session.room.powerlevels.PowerLevelsHelper import im.vector.matrix.android.api.session.widgets.WidgetPostAPIMediator import im.vector.matrix.android.api.util.JsonDict -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData +import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes import im.vector.riotx.R import im.vector.riotx.core.resources.StringProvider import timber.log.Timber @@ -280,7 +280,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo ) ) session.updateAccountData( - type = UserAccountData.TYPE_WIDGETS, + type = UserAccountDataTypes.TYPE_WIDGETS, content = addUserWidgetBody, callback = createWidgetAPICallback(widgetPostAPIMediator, eventData) ) diff --git a/vector/src/main/java/im/vector/riotx/features/workers/signout/ServerBackupStatusViewModel.kt b/vector/src/main/java/im/vector/riotx/features/workers/signout/ServerBackupStatusViewModel.kt index bfeb959534..35dff87ecb 100644 --- a/vector/src/main/java/im/vector/riotx/features/workers/signout/ServerBackupStatusViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/workers/signout/ServerBackupStatusViewModel.kt @@ -28,6 +28,7 @@ import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.extensions.orFalse import im.vector.matrix.android.api.session.Session +import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent import im.vector.matrix.android.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo import im.vector.matrix.android.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME @@ -36,7 +37,6 @@ import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupStateListener import im.vector.matrix.android.api.util.Optional import im.vector.matrix.android.internal.crypto.store.PrivateKeysInfo -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData import im.vector.matrix.rx.rx import im.vector.riotx.core.platform.EmptyAction import im.vector.riotx.core.platform.EmptyViewEvents @@ -97,7 +97,7 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS keysBackupState.value = session.cryptoService().keysBackupService().state - Observable.combineLatest, Optional, KeysBackupState, Optional, BannerState>( + Observable.combineLatest, Optional, KeysBackupState, Optional, BannerState>( session.rx().liveAccountData(setOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME)), session.rx().liveCrossSigningInfo(session.myUserId), keyBackupPublishSubject, From c880e2b848b04f12ecd24e863a0c23b5f91b113d Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 20 Jul 2020 20:24:04 +0200 Subject: [PATCH 13/21] Fix Requesting avatar thumbnails in Element uses wrong http "user-agent" string #1725 --- .../matrix/android/internal/network/UserAgentInterceptor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/UserAgentInterceptor.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/UserAgentInterceptor.kt index f4e51e6173..41b93ef3d8 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/UserAgentInterceptor.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/UserAgentInterceptor.kt @@ -29,7 +29,7 @@ internal class UserAgentInterceptor @Inject constructor(private val userAgentHol userAgentHolder.userAgent .takeIf { it.isNotBlank() } ?.let { - newRequestBuilder.addHeader(HttpHeaders.UserAgent, it) + newRequestBuilder.header(HttpHeaders.UserAgent, it) } request = newRequestBuilder.build() return chain.proceed(request) From fb247f8bea1753552202c0a6fbffafa5f13db71e Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 20 Jul 2020 20:29:52 +0200 Subject: [PATCH 14/21] Update CHANGES and clean code --- CHANGES.md | 4 ++++ .../android/api/session/accountdata/UserAccountDataTypes.kt | 1 - .../android/internal/session/room/send/SendEventWorker.kt | 2 +- .../android/internal/session/widgets/WidgetManager.kt | 6 +++--- .../settings/devtools/AccountDataEpoxyController.kt | 1 - .../riotx/features/settings/devtools/AccountDataFragment.kt | 1 - 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 004c999246..f455e18a54 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,10 @@ Bugfix 🐛: - Fix theme issue on Room directory screen (#1613) - Fix notification not dismissing when entering a room - Fix uploads don't work with Room v6 (#1558) + - Fix Requesting avatar thumbnails in Element uses wrong http "user-agent" string (#1725) + - Fix 404 on EMS (#1761) + - Fix Infinite loop at startup when migrating account from Riot (#1699) + - Fix Element crashes in loop after initial sync (#1709) Translations 🗣: - diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/UserAccountDataTypes.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/UserAccountDataTypes.kt index 49b0c56726..83fdb61925 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/UserAccountDataTypes.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/UserAccountDataTypes.kt @@ -28,5 +28,4 @@ object UserAccountDataTypes { const val TYPE_ALLOWED_WIDGETS = "im.vector.setting.allowed_widgets" const val TYPE_IDENTITY_SERVER = "m.identity_server" const val TYPE_ACCEPTED_TERMS = "m.accepted_terms" - } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt index 2cfdc22aae..ff128eb96b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt @@ -44,7 +44,7 @@ internal class SendEventWorker(context: Context, @JsonClass(generateAdapter = true) internal data class Params( override val sessionId: String, - //TODO remove after some time, it's used for compat + // TODO remove after some time, it's used for compat val event: Event? = null, val eventId: String? = null, val roomId: String? = null, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/WidgetManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/WidgetManager.kt index ee80332110..05c0b01f0e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/WidgetManager.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/WidgetManager.kt @@ -23,6 +23,8 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.Transformations import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.query.QueryStringValue +import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent +import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes import im.vector.matrix.android.api.session.events.model.Content import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.EventType @@ -38,8 +40,6 @@ import im.vector.matrix.android.internal.session.SessionLifecycleObserver import im.vector.matrix.android.internal.session.SessionScope import im.vector.matrix.android.internal.session.integrationmanager.IntegrationManager import im.vector.matrix.android.internal.session.room.state.StateEventDataSource -import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes -import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent import im.vector.matrix.android.internal.session.user.accountdata.AccountDataDataSource import im.vector.matrix.android.internal.session.widgets.helper.WidgetFactory import im.vector.matrix.android.internal.session.widgets.helper.extractWidgetSequence @@ -151,7 +151,7 @@ internal class WidgetManager @Inject constructor(private val integrationManager: } private fun UserAccountDataEvent.mapToWidgets(widgetTypes: Set? = null, - excludedTypes: Set? = null): List { + excludedTypes: Set? = null): List { return extractWidgetSequence(widgetFactory) .filter { val widgetType = it.widgetContent.type ?: return@filter false diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataEpoxyController.kt index 821a654342..bc3a3eb13d 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataEpoxyController.kt @@ -22,7 +22,6 @@ import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Loading import com.airbnb.mvrx.Success import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent -import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes import im.vector.riotx.R import im.vector.riotx.core.epoxy.loadingItem import im.vector.riotx.core.resources.StringProvider diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataFragment.kt index c873805d7c..4f9cf827cc 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/devtools/AccountDataFragment.kt @@ -21,7 +21,6 @@ import android.view.View import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.matrix.android.internal.di.MoshiProvider -import im.vector.matrix.android.api.session.accountdata.UserAccountDataTypes import im.vector.matrix.android.api.session.accountdata.UserAccountDataEvent import im.vector.riotx.R import im.vector.riotx.core.extensions.cleanup From e5596f6a97f4aa42c704fc2f12afd8d9871305c9 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 21 Jul 2020 10:39:45 +0200 Subject: [PATCH 15/21] Use Any instead of JsonDict so users won't loose ignored users --- .../session/sync/model/accountdata/IgnoredUsersContent.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/IgnoredUsersContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/IgnoredUsersContent.kt index ea591d79b0..66db603d4e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/IgnoredUsersContent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/IgnoredUsersContent.kt @@ -18,7 +18,6 @@ package im.vector.matrix.android.internal.session.sync.model.accountdata import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import im.vector.matrix.android.api.util.JsonDict import im.vector.matrix.android.api.util.emptyJsonDict @JsonClass(generateAdapter = true) @@ -26,7 +25,7 @@ internal data class IgnoredUsersContent( /** * Required. The map of users to ignore. UserId -> empty object for future enhancement */ - @Json(name = "ignored_users") val ignoredUsers: Map + @Json(name = "ignored_users") val ignoredUsers: Map ) { companion object { From d7558902f756a14e9d5f3e68a33dc89cce56bd2e Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 22 Jul 2020 11:12:37 +0200 Subject: [PATCH 16/21] Sending: limit to 3 retry before failing --- .../internal/crypto/tasks/EncryptEventTask.kt | 6 +- .../internal/crypto/tasks/SendEventTask.kt | 10 ++-- .../tasks/SendVerificationMessageTask.kt | 10 ++-- .../session/room/send/DefaultSendService.kt | 1 + .../session/room/send/EncryptEventWorker.kt | 8 +-- .../session/room/send/LocalEchoRepository.kt | 40 +++++++++++-- .../session/room/send/LocalEchoUpdater.kt | 57 ------------------- .../MultipleEventSendingDispatcherWorker.kt | 4 +- .../session/room/send/SendEventWorker.kt | 24 ++++---- .../session/room/timeline/DefaultTimeline.kt | 7 +-- 10 files changed, 69 insertions(+), 98 deletions(-) delete mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoUpdater.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/EncryptEventTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/EncryptEventTask.kt index 951bc6385a..b44ff8ed1c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/EncryptEventTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/EncryptEventTask.kt @@ -19,7 +19,7 @@ import im.vector.matrix.android.api.session.crypto.CryptoService import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.room.send.SendState import im.vector.matrix.android.internal.crypto.model.MXEncryptEventContentResult -import im.vector.matrix.android.internal.session.room.send.LocalEchoUpdater +import im.vector.matrix.android.internal.session.room.send.LocalEchoRepository import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.util.awaitCallback import javax.inject.Inject @@ -35,7 +35,7 @@ internal interface EncryptEventTask : Task { internal class DefaultEncryptEventTask @Inject constructor( // private val crypto: CryptoService - private val localEchoUpdater: LocalEchoUpdater + private val localEchoRepository: LocalEchoRepository ) : EncryptEventTask { override suspend fun execute(params: EncryptEventTask.Params): Event { if (!params.crypto.isRoomEncrypted(params.roomId)) return params.event @@ -44,7 +44,7 @@ internal class DefaultEncryptEventTask @Inject constructor( throw IllegalArgumentException() } - localEchoUpdater.updateSendState(localEvent.eventId, SendState.ENCRYPTING) + localEchoRepository.updateSendState(localEvent.eventId, SendState.ENCRYPTING) val localMutableContent = localEvent.content?.toMutableMap() ?: mutableMapOf() params.keepKeys?.forEach { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/SendEventTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/SendEventTask.kt index 637db1790e..2cffdcf267 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/SendEventTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/SendEventTask.kt @@ -20,7 +20,7 @@ import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.room.send.SendState import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.session.room.RoomAPI -import im.vector.matrix.android.internal.session.room.send.LocalEchoUpdater +import im.vector.matrix.android.internal.session.room.send.LocalEchoRepository import im.vector.matrix.android.internal.session.room.send.SendResponse import im.vector.matrix.android.internal.task.Task import org.greenrobot.eventbus.EventBus @@ -34,7 +34,7 @@ internal interface SendEventTask : Task { } internal class DefaultSendEventTask @Inject constructor( - private val localEchoUpdater: LocalEchoUpdater, + private val localEchoRepository: LocalEchoRepository, private val encryptEventTask: DefaultEncryptEventTask, private val roomAPI: RoomAPI, private val eventBus: EventBus) : SendEventTask { @@ -44,7 +44,7 @@ internal class DefaultSendEventTask @Inject constructor( val localId = event.eventId!! try { - localEchoUpdater.updateSendState(localId, SendState.SENDING) + localEchoRepository.updateSendState(localId, SendState.SENDING) val executeRequest = executeRequest(eventBus) { apiCall = roomAPI.send( localId, @@ -53,10 +53,10 @@ internal class DefaultSendEventTask @Inject constructor( eventType = event.type ) } - localEchoUpdater.updateSendState(localId, SendState.SENT) + localEchoRepository.updateSendState(localId, SendState.SENT) return executeRequest.eventId } catch (e: Throwable) { - localEchoUpdater.updateSendState(localId, SendState.UNDELIVERED) + localEchoRepository.updateSendState(localId, SendState.UNDELIVERED) throw e } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/SendVerificationMessageTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/SendVerificationMessageTask.kt index fef6c25ff7..aede23f795 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/SendVerificationMessageTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/SendVerificationMessageTask.kt @@ -20,7 +20,7 @@ import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.room.send.SendState import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.session.room.RoomAPI -import im.vector.matrix.android.internal.session.room.send.LocalEchoUpdater +import im.vector.matrix.android.internal.session.room.send.LocalEchoRepository import im.vector.matrix.android.internal.session.room.send.SendResponse import im.vector.matrix.android.internal.task.Task import org.greenrobot.eventbus.EventBus @@ -34,7 +34,7 @@ internal interface SendVerificationMessageTask : Task(eventBus) { apiCall = roomAPI.send( localId, @@ -53,10 +53,10 @@ internal class DefaultSendVerificationMessageTask @Inject constructor( eventType = event.type ) } - localEchoUpdater.updateSendState(localId, SendState.SENT) + localEchoRepository.updateSendState(localId, SendState.SENT) return executeRequest.eventId } catch (e: Throwable) { - localEchoUpdater.updateSendState(localId, SendState.UNDELIVERED) + localEchoRepository.updateSendState(localId, SendState.UNDELIVERED) throw e } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt index 6db44314e5..73b35c268a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt @@ -128,6 +128,7 @@ internal class DefaultSendService @AssistedInject constructor( override fun resendTextMessage(localEcho: TimelineEvent): Cancelable? { if (localEcho.root.isTextMessage() && localEcho.root.sendState.hasFailed()) { + localEchoRepository.updateSendState(localEcho.eventId, SendState.UNSENT) return sendEvent(localEcho.root) } return null diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt index 6af2f8dab6..3d8e63cb97 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt @@ -52,7 +52,7 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters) ) : SessionWorkerParams @Inject lateinit var crypto: CryptoService - @Inject lateinit var localEchoUpdater: LocalEchoUpdater + @Inject lateinit var localEchoRepository: LocalEchoRepository override suspend fun doWork(): Result { Timber.v("Start Encrypt work") @@ -74,7 +74,7 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters) if (localEvent.eventId == null) { return Result.success() } - localEchoUpdater.updateSendState(localEvent.eventId, SendState.ENCRYPTING) + localEchoRepository.updateSendState(localEvent.eventId, SendState.ENCRYPTING) val localMutableContent = localEvent.content?.toMutableMap() ?: mutableMapOf() params.keepKeys?.forEach { @@ -116,7 +116,7 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters) senderCurve25519Key = result.eventContent["sender_key"] as? String, claimedEd25519Key = crypto.getMyDevice().fingerprint() ) - localEchoUpdater.updateEncryptedEcho(localEvent.eventId, safeResult.eventContent, decryptionLocalEcho) + localEchoRepository.updateEncryptedEcho(localEvent.eventId, safeResult.eventContent, decryptionLocalEcho) } val nextWorkerParams = SendEventWorker.Params(params.sessionId, encryptedEvent) @@ -126,7 +126,7 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters) is Failure.CryptoError -> SendState.FAILED_UNKNOWN_DEVICES else -> SendState.UNDELIVERED } - localEchoUpdater.updateSendState(localEvent.eventId, sendState) + localEchoRepository.updateSendState(localEvent.eventId, sendState) // always return success, or the chain will be stuck for ever! val nextWorkerParams = SendEventWorker.Params(params.sessionId, localEvent, error?.localizedMessage ?: "Error") diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoRepository.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoRepository.kt index 9ebced26e0..3c6ce786a5 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoRepository.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoRepository.kt @@ -17,6 +17,7 @@ package im.vector.matrix.android.internal.session.room.send import com.zhuinden.monarchy.Monarchy +import im.vector.matrix.android.api.session.events.model.Content import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel @@ -24,7 +25,9 @@ import im.vector.matrix.android.api.session.room.model.message.MessageContent import im.vector.matrix.android.api.session.room.model.message.MessageType import im.vector.matrix.android.api.session.room.send.SendState import im.vector.matrix.android.api.session.room.timeline.TimelineEvent +import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult import im.vector.matrix.android.internal.database.helper.nextId +import im.vector.matrix.android.internal.database.mapper.ContentMapper import im.vector.matrix.android.internal.database.mapper.TimelineEventMapper import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.mapper.toEntity @@ -36,8 +39,8 @@ import im.vector.matrix.android.internal.database.model.TimelineEventEntity import im.vector.matrix.android.internal.database.query.findAllInRoomWithSendStates import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.di.SessionDatabase -import im.vector.matrix.android.internal.session.room.summary.RoomSummaryUpdater import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper +import im.vector.matrix.android.internal.session.room.summary.RoomSummaryUpdater import im.vector.matrix.android.internal.session.room.timeline.DefaultTimeline import im.vector.matrix.android.internal.util.awaitTransaction import io.realm.Realm @@ -83,6 +86,31 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private } } + fun updateSendState(eventId: String, sendState: SendState) { + Timber.v("Update local state of $eventId to ${sendState.name}") + monarchy.writeAsync { realm -> + val sendingEventEntity = EventEntity.where(realm, eventId).findFirst() + if (sendingEventEntity != null) { + if (sendState == SendState.SENT && sendingEventEntity.sendState == SendState.SYNCED) { + // If already synced, do not put as sent + } else { + sendingEventEntity.sendState = sendState + } + } + } + } + + fun updateEncryptedEcho(eventId: String, encryptedContent: Content, mxEventDecryptionResult: MXEventDecryptionResult) { + monarchy.writeAsync { realm -> + val sendingEventEntity = EventEntity.where(realm, eventId).findFirst() + if (sendingEventEntity != null) { + sendingEventEntity.type = EventType.ENCRYPTED + sendingEventEntity.content = ContentMapper.map(encryptedContent) + sendingEventEntity.setDecryptionResult(mxEventDecryptionResult) + } + } + } + suspend fun deleteFailedEcho(roomId: String, localEcho: TimelineEvent) { monarchy.awaitTransaction { realm -> TimelineEventEntity.where(realm, roomId = roomId, eventId = localEcho.root.eventId ?: "").findFirst()?.deleteFromRealm() @@ -92,11 +120,11 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private suspend fun clearSendingQueue(roomId: String) { monarchy.awaitTransaction { realm -> - RoomEntity.where(realm, roomId).findFirst()?.let { room -> - room.sendingTimelineEvents.forEach { - it.root?.sendState = SendState.UNDELIVERED - } - } + TimelineEventEntity + .findAllInRoomWithSendStates(realm, roomId, SendState.IS_SENDING_STATES) + .forEach { + it.root?.sendState = SendState.UNSENT + } } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoUpdater.kt deleted file mode 100644 index cd074a7548..0000000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoUpdater.kt +++ /dev/null @@ -1,57 +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.matrix.android.internal.session.room.send - -import com.zhuinden.monarchy.Monarchy -import im.vector.matrix.android.api.session.events.model.Content -import im.vector.matrix.android.api.session.events.model.EventType -import im.vector.matrix.android.api.session.room.send.SendState -import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult -import im.vector.matrix.android.internal.database.mapper.ContentMapper -import im.vector.matrix.android.internal.database.model.EventEntity -import im.vector.matrix.android.internal.database.query.where -import im.vector.matrix.android.internal.di.SessionDatabase -import timber.log.Timber -import javax.inject.Inject - -internal class LocalEchoUpdater @Inject constructor(@SessionDatabase private val monarchy: Monarchy) { - - fun updateSendState(eventId: String, sendState: SendState) { - Timber.v("Update local state of $eventId to ${sendState.name}") - monarchy.writeAsync { realm -> - val sendingEventEntity = EventEntity.where(realm, eventId).findFirst() - if (sendingEventEntity != null) { - if (sendState == SendState.SENT && sendingEventEntity.sendState == SendState.SYNCED) { - // If already synced, do not put as sent - } else { - sendingEventEntity.sendState = sendState - } - } - } - } - - fun updateEncryptedEcho(eventId: String, encryptedContent: Content, mxEventDecryptionResult: MXEventDecryptionResult) { - monarchy.writeAsync { realm -> - val sendingEventEntity = EventEntity.where(realm, eventId).findFirst() - if (sendingEventEntity != null) { - sendingEventEntity.type = EventType.ENCRYPTED - sendingEventEntity.content = ContentMapper.map(encryptedContent) - sendingEventEntity.setDecryptionResult(mxEventDecryptionResult) - } - } - } -} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt index aec7cb3c5c..5e272ceff3 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt @@ -54,7 +54,7 @@ internal class MultipleEventSendingDispatcherWorker(context: Context, params: Wo @Inject lateinit var workManagerProvider: WorkManagerProvider @Inject lateinit var timelineSendEventWorkCommon: TimelineSendEventWorkCommon - @Inject lateinit var localEchoUpdater: LocalEchoUpdater + @Inject lateinit var localEchoRepository: LocalEchoRepository override suspend fun doWork(): Result { Timber.v("Start dispatch sending multiple event work") @@ -67,7 +67,7 @@ internal class MultipleEventSendingDispatcherWorker(context: Context, params: Wo if (params.lastFailureMessage != null) { params.events.forEach { event -> - event.eventId?.let { localEchoUpdater.updateSendState(it, SendState.UNDELIVERED) } + event.eventId?.let { localEchoRepository.updateSendState(it, SendState.UNDELIVERED) } } // Transmit the error if needed? return Result.success(inputData) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt index ff128eb96b..8563d5959b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt @@ -33,6 +33,8 @@ import org.greenrobot.eventbus.EventBus import timber.log.Timber import javax.inject.Inject +private const val MAX_NUMBER_OF_RETRY_BEFORE_FAILING = 3 + /** * Possible previous worker: [EncryptEventWorker] or first worker * Possible next worker : None @@ -63,7 +65,7 @@ internal class SendEventWorker(context: Context, ) } - @Inject lateinit var localEchoUpdater: LocalEchoUpdater + @Inject lateinit var localEchoRepository: LocalEchoRepository @Inject lateinit var roomAPI: RoomAPI @Inject lateinit var eventBus: EventBus @@ -74,16 +76,15 @@ internal class SendEventWorker(context: Context, val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success() sessionComponent.inject(this) - if (params.eventId == null || params.roomId == null || params.type == null) { // compat with old params, make it fail if any if (params.event?.eventId != null) { - localEchoUpdater.updateSendState(params.event.eventId, SendState.UNDELIVERED) + localEchoRepository.updateSendState(params.event.eventId, SendState.UNDELIVERED) } return Result.success() } if (params.lastFailureMessage != null) { - localEchoUpdater.updateSendState(params.eventId, SendState.UNDELIVERED) + localEchoRepository.updateSendState(params.eventId, SendState.UNDELIVERED) // Transmit the error return Result.success(inputData) .also { Timber.e("Work cancelled due to input error from parent") } @@ -92,21 +93,22 @@ internal class SendEventWorker(context: Context, sendEvent(params.eventId, params.roomId, params.type, params.contentStr) Result.success() } catch (exception: Throwable) { - if (exception.shouldBeRetried()) { - Result.retry() + // It does start from 0, we want it to stop if it fails the third time + val currentAttemptCount = runAttemptCount + 1 + if (currentAttemptCount >= MAX_NUMBER_OF_RETRY_BEFORE_FAILING || !exception.shouldBeRetried()) { + localEchoRepository.updateSendState(params.eventId, SendState.UNDELIVERED) + return Result.success() } else { - localEchoUpdater.updateSendState(params.eventId, SendState.UNDELIVERED) - // always return success, or the chain will be stuck for ever! - Result.success() + Result.retry() } } } private suspend fun sendEvent(eventId: String, roomId: String, type: String, contentStr: String?) { - localEchoUpdater.updateSendState(eventId, SendState.SENDING) + localEchoRepository.updateSendState(eventId, SendState.SENDING) executeRequest(eventBus) { apiCall = roomAPI.send(eventId, roomId, type, contentStr) } - localEchoUpdater.updateSendState(eventId, SendState.SENT) + localEchoRepository.updateSendState(eventId, SendState.SENT) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt index 567698668b..3bb9eca766 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt @@ -342,21 +342,18 @@ internal class DefaultTimeline( private fun updateLoadingStates(results: RealmResults) { val lastCacheEvent = results.lastOrNull() - val lastBuiltEvent = builtEvents.lastOrNull() val firstCacheEvent = results.firstOrNull() - val firstBuiltEvent = builtEvents.firstOrNull() val chunkEntity = getLiveChunk() updateState(Timeline.Direction.FORWARDS) { it.copy( - hasMoreInCache = firstBuiltEvent != null && firstBuiltEvent.displayIndex < firstCacheEvent?.displayIndex ?: Int.MIN_VALUE, + hasMoreInCache = !builtEventsIdMap.containsKey(firstCacheEvent?.eventId), hasReachedEnd = chunkEntity?.isLastForward ?: false ) } - updateState(Timeline.Direction.BACKWARDS) { it.copy( - hasMoreInCache = lastBuiltEvent == null || lastBuiltEvent.displayIndex > lastCacheEvent?.displayIndex ?: Int.MAX_VALUE, + hasMoreInCache = !builtEventsIdMap.containsKey(lastCacheEvent?.eventId), hasReachedEnd = chunkEntity?.isLastBackward ?: false || lastCacheEvent?.root?.type == EventType.STATE_ROOM_CREATE ) } From aa5ae45a0c54507f3ff9d41e3fa891abe1c95ff9 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 22 Jul 2020 15:21:48 +0200 Subject: [PATCH 17/21] Add hasFailedSending in RoomSummary and a small warning icon on room list --- .../android/api/session/room/model/RoomSummary.kt | 3 ++- .../internal/database/mapper/RoomSummaryMapper.kt | 3 ++- .../internal/database/model/RoomSummaryEntity.kt | 3 ++- .../database/query/TimelineEventEntityQueries.kt | 11 +++++++---- .../session/room/send/LocalEchoRepository.kt | 6 +++++- .../session/room/summary/RoomSummaryUpdater.kt | 14 ++++++++++++++ .../home/room/detail/RoomDetailViewModel.kt | 7 ++++--- .../features/home/room/list/RoomSummaryItem.kt | 3 +++ .../home/room/list/RoomSummaryItemFactory.kt | 1 + vector/src/main/res/layout/item_room.xml | 11 +++++++++++ 10 files changed, 51 insertions(+), 11 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt index ba34e0e01d..b6b0555433 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt @@ -53,7 +53,8 @@ data class RoomSummary constructor( val typingUsers: List, val inviterId: String? = null, val breadcrumbsIndex: Int = NOT_IN_BREADCRUMBS, - val roomEncryptionTrustLevel: RoomEncryptionTrustLevel? = null + val roomEncryptionTrustLevel: RoomEncryptionTrustLevel? = null, + val hasFailedSending: Boolean = false ) { val isVersioned: Boolean diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt index fb155316ee..cdd38ad2f6 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt @@ -62,7 +62,8 @@ internal class RoomSummaryMapper @Inject constructor(private val timelineEventMa encryptionEventTs = roomSummaryEntity.encryptionEventTs, breadcrumbsIndex = roomSummaryEntity.breadcrumbsIndex, roomEncryptionTrustLevel = roomSummaryEntity.roomEncryptionTrustLevel, - inviterId = roomSummaryEntity.inviterId + inviterId = roomSummaryEntity.inviterId, + hasFailedSending = roomSummaryEntity.hasFailedSending ) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/RoomSummaryEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/RoomSummaryEntity.kt index acfd484deb..eb49844ed6 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/RoomSummaryEntity.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/RoomSummaryEntity.kt @@ -51,7 +51,8 @@ internal open class RoomSummaryEntity( var isEncrypted: Boolean = false, var encryptionEventTs: Long? = 0, var roomEncryptionTrustLevelStr: String? = null, - var inviterId: String? = null + var inviterId: String? = null, + var hasFailedSending: Boolean = false ) : RealmObject() { private var membershipStr: String = Membership.NONE.name diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventEntityQueries.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventEntityQueries.kt index fb1cc8136a..db1b01fd7a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventEntityQueries.kt @@ -93,9 +93,12 @@ internal fun TimelineEventEntity.Companion.findAllInRoomWithSendStates(realm: Re roomId: String, sendStates: List) : RealmResults { - val sendStatesStr = sendStates.map { it.name }.toTypedArray() - return realm.where() - .equalTo(TimelineEventEntityFields.ROOM_ID, roomId) - .`in`(TimelineEventEntityFields.ROOT.SEND_STATE_STR, sendStatesStr) + return whereRoomId(realm, roomId) + .filterSendStates(sendStates) .findAll() } + +internal fun RealmQuery.filterSendStates(sendStates: List): RealmQuery { + val sendStatesStr = sendStates.map { it.name }.toTypedArray() + return `in`(TimelineEventEntityFields.ROOT.SEND_STATE_STR, sendStatesStr) +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoRepository.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoRepository.kt index 3c6ce786a5..bd6927032a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoRepository.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoRepository.kt @@ -82,7 +82,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private realm.insert(eventInsertEntity) val roomEntity = RoomEntity.where(realm, roomId = roomId).findFirst() ?: return@writeAsync roomEntity.sendingTimelineEvents.add(0, timelineEventEntity) - roomSummaryUpdater.update(realm, roomId) + roomSummaryUpdater.updateSendingInformation(realm, roomId) } } @@ -96,6 +96,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private } else { sendingEventEntity.sendState = sendState } + roomSummaryUpdater.update(realm, sendingEventEntity.roomId) } } } @@ -115,6 +116,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private monarchy.awaitTransaction { realm -> TimelineEventEntity.where(realm, roomId = roomId, eventId = localEcho.root.eventId ?: "").findFirst()?.deleteFromRealm() EventEntity.where(realm, eventId = localEcho.root.eventId ?: "").findFirst()?.deleteFromRealm() + roomSummaryUpdater.updateSendingInformation(realm, roomId) } } @@ -125,6 +127,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private .forEach { it.root?.sendState = SendState.UNSENT } + roomSummaryUpdater.updateSendingInformation(realm, roomId) } } @@ -134,6 +137,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private timelineEvents.forEach { it.root?.sendState = sendState } + roomSummaryUpdater.updateSendingInformation(realm, roomId) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/summary/RoomSummaryUpdater.kt index d61ebc4fc1..342926f65f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/summary/RoomSummaryUpdater.kt @@ -25,6 +25,7 @@ import im.vector.matrix.android.api.session.room.model.RoomAliasesContent import im.vector.matrix.android.api.session.room.model.RoomCanonicalAliasContent import im.vector.matrix.android.api.session.room.model.RoomNameContent import im.vector.matrix.android.api.session.room.model.RoomTopicContent +import im.vector.matrix.android.api.session.room.send.SendState import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import im.vector.matrix.android.internal.crypto.crosssigning.SessionToCryptoRoomMembersUpdate import im.vector.matrix.android.internal.database.mapper.ContentMapper @@ -34,6 +35,7 @@ import im.vector.matrix.android.internal.database.model.EventEntityFields import im.vector.matrix.android.internal.database.model.RoomMemberSummaryEntityFields import im.vector.matrix.android.internal.database.model.RoomSummaryEntity import im.vector.matrix.android.internal.database.model.TimelineEventEntity +import im.vector.matrix.android.internal.database.query.findAllInRoomWithSendStates import im.vector.matrix.android.internal.database.query.getOrCreate import im.vector.matrix.android.internal.database.query.getOrNull import im.vector.matrix.android.internal.database.query.isEventRead @@ -145,6 +147,7 @@ internal class RoomSummaryUpdater @Inject constructor( } else if (roomSummaryEntity.membership != Membership.INVITE) { roomSummaryEntity.inviterId = null } + roomSummaryEntity.updateHasFailedSending() if (latestPreviewableEvent?.root?.type == EventType.ENCRYPTED && latestPreviewableEvent.root?.decryptionResultJson == null) { Timber.v("Should decrypt ${latestPreviewableEvent.eventId}") @@ -167,6 +170,17 @@ internal class RoomSummaryUpdater @Inject constructor( } } + private fun RoomSummaryEntity.updateHasFailedSending() { + hasFailedSending = TimelineEventEntity.findAllInRoomWithSendStates(realm, roomId, SendState.HAS_FAILED_STATES).isNotEmpty() + } + + fun updateSendingInformation(realm: Realm, roomId: String) { + val roomSummaryEntity = RoomSummaryEntity.getOrCreate(realm, roomId) + roomSummaryEntity.updateHasFailedSending() + roomSummaryEntity.latestPreviewableEvent = TimelineEventEntity.latestEvent(realm, roomId, includesSending = true, + filterTypes = PREVIEWABLE_TYPES, filterContentRelation = true) + } + fun updateShieldTrust(realm: Realm, roomId: String, trust: RoomEncryptionTrustLevel?) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt index a396152f6b..912eb90a0f 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt @@ -30,6 +30,7 @@ import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.MatrixPatterns import im.vector.matrix.android.api.NoOpMatrixCallback +import im.vector.matrix.android.api.extensions.orFalse import im.vector.matrix.android.api.query.QueryStringValue import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.crypto.MXCryptoError @@ -415,11 +416,11 @@ class RoomDetailViewModel @AssistedInject constructor( R.id.clear_message_queue -> // For now always disable when not in developer mode, worker cancellation is not working properly timeline.pendingEventCount() > 0 && vectorPreferences.developerMode() - R.id.resend_all -> timeline.failedToDeliverEventCount() > 0 - R.id.clear_all -> timeline.failedToDeliverEventCount() > 0 + R.id.resend_all -> state.asyncRoomSummary()?.hasFailedSending == true + R.id.clear_all -> state.asyncRoomSummary()?.hasFailedSending == true R.id.open_matrix_apps -> true R.id.voice_call, - R.id.video_call -> room.canStartCall() && webRtcPeerConnectionManager.currentCall == null + R.id.video_call -> state.asyncRoomSummary()?.canStartCall == true && webRtcPeerConnectionManager.currentCall == null R.id.hangup_call -> webRtcPeerConnectionManager.currentCall != null else -> false } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItem.kt index 04193dba0d..0eebd12ff4 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItem.kt @@ -52,6 +52,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { @EpoxyAttribute var hasUnreadMessage: Boolean = false @EpoxyAttribute var hasDraft: Boolean = false @EpoxyAttribute var showHighlighted: Boolean = false + @EpoxyAttribute var hasFailedSending: Boolean = false @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemLongClickListener: View.OnLongClickListener? = null @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemClickListener: View.OnClickListener? = null @EpoxyAttribute var showSelected: Boolean = false @@ -72,6 +73,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { avatarRenderer.render(matrixItem, holder.avatarImageView) holder.roomAvatarDecorationImageView.isVisible = encryptionTrustLevel != null holder.roomAvatarDecorationImageView.setImageResource(encryptionTrustLevel.toImageRes()) + holder.roomAvatarFailSendingImageView.isVisible = hasFailedSending renderSelection(holder, showSelected) holder.typingView.setTextOrHide(typingMessage) holder.lastEventView.isInvisible = holder.typingView.isVisible @@ -106,6 +108,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { val avatarCheckedImageView by bind(R.id.roomAvatarCheckedImageView) val avatarImageView by bind(R.id.roomAvatarImageView) val roomAvatarDecorationImageView by bind(R.id.roomAvatarDecorationImageView) + val roomAvatarFailSendingImageView by bind(R.id.roomAvatarFailSendingImageView) val rootView by bind(R.id.itemRoomLayout) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt index f33166504d..cd2bb2d7d0 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt @@ -109,6 +109,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor .lastFormattedEvent(latestFormattedEvent) .showHighlighted(showHighlighted) .showSelected(showSelected) + .hasFailedSending(roomSummary.hasFailedSending) .unreadNotificationCount(unreadCount) .hasUnreadMessage(roomSummary.hasUnreadMessages) .hasDraft(roomSummary.userDrafts.isNotEmpty()) diff --git a/vector/src/main/res/layout/item_room.xml b/vector/src/main/res/layout/item_room.xml index 84fc0956a2..cf148043ec 100644 --- a/vector/src/main/res/layout/item_room.xml +++ b/vector/src/main/res/layout/item_room.xml @@ -47,6 +47,17 @@ + + Date: Wed, 22 Jul 2020 16:02:38 +0200 Subject: [PATCH 18/21] Composer: set max lines to 6 so it can scroll --- .../layout/constraint_set_composer_layout_compact.xml | 7 +------ .../layout/constraint_set_composer_layout_expanded.xml | 7 +------ vector/src/main/res/layout/merge_composer_layout.xml | 6 +----- vector/src/main/res/values/styles_riot.xml | 10 ++++++++++ 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/vector/src/main/res/layout/constraint_set_composer_layout_compact.xml b/vector/src/main/res/layout/constraint_set_composer_layout_compact.xml index a2bf24551d..070e9ee575 100644 --- a/vector/src/main/res/layout/constraint_set_composer_layout_compact.xml +++ b/vector/src/main/res/layout/constraint_set_composer_layout_compact.xml @@ -158,17 +158,12 @@ diff --git a/vector/src/main/res/values/styles_riot.xml b/vector/src/main/res/values/styles_riot.xml index d36575df1f..72801f02c4 100644 --- a/vector/src/main/res/values/styles_riot.xml +++ b/vector/src/main/res/values/styles_riot.xml @@ -385,4 +385,14 @@ 40dp + + \ No newline at end of file From 3e429490e7e4f98cad33dbc8dd307d71d350d87d Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 22 Jul 2020 17:04:48 +0200 Subject: [PATCH 19/21] Update CHANGES --- CHANGES.md | 3 ++- .../riotx/features/home/room/detail/RoomDetailViewModel.kt | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index acc0a74055..b1e85e239d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,8 @@ Features ✨: - Improvements 🙌: - - + - Sending events is now retried only 3 times, so we avoid blocking the sending queue too long. + - Display warning when fail to send events in room list Bugfix 🐛: - Fix theme issue on Room directory screen (#1613) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt index 912eb90a0f..2bec8017f0 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt @@ -30,7 +30,6 @@ import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.MatrixPatterns import im.vector.matrix.android.api.NoOpMatrixCallback -import im.vector.matrix.android.api.extensions.orFalse import im.vector.matrix.android.api.query.QueryStringValue import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.crypto.MXCryptoError From cac80991178f958f62de7651ba2aa13725722afa Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 23 Jul 2020 16:38:17 +0200 Subject: [PATCH 20/21] Local echo: use missing updateSendingInformation on RoomSummaryUpdater --- .../android/internal/session/room/send/LocalEchoRepository.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoRepository.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoRepository.kt index bd6927032a..bbb20802f5 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoRepository.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoRepository.kt @@ -96,7 +96,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private } else { sendingEventEntity.sendState = sendState } - roomSummaryUpdater.update(realm, sendingEventEntity.roomId) + roomSummaryUpdater.updateSendingInformation(realm, sendingEventEntity.roomId) } } } From 407595e6133fcde8696bd74405fb0900bcb7564a Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 23 Jul 2020 16:38:42 +0200 Subject: [PATCH 21/21] Change warning badge (white background) --- .../action/MessageActionsEpoxyController.kt | 2 +- vector/src/main/res/drawable/ic_warning_badge.xml | 15 +++++++++++++++ vector/src/main/res/drawable/ic_warning_small.xml | 14 -------------- .../layout/fragment_bootstrap_setup_recovery.xml | 2 +- .../layout/item_bottom_sheet_message_status.xml | 2 +- vector/src/main/res/layout/item_room.xml | 2 +- .../res/layout/item_timeline_event_base_state.xml | 2 +- .../item_timeline_event_media_message_stub.xml | 2 +- 8 files changed, 21 insertions(+), 20 deletions(-) create mode 100644 vector/src/main/res/drawable/ic_warning_badge.xml delete mode 100644 vector/src/main/res/drawable/ic_warning_small.xml diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt index e77d9ec73f..e063016be1 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt @@ -69,7 +69,7 @@ class MessageActionsEpoxyController @Inject constructor( id("send_state") showProgress(false) text(stringProvider.getString(R.string.unable_to_send_message)) - drawableStart(R.drawable.ic_warning_small) + drawableStart(R.drawable.ic_warning_badge) } } diff --git a/vector/src/main/res/drawable/ic_warning_badge.xml b/vector/src/main/res/drawable/ic_warning_badge.xml new file mode 100644 index 0000000000..66c2422b4a --- /dev/null +++ b/vector/src/main/res/drawable/ic_warning_badge.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/vector/src/main/res/drawable/ic_warning_small.xml b/vector/src/main/res/drawable/ic_warning_small.xml deleted file mode 100644 index 456491ec82..0000000000 --- a/vector/src/main/res/drawable/ic_warning_small.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - diff --git a/vector/src/main/res/layout/fragment_bootstrap_setup_recovery.xml b/vector/src/main/res/layout/fragment_bootstrap_setup_recovery.xml index ffe1e4680c..60d20942e1 100644 --- a/vector/src/main/res/layout/fragment_bootstrap_setup_recovery.xml +++ b/vector/src/main/res/layout/fragment_bootstrap_setup_recovery.xml @@ -83,7 +83,7 @@ android:layout_marginEnd="16dp" android:text="@string/reset_secure_backup_warning" android:textColor="@color/riotx_destructive_accent" - android:drawableStart="@drawable/ic_warning_small" + android:drawableStart="@drawable/ic_warning_badge" android:drawablePadding="4dp" android:textSize="14sp" /> diff --git a/vector/src/main/res/layout/item_bottom_sheet_message_status.xml b/vector/src/main/res/layout/item_bottom_sheet_message_status.xml index 10c129cf58..742fa69a7b 100644 --- a/vector/src/main/res/layout/item_bottom_sheet_message_status.xml +++ b/vector/src/main/res/layout/item_bottom_sheet_message_status.xml @@ -24,7 +24,7 @@ android:layout_height="wrap_content" android:layout_marginEnd="16dp" android:layout_weight="1" - android:drawableStart="@drawable/ic_warning_small" + android:drawableStart="@drawable/ic_warning_badge" android:drawablePadding="4dp" android:textColor="?riotx_text_secondary" android:textStyle="bold" diff --git a/vector/src/main/res/layout/item_room.xml b/vector/src/main/res/layout/item_room.xml index cf148043ec..9387f9ba75 100644 --- a/vector/src/main/res/layout/item_room.xml +++ b/vector/src/main/res/layout/item_room.xml @@ -55,7 +55,7 @@ app:layout_constraintCircleAngle="45" app:layout_constraintCircleRadius="30dp" tools:ignore="MissingConstraints" - android:src="@drawable/ic_warning_small" + android:src="@drawable/ic_warning_badge" />