Unverified Commit 03875bab authored by Rafael Kellermann Streit's avatar Rafael Kellermann Streit Committed by GitHub

Merge pull request #1156 from RocketChat/develop

[RELEASE] Merge develop into master
parents a886add5 16f3a41c
...@@ -47,6 +47,10 @@ android { ...@@ -47,6 +47,10 @@ android {
packagingOptions { packagingOptions {
exclude 'META-INF/core.kotlin_module' exclude 'META-INF/core.kotlin_module'
} }
lintOptions{
disable 'MissingTranslation'
}
} }
dependencies { dependencies {
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission <permission
......
...@@ -11,8 +11,19 @@ interface VersionCheckView { ...@@ -11,8 +11,19 @@ interface VersionCheckView {
*/ */
fun blockAndAlertNotRequiredVersion() fun blockAndAlertNotRequiredVersion()
/**
* Alerts the user that an error has occurred while checking the server version
* This is optional.
*/
fun errorCheckingServerVersion() {}
/** /**
* Do some action if version is ok. This is optional. * Do some action if version is ok. This is optional.
*/ */
fun versionOk() {} fun versionOk() {}
/**
* Alters the user this protocol is invalid. This is optional.
*/
fun errorInvalidProtocol() {}
} }
\ No newline at end of file
...@@ -8,6 +8,8 @@ import android.view.LayoutInflater ...@@ -8,6 +8,8 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import android.widget.AdapterView
import android.widget.ArrayAdapter
import chat.rocket.android.BuildConfig import chat.rocket.android.BuildConfig
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo import chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo
...@@ -38,6 +40,8 @@ class ServerFragment : Fragment(), ServerView { ...@@ -38,6 +40,8 @@ class ServerFragment : Fragment(), ServerView {
} }
} }
private var protocol = "https://"
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
...@@ -55,9 +59,40 @@ class ServerFragment : Fragment(), ServerView { ...@@ -55,9 +59,40 @@ class ServerFragment : Fragment(), ServerView {
deepLinkInfo?.let { deepLinkInfo?.let {
val uri = Uri.parse(it.url) val uri = Uri.parse(it.url)
uri?.let { text_server_protocol.hintContent = it.host } uri?.let { text_server_url.hintContent = it.host }
presenter.deepLink(it) presenter.deepLink(it)
} }
text_server_protocol.adapter = ArrayAdapter<String>(activity,
android.R.layout.simple_dropdown_item_1line, arrayOf("https://", "http://"))
text_server_protocol.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
when(position) {
0 -> {
protocol = "https://"
}
1 -> {
ui{
AlertDialog.Builder(it)
.setTitle(R.string.msg_warning)
.setMessage(R.string.msg_http_insecure)
.setPositiveButton(R.string.msg_proceed) { _, _ ->
protocol = "http://"
}
.setNegativeButton(R.string.msg_cancel) { _, _ ->
text_server_protocol.setSelection(0)
}
.setCancelable(false)
.create()
.show()
}
}
}
}
override fun onNothingSelected(parent: AdapterView<*>?) {
}
}
} }
override fun onDestroyView() { override fun onDestroyView() {
...@@ -129,13 +164,23 @@ class ServerFragment : Fragment(), ServerView { ...@@ -129,13 +164,23 @@ class ServerFragment : Fragment(), ServerView {
performConnect() performConnect()
} }
override fun errorCheckingServerVersion() {
hideLoading()
showMessage(R.string.msg_error_checking_server_version)
}
override fun errorInvalidProtocol() {
hideLoading()
showMessage(R.string.msg_invalid_server_protocol)
}
private fun performConnect() { private fun performConnect() {
ui { ui {
deepLinkInfo?.let { deepLinkInfo?.let {
presenter.deepLink(it) presenter.deepLink(it)
}.ifNull { }.ifNull {
val url = text_server_url.textContent.ifEmpty(text_server_url.hintContent) val url = text_server_url.textContent.ifEmpty(text_server_url.hintContent)
presenter.connect(text_server_protocol.textContent + url) presenter.connect("${protocol}${url.sanitize()}")
} }
} }
} }
...@@ -149,7 +194,7 @@ class ServerFragment : Fragment(), ServerView { ...@@ -149,7 +194,7 @@ class ServerFragment : Fragment(), ServerView {
ui { ui {
button_connect.setOnClickListener { button_connect.setOnClickListener {
val url = text_server_url.textContent.ifEmpty(text_server_url.hintContent) val url = text_server_url.textContent.ifEmpty(text_server_url.hintContent)
presenter.checkServer(text_server_protocol.textContent + url) presenter.checkServer("${protocol}${url.sanitize()}")
} }
} }
} }
......
package chat.rocket.android.chatroom.ui package chat.rocket.android.chatroom.ui
import android.Manifest
import android.app.Activity import android.app.Activity
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.support.annotation.DrawableRes import android.support.annotation.DrawableRes
import android.support.v4.app.ActivityCompat
import android.support.v4.app.Fragment import android.support.v4.app.Fragment
import android.support.v4.content.ContextCompat
import android.support.v7.widget.DefaultItemAnimator import android.support.v7.widget.DefaultItemAnimator
import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
...@@ -468,31 +464,13 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -468,31 +464,13 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
override fun showFileSelection(filter: Array<String>) { override fun showFileSelection(filter: Array<String>) {
ui { ui {
if (ContextCompat.checkSelfPermission(it, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(it,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
1)
} else {
val intent = Intent(Intent.ACTION_GET_CONTENT) val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "*/*" intent.type = "*/*"
intent.putExtra(Intent.EXTRA_MIME_TYPES, filter) intent.putExtra(Intent.EXTRA_MIME_TYPES, filter)
intent.addCategory(Intent.CATEGORY_OPENABLE)
startActivityForResult(intent, REQUEST_CODE_FOR_PERFORM_SAF) startActivityForResult(intent, REQUEST_CODE_FOR_PERFORM_SAF)
} }
} }
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
when (requestCode) {
1 -> {
if (!(grantResults.isNotEmpty() && grantResults.first() == PackageManager.PERMISSION_GRANTED)) {
handler.postDelayed({
ui { hideAttachmentOptions() }
}, 400)
}
}
}
}
override fun showInvalidFileSize(fileSize: Int, maxFileSize: Int) { override fun showInvalidFileSize(fileSize: Int, maxFileSize: Int) {
showMessage(getString(R.string.max_file_size_exceeded, fileSize, maxFileSize)) showMessage(getString(R.string.max_file_size_exceeded, fileSize, maxFileSize))
......
...@@ -118,6 +118,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView, ...@@ -118,6 +118,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
type = RoomType.DIRECT_MESSAGE, type = RoomType.DIRECT_MESSAGE,
user = SimpleUser(username = it.username, name = it.name, id = null), user = SimpleUser(username = it.username, name = it.name, id = null),
name = it.name ?: "", name = it.name ?: "",
status = null,
fullName = it.name, fullName = it.name,
readonly = false, readonly = false,
updatedAt = null, updatedAt = null,
...@@ -144,6 +145,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView, ...@@ -144,6 +145,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
type = it.type, type = it.type,
user = it.user, user = it.user,
name = it.name ?: "", name = it.name ?: "",
status = null,
fullName = it.fullName, fullName = it.fullName,
readonly = it.readonly, readonly = it.readonly,
updatedAt = it.updatedAt, updatedAt = it.updatedAt,
...@@ -349,6 +351,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView, ...@@ -349,6 +351,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
type = room.type, type = room.type,
user = room.user ?: user, user = room.user ?: user,
name = room.name ?: name, name = room.name ?: name,
status = null,
fullName = room.fullName ?: fullName, fullName = room.fullName ?: fullName,
readonly = room.readonly, readonly = room.readonly,
updatedAt = room.updatedAt ?: updatedAt, updatedAt = room.updatedAt ?: updatedAt,
...@@ -382,6 +385,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView, ...@@ -382,6 +385,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
type = subscription.type, type = subscription.type,
user = subscription.user ?: user, user = subscription.user ?: user,
name = subscription.name, name = subscription.name,
status = null,
fullName = subscription.fullName ?: fullName, fullName = subscription.fullName ?: fullName,
readonly = subscription.readonly ?: readonly, readonly = subscription.readonly ?: readonly,
updatedAt = subscription.updatedAt ?: updatedAt, updatedAt = subscription.updatedAt ?: updatedAt,
......
...@@ -2,15 +2,15 @@ package chat.rocket.android.server.infraestructure ...@@ -2,15 +2,15 @@ package chat.rocket.android.server.infraestructure
import chat.rocket.common.model.BaseRoom import chat.rocket.common.model.BaseRoom
import chat.rocket.core.RocketChatClient import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.realtime.subscribeSubscriptions
import chat.rocket.core.internal.realtime.subscribeRooms
import chat.rocket.core.internal.realtime.subscribeUserData
import chat.rocket.core.internal.realtime.subscribeRoomMessages
import chat.rocket.core.internal.realtime.unsubscribe import chat.rocket.core.internal.realtime.unsubscribe
import chat.rocket.core.internal.realtime.socket.connect import chat.rocket.core.internal.realtime.socket.connect
import chat.rocket.core.internal.realtime.socket.disconnect import chat.rocket.core.internal.realtime.socket.disconnect
import chat.rocket.core.internal.realtime.socket.model.State import chat.rocket.core.internal.realtime.socket.model.State
import chat.rocket.core.internal.realtime.socket.model.StreamMessage import chat.rocket.core.internal.realtime.socket.model.StreamMessage
import chat.rocket.core.internal.realtime.subscribeRoomMessages
import chat.rocket.core.internal.realtime.subscribeRooms
import chat.rocket.core.internal.realtime.subscribeSubscriptions
import chat.rocket.core.internal.realtime.subscribeUserDataChanges
import chat.rocket.core.internal.rest.chatRooms import chat.rocket.core.internal.rest.chatRooms
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
import chat.rocket.core.model.Myself import chat.rocket.core.model.Myself
...@@ -60,7 +60,7 @@ class ConnectionManager(internal val client: RocketChatClient) { ...@@ -60,7 +60,7 @@ class ConnectionManager(internal val client: RocketChatClient) {
Timber.d("Subscribed to rooms: $id") Timber.d("Subscribed to rooms: $id")
roomsId = id roomsId = id
} }
client.subscribeUserDataChanges { _, id -> client.subscribeUserData { _, id ->
Timber.d("Subscribed to the user: $id") Timber.d("Subscribed to the user: $id")
userId = id userId = id
} }
......
...@@ -7,6 +7,7 @@ import chat.rocket.android.server.infraestructure.RocketChatClientFactory ...@@ -7,6 +7,7 @@ import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.VersionInfo import chat.rocket.android.util.VersionInfo
import chat.rocket.android.util.extensions.launchUI import chat.rocket.android.util.extensions.launchUI
import chat.rocket.android.util.retryIO import chat.rocket.android.util.retryIO
import chat.rocket.common.RocketChatInvalidProtocolException
import chat.rocket.core.RocketChatClient import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.serverInfo import chat.rocket.core.internal.rest.serverInfo
import kotlinx.coroutines.experimental.Deferred import kotlinx.coroutines.experimental.Deferred
...@@ -42,6 +43,14 @@ abstract class CheckServerPresenter constructor(private val strategy: CancelStra ...@@ -42,6 +43,14 @@ abstract class CheckServerPresenter constructor(private val strategy: CancelStra
} }
} catch (ex: Exception) { } catch (ex: Exception) {
Timber.d(ex, "Error getting server info") Timber.d(ex, "Error getting server info")
when(ex) {
is RocketChatInvalidProtocolException -> {
view.errorInvalidProtocol()
}
else -> {
view.errorCheckingServerVersion()
}
}
} }
} }
} }
......
...@@ -4,12 +4,17 @@ import android.util.Patterns ...@@ -4,12 +4,17 @@ import android.util.Patterns
fun String.removeTrailingSlash(): String { fun String.removeTrailingSlash(): String {
return if (isNotEmpty() && this[length - 1] == '/') { return if (isNotEmpty() && this[length - 1] == '/') {
this.replace("/+$", "") this.substring(0, length - 1)
} else { } else {
this this
} }
} }
fun String.sanitize(): String {
val tmp = this.trim()
return tmp.removeTrailingSlash()
}
fun String.avatarUrl(avatar: String, isGroupOrChannel: Boolean = false, format: String = "jpeg"): String { fun String.avatarUrl(avatar: String, isGroupOrChannel: Boolean = false, format: String = "jpeg"): String {
return if (isGroupOrChannel) { return if (isGroupOrChannel) {
"${removeTrailingSlash()}/avatar/%23${avatar.removeTrailingSlash()}?format=$format" "${removeTrailingSlash()}/avatar/%23${avatar.removeTrailingSlash()}?format=$format"
......
...@@ -18,24 +18,30 @@ ...@@ -18,24 +18,30 @@
android:id="@+id/text_server_url" android:id="@+id/text_server_url"
style="@style/Authentication.EditText" style="@style/Authentication.EditText"
android:layout_below="@id/text_headline" android:layout_below="@id/text_headline"
android:layout_marginStart="-4dp" android:layout_marginStart="-6dp"
android:layout_marginTop="32dp" android:layout_marginTop="32dp"
android:layout_toEndOf="@id/text_server_protocol" android:layout_toEndOf="@id/protocol_container"
android:cursorVisible="false" android:cursorVisible="false"
android:hint="@string/default_server" android:hint="@string/default_server"
android:imeOptions="actionDone" android:imeOptions="actionDone"
android:digits="0123456789abcdefghijklmnopqrstuvwxyz.-/:" android:inputType="text|textUri"
android:inputType="textUri" android:paddingEnd="0dp" />
android:paddingEnd="0dp"
android:paddingStart="4dp" />
<TextView <FrameLayout
android:id="@+id/text_server_protocol" android:id="@+id/protocol_container"
style="@style/Authentication.TextView" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/style_edit_text_authentication"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins"
android:layout_below="@id/text_headline" android:layout_below="@id/text_headline"
android:layout_marginTop="32dp" android:layout_marginTop="32dp">
android:gravity="center_vertical" <Spinner
android:text="@string/default_protocol" /> android:id="@+id/text_server_protocol"
android:spinnerMode="dropdown"
android:layout_width="120dp"
android:layout_height="50dp"
android:backgroundTint="@color/actionMenuColor" />
</FrameLayout>
<com.wang.avi.AVLoadingIndicatorView <com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_loading" android:id="@+id/view_loading"
......
<resources> <resources
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="MissingTranslation">
<!-- Titles --> <!-- Titles -->
<string name="title_sign_in_your_server">अपने सर्वर में साइन इन करें</string> <string name="title_sign_in_your_server">अपने सर्वर में साइन इन करें</string>
......
...@@ -89,6 +89,12 @@ ...@@ -89,6 +89,12 @@
<string name="msg_ver_not_minimum"> <string name="msg_ver_not_minimum">
Parece que a versão do seu servidor está abaixo da mínima requerida %1$s.\nPor favor, atualize seus servidores antes de continuar! Parece que a versão do seu servidor está abaixo da mínima requerida %1$s.\nPor favor, atualize seus servidores antes de continuar!
</string> </string>
<string name="msg_proceed">CONTINUAR</string>
<string name="msg_cancel">CANCELAR</string>
<string name="msg_warning">AVISO</string>
<string name="msg_http_insecure">Usando HTTP, você estará conectando a um servidor não seguro, não recomendamos sua utilização.</string>
<string name="msg_error_checking_server_version">Ocorreu um erro verificando a versão do servidor, por favor tente novamente</string>
<string name="msg_invalid_server_protocol">O protocolo selecionado não é suportado pelo servidor, por favor utilize HTTPS e tente novamente</string>
<!-- System messages --> <!-- System messages -->
<string name="message_room_name_changed">Nome da sala alterado para: %1$s por %2$s</string> <string name="message_room_name_changed">Nome da sala alterado para: %1$s por %2$s</string>
...@@ -130,12 +136,12 @@ ...@@ -130,12 +136,12 @@
<string name="max_file_size_exceeded">Tamanho de arquivo (%1$d bytes) excedeu tamanho máximo de upload (%2$d bytes)</string> <string name="max_file_size_exceeded">Tamanho de arquivo (%1$d bytes) excedeu tamanho máximo de upload (%2$d bytes)</string>
<!-- Socket status --> <!-- Socket status -->
<string name="status_connected">conectado</string> <string name="status_connected">Conectado</string>
<string name="status_disconnected">desconetado</string> <string name="status_disconnected">Desconetado</string>
<string name="status_connecting">conectando</string> <string name="status_connecting">Conectando</string>
<string name="status_authenticating">autenticando</string> <string name="status_authenticating">Autenticando</string>
<string name="status_disconnecting">desconectando</string> <string name="status_disconnecting">Desconectando</string>
<string name="status_waiting">conectando em %d segundos</string> <string name="status_waiting">Conectando em %d segundos</string>
<!--Suggestions--> <!--Suggestions-->
<string name="suggest_all_description">Notifica todos nesta sala</string> <string name="suggest_all_description">Notifica todos nesta sala</string>
......
...@@ -90,6 +90,12 @@ ...@@ -90,6 +90,12 @@
<string name="msg_ver_not_minimum"> <string name="msg_ver_not_minimum">
Looks like your server version is below the minimum required version %1$s.\nPlease upgrade your server to login! Looks like your server version is below the minimum required version %1$s.\nPlease upgrade your server to login!
</string> </string>
<string name="msg_proceed">PROCEED</string>
<string name="msg_cancel">CANCEL</string>
<string name="msg_warning">WARNING</string>
<string name="msg_http_insecure">When using HTTP, you\'re connecting to an insecure server. We don\'t recommend you doing that.</string>
<string name="msg_error_checking_server_version">An error has occurred while checking your server version, please try again</string>
<string name="msg_invalid_server_protocol">The selected protocol is not accepted by this server, try using HTTPS</string>
<!-- System messages --> <!-- System messages -->
<string name="message_room_name_changed">Room name changed to: %1$s by %2$s</string> <string name="message_room_name_changed">Room name changed to: %1$s by %2$s</string>
...@@ -131,12 +137,12 @@ ...@@ -131,12 +137,12 @@
<string name="max_file_size_exceeded">File size %1$d bytes exceeded max upload size of %2$d bytes</string> <string name="max_file_size_exceeded">File size %1$d bytes exceeded max upload size of %2$d bytes</string>
<!-- Socket status --> <!-- Socket status -->
<string name="status_connected">connected</string> <string name="status_connected">Connected</string>
<string name="status_disconnected">disconnected</string> <string name="status_disconnected">Disconnected</string>
<string name="status_connecting">connecting</string> <string name="status_connecting">Connecting</string>
<string name="status_authenticating">authenticating</string> <string name="status_authenticating">Authenticating</string>
<string name="status_disconnecting">disconnecting</string> <string name="status_disconnecting">Disconnecting</string>
<string name="status_waiting">connecting in %d seconds</string> <string name="status_waiting">Connecting in %d seconds</string>
<!--Suggestions--> <!--Suggestions-->
<string name="suggest_all_description">Notify all in this room</string> <string name="suggest_all_description">Notify all in this room</string>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment