From aaed948b00613b856e5202e198541aafd96b5f19 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 24 Aug 2018 13:03:21 +0200 Subject: [PATCH 1/6] Create room with bot for any home server and not only matrix.org --- .../java/im/vector/webview/ConsentWebViewEventListener.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/webview/ConsentWebViewEventListener.kt b/vector/src/main/java/im/vector/webview/ConsentWebViewEventListener.kt index ee74c8677..763fd249a 100644 --- a/vector/src/main/java/im/vector/webview/ConsentWebViewEventListener.kt +++ b/vector/src/main/java/im/vector/webview/ConsentWebViewEventListener.kt @@ -16,7 +16,6 @@ package im.vector.webview -import android.text.TextUtils import im.vector.Matrix import im.vector.activity.VectorAppCompatActivity import im.vector.util.weak @@ -25,7 +24,7 @@ import org.matrix.androidsdk.rest.model.MatrixError import org.matrix.androidsdk.rest.model.RoomMember import org.matrix.androidsdk.util.Log -private const val SUCCESS_URL = "https://matrix.org/_matrix/consent" +private const val SUCCESS_URL_SUFFIX = "/_matrix/consent" private const val RIOT_BOT_ID = "@riot-bot:matrix.org" private const val LOG_TAG = "ConsentWebViewEventListener" @@ -40,7 +39,7 @@ class ConsentWebViewEventListener(activity: VectorAppCompatActivity, private val override fun onPageFinished(url: String) { delegate.onPageFinished(url) - if (TextUtils.equals(url, SUCCESS_URL)) { + if (url.endsWith(SUCCESS_URL_SUFFIX)) { createRiotBotRoomIfNeeded() } } From ef3d1750be9387943f7267568b8abb66ef8cafbf Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 24 Aug 2018 15:48:42 +0200 Subject: [PATCH 2/6] Ensure we can create a Room with riot-bot, to avoid being stuck and create a lot of empty rooms. --- .../im/vector/webview/ConsentWebViewEventListener.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/webview/ConsentWebViewEventListener.kt b/vector/src/main/java/im/vector/webview/ConsentWebViewEventListener.kt index 763fd249a..c7371c9cd 100644 --- a/vector/src/main/java/im/vector/webview/ConsentWebViewEventListener.kt +++ b/vector/src/main/java/im/vector/webview/ConsentWebViewEventListener.kt @@ -20,6 +20,7 @@ import im.vector.Matrix import im.vector.activity.VectorAppCompatActivity import im.vector.util.weak import org.matrix.androidsdk.rest.callback.ApiCallback +import org.matrix.androidsdk.rest.callback.SimpleApiCallback import org.matrix.androidsdk.rest.model.MatrixError import org.matrix.androidsdk.rest.model.RoomMember import org.matrix.androidsdk.util.Log @@ -55,7 +56,14 @@ class ConsentWebViewEventListener(activity: VectorAppCompatActivity, private val } if (joinedRooms.isEmpty()) { it.showWaitingView() - session.createDirectMessageRoom(RIOT_BOT_ID, createRiotBotRoomCallback) + // Ensure we can create a Room with riot-bot. Error can be a MatrixError: "Federation denied with matrix.org.", or any other error. + session.profileApiClient + .displayname(RIOT_BOT_ID, object : SimpleApiCallback(createRiotBotRoomCallback) { + override fun onSuccess(info: String?) { + // Ok, the Home Server knows riot-Bot, so create a Room with him + session.createDirectMessageRoom(RIOT_BOT_ID, createRiotBotRoomCallback) + } + }) } else { it.finish() } From d9e2685c1ae42c8aa9e04e5ab3a59728588bd14c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 24 Aug 2018 15:50:07 +0200 Subject: [PATCH 3/6] SimpleApiCallback does not implements onSuccess() anymore --- vector/src/main/java/im/vector/LoginHandler.java | 10 ++++++++++ .../java/im/vector/UnrecognizedCertApiCallback.java | 6 ++---- .../java/im/vector/activity/VectorRoomActivity.java | 7 ++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/vector/src/main/java/im/vector/LoginHandler.java b/vector/src/main/java/im/vector/LoginHandler.java index 0bdd8c6be..b6ddef5aa 100644 --- a/vector/src/main/java/im/vector/LoginHandler.java +++ b/vector/src/main/java/im/vector/LoginHandler.java @@ -151,6 +151,11 @@ public void getSupportedLoginFlows(Context ctx, final HomeServerConnectionConfig LoginRestClient client = new LoginRestClient(hsConfig); client.getSupportedLoginFlows(new UnrecognizedCertApiCallback>(hsConfig, callback) { + @Override + public void onSuccess(List info) { + callback.onSuccess(info); + } + @Override public void onAcceptedCert() { getSupportedLoginFlows(appCtx, hsConfig, callback); @@ -221,6 +226,11 @@ public void submitEmailTokenValidation(final Context aCtx, ThirdPidRestClient restClient = new ThirdPidRestClient(aHomeServerConfig); pid.submitValidationToken(restClient, aToken, aClientSecret, aSid, new UnrecognizedCertApiCallback(aHomeServerConfig, aRespCallback) { + @Override + public void onSuccess(Boolean info) { + aRespCallback.onSuccess(info); + } + @Override public void onAcceptedCert() { submitEmailTokenValidation(aCtx, aHomeServerConfig, aToken, aClientSecret, aSid, aRespCallback); diff --git a/vector/src/main/java/im/vector/UnrecognizedCertApiCallback.java b/vector/src/main/java/im/vector/UnrecognizedCertApiCallback.java index bdd4beffd..6bed6d90a 100644 --- a/vector/src/main/java/im/vector/UnrecognizedCertApiCallback.java +++ b/vector/src/main/java/im/vector/UnrecognizedCertApiCallback.java @@ -7,7 +7,7 @@ /** * Handle certificate errors in API callbacks */ -public class UnrecognizedCertApiCallback extends SimpleApiCallback { +public abstract class UnrecognizedCertApiCallback extends SimpleApiCallback { private HomeServerConnectionConfig mHsConfig; private ApiCallback mCallback; @@ -27,9 +27,7 @@ public UnrecognizedCertApiCallback(HomeServerConnectionConfig hsConfig) { * * The usual behavior is to play the request again */ - public void onAcceptedCert() { - - } + public abstract void onAcceptedCert(); /** * The request failed because of an unknown TLS certificate or a network error diff --git a/vector/src/main/java/im/vector/activity/VectorRoomActivity.java b/vector/src/main/java/im/vector/activity/VectorRoomActivity.java index ef2b0e52b..18642e15d 100755 --- a/vector/src/main/java/im/vector/activity/VectorRoomActivity.java +++ b/vector/src/main/java/im/vector/activity/VectorRoomActivity.java @@ -2128,7 +2128,12 @@ private void cancelTypingNotification() { mLastTypingDate = 0; - mRoom.sendTypingNotification(false, -1, new SimpleApiCallback(this)); + mRoom.sendTypingNotification(false, -1, new SimpleApiCallback(this) { + @Override + public void onSuccess(Void info) { + // Ignore + } + }); } } From 9cc639aedd4426206c0c631dfea8bcc09cb626a7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 24 Aug 2018 17:54:08 +0200 Subject: [PATCH 4/6] "admin_contact" is optional --- .../dialogs/ResourceLimitDialogHelper.kt | 27 ++++++++++--------- .../error/ResourceLimitErrorFormatter.kt | 15 ++++++----- .../vector/util/ExternalApplicationsUtil.kt | 15 ++++++++++- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/vector/src/main/java/im/vector/dialogs/ResourceLimitDialogHelper.kt b/vector/src/main/java/im/vector/dialogs/ResourceLimitDialogHelper.kt index a8240b7f7..b924bfdd7 100644 --- a/vector/src/main/java/im/vector/dialogs/ResourceLimitDialogHelper.kt +++ b/vector/src/main/java/im/vector/dialogs/ResourceLimitDialogHelper.kt @@ -25,9 +25,8 @@ import com.binaryfork.spanny.Spanny import im.vector.R import im.vector.activity.interfaces.Restorable import im.vector.error.ResourceLimitErrorFormatter -import im.vector.util.sendMailTo +import im.vector.util.openUri import org.matrix.androidsdk.rest.model.MatrixError -import org.matrix.androidsdk.util.Log private const val LOG_TAG = "ResourceLimitDialogHelper" @@ -48,22 +47,26 @@ class ResourceLimitDialogHelper private constructor(private val activity: Activi * Display the resource limit dialog, if not already displayed */ fun displayDialog(matrixError: MatrixError) { - if (matrixError.adminContact == null) { - Log.e(LOG_TAG, "Missing required parameter 'admin_contact'") - return - } - dialogLocker.displayDialog { val title = Spanny(activity.getString(R.string.resource_limit_exceeded_title), StyleSpan(Typeface.BOLD)) val message = formatter.format(matrixError, ResourceLimitErrorFormatter.Mode.Hard, separator = "\n\n") - AlertDialog.Builder(activity, R.style.AppTheme_Dialog_Light) + val builder = AlertDialog.Builder(activity, R.style.AppTheme_Dialog_Light) .setTitle(title) .setMessage(message) - .setPositiveButton(R.string.resource_limit_contact_action) { _, _ -> - sendMailTo(matrixError.adminContact, activity = activity) - } - .setNegativeButton(R.string.cancel, null) + + if (matrixError.adminUri != null) { + builder + .setPositiveButton(R.string.resource_limit_contact_action) { _, _ -> + openUri(activity, matrixError.adminUri!!) + } + .setNegativeButton(R.string.cancel, null) + + } else { + builder.setPositiveButton(R.string.ok, null) + } + + builder } } diff --git a/vector/src/main/java/im/vector/error/ResourceLimitErrorFormatter.kt b/vector/src/main/java/im/vector/error/ResourceLimitErrorFormatter.kt index 66f540977..9716b55fb 100644 --- a/vector/src/main/java/im/vector/error/ResourceLimitErrorFormatter.kt +++ b/vector/src/main/java/im/vector/error/ResourceLimitErrorFormatter.kt @@ -38,30 +38,31 @@ class ResourceLimitErrorFormatter(private val context: Context) { mode: Mode, separator: CharSequence = " ", clickable: Boolean = false): CharSequence { - - val error = if (MatrixError.LIMITE_TYPE_MAU == matrixError.limitType) { + val error = if (MatrixError.LIMIT_TYPE_MAU == matrixError.limitType) { context.getString(mode.mauErrorRes) } else { context.getString(mode.defaultErrorRes) } - val contact = if (clickable) { - val contactSubString = contactAsLink(matrixError.adminContact) + + val contact = if (clickable && matrixError.adminUri != null) { + val contactSubString = uriAsLink(matrixError.adminUri!!) val contactFullString = context.getString(mode.contactRes, contactSubString) Html.fromHtml(contactFullString) } else { val contactSubString = context.getString(R.string.resource_limit_contact_admin) context.getString(mode.contactRes, contactSubString) } + return Spanny(error) .append(separator) .append(contact) } /** - * Create a HTML link with an email address + * Create a HTML link with a uri */ - private fun contactAsLink(email: String): String { + private fun uriAsLink(uri: String): String { val contactStr = context.getString(R.string.resource_limit_contact_admin) - return "$contactStr" + return "$contactStr" } } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/util/ExternalApplicationsUtil.kt b/vector/src/main/java/im/vector/util/ExternalApplicationsUtil.kt index d103f26b0..538c2fc43 100644 --- a/vector/src/main/java/im/vector/util/ExternalApplicationsUtil.kt +++ b/vector/src/main/java/im/vector/util/ExternalApplicationsUtil.kt @@ -191,4 +191,17 @@ fun sendMailTo(address: String, subject: String? = null, message: String? = null } catch (activityNotFoundException: ActivityNotFoundException) { activity.toast(R.string.error_no_external_application_found) } -} \ No newline at end of file +} + +/** + * Open an arbitrary uri + */ +fun openUri(activity: Activity, uri: String) { + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(uri)) + + try { + activity.startActivity(intent) + } catch (activityNotFoundException: ActivityNotFoundException) { + activity.toast(R.string.error_no_external_application_found) + } +} From a33e8b04e6bb4a4341a1c9ade954d965301ac937 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 24 Aug 2018 18:03:57 +0200 Subject: [PATCH 5/6] Fix UI: A white line was displayed below the NotificationArea --- .../main/java/im/vector/activity/VectorRoomActivity.java | 8 +++++++- vector/src/main/res/layout/activity_vector_room.xml | 1 + vector/src/main/res/layout/view_notification_area.xml | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/activity/VectorRoomActivity.java b/vector/src/main/java/im/vector/activity/VectorRoomActivity.java index 18642e15d..7dba87458 100755 --- a/vector/src/main/java/im/vector/activity/VectorRoomActivity.java +++ b/vector/src/main/java/im/vector/activity/VectorRoomActivity.java @@ -225,6 +225,9 @@ public class VectorRoomActivity extends MXCActionBarActivity implements private ImageView mAvatarImageView; + @BindView(R.id.bottom_separator) + View mBottomSeparator; + @BindView(R.id.room_cannot_post_textview) View mCanNotPostTextView; @@ -788,7 +791,7 @@ public void onTextChanged(CharSequence s, int start, int before, int count) { if ((!TextUtils.isEmpty(mEventId) || (null != sRoomPreviewData)) || hasBeenKicked) { if (!mIsUnreadPreviewMode || hasBeenKicked) { mNotificationsArea.setVisibility(View.GONE); - findViewById(R.id.bottom_separator).setVisibility(View.GONE); + mBottomSeparator.setVisibility(View.GONE); findViewById(R.id.room_notification_separator).setVisibility(View.GONE); } @@ -2949,11 +2952,14 @@ private void checkSendEventStatus() { if (canSendMessages(state)) { mBottomLayout.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT; + mBottomSeparator.setVisibility(View.VISIBLE); mSendingMessagesLayout.setVisibility(View.VISIBLE); mCanNotPostTextView.setVisibility(View.GONE); } else if (state.isVersioned() || mResourceLimitExceededError != null) { + mBottomSeparator.setVisibility(View.GONE); mBottomLayout.getLayoutParams().height = 0; } else { + mBottomSeparator.setVisibility(View.GONE); mSendingMessagesLayout.setVisibility(View.GONE); mCanNotPostTextView.setVisibility(View.VISIBLE); } diff --git a/vector/src/main/res/layout/activity_vector_room.xml b/vector/src/main/res/layout/activity_vector_room.xml index 0009f7123..9cd8324cb 100644 --- a/vector/src/main/res/layout/activity_vector_room.xml +++ b/vector/src/main/res/layout/activity_vector_room.xml @@ -345,6 +345,7 @@ android:paddingBottom="8dp" android:paddingTop="8dp" android:visibility="invisible" + tools:background="@color/vector_fuchsia_color" tools:visibility="visible" /> Date: Fri, 24 Aug 2018 18:33:11 +0200 Subject: [PATCH 6/6] Handle resource limit reach for registration --- .../java/im/vector/RegistrationManager.java | 22 +++++++++++++++++++ .../im/vector/activity/LoginActivity.java | 6 +++++ 2 files changed, 28 insertions(+) diff --git a/vector/src/main/java/im/vector/RegistrationManager.java b/vector/src/main/java/im/vector/RegistrationManager.java index 133b22ef0..201846370 100644 --- a/vector/src/main/java/im/vector/RegistrationManager.java +++ b/vector/src/main/java/im/vector/RegistrationManager.java @@ -215,6 +215,12 @@ public void onRegistrationSuccess() { public void onRegistrationFailed(String message) { listener.onUsernameAvailabilityChecked(!TextUtils.equals(MatrixError.USER_IN_USE, message)); } + + @Override + public void onResourceLimitExceeded(MatrixError e) { + // Should not happen, consider user is available, registration will fail later on + listener.onUsernameAvailabilityChecked(true); + } }); } } @@ -353,6 +359,11 @@ public void onRegistrationFailed(String message) { listener.onRegistrationFailed(message); } } + + @Override + public void onResourceLimitExceeded(MatrixError e) { + listener.onResourceLimitExceeded(e); + } }); } } @@ -402,6 +413,11 @@ public void onRegistrationFailed(String message) { listener.onRegistrationFailed(message); } } + + @Override + public void onResourceLimitExceeded(MatrixError e) { + listener.onResourceLimitExceeded(e); + } }); } @@ -973,6 +989,8 @@ public void onMatrixError(MatrixError e) { Log.e(LOG_TAG, "JsonUtils.toRegistrationFlowResponse " + castExcept.getLocalizedMessage(), castExcept); } listener.onRegistrationFailed(ERROR_MISSING_STAGE); + } else if (TextUtils.equals(e.errcode, MatrixError.RESOURCE_LIMIT_EXCEEDED)) { + listener.onResourceLimitExceeded(e); } else { listener.onRegistrationFailed(""); } @@ -991,6 +1009,8 @@ private interface InternalRegistrationListener { void onRegistrationSuccess(); void onRegistrationFailed(String message); + + void onResourceLimitExceeded(MatrixError e); } /* @@ -1023,5 +1043,7 @@ public interface RegistrationListener { void onWaitingCaptcha(); void onThreePidRequestFailed(String message); + + void onResourceLimitExceeded(MatrixError e); } } diff --git a/vector/src/main/java/im/vector/activity/LoginActivity.java b/vector/src/main/java/im/vector/activity/LoginActivity.java index 279302419..2a1cc62d5 100644 --- a/vector/src/main/java/im/vector/activity/LoginActivity.java +++ b/vector/src/main/java/im/vector/activity/LoginActivity.java @@ -2497,4 +2497,10 @@ public void onUsernameAvailabilityChecked(boolean isAvailable) { } } } + + @Override + public void onResourceLimitExceeded(MatrixError e) { + enableLoadingScreen(false); + mResourceLimitDialogHelper.displayDialog(e); + } }