Skip to content

Commit

Permalink
Merge branch 'release/0.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
bmarty committed Jul 18, 2019
2 parents 52dced4 + d609c49 commit df6080b
Show file tree
Hide file tree
Showing 169 changed files with 3,065 additions and 1,032 deletions.
28 changes: 19 additions & 9 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
Changes in RiotX 0.XX (2019-XX-XX)
Changes in RiotX 0.2.0 (2019-07-18)
===================================================

Features:
- Contextual action menu for messages in room
- Message Editing: View edit history (#121)
- Rooms filtering (#304)
- Edit in encrypted room

Improvements:
-
- Handle click on redacted events: view source and create permalink
- Improve long tap menu: reply on top, more compact (#368)
- Quick reply in timeline with swipe gesture (#167)
- Improve edit of replies
- Improve performance on Room Members and Users management (#381)

Other changes:
-
- migrate from rxbinding 2 to rxbinding 3

Bugfix:
-
- Fix regression on permalink click
- Fix crash reported by the PlayStore (#341)
- Fix Chat composer separator color in dark/black theme
- Fix bad layout for room directory filter (#349)
- Fix Copying link from a message shouldn't open context menu (#364)

Translations:
-
Changes in RiotX 0.1.0 (2019-07-11)
===================================================

Build:
-
First release!

Mode details here: https://medium.com/@RiotChat/introducing-the-riotx-beta-for-android-b17952e8f771


=======================================================
Expand Down
29 changes: 23 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[![Buildkite](https://badge.buildkite.com/657d3db27364448d69d54f66c690f7788bc6aa80a7628e37f3.svg?branch=develop)](https://buildkite.com/matrix-dot-org/riotx-android)
[![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)
[![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=vector.android.riotx&metric=alert_status)](https://sonarcloud.io/dashboard?id=vector.android.riotx)
Expand All @@ -7,14 +7,31 @@

# RiotX Android

RiotX is an Android Matrix Client currently in development. The application is not yet available on the PlayStore.
RiotX is an Android Matrix Client currently in beta but in active development.

It's based on a new Matrix SDK, written in Kotlin.
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.

Download nightly build here: [![Buildkite](https://badge.buildkite.com/657d3db27364448d69d54f66c690f7788bc6aa80a7628e37f3.svg?branch=develop)](https://buildkite.com/matrix-dot-org/riotx-android/builds?branch=develop)
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" alt="Get it on Google Play" height="60">](https://play.google.com/store/apps/details?id=im.vector.riotx)

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 API 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

Matrix Room: [![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)

## Contributing

Please refer to [CONTRIBUTING.md](https://github.com/vector-im/riotX-android/blob/develop/CONTRIBUTING.md) if you want to contribute the Matrix on Android projects!
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).
21 changes: 21 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import javax.tools.JavaCompiler

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
Expand Down Expand Up @@ -45,7 +47,26 @@ allprojects {
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
google()
jcenter()
maven {
url 'https://repo.adobe.com/nexus/content/repositories/public/'
content {
includeGroupByRegex "diff_match_patch"
}
}
}

tasks.withType(JavaCompile).all {
options.compilerArgs += [
'-Adagger.gradle.incremental=enabled'
]
}

afterEvaluate {
extensions.findByName("kapt")?.arguments {
arg("dagger.gradle.incremental", "enabled")
}
}

}

task clean(type: Delete) {
Expand Down
8 changes: 4 additions & 4 deletions docs/notifications.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
This document aims to describe how Riot X android displays notifications to the end user. It also clarifies notifications and background settings in the app.
This document aims to describe how RiotX 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)
Expand Down Expand Up @@ -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 Riot X Android app is open (i.e in foreground state), the default timeout is 30 seconds, and delay is 0.
When the RiotX 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

Expand Down Expand Up @@ -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 Riot X 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 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.

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.

Expand Down Expand Up @@ -223,7 +223,7 @@ Upon reception of the FCM push, RiotX will perform a sync call to the Home Serve
* 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.

Riot X implements several strategies in these cases (TODO document)
RiotX implements several strategies in these cases (TODO document)

## FCM Fallback mode

Expand Down
6 changes: 3 additions & 3 deletions matrix-sdk-android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,14 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"

implementation "androidx.appcompat:appcompat:1.1.0-beta01"
implementation "androidx.recyclerview:recyclerview:1.1.0-alpha06"
implementation "androidx.appcompat:appcompat:1.1.0-rc01"
implementation "androidx.recyclerview:recyclerview:1.1.0-beta01"

implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"

// Network
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:retrofit:2.6.0'
implementation 'com.squareup.retrofit2:converter-moshi:2.4.0'
implementation 'com.squareup.okhttp3:okhttp:3.14.1'
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ object MatrixLinkify {
hasMatch = true
val startPos = match.range.first
if (startPos == 0 || text[startPos - 1] != '/') {
val endPos = match.range.last
val endPos = match.range.last + 1
val url = text.substring(match.range)
val span = MatrixPermalinkSpan(url, callback)
spannable.setSpan(span, startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
Expand All @@ -51,5 +51,5 @@ object MatrixLinkify {
}
return hasMatch
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ interface Session :
*/
val sessionParams: SessionParams

/**
* Useful shortcut to get access to the userId
*/
val myUserId: String
get() = sessionParams.credentials.userId

Expand Down Expand Up @@ -84,7 +87,7 @@ interface Session :
/**
* This method start the sync thread.
*/
fun startSync()
fun startSync(fromForeground : Boolean)

/**
* This method stop the sync thread.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ package im.vector.matrix.android.api.session.events.model


/**
* Constants defining known event relation types from Matrix specifications.
* Constants defining known event relation types from Matrix specifications
*/
object RelationType {

/** Lets you define an event which annotates an existing event.*/
const val ANNOTATION = "m.annotation"
/** Lets you define an event which replaces an existing event.*/
const val REPLACE = "m.replace"
/** ets you define an event which references an existing event.*/
/** Lets you define an event which references an existing event.*/
const val REFERENCE = "m.reference"

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@ interface MessageContent {
val body: String
val relatesTo: RelationDefaultContent?
val newContent: Content?
}


fun MessageContent?.isReply(): Boolean {
return this?.relatesTo?.inReplyTo != null
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@

package im.vector.matrix.android.api.session.room.model.relation

import im.vector.matrix.android.api.session.events.model.RelationType

interface RelationContent {
/** See [RelationType] for known possible values */
val type: String?
val eventId: String?
val inReplyTo: ReplyToContent?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package im.vector.matrix.android.api.session.room.model.relation

import androidx.lifecycle.LiveData
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.api.util.Cancelable
Expand Down Expand Up @@ -79,6 +81,25 @@ interface RelationService {
compatibilityBodyText: String = "* $newBodyText"): Cancelable


/**
* Edit a reply. This is a special case because replies contains fallback text as a prefix.
* This method will take the new body (stripped from fallbacks) and re-add them before sending.
* @param replyToEdit The event to edit
* @param originalTimelineEvent the message that this reply (being edited) is relating to
* @param newBodyText The edited body (stripped from in reply to content)
* @param compatibilityBodyText The text that will appear on clients that don't support yet edition
*/
fun editReply(replyToEdit: TimelineEvent,
originalTimelineEvent: TimelineEvent,
newBodyText: String,
compatibilityBodyText: String = "* $newBodyText"): Cancelable

/**
* Get's the edit history of the given event
*/
fun fetchEditHistory(eventId: String, callback: MatrixCallback<List<Event>>)


/**
* Reply to an event in the timeline (must be in same room)
* https://matrix.org/docs/spec/client_server/r0.4.0.html#id350
Expand All @@ -91,4 +112,6 @@ interface RelationService {
autoMarkdown: Boolean = false): Cancelable?

fun getEventSummaryLive(eventId: String): LiveData<EventAnnotationsSummary>


}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ 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.EventAnnotationsSummary
import im.vector.matrix.android.api.session.room.model.message.MessageContent
import im.vector.matrix.android.api.session.room.model.message.isReply
import im.vector.matrix.android.api.session.room.send.SendState
import im.vector.matrix.android.api.util.ContentUtils.extractUsefulTextFromReply
import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent

/**
* This data class is a wrapper around an Event. It allows to get useful data in the context of a timeline.
Expand Down Expand Up @@ -88,3 +91,15 @@ data class TimelineEvent(
*/
fun TimelineEvent.getLastMessageContent(): MessageContent? = annotations?.editSummary?.aggregatedContent?.toModel()
?: root.getClearContent().toModel()


fun TimelineEvent.getTextEditableContent(): String? {
val originalContent = root.getClearContent().toModel<MessageContent>() ?: return null
val isReply = originalContent.isReply() || root.content.toModel<EncryptedEventContent>()?.relatesTo?.inReplyTo?.eventId != null
val lastContent = getLastMessageContent()
return if (isReply) {
return extractUsefulTextFromReply(lastContent?.body ?: "")
} else {
lastContent?.body ?: ""
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package im.vector.matrix.android.api.session.sync

sealed class SyncState {
object IDLE : SyncState()
data class RUNNING(val catchingUp: Boolean) : SyncState()
data class RUNNING(val afterPause: Boolean) : SyncState()
object PAUSED : SyncState()
object KILLING : SyncState()
object KILLED : SyncState()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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.util


object ContentUtils {
fun extractUsefulTextFromReply(repliedBody: String): String {
val lines = repliedBody.lines()
var wellFormed = repliedBody.startsWith(">")
var endOfPreviousFound = false
val usefullines = ArrayList<String>()
lines.forEach {
if (it == "") {
endOfPreviousFound = true
return@forEach
}
if (!endOfPreviousFound) {
wellFormed = wellFormed && it.startsWith(">")
} else {
usefullines.add(it)
}
}
return usefullines.joinToString("\n").takeIf { wellFormed } ?: repliedBody
}

fun extractUsefulTextFromHtmlReply(repliedBody: String): String {
if (repliedBody.startsWith("<mx-reply>")) {
val closingTagIndex = repliedBody.lastIndexOf("</mx-reply>")
if (closingTagIndex != -1)
return repliedBody.substring(closingTagIndex + "</mx-reply>".length).trim()
}
return repliedBody
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,10 @@ internal class SessionManager @Inject constructor(private val matrixComponent: M
}

private fun getOrCreateSessionComponent(sessionParams: SessionParams): SessionComponent {
val userId = sessionParams.credentials.userId
if (sessionComponents.containsKey(userId)) {
return sessionComponents[userId]!!
return sessionComponents.getOrPut(sessionParams.credentials.userId) {
DaggerSessionComponent
.factory()
.create(matrixComponent, sessionParams)
}
return DaggerSessionComponent
.factory()
.create(matrixComponent, sessionParams)
.also {
sessionComponents[sessionParams.credentials.userId] = it
}
}

}
Loading

0 comments on commit df6080b

Please sign in to comment.