Commit 913d062e authored by Leonardo Aramaki's avatar Leonardo Aramaki

Prefix keys on SharedPreferencesMessageRepository with the server url

parent 480d5032
...@@ -9,6 +9,7 @@ import chat.rocket.android.util.extensions.isValidUrl ...@@ -9,6 +9,7 @@ import chat.rocket.android.util.extensions.isValidUrl
import chat.rocket.android.util.extensions.launchUI import chat.rocket.android.util.extensions.launchUI
import chat.rocket.common.util.ifNull import chat.rocket.common.util.ifNull
import javax.inject.Inject import javax.inject.Inject
import javax.net.ssl.SSLHandshakeException
class ServerPresenter @Inject constructor(private val view: ServerView, class ServerPresenter @Inject constructor(private val view: ServerView,
private val strategy: CancelStrategy, private val strategy: CancelStrategy,
...@@ -16,6 +17,8 @@ class ServerPresenter @Inject constructor(private val view: ServerView, ...@@ -16,6 +17,8 @@ class ServerPresenter @Inject constructor(private val view: ServerView,
private val serverInteractor: SaveCurrentServerInteractor, private val serverInteractor: SaveCurrentServerInteractor,
private val refreshSettingsInteractor: RefreshSettingsInteractor, private val refreshSettingsInteractor: RefreshSettingsInteractor,
private val getAccountsInteractor: GetAccountsInteractor) { private val getAccountsInteractor: GetAccountsInteractor) {
private var retryCount = 0
fun connect(server: String) { fun connect(server: String) {
if (!server.isValidUrl()) { if (!server.isValidUrl()) {
view.showInvalidServerUrlMessage() view.showInvalidServerUrlMessage()
...@@ -34,10 +37,15 @@ class ServerPresenter @Inject constructor(private val view: ServerView, ...@@ -34,10 +37,15 @@ class ServerPresenter @Inject constructor(private val view: ServerView,
serverInteractor.save(server) serverInteractor.save(server)
navigator.toLogin() navigator.toLogin()
} catch (ex: Exception) { } catch (ex: Exception) {
ex.message?.let { if (ex.cause is SSLHandshakeException && retryCount < MAX_RETRY_ATTEMPTS) {
view.showMessage(it) retryCount++
}.ifNull { connect(server.replace("https", "http"))
view.showGenericErrorMessage() } else {
ex.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
} }
} finally { } finally {
view.hideLoading() view.hideLoading()
...@@ -45,4 +53,8 @@ class ServerPresenter @Inject constructor(private val view: ServerView, ...@@ -45,4 +53,8 @@ class ServerPresenter @Inject constructor(private val view: ServerView,
} }
} }
} }
companion object {
const val MAX_RETRY_ATTEMPTS = 1
}
} }
\ No newline at end of file
...@@ -225,9 +225,9 @@ class AppModule { ...@@ -225,9 +225,9 @@ class AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideMessageRepository(context: Application, moshi: Moshi): MessagesRepository { fun provideMessageRepository(context: Application, moshi: Moshi, currentServerInteractor: GetCurrentServerInteractor): MessagesRepository {
val preferences = context.getSharedPreferences("messages", Context.MODE_PRIVATE) val preferences = context.getSharedPreferences("messages", Context.MODE_PRIVATE)
return SharedPreferencesMessagesRepository(preferences, moshi) return SharedPreferencesMessagesRepository(preferences, moshi, currentServerInteractor)
} }
@Provides @Provides
......
package chat.rocket.android.server.infraestructure package chat.rocket.android.server.infraestructure
import android.content.SharedPreferences import android.content.SharedPreferences
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.domain.MessagesRepository import chat.rocket.android.server.domain.MessagesRepository
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
...@@ -9,31 +10,40 @@ import kotlinx.coroutines.experimental.withContext ...@@ -9,31 +10,40 @@ import kotlinx.coroutines.experimental.withContext
class SharedPreferencesMessagesRepository( class SharedPreferencesMessagesRepository(
private val prefs: SharedPreferences, private val prefs: SharedPreferences,
private val moshi: Moshi) private val moshi: Moshi,
private val currentServerInteractor: GetCurrentServerInteractor)
: MessagesRepository { : MessagesRepository {
override suspend fun getById(id: String): Message? = withContext(CommonPool) { override suspend fun getById(id: String): Message? = withContext(CommonPool) {
val adapter = moshi.adapter<Message>(Message::class.java) currentServerInteractor.get()?.also { server ->
if (prefs.all.values.isEmpty()) { if (prefs.all.values.isEmpty()) {
return@withContext null return@withContext null
}
val adapter = moshi.adapter<Message>(Message::class.java)
val values = prefs.all.entries.filter { it.key.startsWith(server) }
.map { it.value } as Collection<String>
return@withContext values.map { adapter.fromJson(it) }.firstOrNull { it?.id == id }
} }
val values = prefs.all.values as Collection<String> return@withContext null
return@withContext values.map { adapter.fromJson(it) }.firstOrNull { it?.id == id }
} }
override suspend fun getByRoomId(rid: String): List<Message> = withContext(CommonPool) { override suspend fun getByRoomId(rid: String): List<Message> = withContext(CommonPool) {
val adapter = moshi.adapter<Message>(Message::class.java) currentServerInteractor.get()?.also { server ->
if (prefs.all.values.isEmpty()) { val adapter = moshi.adapter<Message>(Message::class.java)
return@withContext emptyList<Message>() if (prefs.all.values.isEmpty()) {
return@withContext emptyList<Message>()
}
val values = prefs.all.entries.filter { it.key.startsWith(server) }
.map { it.value } as Collection<String>
return@withContext values.mapNotNull { adapter.fromJson(it) }.filter {
it.roomId == rid
}.toList().sortedWith(compareBy(Message::timestamp)).reversed()
} }
val values = prefs.all.values as Collection<String> return@withContext emptyList<Message>()
return@withContext values.mapNotNull { adapter.fromJson(it) }.filter {
it.roomId == rid
}.toList().sortedWith(compareBy(Message::timestamp)).reversed()
} }
override suspend fun getRecentMessages(rid: String, count: Long): List<Message> { override suspend fun getRecentMessages(rid: String, count: Long): List<Message> = withContext(CommonPool) {
return getByRoomId(rid).sortedByDescending { it.timestamp } return@withContext getByRoomId(rid).sortedByDescending { it.timestamp }
.distinctBy { it.sender }.take(count.toInt()) .distinctBy { it.sender }.take(count.toInt())
} }
...@@ -42,18 +52,26 @@ class SharedPreferencesMessagesRepository( ...@@ -42,18 +52,26 @@ class SharedPreferencesMessagesRepository(
if (prefs.all.values.isEmpty()) { if (prefs.all.values.isEmpty()) {
return@withContext emptyList<Message>() return@withContext emptyList<Message>()
} }
val values = prefs.all.values as Collection<String> currentServerInteractor.get()?.also { server ->
return@withContext values.mapNotNull { adapter.fromJson(it) } val values = prefs.all.entries.filter { it.key.startsWith(server) }
.map { it.value } as Collection<String>
return@withContext values.mapNotNull { adapter.fromJson(it) }
}
return@withContext emptyList<Message>()
} }
override suspend fun getAllUnsent(): List<Message> = withContext(CommonPool) { override suspend fun getAllUnsent(): List<Message> = withContext(CommonPool) {
if (prefs.all.values.isEmpty()) { if (prefs.all.values.isEmpty()) {
return@withContext emptyList<Message>() return@withContext emptyList<Message>()
} }
val all = prefs.all.values as Collection<String> currentServerInteractor.get()?.also { server ->
val adapter = moshi.adapter<Message>(Message::class.java) val values = prefs.all.entries.filter { it.key.startsWith(server) }
return@withContext all.mapNotNull { adapter.fromJson(it) } .map { it.value } as Collection<String>
.filter { it.isTemporary ?: false } val adapter = moshi.adapter<Message>(Message::class.java)
return@withContext values.mapNotNull { adapter.fromJson(it) }
.filter { it.isTemporary ?: false }
}
return@withContext emptyList<Message>()
} }
override suspend fun getUnsentByRoomId(roomId: String): List<Message> = withContext(CommonPool) { override suspend fun getUnsentByRoomId(roomId: String): List<Message> = withContext(CommonPool) {
...@@ -64,42 +82,56 @@ class SharedPreferencesMessagesRepository( ...@@ -64,42 +82,56 @@ class SharedPreferencesMessagesRepository(
return@withContext allByRoomId.filter { it.isTemporary ?: false } return@withContext allByRoomId.filter { it.isTemporary ?: false }
} }
override suspend fun save(message: Message) = withContext(CommonPool) { override suspend fun save(message: Message) {
val adapter = moshi.adapter<Message>(Message::class.java) withContext(CommonPool) {
prefs.edit().putString(message.id, adapter.toJson(message)).apply() currentServerInteractor.get()?.also {
val adapter = moshi.adapter<Message>(Message::class.java)
prefs.edit().putString("${it}_${message.id}", adapter.toJson(message)).apply()
}
}
} }
override suspend fun saveAll(newMessages: List<Message>) = withContext(CommonPool) { override suspend fun saveAll(newMessages: List<Message>) {
val adapter = moshi.adapter<Message>(Message::class.java) withContext(CommonPool) {
val editor = prefs.edit() currentServerInteractor.get()?.also {
for (msg in newMessages) { val adapter = moshi.adapter<Message>(Message::class.java)
editor.putString(msg.id, adapter.toJson(msg)) val editor = prefs.edit()
for (msg in newMessages) {
editor.putString("${it}_${msg.id}", adapter.toJson(msg))
}
editor.apply()
}
} }
editor.apply()
} }
override suspend fun clear() = withContext(CommonPool) { override suspend fun clear() = withContext(CommonPool) {
prefs.edit().clear().apply() prefs.edit().clear().apply()
} }
override suspend fun removeById(id: String) = withContext(CommonPool) { override suspend fun removeById(id: String) {
prefs.edit().putString(id, null).apply() withContext(CommonPool) {
currentServerInteractor.get()?.also {
prefs.edit().putString("${it}_$id", null).apply()
}
}
} }
override suspend fun removeByRoomId(rid: String) { override suspend fun removeByRoomId(rid: String) {
withContext(CommonPool) { withContext(CommonPool) {
val adapter = moshi.adapter<Message>(Message::class.java) currentServerInteractor.get()?.also { server ->
val editor = prefs.edit() val adapter = moshi.adapter<Message>(Message::class.java)
prefs.all.entries.forEach { val editor = prefs.edit()
val value = it.value prefs.all.entries.forEach {
if (value is String) { val value = it.value
val message = adapter.fromJson(value) if (value is String) {
if (message?.roomId == rid) { val message = adapter.fromJson(value)
editor.putString(message.id, null) if (message?.roomId == rid) {
editor.putString("${server}_${message.id}", null)
}
} }
} }
editor.apply()
} }
editor.apply()
} }
} }
} }
\ No newline at end of file
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