Unverified Commit 9f55d568 authored by Filipe de Lima Brito's avatar Filipe de Lima Brito Committed by GitHub

Merge pull request #1242 from RocketChat/new/check-permissions-ro-channel

[NEW] Check permissions to post messages to RO channels
parents 7775d05f c6f9636b
...@@ -12,8 +12,8 @@ import chat.rocket.android.chatroom.viewmodel.suggestion.CommandSuggestionViewMo ...@@ -12,8 +12,8 @@ import chat.rocket.android.chatroom.viewmodel.suggestion.CommandSuggestionViewMo
import chat.rocket.android.chatroom.viewmodel.suggestion.PeopleSuggestionViewModel import chat.rocket.android.chatroom.viewmodel.suggestion.PeopleSuggestionViewModel
import chat.rocket.android.core.behaviours.showMessage import chat.rocket.android.core.behaviours.showMessage
import chat.rocket.android.core.lifecycle.CancelStrategy import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.helper.UserHelper
import chat.rocket.android.infrastructure.LocalRepository import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.infrastructure.username
import chat.rocket.android.server.domain.* import chat.rocket.android.server.domain.*
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import chat.rocket.android.server.infraestructure.state import chat.rocket.android.server.infraestructure.state
...@@ -48,12 +48,13 @@ class ChatRoomPresenter @Inject constructor( ...@@ -48,12 +48,13 @@ class ChatRoomPresenter @Inject constructor(
getSettingsInteractor: GetSettingsInteractor, getSettingsInteractor: GetSettingsInteractor,
serverInteractor: GetCurrentServerInteractor, serverInteractor: GetCurrentServerInteractor,
private val getChatRoomsInteractor: GetChatRoomsInteractor, private val getChatRoomsInteractor: GetChatRoomsInteractor,
private val permissions: GetPermissionsInteractor, private val permissions: PermissionsInteractor,
private val uriInteractor: UriInteractor, private val uriInteractor: UriInteractor,
private val messagesRepository: MessagesRepository, private val messagesRepository: MessagesRepository,
private val usersRepository: UsersRepository, private val usersRepository: UsersRepository,
private val roomsRepository: RoomRepository, private val roomsRepository: RoomRepository,
private val localRepository: LocalRepository, private val localRepository: LocalRepository,
private val userHelper: UserHelper,
factory: ConnectionManagerFactory, factory: ConnectionManagerFactory,
private val mapper: ViewModelMapper, private val mapper: ViewModelMapper,
private val jobSchedulerInteractor: JobSchedulerInteractor private val jobSchedulerInteractor: JobSchedulerInteractor
...@@ -70,6 +71,13 @@ class ChatRoomPresenter @Inject constructor( ...@@ -70,6 +71,13 @@ class ChatRoomPresenter @Inject constructor(
private val stateChannel = Channel<State>() private val stateChannel = Channel<State>()
private var lastState = manager.state private var lastState = manager.state
fun setupChatRoom() {
launchUI(strategy) {
val canPost = permissions.canPostToReadOnlyChannels()
view.onRoomChanged(canPost)
}
}
fun loadMessages(chatRoomId: String, chatRoomType: String, offset: Long = 0) { fun loadMessages(chatRoomId: String, chatRoomType: String, offset: Long = 0) {
this.chatRoomId = chatRoomId this.chatRoomId = chatRoomId
this.chatRoomType = chatRoomType this.chatRoomType = chatRoomType
...@@ -127,7 +135,7 @@ class ChatRoomPresenter @Inject constructor( ...@@ -127,7 +135,7 @@ class ChatRoomPresenter @Inject constructor(
// ignore message for now, will receive it on the stream // ignore message for now, will receive it on the stream
val id = UUID.randomUUID().toString() val id = UUID.randomUUID().toString()
val message = if (messageId == null) { val message = if (messageId == null) {
val username = localRepository.username() val username = userHelper.username()
val newMessage = Message( val newMessage = Message(
id = id, id = id,
roomId = chatRoomId, roomId = chatRoomId,
...@@ -532,7 +540,8 @@ class ChatRoomPresenter @Inject constructor( ...@@ -532,7 +540,8 @@ class ChatRoomPresenter @Inject constructor(
launchUI(strategy) { launchUI(strategy) {
try { try {
retryIO("joinChat($chatRoomId)") { client.joinChat(chatRoomId) } retryIO("joinChat($chatRoomId)") { client.joinChat(chatRoomId) }
view.onJoined() val canPost = permissions.canPostToReadOnlyChannels()
view.onJoined(canPost)
} catch (ex: RocketChatException) { } catch (ex: RocketChatException) {
Timber.e(ex) Timber.e(ex)
} }
...@@ -545,7 +554,7 @@ class ChatRoomPresenter @Inject constructor( ...@@ -545,7 +554,7 @@ class ChatRoomPresenter @Inject constructor(
fun react(messageId: String, emoji: String) { fun react(messageId: String, emoji: String) {
launchUI(strategy) { launchUI(strategy) {
try { try {
retryIO("toogleEmoji($messageId, $emoji)") { retryIO("toggleEmoji($messageId, $emoji)") {
client.toggleReaction(messageId, emoji.removeSurrounding(":")) client.toggleReaction(messageId, emoji.removeSurrounding(":"))
} }
} catch (ex: RocketChatException) { } catch (ex: RocketChatException) {
......
...@@ -109,8 +109,10 @@ interface ChatRoomView : LoadingView, MessageView { ...@@ -109,8 +109,10 @@ interface ChatRoomView : LoadingView, MessageView {
fun populateRoomSuggestions(chatRooms: List<ChatRoomSuggestionViewModel>) fun populateRoomSuggestions(chatRooms: List<ChatRoomSuggestionViewModel>)
/** /**
* This user has joined the chat callback. * This user has joined the chat callback.
*
* @param canPost Whether the user can post a message or not.
*/ */
fun onJoined() fun onJoined(canPost: Boolean)
fun showReactionsPopup(messageId: String) fun showReactionsPopup(messageId: String)
...@@ -120,4 +122,6 @@ interface ChatRoomView : LoadingView, MessageView { ...@@ -120,4 +122,6 @@ interface ChatRoomView : LoadingView, MessageView {
* @param commands The list of available commands. * @param commands The list of available commands.
*/ */
fun populateCommandSuggestions(commands: List<CommandSuggestionViewModel>) fun populateCommandSuggestions(commands: List<CommandSuggestionViewModel>)
fun onRoomChanged(canPost: Boolean)
} }
\ No newline at end of file
...@@ -27,22 +27,25 @@ fun Context.chatRoomIntent( ...@@ -27,22 +27,25 @@ fun Context.chatRoomIntent(
chatRoomType: String, chatRoomType: String,
isChatRoomReadOnly: Boolean, isChatRoomReadOnly: Boolean,
chatRoomLastSeen: Long, chatRoomLastSeen: Long,
isChatRoomSubscribed: Boolean = true isChatRoomSubscribed: Boolean = true,
isChatRoomOwner: Boolean = false
): Intent { ): Intent {
return Intent(this, ChatRoomActivity::class.java).apply { return Intent(this, ChatRoomActivity::class.java).apply {
putExtra(INTENT_CHAT_ROOM_ID, chatRoomId) putExtra(INTENT_CHAT_ROOM_ID, chatRoomId)
putExtra(INTENT_CHAT_ROOM_NAME, chatRoomName) putExtra(INTENT_CHAT_ROOM_NAME, chatRoomName)
putExtra(INTENT_CHAT_ROOM_TYPE, chatRoomType) putExtra(INTENT_CHAT_ROOM_TYPE, chatRoomType)
putExtra(INTENT_IS_CHAT_ROOM_READ_ONLY, isChatRoomReadOnly) putExtra(INTENT_CHAT_ROOM_IS_READ_ONLY, isChatRoomReadOnly)
putExtra(INTENT_CHAT_ROOM_LAST_SEEN, chatRoomLastSeen) putExtra(INTENT_CHAT_ROOM_LAST_SEEN, chatRoomLastSeen)
putExtra(INTENT_CHAT_IS_SUBSCRIBED, isChatRoomSubscribed) putExtra(INTENT_CHAT_IS_SUBSCRIBED, isChatRoomSubscribed)
putExtra(INTENT_CHAT_ROOM_IS_OWNER, isChatRoomOwner)
} }
} }
private const val INTENT_CHAT_ROOM_ID = "chat_room_id" private const val INTENT_CHAT_ROOM_ID = "chat_room_id"
private const val INTENT_CHAT_ROOM_NAME = "chat_room_name" private const val INTENT_CHAT_ROOM_NAME = "chat_room_name"
private const val INTENT_CHAT_ROOM_TYPE = "chat_room_type" private const val INTENT_CHAT_ROOM_TYPE = "chat_room_type"
private const val INTENT_IS_CHAT_ROOM_READ_ONLY = "is_chat_room_read_only" private const val INTENT_CHAT_ROOM_IS_READ_ONLY = "chat_room_is_read_only"
private const val INTENT_CHAT_ROOM_IS_OWNER = "chat_room_is_owner"
private const val INTENT_CHAT_ROOM_LAST_SEEN = "chat_room_last_seen" private const val INTENT_CHAT_ROOM_LAST_SEEN = "chat_room_last_seen"
private const val INTENT_CHAT_IS_SUBSCRIBED = "is_chat_room_subscribed" private const val INTENT_CHAT_IS_SUBSCRIBED = "is_chat_room_subscribed"
...@@ -59,6 +62,7 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -59,6 +62,7 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
private lateinit var chatRoomType: String private lateinit var chatRoomType: String
private var isChatRoomReadOnly: Boolean = false private var isChatRoomReadOnly: Boolean = false
private var isChatRoomSubscribed: Boolean = true private var isChatRoomSubscribed: Boolean = true
private var isChatRoomOwner: Boolean = false
private var chatRoomLastSeen: Long = -1L private var chatRoomLastSeen: Long = -1L
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
...@@ -84,8 +88,11 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -84,8 +88,11 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
chatRoomType = intent.getStringExtra(INTENT_CHAT_ROOM_TYPE) chatRoomType = intent.getStringExtra(INTENT_CHAT_ROOM_TYPE)
requireNotNull(chatRoomType) { "no chat_room_type provided in Intent extras" } requireNotNull(chatRoomType) { "no chat_room_type provided in Intent extras" }
isChatRoomReadOnly = intent.getBooleanExtra(INTENT_IS_CHAT_ROOM_READ_ONLY, true) isChatRoomReadOnly = intent.getBooleanExtra(INTENT_CHAT_ROOM_IS_READ_ONLY, true)
requireNotNull(chatRoomType) { "no is_chat_room_read_only provided in Intent extras" } requireNotNull(isChatRoomReadOnly) { "no chat_room_is_read_only provided in Intent extras" }
isChatRoomOwner = intent.getBooleanExtra(INTENT_CHAT_ROOM_IS_OWNER, false)
requireNotNull(isChatRoomOwner) { "no chat_room_is_owner provided in Intent extras" }
setupToolbar() setupToolbar()
...@@ -96,7 +103,7 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -96,7 +103,7 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
if (supportFragmentManager.findFragmentByTag(TAG_CHAT_ROOM_FRAGMENT) == null) { if (supportFragmentManager.findFragmentByTag(TAG_CHAT_ROOM_FRAGMENT) == null) {
addFragment(TAG_CHAT_ROOM_FRAGMENT, R.id.fragment_container) { addFragment(TAG_CHAT_ROOM_FRAGMENT, R.id.fragment_container) {
newInstance(chatRoomId, chatRoomName, chatRoomType, isChatRoomReadOnly, chatRoomLastSeen, newInstance(chatRoomId, chatRoomName, chatRoomType, isChatRoomReadOnly, chatRoomLastSeen,
isChatRoomSubscribed) isChatRoomSubscribed, isChatRoomOwner)
} }
} }
} }
......
...@@ -44,7 +44,8 @@ fun newInstance( ...@@ -44,7 +44,8 @@ fun newInstance(
chatRoomType: String, chatRoomType: String,
isChatRoomReadOnly: Boolean, isChatRoomReadOnly: Boolean,
chatRoomLastSeen: Long, chatRoomLastSeen: Long,
isSubscribed: Boolean = true isSubscribed: Boolean = true,
isChatRoomOwner: Boolean = false
): Fragment { ): Fragment {
return ChatRoomFragment().apply { return ChatRoomFragment().apply {
arguments = Bundle(1).apply { arguments = Bundle(1).apply {
...@@ -54,6 +55,7 @@ fun newInstance( ...@@ -54,6 +55,7 @@ fun newInstance(
putBoolean(BUNDLE_IS_CHAT_ROOM_READ_ONLY, isChatRoomReadOnly) putBoolean(BUNDLE_IS_CHAT_ROOM_READ_ONLY, isChatRoomReadOnly)
putLong(BUNDLE_CHAT_ROOM_LAST_SEEN, chatRoomLastSeen) putLong(BUNDLE_CHAT_ROOM_LAST_SEEN, chatRoomLastSeen)
putBoolean(BUNDLE_CHAT_ROOM_IS_SUBSCRIBED, isSubscribed) putBoolean(BUNDLE_CHAT_ROOM_IS_SUBSCRIBED, isSubscribed)
putBoolean(BUNDLE_CHAT_ROOM_IS_OWNER, isChatRoomOwner)
} }
} }
} }
...@@ -65,6 +67,7 @@ private const val BUNDLE_IS_CHAT_ROOM_READ_ONLY = "is_chat_room_read_only" ...@@ -65,6 +67,7 @@ private const val BUNDLE_IS_CHAT_ROOM_READ_ONLY = "is_chat_room_read_only"
private const val REQUEST_CODE_FOR_PERFORM_SAF = 42 private const val REQUEST_CODE_FOR_PERFORM_SAF = 42
private const val BUNDLE_CHAT_ROOM_LAST_SEEN = "chat_room_last_seen" private const val BUNDLE_CHAT_ROOM_LAST_SEEN = "chat_room_last_seen"
private const val BUNDLE_CHAT_ROOM_IS_SUBSCRIBED = "chat_room_is_subscribed" private const val BUNDLE_CHAT_ROOM_IS_SUBSCRIBED = "chat_room_is_subscribed"
private const val BUNDLE_CHAT_ROOM_IS_OWNER = "chat_room_is_owner"
class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiReactionListener { class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiReactionListener {
@Inject @Inject
...@@ -77,6 +80,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -77,6 +80,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
private lateinit var chatRoomType: String private lateinit var chatRoomType: String
private var isSubscribed: Boolean = true private var isSubscribed: Boolean = true
private var isChatRoomReadOnly: Boolean = false private var isChatRoomReadOnly: Boolean = false
private var isChatRoomOwner: Boolean = false
private lateinit var emojiKeyboardPopup: EmojiKeyboardPopup private lateinit var emojiKeyboardPopup: EmojiKeyboardPopup
private var chatRoomLastSeen: Long = -1 private var chatRoomLastSeen: Long = -1
private lateinit var actionSnackbar: ActionSnackbar private lateinit var actionSnackbar: ActionSnackbar
...@@ -106,6 +110,8 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -106,6 +110,8 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
isChatRoomReadOnly = bundle.getBoolean(BUNDLE_IS_CHAT_ROOM_READ_ONLY) isChatRoomReadOnly = bundle.getBoolean(BUNDLE_IS_CHAT_ROOM_READ_ONLY)
isSubscribed = bundle.getBoolean(BUNDLE_CHAT_ROOM_IS_SUBSCRIBED) isSubscribed = bundle.getBoolean(BUNDLE_CHAT_ROOM_IS_SUBSCRIBED)
chatRoomLastSeen = bundle.getLong(BUNDLE_CHAT_ROOM_LAST_SEEN) chatRoomLastSeen = bundle.getLong(BUNDLE_CHAT_ROOM_LAST_SEEN)
isChatRoomOwner = bundle.getBoolean(BUNDLE_CHAT_ROOM_IS_OWNER)
} else { } else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" } requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
} }
...@@ -124,11 +130,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -124,11 +130,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setupToolbar(chatRoomName) setupToolbar(chatRoomName)
presenter.setupChatRoom()
presenter.loadMessages(chatRoomId, chatRoomType) presenter.loadMessages(chatRoomId, chatRoomType)
presenter.loadChatRooms() presenter.loadChatRooms()
setupRecyclerView() setupRecyclerView()
setupFab() setupFab()
setupMessageComposer()
setupSuggestionsView() setupSuggestionsView()
setupActionSnackbar() setupActionSnackbar()
activity?.apply { activity?.apply {
...@@ -227,6 +233,10 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -227,6 +233,10 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
} }
override fun onRoomChanged(canPost: Boolean) {
setupMessageComposer(isChatRoomOwner || canPost)
}
private fun toggleNoChatView(size: Int) { private fun toggleNoChatView(size: Int) {
if (size == 0){ if (size == 0){
image_chat_icon.setVisible(true) image_chat_icon.setVisible(true)
...@@ -517,12 +527,12 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -517,12 +527,12 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
} }
override fun onJoined() { override fun onJoined(canPost: Boolean) {
ui { ui {
input_container.setVisible(true) input_container.setVisible(true)
button_join_chat.setVisible(false) button_join_chat.setVisible(false)
isSubscribed = true isSubscribed = true
setupMessageComposer() setupMessageComposer(isChatRoomOwner)
} }
} }
...@@ -553,8 +563,8 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -553,8 +563,8 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
} }
private fun setupMessageComposer() { private fun setupMessageComposer(canPost: Boolean) {
if (isChatRoomReadOnly) { if (!canPost && isChatRoomReadOnly) {
text_room_is_read_only.setVisible(true) text_room_is_read_only.setVisible(true)
input_container.setVisible(false) input_container.setVisible(false)
} else if (!isSubscribed) { } else if (!isSubscribed) {
......
package chat.rocket.android.chatrooms.presentation package chat.rocket.android.chatrooms.presentation
import chat.rocket.android.R
import chat.rocket.android.chatroom.viewmodel.ViewModelMapper import chat.rocket.android.chatroom.viewmodel.ViewModelMapper
import chat.rocket.android.core.lifecycle.CancelStrategy import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.helper.ChatRoomsSortOrder import chat.rocket.android.helper.ChatRoomsSortOrder
import chat.rocket.android.helper.Constants import chat.rocket.android.helper.Constants
import chat.rocket.android.helper.SharedPreferenceHelper import chat.rocket.android.helper.SharedPreferenceHelper
import chat.rocket.android.helper.UserHelper
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.main.presentation.MainNavigator import chat.rocket.android.main.presentation.MainNavigator
import chat.rocket.android.server.domain.* import chat.rocket.android.server.domain.*
import chat.rocket.android.server.infraestructure.ConnectionManager import chat.rocket.android.server.infraestructure.ConnectionManager
...@@ -23,6 +26,8 @@ import chat.rocket.core.internal.model.Subscription ...@@ -23,6 +26,8 @@ import chat.rocket.core.internal.model.Subscription
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.socket.model.Type import chat.rocket.core.internal.realtime.socket.model.Type
import chat.rocket.core.internal.rest.me
import chat.rocket.core.internal.rest.permissions
import chat.rocket.core.internal.rest.spotlight import chat.rocket.core.internal.rest.spotlight
import chat.rocket.core.model.ChatRoom import chat.rocket.core.model.ChatRoom
import chat.rocket.core.model.Room import chat.rocket.core.model.Room
...@@ -45,6 +50,9 @@ class ChatRoomsPresenter @Inject constructor( ...@@ -45,6 +50,9 @@ class ChatRoomsPresenter @Inject constructor(
private val refreshSettingsInteractor: RefreshSettingsInteractor, private val refreshSettingsInteractor: RefreshSettingsInteractor,
private val viewModelMapper: ViewModelMapper, private val viewModelMapper: ViewModelMapper,
private val jobSchedulerInteractor: JobSchedulerInteractor, private val jobSchedulerInteractor: JobSchedulerInteractor,
private val permissionsInteractor: PermissionsInteractor,
private val localRepository: LocalRepository,
private val userHelper: UserHelper,
settingsRepository: SettingsRepository, settingsRepository: SettingsRepository,
factory: ConnectionManagerFactory factory: ConnectionManagerFactory
) { ) {
...@@ -69,6 +77,8 @@ class ChatRoomsPresenter @Inject constructor( ...@@ -69,6 +77,8 @@ class ChatRoomsPresenter @Inject constructor(
refreshSettingsInteractor.refresh(currentServer) refreshSettingsInteractor.refresh(currentServer)
} }
view.updateChatRooms(getUserChatRooms()) view.updateChatRooms(getUserChatRooms())
val permissions = retryIO { client.permissions() }
permissionsInteractor.saveAll(permissions)
} catch (ex: RocketChatException) { } catch (ex: RocketChatException) {
ex.message?.let { ex.message?.let {
view.showMessage(it) view.showMessage(it)
...@@ -85,7 +95,8 @@ class ChatRoomsPresenter @Inject constructor( ...@@ -85,7 +95,8 @@ class ChatRoomsPresenter @Inject constructor(
} }
fun loadChatRoom(chatRoom: ChatRoom) { fun loadChatRoom(chatRoom: ChatRoom) {
val roomName = if (chatRoom.type is RoomType.DirectMessage val isDirectMessage = chatRoom.type is RoomType.DirectMessage
val roomName = if (isDirectMessage
&& chatRoom.fullName != null && chatRoom.fullName != null
&& settings.useRealName()) { && settings.useRealName()) {
chatRoom.fullName!! chatRoom.fullName!!
...@@ -93,10 +104,40 @@ class ChatRoomsPresenter @Inject constructor( ...@@ -93,10 +104,40 @@ class ChatRoomsPresenter @Inject constructor(
chatRoom.name chatRoom.name
} }
navigator.toChatRoom(chatRoom.id, roomName, launchUI(strategy) {
chatRoom.type.toString(), chatRoom.readonly ?: false, val myself = getCurrentUser()
chatRoom.lastSeen ?: -1, if (myself?.username == null) {
chatRoom.open) view.showMessage(R.string.msg_generic_error)
} else {
val isChatRoomOwner = chatRoom.user?.username == myself.username || isDirectMessage
navigator.toChatRoom(chatRoom.id, roomName,
chatRoom.type.toString(), chatRoom.readonly ?: false,
chatRoom.lastSeen ?: -1,
chatRoom.open, isChatRoomOwner)
}
}
}
private suspend fun getCurrentUser(): User? {
userHelper.user()?.let {
return it
}
try {
val myself = retryIO { client.me() }
val user = User(
id = myself.id,
username = myself.username,
name = myself.name,
status = myself.status,
utcOffset = myself.utcOffset,
emails = null,
roles = myself.roles
)
localRepository.saveCurrentUser(url = currentServer, user = user)
} catch (ex: RocketChatException) {
Timber.e(ex)
}
return null
} }
/** /**
...@@ -415,7 +456,7 @@ class ChatRoomsPresenter @Inject constructor( ...@@ -415,7 +456,7 @@ class ChatRoomsPresenter @Inject constructor(
val newRoom = ChatRoom( val newRoom = ChatRoom(
id = room.id, id = room.id,
type = room.type, type = room.type,
user = room.user ?: user, user = room.user,
status = getActiveUsersInteractor.getActiveUserByUsername( status = getActiveUsersInteractor.getActiveUserByUsername(
currentServer, currentServer,
room.name ?: name room.name ?: name
...@@ -454,7 +495,7 @@ class ChatRoomsPresenter @Inject constructor( ...@@ -454,7 +495,7 @@ class ChatRoomsPresenter @Inject constructor(
val newRoom = ChatRoom( val newRoom = ChatRoom(
id = subscription.roomId, id = subscription.roomId,
type = subscription.type, type = subscription.type,
user = subscription.user ?: user, user = user,
status = getActiveUsersInteractor.getActiveUserByUsername( status = getActiveUsersInteractor.getActiveUserByUsername(
currentServer, currentServer,
subscription.name subscription.name
......
...@@ -25,10 +25,13 @@ import com.facebook.drawee.view.SimpleDraweeView ...@@ -25,10 +25,13 @@ import com.facebook.drawee.view.SimpleDraweeView
import kotlinx.android.synthetic.main.item_chat.view.* import kotlinx.android.synthetic.main.item_chat.view.*
import kotlinx.android.synthetic.main.unread_messages_badge.view.* import kotlinx.android.synthetic.main.unread_messages_badge.view.*
class ChatRoomsAdapter(private val context: Context, class ChatRoomsAdapter(
private val settings: PublicSettings, private val context: Context,
private val localRepository: LocalRepository, private val settings: PublicSettings,
private val listener: (ChatRoom) -> Unit) : RecyclerView.Adapter<ChatRoomsAdapter.ViewHolder>() { private val localRepository: LocalRepository,
private val listener: (ChatRoom) -> Unit
) : RecyclerView.Adapter<ChatRoomsAdapter.ViewHolder>() {
var dataSet: MutableList<ChatRoom> = ArrayList() var dataSet: MutableList<ChatRoom> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder = ViewHolder(parent.inflate(R.layout.item_chat)) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder = ViewHolder(parent.inflate(R.layout.item_chat))
......
...@@ -23,7 +23,6 @@ import chat.rocket.android.helper.SharedPreferenceHelper ...@@ -23,7 +23,6 @@ import chat.rocket.android.helper.SharedPreferenceHelper
import chat.rocket.android.infrastructure.LocalRepository import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.server.domain.GetCurrentServerInteractor import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.domain.SettingsRepository import chat.rocket.android.server.domain.SettingsRepository
import chat.rocket.android.server.domain.showLastMessage
import chat.rocket.android.util.extensions.* import chat.rocket.android.util.extensions.*
import chat.rocket.android.widget.DividerItemDecoration import chat.rocket.android.widget.DividerItemDecoration
import chat.rocket.common.model.RoomType import chat.rocket.common.model.RoomType
...@@ -37,10 +36,14 @@ import timber.log.Timber ...@@ -37,10 +36,14 @@ import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
class ChatRoomsFragment : Fragment(), ChatRoomsView { class ChatRoomsFragment : Fragment(), ChatRoomsView {
@Inject lateinit var presenter: ChatRoomsPresenter @Inject
@Inject lateinit var serverInteractor: GetCurrentServerInteractor lateinit var presenter: ChatRoomsPresenter
@Inject lateinit var settingsRepository: SettingsRepository @Inject
@Inject lateinit var localRepository: LocalRepository lateinit var serverInteractor: GetCurrentServerInteractor
@Inject
lateinit var settingsRepository: SettingsRepository
@Inject
lateinit var localRepository: LocalRepository
private lateinit var preferences: SharedPreferences private lateinit var preferences: SharedPreferences
private var searchView: SearchView? = null private var searchView: SearchView? = null
private val handler = Handler() private val handler = Handler()
...@@ -136,9 +139,9 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -136,9 +139,9 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
}) })
val dialogSort = AlertDialog.Builder(context) val dialogSort = AlertDialog.Builder(context)
.setTitle(R.string.dialog_sort_title) .setTitle(R.string.dialog_sort_title)
.setView(dialogLayout) .setView(dialogLayout)
.setPositiveButton("Done", { dialog, _ -> dialog.dismiss() }) .setPositiveButton("Done", { dialog, _ -> dialog.dismiss() })
dialogSort.show() dialogSort.show()
} }
...@@ -146,9 +149,9 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -146,9 +149,9 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
return super.onOptionsItemSelected(item) return super.onOptionsItemSelected(item)
} }
private fun invalidateQueryOnSearch(){ private fun invalidateQueryOnSearch() {
searchView?.let { searchView?.let {
if (!searchView!!.isIconified){ if (!searchView!!.isIconified) {
queryChatRoomsByName(searchView!!.query.toString()) queryChatRoomsByName(searchView!!.query.toString())
} }
} }
...@@ -183,7 +186,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -183,7 +186,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
ui { text_no_data_to_display.setVisible(true) } ui { text_no_data_to_display.setVisible(true) }
} }
override fun showLoading(){ override fun showLoading() {
ui { view_loading.setVisible(true) } ui { view_loading.setVisible(true) }
} }
...@@ -240,19 +243,18 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -240,19 +243,18 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
ui { ui {
recycler_view.layoutManager = LinearLayoutManager(it, LinearLayoutManager.VERTICAL, false) recycler_view.layoutManager = LinearLayoutManager(it, LinearLayoutManager.VERTICAL, false)
recycler_view.addItemDecoration(DividerItemDecoration(it, recycler_view.addItemDecoration(DividerItemDecoration(it,
resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_start), resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_start),
resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_end))) resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_end)))
recycler_view.itemAnimator = DefaultItemAnimator() recycler_view.itemAnimator = DefaultItemAnimator()
// TODO - use a ViewModel Mapper instead of using settings on the adapter // TODO - use a ViewModel Mapper instead of using settings on the adapter
println(serverInteractor.get() + " -> ${settingsRepository.get(serverInteractor.get()!!).showLastMessage()}")
val baseAdapter = ChatRoomsAdapter(it, val baseAdapter = ChatRoomsAdapter(it,
settingsRepository.get(serverInteractor.get()!!), localRepository) { settingsRepository.get(serverInteractor.get()!!), localRepository) { chatRoom ->
chatRoom -> presenter.loadChatRoom(chatRoom) presenter.loadChatRoom(chatRoom)
} }
sectionedAdapter = SimpleSectionedRecyclerViewAdapter(it, sectionedAdapter = SimpleSectionedRecyclerViewAdapter(it,
R.layout.item_chatroom_header, R.id.text_chatroom_header, baseAdapter) R.layout.item_chatroom_header, R.id.text_chatroom_header, baseAdapter)
recycler_view.adapter = sectionedAdapter recycler_view.adapter = sectionedAdapter
} }
} }
......
...@@ -17,7 +17,7 @@ import chat.rocket.android.chatroom.service.MessageService ...@@ -17,7 +17,7 @@ import chat.rocket.android.chatroom.service.MessageService
import chat.rocket.android.dagger.qualifier.ForMessages import chat.rocket.android.dagger.qualifier.ForMessages
import chat.rocket.android.helper.MessageParser import chat.rocket.android.helper.MessageParser
import chat.rocket.android.infrastructure.LocalRepository import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.infrastructure.SharedPrefsLocalRepository import chat.rocket.android.infrastructure.SharedPreferencesLocalRepository
import chat.rocket.android.push.GroupedPush import chat.rocket.android.push.GroupedPush
import chat.rocket.android.push.PushManager import chat.rocket.android.push.PushManager
import chat.rocket.android.server.domain.* import chat.rocket.android.server.domain.*
...@@ -108,11 +108,11 @@ class AppModule { ...@@ -108,11 +108,11 @@ class AppModule {
@Singleton @Singleton
fun provideOkHttpClient(logger: HttpLoggingInterceptor): OkHttpClient { fun provideOkHttpClient(logger: HttpLoggingInterceptor): OkHttpClient {
return OkHttpClient.Builder() return OkHttpClient.Builder()
.addInterceptor(logger) .addInterceptor(logger)
.connectTimeout(15, TimeUnit.SECONDS) .connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS) .readTimeout(20, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS) .writeTimeout(15, TimeUnit.SECONDS)
.build() .build()
} }
@Provides @Provides
...@@ -158,8 +158,8 @@ class AppModule { ...@@ -158,8 +158,8 @@ class AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideLocalRepository(prefs: SharedPreferences): LocalRepository { fun provideLocalRepository(prefs: SharedPreferences, moshi: Moshi): LocalRepository {
return SharedPrefsLocalRepository(prefs) return SharedPreferencesLocalRepository(prefs, moshi)
} }
@Provides @Provides
...@@ -174,6 +174,12 @@ class AppModule { ...@@ -174,6 +174,12 @@ class AppModule {
return SharedPreferencesSettingsRepository(localRepository) return SharedPreferencesSettingsRepository(localRepository)
} }
@Provides
@Singleton
fun providePermissionsRepository(localRepository: LocalRepository, moshi: Moshi): PermissionsRepository {
return SharedPreferencesPermissionsRepository(localRepository, moshi)
}
@Provides @Provides
@Singleton @Singleton
fun provideRoomRepository(): RoomRepository { fun provideRoomRepository(): RoomRepository {
...@@ -239,7 +245,7 @@ class AppModule { ...@@ -239,7 +245,7 @@ class AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideConfiguration(context: Application, client: OkHttpClient): SpannableConfiguration { fun provideConfiguration(context: Application): SpannableConfiguration {
val res = context.resources val res = context.resources
return SpannableConfiguration.builder(context) return SpannableConfiguration.builder(context)
.theme(SpannableTheme.builder() .theme(SpannableTheme.builder()
...@@ -254,12 +260,6 @@ class AppModule { ...@@ -254,12 +260,6 @@ class AppModule {
return MessageParser(context, configuration, settingsInteractor.get(url)) return MessageParser(context, configuration, settingsInteractor.get(url))
} }
@Provides
@Singleton
fun providePermissionInteractor(settingsRepository: SettingsRepository, serverRepository: CurrentServerRepository): GetPermissionsInteractor {
return GetPermissionsInteractor(settingsRepository, serverRepository)
}
@Provides @Provides
@Singleton @Singleton
fun provideAccountsRepository(preferences: SharedPreferences, moshi: Moshi): AccountsRepository = fun provideAccountsRepository(preferences: SharedPreferences, moshi: Moshi): AccountsRepository =
......
...@@ -3,7 +3,21 @@ package chat.rocket.android.dagger.module ...@@ -3,7 +3,21 @@ package chat.rocket.android.dagger.module
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import chat.rocket.android.infrastructure.LocalRepository import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.infrastructure.SharedPrefsLocalRepository import chat.rocket.android.infrastructure.SharedPreferencesLocalRepository
import chat.rocket.android.server.domain.CurrentServerRepository
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.infraestructure.SharedPrefsCurrentServerRepository
import chat.rocket.android.util.AppJsonAdapterFactory
import chat.rocket.android.util.TimberLogger
import chat.rocket.common.internal.FallbackSealedClassJsonAdapter
import chat.rocket.common.internal.ISO8601Date
import chat.rocket.common.model.TimestampAdapter
import chat.rocket.common.util.CalendarISO8601Converter
import chat.rocket.common.util.Logger
import chat.rocket.common.util.PlatformLogger
import chat.rocket.core.internal.AttachmentAdapterFactory
import chat.rocket.core.internal.ReactionsAdapter
import com.squareup.moshi.Moshi
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import javax.inject.Singleton import javax.inject.Singleton
...@@ -11,14 +25,53 @@ import javax.inject.Singleton ...@@ -11,14 +25,53 @@ import javax.inject.Singleton
@Module @Module
class LocalModule { class LocalModule {
@Provides
@Singleton
fun providePlatformLogger(): PlatformLogger {
return TimberLogger
}
@Provides
@Singleton
fun provideCurrentServerRepository(prefs: SharedPreferences): CurrentServerRepository {
return SharedPrefsCurrentServerRepository(prefs)
}
@Provides
@Singleton
fun provideMoshi(
logger: PlatformLogger,
currentServerInteractor: GetCurrentServerInteractor
): Moshi {
val url = currentServerInteractor.get() ?: ""
return Moshi.Builder()
.add(FallbackSealedClassJsonAdapter.ADAPTER_FACTORY)
.add(AppJsonAdapterFactory.INSTANCE)
.add(AttachmentAdapterFactory(Logger(logger, url)))
.add(
java.lang.Long::class.java,
ISO8601Date::class.java,
TimestampAdapter(CalendarISO8601Converter())
)
.add(
Long::class.java,
ISO8601Date::class.java,
TimestampAdapter(CalendarISO8601Converter())
)
.add(ReactionsAdapter())
.build()
}
@Provides @Provides
fun provideSharedPreferences(context: Context): SharedPreferences { fun provideSharedPreferences(context: Context): SharedPreferences {
return context.getSharedPreferences("rocket.chat", Context.MODE_PRIVATE) return context.getSharedPreferences("rocket.chat", Context.MODE_PRIVATE)
} }
@Provides @Provides
@Singleton @Singleton
fun provideLocalRepository(prefs: SharedPreferences): LocalRepository { fun provideLocalRepository(sharedPreferences: SharedPreferences, moshi: Moshi): LocalRepository {
return SharedPrefsLocalRepository(prefs) return SharedPreferencesLocalRepository(sharedPreferences, moshi)
} }
} }
\ No newline at end of file
package chat.rocket.android.helper
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.domain.PublicSettings
import chat.rocket.android.server.domain.SettingsRepository
import chat.rocket.android.server.domain.useRealName
import chat.rocket.common.model.User
import javax.inject.Inject
class UserHelper @Inject constructor(
private val localRepository: LocalRepository,
private val getCurrentServerInteractor: GetCurrentServerInteractor,
settingsRepository: SettingsRepository
) {
private val settings: PublicSettings = settingsRepository.get(getCurrentServerInteractor.get()!!)
/**
* Return the display name for the given [user].
* If setting 'Use_Real_Name' is true then the real name will be given, or else
* the username without the '@' is yielded. The fallback for any case is the username, which
* could be null.
*/
fun displayName(user: User): String? {
return if (settings.useRealName()) user.name ?: user.username else user.username
}
/**
* Return current logged user's display name.
*
* @see displayName
*/
fun displayName(): String? {
user()?.let {
return displayName(it)
}
return null
}
/**
* Return current logged [User].
*/
fun user(): User? {
return localRepository.getCurrentUser(serverUrl())
}
/**
* Return the username for the current logged [User].
*/
fun username(): String? = user()?.username
/**
* Whether current [User] is admin on the current server.
*/
fun isAdmin(): Boolean {
return user()?.roles?.find { it.equals("admin", ignoreCase = true) } != null
}
private fun serverUrl(): String {
return getCurrentServerInteractor.get()!!
}
}
\ No newline at end of file
package chat.rocket.android.infrastructure package chat.rocket.android.infrastructure
import chat.rocket.common.model.User
interface LocalRepository { interface LocalRepository {
fun save(key: String, value: String?) fun save(key: String, value: String?)
...@@ -14,12 +16,16 @@ interface LocalRepository { ...@@ -14,12 +16,16 @@ interface LocalRepository {
fun getLong(key: String, defValue: Long = -1L): Long fun getLong(key: String, defValue: Long = -1L): Long
fun clear(key: String) fun clear(key: String)
fun clearAllFromServer(server: String) fun clearAllFromServer(server: String)
fun getCurrentUser(url: String): User?
fun saveCurrentUser(url: String, user: User)
companion object { companion object {
const val KEY_PUSH_TOKEN = "KEY_PUSH_TOKEN" const val KEY_PUSH_TOKEN = "KEY_PUSH_TOKEN"
const val MIGRATION_FINISHED_KEY = "MIGRATION_FINISHED_KEY" const val MIGRATION_FINISHED_KEY = "MIGRATION_FINISHED_KEY"
const val TOKEN_KEY = "token_" const val TOKEN_KEY = "token_"
const val SETTINGS_KEY = "settings_" const val SETTINGS_KEY = "settings_"
const val PERMISSIONS_KEY = "permissions_"
const val USER_KEY = "user_"
const val CURRENT_USERNAME_KEY = "username_" const val CURRENT_USERNAME_KEY = "username_"
} }
} }
......
...@@ -2,8 +2,26 @@ package chat.rocket.android.infrastructure ...@@ -2,8 +2,26 @@ package chat.rocket.android.infrastructure
import android.content.SharedPreferences import android.content.SharedPreferences
import androidx.core.content.edit import androidx.core.content.edit
import chat.rocket.common.model.User
import com.squareup.moshi.Moshi
class SharedPreferencesLocalRepository(
private val preferences: SharedPreferences,
moshi: Moshi
) : LocalRepository {
private val userAdapter = moshi.adapter(User::class.java)
override fun getCurrentUser(url: String): User? {
return get("${url}_${LocalRepository.USER_KEY}", null)?.let {
userAdapter.fromJson(it)
}
}
override fun saveCurrentUser(url: String, user: User) {
save("${url}_${LocalRepository.USER_KEY}", userAdapter.toJson(user))
}
class SharedPrefsLocalRepository(private val preferences: SharedPreferences) : LocalRepository {
override fun getBoolean(key: String, defValue: Boolean) = preferences.getBoolean(key, defValue) override fun getBoolean(key: String, defValue: Boolean) = preferences.getBoolean(key, defValue)
override fun getFloat(key: String, defValue: Float) = preferences.getFloat(key, defValue) override fun getFloat(key: String, defValue: Float) = preferences.getFloat(key, defValue)
......
...@@ -36,9 +36,10 @@ class MainNavigator(internal val activity: MainActivity) { ...@@ -36,9 +36,10 @@ class MainNavigator(internal val activity: MainActivity) {
chatRoomType: String, chatRoomType: String,
isChatRoomReadOnly: Boolean, isChatRoomReadOnly: Boolean,
chatRoomLastSeen: Long, chatRoomLastSeen: Long,
isChatRoomSubscribed: Boolean) { isChatRoomSubscribed: Boolean,
isChatRoomOwner: Boolean) {
activity.startActivity(activity.chatRoomIntent(chatRoomId, chatRoomName, chatRoomType, activity.startActivity(activity.chatRoomIntent(chatRoomId, chatRoomName, chatRoomType,
isChatRoomReadOnly, chatRoomLastSeen, isChatRoomSubscribed)) isChatRoomReadOnly, chatRoomLastSeen, isChatRoomSubscribed, isChatRoomOwner))
activity.overridePendingTransition(R.anim.open_enter, R.anim.open_exit) activity.overridePendingTransition(R.anim.open_enter, R.anim.open_exit)
} }
......
package chat.rocket.android.server.domain package chat.rocket.android.server.domain
import chat.rocket.android.helper.UserHelper
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.core.model.Permission
import javax.inject.Inject import javax.inject.Inject
class GetPermissionsInteractor @Inject constructor(private val settingsRepository: SettingsRepository, // Creating rooms
private val currentServerRepository: CurrentServerRepository) { const val CREATE_PUBLIC_CHANNELS = "create-c"
const val CREATE_DIRECT_MESSAGES = "create-d"
const val CREATE_PRIVATE_CHANNELS = "create-p"
private fun publicSettings(): PublicSettings? = settingsRepository.get(currentServerRepository.get()!!) // Messages
const val DELETE_MESSAGE = "delete-message"
const val FORCE_DELETE_MESSAGE = "force-delete-message"
const val EDIT_MESSAGE = "edit-message"
const val PIN_MESSAGE = "pin-message"
const val POST_READONLY = "post-readonly"
class PermissionsInteractor @Inject constructor(
private val settingsRepository: SettingsRepository,
private val permissionsRepository: PermissionsRepository,
private val getCurrentServerInteractor: GetCurrentServerInteractor,
private val userHelper: UserHelper
) {
private fun publicSettings(): PublicSettings? = settingsRepository.get(currentServerUrl()!!)
fun saveAll(permissions: List<Permission>) {
val url = currentServerUrl()!!
permissions.forEach { permissionsRepository.save(url, it) }
}
/** /**
* Check whether user is allowed to delete a message. * Check whether user is allowed to delete a message.
...@@ -31,4 +55,18 @@ class GetPermissionsInteractor @Inject constructor(private val settingsRepositor ...@@ -31,4 +55,18 @@ class GetPermissionsInteractor @Inject constructor(private val settingsRepositor
* Checks whether should show edited message status. * Checks whether should show edited message status.
*/ */
fun showEditedStatus() = publicSettings()?.showEditedStatus() ?: false fun showEditedStatus() = publicSettings()?.showEditedStatus() ?: false
fun canPostToReadOnlyChannels(): Boolean {
val url = getCurrentServerInteractor.get()!!
val currentUserRoles = userHelper.user()?.roles
return permissionsRepository.get(url, POST_READONLY)?.let { permission ->
currentUserRoles?.isNotEmpty() == true && permission.roles.any {
currentUserRoles.contains(it)
}
} == true || userHelper.isAdmin()
}
private fun currentServerUrl(): String? {
return getCurrentServerInteractor.get()
}
} }
\ No newline at end of file
package chat.rocket.android.server.domain
import chat.rocket.core.model.Permission
interface PermissionsRepository {
/**
* Store [permission] locally.
*
* @param url The server url from where we're interest to store the permission.
* @param permission The permission to store.
*/
fun save(url: String, permission: Permission)
/**
* Get permission given by the [permissionId] and for the server [url].
*
* @param url The server url from where we're interested on getting the permissions.
* @param permissionId the id of the permission to get.
*
* @return The interested [Permission] or null if not found.
*/
fun get(url: String, permissionId: String): Permission?
}
\ No newline at end of file
package chat.rocket.android.server.infraestructure
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.server.domain.PermissionsRepository
import chat.rocket.core.model.Permission
import com.squareup.moshi.Moshi
class SharedPreferencesPermissionsRepository(
private val localRepository: LocalRepository,
moshi: Moshi
) : PermissionsRepository {
private val adapter = moshi.adapter(Permission::class.java)
override fun save(url: String, permission: Permission) {
localRepository.save(getPermissionKey(url, permission.id), adapter.toJson(permission))
}
override fun get(url: String, permissionId: String): Permission? {
return localRepository.get(getPermissionKey(url, permissionId))?.let {
adapter.fromJson(it)
}
}
// Create a key following the pattern: settings_[url]_[permission id]
// eg.: 'settings_https://open.rocket.chat_create-p'
private fun getPermissionKey(url: String, permissionId: String): String {
return "${LocalRepository.PERMISSIONS_KEY}${url}_$permissionId"
}
}
\ No newline at end of file
...@@ -6,7 +6,9 @@ import chat.rocket.android.server.domain.PublicSettings ...@@ -6,7 +6,9 @@ import chat.rocket.android.server.domain.PublicSettings
import chat.rocket.android.server.domain.SettingsRepository import chat.rocket.android.server.domain.SettingsRepository
import chat.rocket.core.internal.SettingsAdapter import chat.rocket.core.internal.SettingsAdapter
class SharedPreferencesSettingsRepository(private val localRepository: LocalRepository) : SettingsRepository { class SharedPreferencesSettingsRepository(
private val localRepository: LocalRepository
) : SettingsRepository {
private val adapter = SettingsAdapter().lenient() private val adapter = SettingsAdapter().lenient()
......
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