Merge branch 'develop' into feature/ui_test
This commit is contained in:
commit
487bbe42a9
|
@ -6,6 +6,7 @@ Features ✨:
|
||||||
|
|
||||||
Improvements 🙌:
|
Improvements 🙌:
|
||||||
- PIN code: request PIN code if phone has been locked
|
- PIN code: request PIN code if phone has been locked
|
||||||
|
- Small optimisation of scrolling experience in timeline (#2114)
|
||||||
|
|
||||||
Bugfix 🐛:
|
Bugfix 🐛:
|
||||||
- Fix Splash layout on small screens
|
- Fix Splash layout on small screens
|
||||||
|
@ -21,6 +22,7 @@ Build 🧱:
|
||||||
|
|
||||||
Other changes:
|
Other changes:
|
||||||
- Added registration/verification automated UI tests
|
- Added registration/verification automated UI tests
|
||||||
|
- Create a script to help getting public information form any homeserver
|
||||||
|
|
||||||
Changes in Element 1.0.8 (2020-09-25)
|
Changes in Element 1.0.8 (2020-09-25)
|
||||||
===================================================
|
===================================================
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
|
||||||
|
### Arguments
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='Get some information about a homeserver.')
|
||||||
|
parser.add_argument('-s',
|
||||||
|
'--homeserver',
|
||||||
|
required=True,
|
||||||
|
help="homeserver URL")
|
||||||
|
parser.add_argument('-v',
|
||||||
|
'--verbose',
|
||||||
|
help="increase output verbosity.",
|
||||||
|
action="store_true")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.verbose:
|
||||||
|
print("Argument:")
|
||||||
|
print(args)
|
||||||
|
|
||||||
|
baseUrl = args.homeserver
|
||||||
|
|
||||||
|
if not baseUrl.startswith("http"):
|
||||||
|
baseUrl = "https://" + baseUrl
|
||||||
|
|
||||||
|
if not baseUrl.endswith("/"):
|
||||||
|
baseUrl = baseUrl + "/"
|
||||||
|
|
||||||
|
print("Get information from " + baseUrl)
|
||||||
|
|
||||||
|
items = [
|
||||||
|
# [Title, URL, True for GET request and False for POST request]
|
||||||
|
["Well-known", baseUrl + ".well-known/matrix/client", True]
|
||||||
|
, ["Version", baseUrl + "_matrix/client/versions", True]
|
||||||
|
, ["Login flow", baseUrl + "_matrix/client/r0/login", True]
|
||||||
|
, ["Registration flow", baseUrl + "_matrix/client/r0/register", False]
|
||||||
|
# Useless , ["Username availability", baseUrl + "_matrix/client/r0/register/available?username=benoit", True]
|
||||||
|
# Useless , ["Public rooms", baseUrl + "_matrix/client/r0/publicRooms?limit=1", True]
|
||||||
|
# Useless , ["Profile", baseUrl + "_matrix/client/r0/profile/@benoit.marty:matrix.org", True]
|
||||||
|
# Need token , ["Capability", baseUrl + "_matrix/client/r0/capabilities", True]
|
||||||
|
# Need token , ["Media config", baseUrl + "_matrix/media/r0/config", True]
|
||||||
|
# Need token , ["Turn", baseUrl + "_matrix/client/r0/voip/turnServer", True]
|
||||||
|
]
|
||||||
|
|
||||||
|
for item in items:
|
||||||
|
print("====================================================================================================")
|
||||||
|
print("# " + item[0] + " (" + item[1] + ")")
|
||||||
|
print("====================================================================================================")
|
||||||
|
if item[2]:
|
||||||
|
os.system("curl -s -X GET '" + item[1] + "' | python -m json.tool")
|
||||||
|
else:
|
||||||
|
os.system("curl -s -X POST --data $'{}' '" + item[1] + "' | python -m json.tool")
|
|
@ -344,6 +344,7 @@ dependencies {
|
||||||
implementation 'com.jakewharton.rxbinding3:rxbinding-material:3.0.0'
|
implementation 'com.jakewharton.rxbinding3:rxbinding-material:3.0.0'
|
||||||
|
|
||||||
implementation("com.airbnb.android:epoxy:$epoxy_version")
|
implementation("com.airbnb.android:epoxy:$epoxy_version")
|
||||||
|
implementation "com.airbnb.android:epoxy-glide-preloading:$epoxy_version"
|
||||||
kapt "com.airbnb.android:epoxy-processor:$epoxy_version"
|
kapt "com.airbnb.android:epoxy-processor:$epoxy_version"
|
||||||
implementation "com.airbnb.android:epoxy-paging:$epoxy_version"
|
implementation "com.airbnb.android:epoxy-paging:$epoxy_version"
|
||||||
implementation 'com.airbnb.android:mvrx:1.3.0'
|
implementation 'com.airbnb.android:mvrx:1.3.0'
|
||||||
|
|
|
@ -53,6 +53,8 @@ import androidx.recyclerview.widget.RecyclerView
|
||||||
import butterknife.BindView
|
import butterknife.BindView
|
||||||
import com.airbnb.epoxy.EpoxyModel
|
import com.airbnb.epoxy.EpoxyModel
|
||||||
import com.airbnb.epoxy.OnModelBuildFinishedListener
|
import com.airbnb.epoxy.OnModelBuildFinishedListener
|
||||||
|
import com.airbnb.epoxy.addGlidePreloader
|
||||||
|
import com.airbnb.epoxy.glidePreloader
|
||||||
import com.airbnb.mvrx.Async
|
import com.airbnb.mvrx.Async
|
||||||
import com.airbnb.mvrx.Fail
|
import com.airbnb.mvrx.Fail
|
||||||
import com.airbnb.mvrx.Loading
|
import com.airbnb.mvrx.Loading
|
||||||
|
@ -75,6 +77,7 @@ import im.vector.app.core.extensions.setTextOrHide
|
||||||
import im.vector.app.core.extensions.showKeyboard
|
import im.vector.app.core.extensions.showKeyboard
|
||||||
import im.vector.app.core.extensions.trackItemsVisibilityChange
|
import im.vector.app.core.extensions.trackItemsVisibilityChange
|
||||||
import im.vector.app.core.glide.GlideApp
|
import im.vector.app.core.glide.GlideApp
|
||||||
|
import im.vector.app.core.glide.GlideRequests
|
||||||
import im.vector.app.core.intent.getMimeTypeFromUri
|
import im.vector.app.core.intent.getMimeTypeFromUri
|
||||||
import im.vector.app.core.platform.VectorBaseFragment
|
import im.vector.app.core.platform.VectorBaseFragment
|
||||||
import im.vector.app.core.resources.ColorProvider
|
import im.vector.app.core.resources.ColorProvider
|
||||||
|
@ -218,7 +221,8 @@ class RoomDetailFragment @Inject constructor(
|
||||||
private val colorProvider: ColorProvider,
|
private val colorProvider: ColorProvider,
|
||||||
private val notificationUtils: NotificationUtils,
|
private val notificationUtils: NotificationUtils,
|
||||||
private val webRtcPeerConnectionManager: WebRtcPeerConnectionManager,
|
private val webRtcPeerConnectionManager: WebRtcPeerConnectionManager,
|
||||||
private val matrixItemColorProvider: MatrixItemColorProvider
|
private val matrixItemColorProvider: MatrixItemColorProvider,
|
||||||
|
private val imageContentRenderer: ImageContentRenderer
|
||||||
) :
|
) :
|
||||||
VectorBaseFragment(),
|
VectorBaseFragment(),
|
||||||
TimelineEventController.Callback,
|
TimelineEventController.Callback,
|
||||||
|
@ -921,6 +925,16 @@ class RoomDetailFragment @Inject constructor(
|
||||||
val touchHelper = ItemTouchHelper(swipeCallback)
|
val touchHelper = ItemTouchHelper(swipeCallback)
|
||||||
touchHelper.attachToRecyclerView(recyclerView)
|
touchHelper.attachToRecyclerView(recyclerView)
|
||||||
}
|
}
|
||||||
|
recyclerView.addGlidePreloader(
|
||||||
|
epoxyController = timelineEventController,
|
||||||
|
requestManager = GlideApp.with(this),
|
||||||
|
preloader = glidePreloader { requestManager, epoxyModel: MessageImageVideoItem, _ ->
|
||||||
|
imageContentRenderer.createGlideRequest(
|
||||||
|
epoxyModel.mediaData,
|
||||||
|
ImageContentRenderer.Mode.THUMBNAIL,
|
||||||
|
requestManager as GlideRequests
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateJumpToReadMarkerViewVisibility() {
|
private fun updateJumpToReadMarkerViewVisibility() {
|
||||||
|
|
|
@ -56,6 +56,8 @@ import org.matrix.android.sdk.api.session.room.timeline.Timeline
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
private const val DEFAULT_PREFETCH_THRESHOLD = 30
|
||||||
|
|
||||||
class TimelineEventController @Inject constructor(private val dateFormatter: VectorDateFormatter,
|
class TimelineEventController @Inject constructor(private val dateFormatter: VectorDateFormatter,
|
||||||
private val contentUploadStateTrackerBinder: ContentUploadStateTrackerBinder,
|
private val contentUploadStateTrackerBinder: ContentUploadStateTrackerBinder,
|
||||||
private val contentDownloadStateTrackerBinder: ContentDownloadStateTrackerBinder,
|
private val contentDownloadStateTrackerBinder: ContentDownloadStateTrackerBinder,
|
||||||
|
@ -116,6 +118,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
|
||||||
private var unreadState: UnreadState = UnreadState.Unknown
|
private var unreadState: UnreadState = UnreadState.Unknown
|
||||||
private var positionOfReadMarker: Int? = null
|
private var positionOfReadMarker: Int? = null
|
||||||
private var eventIdToHighlight: String? = null
|
private var eventIdToHighlight: String? = null
|
||||||
|
private var previousModelsSize = 0
|
||||||
|
|
||||||
var callback: Callback? = null
|
var callback: Callback? = null
|
||||||
var timeline: Timeline? = null
|
var timeline: Timeline? = null
|
||||||
|
@ -191,6 +194,29 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
|
||||||
models.add(position, readMarker)
|
models.add(position, readMarker)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val shouldAddBackwardPrefetch = timeline?.hasMoreToLoad(Timeline.Direction.BACKWARDS) ?: false
|
||||||
|
if (shouldAddBackwardPrefetch) {
|
||||||
|
val indexOfPrefetchBackward = (previousModelsSize - 1)
|
||||||
|
.coerceAtMost(models.size - DEFAULT_PREFETCH_THRESHOLD)
|
||||||
|
.coerceAtLeast(0)
|
||||||
|
|
||||||
|
val loadingItem = LoadingItem_()
|
||||||
|
.id("prefetch_backward_loading${System.currentTimeMillis()}")
|
||||||
|
.showLoader(false)
|
||||||
|
.setVisibilityStateChangedListener(Timeline.Direction.BACKWARDS)
|
||||||
|
|
||||||
|
models.add(indexOfPrefetchBackward, loadingItem)
|
||||||
|
}
|
||||||
|
val shouldAddForwardPrefetch = timeline?.hasMoreToLoad(Timeline.Direction.FORWARDS) ?: false
|
||||||
|
if (shouldAddForwardPrefetch) {
|
||||||
|
val indexOfPrefetchForward = DEFAULT_PREFETCH_THRESHOLD.coerceAtMost(models.size - 1)
|
||||||
|
val loadingItem = LoadingItem_()
|
||||||
|
.id("prefetch_forward_loading${System.currentTimeMillis()}")
|
||||||
|
.showLoader(false)
|
||||||
|
.setVisibilityStateChangedListener(Timeline.Direction.FORWARDS)
|
||||||
|
models.add(indexOfPrefetchForward, loadingItem)
|
||||||
|
}
|
||||||
|
previousModelsSize = models.size
|
||||||
}
|
}
|
||||||
|
|
||||||
fun update(viewState: RoomDetailViewState) {
|
fun update(viewState: RoomDetailViewState) {
|
||||||
|
@ -355,9 +381,6 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
|
||||||
return shouldAdd
|
return shouldAdd
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if added
|
|
||||||
*/
|
|
||||||
private fun LoadingItem_.setVisibilityStateChangedListener(direction: Timeline.Direction): LoadingItem_ {
|
private fun LoadingItem_.setVisibilityStateChangedListener(direction: Timeline.Direction): LoadingItem_ {
|
||||||
return onVisibilityStateChanged { _, _, visibilityState ->
|
return onVisibilityStateChanged { _, _, visibilityState ->
|
||||||
if (visibilityState == VisibilityState.VISIBLE) {
|
if (visibilityState == VisibilityState.VISIBLE) {
|
||||||
|
|
|
@ -33,6 +33,7 @@ import im.vector.app.R
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.glide.GlideApp
|
import im.vector.app.core.glide.GlideApp
|
||||||
import im.vector.app.core.glide.GlideRequest
|
import im.vector.app.core.glide.GlideRequest
|
||||||
|
import im.vector.app.core.glide.GlideRequests
|
||||||
import im.vector.app.core.ui.model.Size
|
import im.vector.app.core.ui.model.Size
|
||||||
import im.vector.app.core.utils.DimensionConverter
|
import im.vector.app.core.utils.DimensionConverter
|
||||||
import im.vector.app.core.utils.isLocalFile
|
import im.vector.app.core.utils.isLocalFile
|
||||||
|
@ -206,12 +207,14 @@ class ImageContentRenderer @Inject constructor(private val activeSessionHolder:
|
||||||
.into(imageView)
|
.into(imageView)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createGlideRequest(data: Data, mode: Mode, imageView: ImageView, size: Size): GlideRequest<Drawable> {
|
fun createGlideRequest(data: Data, mode: Mode, imageView: ImageView, size: Size): GlideRequest<Drawable> {
|
||||||
|
return createGlideRequest(data, mode, GlideApp.with(imageView), size)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createGlideRequest(data: Data, mode: Mode, glideRequests: GlideRequests, size: Size = processSize(data, mode)): GlideRequest<Drawable> {
|
||||||
return if (data.elementToDecrypt != null) {
|
return if (data.elementToDecrypt != null) {
|
||||||
// Encrypted image
|
// Encrypted image
|
||||||
GlideApp
|
glideRequests.load(data)
|
||||||
.with(imageView)
|
|
||||||
.load(data)
|
|
||||||
} else {
|
} else {
|
||||||
// Clear image
|
// Clear image
|
||||||
val contentUrlResolver = activeSessionHolder.getActiveSession().contentUrlResolver()
|
val contentUrlResolver = activeSessionHolder.getActiveSession().contentUrlResolver()
|
||||||
|
@ -223,15 +226,12 @@ class ImageContentRenderer @Inject constructor(private val activeSessionHolder:
|
||||||
// Fallback to base url
|
// Fallback to base url
|
||||||
?: data.url.takeIf { it?.startsWith("content://") == true }
|
?: data.url.takeIf { it?.startsWith("content://") == true }
|
||||||
|
|
||||||
GlideApp
|
glideRequests
|
||||||
.with(imageView)
|
|
||||||
.load(resolvedUrl)
|
.load(resolvedUrl)
|
||||||
.apply {
|
.apply {
|
||||||
if (mode == Mode.THUMBNAIL) {
|
if (mode == Mode.THUMBNAIL) {
|
||||||
error(
|
error(
|
||||||
GlideApp
|
glideRequests.load(resolveUrl(data))
|
||||||
.with(imageView)
|
|
||||||
.load(resolveUrl(data))
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue