Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
AloqaIM-Android
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
AloqaIM-Android
Commits
2f934213
Unverified
Commit
2f934213
authored
Apr 13, 2018
by
Leonardo Aramaki
Committed by
GitHub
Apr 13, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop-2.x' into new/color-attachment
parents
7c3e43aa
3e480b2f
Changes
30
Show whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
642 additions
and
258 deletions
+642
-258
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+7
-2
ServerPresenter.kt
...oid/authentication/server/presentation/ServerPresenter.kt
+1
-0
ChatRoomAdapter.kt
...a/chat/rocket/android/chatroom/adapter/ChatRoomAdapter.kt
+12
-2
MessageViewHolder.kt
...chat/rocket/android/chatroom/adapter/MessageViewHolder.kt
+4
-0
MessageServiceProvider.kt
...chat/rocket/android/chatroom/di/MessageServiceProvider.kt
+11
-0
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+108
-69
ChatRoomView.kt
...chat/rocket/android/chatroom/presentation/ChatRoomView.kt
+1
-3
MessageService.kt
...va/chat/rocket/android/chatroom/service/MessageService.kt
+78
-0
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+30
-29
AudioAttachmentViewModel.kt
...et/android/chatroom/viewmodel/AudioAttachmentViewModel.kt
+2
-1
AuthorAttachmentViewModel.kt
...t/android/chatroom/viewmodel/AuthorAttachmentViewModel.kt
+12
-11
BaseViewModel.kt
...a/chat/rocket/android/chatroom/viewmodel/BaseViewModel.kt
+1
-0
ImageAttachmentViewModel.kt
...et/android/chatroom/viewmodel/ImageAttachmentViewModel.kt
+2
-1
MessageAttachmentViewModel.kt
.../android/chatroom/viewmodel/MessageAttachmentViewModel.kt
+2
-1
MessageViewModel.kt
...hat/rocket/android/chatroom/viewmodel/MessageViewModel.kt
+2
-1
UrlPreviewViewModel.kt
.../rocket/android/chatroom/viewmodel/UrlPreviewViewModel.kt
+2
-1
VideoAttachmentViewModel.kt
...et/android/chatroom/viewmodel/VideoAttachmentViewModel.kt
+2
-1
ViewModelMapper.kt
...chat/rocket/android/chatroom/viewmodel/ViewModelMapper.kt
+2
-1
ChatRoomsPresenter.kt
...cket/android/chatrooms/presentation/ChatRoomsPresenter.kt
+85
-83
AppComponent.kt
app/src/main/java/chat/rocket/android/dagger/AppComponent.kt
+3
-0
AppModule.kt
.../main/java/chat/rocket/android/dagger/module/AppModule.kt
+39
-12
ServiceBuilder.kt
.../java/chat/rocket/android/dagger/module/ServiceBuilder.kt
+5
-0
LocalRepository.kt
...ava/chat/rocket/android/infrastructure/LocalRepository.kt
+2
-1
MainPresenter.kt
...va/chat/rocket/android/main/presentation/MainPresenter.kt
+14
-16
JobSchedulerInteractor.kt
...at/rocket/android/server/domain/JobSchedulerInteractor.kt
+8
-0
MessagesRepository.kt
...a/chat/rocket/android/server/domain/MessagesRepository.kt
+13
-9
RemoveAccountInteractor.kt
...t/rocket/android/server/domain/RemoveAccountInteractor.kt
+1
-1
JobSchedulerInteractorImpl.kt
...roid/server/infraestructure/JobSchedulerInteractorImpl.kt
+21
-0
MemoryMessagesRepository.kt
...ndroid/server/infraestructure/MemoryMessagesRepository.kt
+35
-13
SharedPreferencesMessagesRepository.kt
...er/infraestructure/SharedPreferencesMessagesRepository.kt
+137
-0
No files found.
app/src/main/AndroidManifest.xml
View file @
2f934213
...
...
@@ -102,13 +102,18 @@
<action
android:name=
"com.google.android.c2dm.intent.RECEIVE"
/>
</intent-filter>
</service>
<service
android:name=
".chatroom.service.MessageService"
android:exported=
"true"
android:permission=
"android.permission.BIND_JOB_SERVICE"
/>
<meta-data
android:name=
"io.fabric.ApiKey"
android:value=
"12ac6e94f850aaffcdff52001af77ca415d06a43"
/>
<activity
android:name=
".settings.about.ui.AboutActivity"
android:theme=
"@style/AppTheme"
/>
<activity
android:name=
".settings.about.ui.AboutActivity"
android:theme=
"@style/AppTheme"
/>
</application>
</manifest>
app/src/main/java/chat/rocket/android/authentication/server/presentation/ServerPresenter.kt
View file @
2f934213
...
...
@@ -16,6 +16,7 @@ class ServerPresenter @Inject constructor(private val view: ServerView,
private
val
serverInteractor
:
SaveCurrentServerInteractor
,
private
val
refreshSettingsInteractor
:
RefreshSettingsInteractor
,
private
val
getAccountsInteractor
:
GetAccountsInteractor
)
{
fun
connect
(
server
:
String
)
{
if
(!
server
.
isValidUrl
())
{
view
.
showInvalidServerUrlMessage
()
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/ChatRoomAdapter.kt
View file @
2f934213
...
...
@@ -122,12 +122,22 @@ class ChatRoomAdapter(
}
fun
prependData
(
dataSet
:
List
<
BaseViewModel
<*
>>)
{
val
item
=
dataSet
.
firstOrNull
{
newItem
->
val
item
=
dataSet
.
indexOfFirst
{
newItem
->
this
.
dataSet
.
indexOfFirst
{
it
.
messageId
==
newItem
.
messageId
&&
it
.
viewType
==
newItem
.
viewType
}
>
-
1
}
if
(
item
==
null
)
{
if
(
item
==
-
1
)
{
this
.
dataSet
.
addAll
(
0
,
dataSet
)
notifyItemRangeInserted
(
0
,
dataSet
.
size
)
}
else
{
dataSet
.
forEach
{
item
->
val
index
=
this
.
dataSet
.
indexOfFirst
{
item
.
messageId
==
it
.
messageId
&&
item
.
viewType
==
it
.
viewType
}
if
(
index
>
-
1
)
{
this
.
dataSet
[
index
]
=
item
notifyItemChanged
(
index
)
}
}
}
}
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/MessageViewHolder.kt
View file @
2f934213
package
chat.rocket.android.chatroom.adapter
import
android.graphics.Color
import
android.text.method.LinkMovementMethod
import
android.view.View
import
chat.rocket.android.chatroom.viewmodel.MessageViewModel
...
...
@@ -29,6 +30,9 @@ class MessageViewHolder(
text_sender
.
text
=
data
.
senderName
text_content
.
text
=
data
.
content
image_avatar
.
setImageURI
(
data
.
avatar
)
text_content
.
setTextColor
(
if
(
data
.
isTemporary
)
Color
.
GRAY
else
Color
.
BLACK
)
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/di/MessageServiceProvider.kt
0 → 100644
View file @
2f934213
package
chat.rocket.android.chatroom.di
import
chat.rocket.android.chatroom.service.MessageService
import
chat.rocket.android.dagger.module.AppModule
import
dagger.Module
import
dagger.android.ContributesAndroidInjector
@Module
abstract
class
MessageServiceProvider
{
@ContributesAndroidInjector
(
modules
=
[
AppModule
::
class
])
abstract
fun
provideMessageService
():
MessageService
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
View file @
2f934213
...
...
@@ -12,6 +12,7 @@ import chat.rocket.android.chatroom.viewmodel.suggestion.CommandSuggestionViewMo
import
chat.rocket.android.chatroom.viewmodel.suggestion.PeopleSuggestionViewModel
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.infrastructure.username
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.server.infraestructure.state
...
...
@@ -20,6 +21,7 @@ import chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.retryIO
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.RoomType
import
chat.rocket.common.model.SimpleUser
import
chat.rocket.common.model.UserStatus
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.util.ifNull
...
...
@@ -52,7 +54,8 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
private
val
roomsRepository
:
RoomRepository
,
private
val
localRepository
:
LocalRepository
,
factory
:
ConnectionManagerFactory
,
private
val
mapper
:
ViewModelMapper
)
{
private
val
mapper
:
ViewModelMapper
,
private
val
jobSchedulerInteractor
:
JobSchedulerInteractor
)
{
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
manager
=
factory
.
create
(
currentServer
)
private
val
client
=
manager
.
client
...
...
@@ -70,14 +73,18 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
launchUI
(
strategy
)
{
view
.
showLoading
()
try
{
val
messages
=
retryIO
(
description
=
"messages chatRoom: $chatRoomId, type: $chatRoomType, offset: $offset"
)
{
client
.
messages
(
chatRoomId
,
roomTypeOf
(
chatRoomType
),
offset
,
30
).
result
if
(
offset
==
0L
)
{
val
localMessages
=
messagesRepository
.
getByRoomId
(
chatRoomId
)
val
oldMessages
=
mapper
.
map
(
localMessages
)
if
(
oldMessages
.
isNotEmpty
())
{
view
.
showMessages
(
oldMessages
)
loadMissingMessages
()
}
else
{
loadAndShowMessages
(
chatRoomId
,
chatRoomType
,
offset
)
}
}
else
{
loadAndShowMessages
(
chatRoomId
,
chatRoomType
,
offset
)
}
messagesRepository
.
saveAll
(
messages
)
val
messagesViewModels
=
mapper
.
map
(
messages
)
view
.
showMessages
(
messagesViewModels
)
// TODO: For now we are marking the room as read if we can get the messages (I mean, no exception occurs)
// but should mark only when the user see the first unread message.
...
...
@@ -85,7 +92,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
subscribeMessages
(
chatRoomId
)
}
catch
(
ex
:
Exception
)
{
ex
.
printStackTrace
(
)
Timber
.
e
(
ex
)
ex
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
...
...
@@ -101,28 +108,58 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
}
}
private
suspend
fun
loadAndShowMessages
(
chatRoomId
:
String
,
chatRoomType
:
String
,
offset
:
Long
=
0
)
{
val
messages
=
retryIO
(
description
=
"messages chatRoom: $chatRoomId, type: $chatRoomType, offset: $offset"
)
{
client
.
messages
(
chatRoomId
,
roomTypeOf
(
chatRoomType
),
offset
,
30
).
result
}
messagesRepository
.
saveAll
(
messages
)
val
allMessages
=
mapper
.
map
(
messages
)
view
.
showMessages
(
allMessages
)
}
fun
sendMessage
(
chatRoomId
:
String
,
text
:
String
,
messageId
:
String
?)
{
launchUI
(
strategy
)
{
view
.
disableSendMessageButton
()
try
{
// ignore message for now, will receive it on the stream
val
message
=
retryIO
{
if
(
messageId
==
null
)
{
val
id
=
UUID
.
randomUUID
().
toString
()
val
message
=
if
(
messageId
==
null
)
{
val
username
=
localRepository
.
username
()
val
newMessage
=
Message
(
id
=
id
,
roomId
=
chatRoomId
,
message
=
text
,
timestamp
=
Instant
.
now
().
toEpochMilli
(),
sender
=
SimpleUser
(
null
,
username
,
username
),
attachments
=
null
,
avatar
=
currentServer
.
avatarUrl
(
username
!!
),
channels
=
null
,
editedAt
=
null
,
editedBy
=
null
,
groupable
=
false
,
parseUrls
=
false
,
pinned
=
false
,
mentions
=
emptyList
(),
reactions
=
null
,
senderAlias
=
null
,
type
=
null
,
updatedAt
=
null
,
urls
=
null
,
isTemporary
=
true
)
messagesRepository
.
save
(
newMessage
)
view
.
showNewMessage
(
mapper
.
map
(
newMessage
))
client
.
sendMessage
(
id
,
chatRoomId
,
text
)
}
else
{
client
.
updateMessage
(
chatRoomId
,
messageId
,
text
)
}
}
view
.
enableSendMessageButton
(
false
)
view
.
enableSendMessageButton
()
}
catch
(
ex
:
Exception
)
{
Timber
.
d
(
ex
,
"Error sending message..."
)
ex
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
view
.
enableSendMessageButton
(
true
)
jobSchedulerInteractor
.
scheduleSendingMessages
()
}
finally
{
view
.
enableSendMessageButton
()
}
}
}
...
...
@@ -189,6 +226,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
}
if
(
state
is
State
.
Connected
)
{
jobSchedulerInteractor
.
scheduleSendingMessages
()
loadMissingMessages
()
}
}
...
...
@@ -563,12 +601,13 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
// failed, command is not valid so post it
sendMessage
(
roomId
,
text
,
null
)
}
view
.
enableSendMessageButton
(
false
)
}
}
catch
(
ex
:
RocketChatException
)
{
Timber
.
e
(
ex
)
// command is not valid, post it
sendMessage
(
roomId
,
text
,
null
)
}
finally
{
view
.
enableSendMessageButton
()
}
}
}
...
...
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomView.kt
View file @
2f934213
...
...
@@ -92,10 +92,8 @@ interface ChatRoomView : LoadingView, MessageView {
/**
* Enables the send message button.
*
* @param sendFailed Whether the sent message has failed.
*/
fun
enableSendMessageButton
(
sendFailed
:
Boolean
)
fun
enableSendMessageButton
()
/**
* Clears the message composition.
...
...
app/src/main/java/chat/rocket/android/chatroom/service/MessageService.kt
0 → 100644
View file @
2f934213
package
chat.rocket.android.chatroom.service
import
android.app.job.JobParameters
import
android.app.job.JobService
import
chat.rocket.android.server.domain.CurrentServerRepository
import
chat.rocket.android.server.domain.MessagesRepository
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.common.RocketChatException
import
chat.rocket.core.internal.rest.sendMessage
import
chat.rocket.core.model.Message
import
dagger.android.AndroidInjection
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.launch
import
timber.log.Timber
import
javax.inject.Inject
class
MessageService
:
JobService
()
{
@Inject
lateinit
var
factory
:
ConnectionManagerFactory
@Inject
lateinit
var
currentServerRepository
:
CurrentServerRepository
@Inject
lateinit
var
messageRepository
:
MessagesRepository
override
fun
onCreate
()
{
super
.
onCreate
()
AndroidInjection
.
inject
(
this
)
}
override
fun
onStopJob
(
params
:
JobParameters
?):
Boolean
{
return
false
}
override
fun
onStartJob
(
params
:
JobParameters
?):
Boolean
{
launch
(
CommonPool
)
{
val
currentServer
=
currentServerRepository
.
get
()
if
(
currentServer
!=
null
)
{
retrySendingMessages
(
params
,
currentServer
)
jobFinished
(
params
,
false
)
}
}
return
true
}
private
suspend
fun
retrySendingMessages
(
params
:
JobParameters
?,
currentServer
:
String
)
{
val
temporaryMessages
=
messageRepository
.
getAllUnsent
()
.
sortedWith
(
compareBy
(
Message
::
timestamp
))
if
(
temporaryMessages
.
isNotEmpty
())
{
val
connectionManager
=
factory
.
create
(
currentServer
)
val
client
=
connectionManager
.
client
temporaryMessages
.
forEach
{
message
->
try
{
client
.
sendMessage
(
message
=
message
.
message
,
messageId
=
message
.
id
,
roomId
=
message
.
roomId
,
avatar
=
message
.
avatar
,
attachments
=
message
.
attachments
,
alias
=
message
.
senderAlias
)
messageRepository
.
save
(
message
.
copy
(
isTemporary
=
false
))
Timber
.
d
(
"Sent scheduled message given by id: ${message.id}"
)
}
catch
(
ex
:
RocketChatException
)
{
Timber
.
e
(
ex
)
if
(
ex
.
message
?.
contains
(
"E11000"
,
true
)
==
true
)
{
// XXX: Temporary solution. We need proper error codes from the api.
messageRepository
.
save
(
message
.
copy
(
isTemporary
=
false
))
}
jobFinished
(
params
,
true
)
}
}
}
}
companion
object
{
const
val
RETRY_SEND_MESSAGE_ID
=
1
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
2f934213
...
...
@@ -4,7 +4,6 @@ import android.Manifest
import
android.app.Activity
import
android.content.ClipData
import
android.content.ClipboardManager
import
android.content.Context
import
android.content.Intent
import
android.content.pm.PackageManager
import
android.net.Uri
...
...
@@ -70,8 +69,10 @@ private const val BUNDLE_CHAT_ROOM_LAST_SEEN = "chat_room_last_seen"
private
const
val
BUNDLE_CHAT_ROOM_IS_SUBSCRIBED
=
"chat_room_is_subscribed"
class
ChatRoomFragment
:
Fragment
(),
ChatRoomView
,
EmojiKeyboardListener
,
EmojiReactionListener
{
@Inject
lateinit
var
presenter
:
ChatRoomPresenter
@Inject
lateinit
var
parser
:
MessageParser
@Inject
lateinit
var
presenter
:
ChatRoomPresenter
@Inject
lateinit
var
parser
:
MessageParser
private
lateinit
var
adapter
:
ChatRoomAdapter
private
lateinit
var
chatRoomId
:
String
private
lateinit
var
chatRoomName
:
String
...
...
@@ -316,15 +317,14 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
}
}
override
fun
enableSendMessageButton
(
sendFailed
:
Boolean
)
{
override
fun
enableSendMessageButton
()
{
ui
{
button_send
.
isEnabled
=
true
text_message
.
isEnabled
=
true
if
(!
sendFailed
)
{
clearMessageComposition
()
}
}
}
override
fun
clearMessageComposition
()
{
ui
{
...
...
@@ -589,6 +589,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
var
textMessage
=
citation
?:
""
textMessage
+=
text_message
.
textContent
sendMessage
(
textMessage
)
clearMessageComposition
()
}
button_show_attachment_options
.
setOnClickListener
{
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/AudioAttachmentViewModel.kt
View file @
2f934213
...
...
@@ -13,7 +13,8 @@ data class AudioAttachmentViewModel(
override
val
id
:
Long
,
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
,
override
var
preview
:
Message
?
=
null
override
var
preview
:
Message
?
=
null
,
override
var
isTemporary
:
Boolean
=
false
)
:
BaseFileAttachmentViewModel
<
AudioAttachment
>
{
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
AUDIO_ATTACHMENT
.
viewType
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/AuthorAttachmentViewModel.kt
View file @
2f934213
...
...
@@ -15,7 +15,8 @@ data class AuthorAttachmentViewModel(
override
val
messageId
:
String
,
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
,
override
var
preview
:
Message
?
=
null
override
var
preview
:
Message
?
=
null
,
override
var
isTemporary
:
Boolean
=
false
)
:
BaseAttachmentViewModel
<
AuthorAttachment
>
{
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
AUTHOR_ATTACHMENT
.
viewType
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/BaseViewModel.kt
View file @
2f934213
...
...
@@ -12,6 +12,7 @@ interface BaseViewModel<out T> {
var
reactions
:
List
<
ReactionViewModel
>
var
nextDownStreamMessage
:
BaseViewModel
<*>?
var
preview
:
Message
?
var
isTemporary
:
Boolean
enum
class
ViewType
(
val
viewType
:
Int
)
{
MESSAGE
(
0
),
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/ImageAttachmentViewModel.kt
View file @
2f934213
...
...
@@ -13,7 +13,8 @@ data class ImageAttachmentViewModel(
override
val
id
:
Long
,
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
,
override
var
preview
:
Message
?
=
null
override
var
preview
:
Message
?
=
null
,
override
var
isTemporary
:
Boolean
=
false
)
:
BaseFileAttachmentViewModel
<
ImageAttachment
>
{
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
IMAGE_ATTACHMENT
.
viewType
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/MessageAttachmentViewModel.kt
View file @
2f934213
...
...
@@ -14,7 +14,8 @@ data class MessageAttachmentViewModel(
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
,
var
messageLink
:
String
?
=
null
,
override
var
preview
:
Message
?
=
null
override
var
preview
:
Message
?
=
null
,
override
var
isTemporary
:
Boolean
=
false
)
:
BaseViewModel
<
Message
>
{
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
MESSAGE_ATTACHMENT
.
viewType
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/MessageViewModel.kt
View file @
2f934213
...
...
@@ -15,7 +15,8 @@ data class MessageViewModel(
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
,
override
var
preview
:
Message
?
=
null
,
var
isFirstUnread
:
Boolean
var
isFirstUnread
:
Boolean
,
override
var
isTemporary
:
Boolean
=
false
)
:
BaseMessageViewModel
<
Message
>
{
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
MESSAGE
.
viewType
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/UrlPreviewViewModel.kt
View file @
2f934213
...
...
@@ -14,7 +14,8 @@ data class UrlPreviewViewModel(
val
thumbUrl
:
String
?,
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
,
override
var
preview
:
Message
?
=
null
override
var
preview
:
Message
?
=
null
,
override
var
isTemporary
:
Boolean
=
false
)
:
BaseViewModel
<
Url
>
{
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
URL_PREVIEW
.
viewType
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/VideoAttachmentViewModel.kt
View file @
2f934213
...
...
@@ -13,7 +13,8 @@ data class VideoAttachmentViewModel(
override
val
id
:
Long
,
override
var
reactions
:
List
<
ReactionViewModel
>,
override
var
nextDownStreamMessage
:
BaseViewModel
<*>?
=
null
,
override
var
preview
:
Message
?
=
null
override
var
preview
:
Message
?
=
null
,
override
var
isTemporary
:
Boolean
=
false
)
:
BaseFileAttachmentViewModel
<
VideoAttachment
>
{
override
val
viewType
:
Int
get
()
=
BaseViewModel
.
ViewType
.
VIDEO_ATTACHMENT
.
viewType
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/ViewModelMapper.kt
View file @
2f934213
...
...
@@ -226,12 +226,13 @@ class ViewModelMapper @Inject constructor(private val context: Context,
val
time
=
getTime
(
message
.
timestamp
)
val
avatar
=
getUserAvatar
(
message
)
val
preview
=
mapMessagePreview
(
message
)
val
isTemp
=
message
.
isTemporary
?:
false
val
content
=
getContent
(
stripMessageQuotes
(
message
))
MessageViewModel
(
message
=
stripMessageQuotes
(
message
),
rawData
=
message
,
messageId
=
message
.
id
,
avatar
=
avatar
!!
,
time
=
time
,
senderName
=
sender
,
content
=
content
,
isPinned
=
message
.
pinned
,
reactions
=
getReactions
(
message
),
isFirstUnread
=
false
,
preview
=
preview
)
isFirstUnread
=
false
,
preview
=
preview
,
isTemporary
=
isTemp
)
}
private
suspend
fun
mapMessagePreview
(
message
:
Message
):
Message
{
...
...
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsPresenter.kt
View file @
2f934213
...
...
@@ -40,6 +40,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
private
val
saveChatRoomsInteractor
:
SaveChatRoomsInteractor
,
private
val
refreshSettingsInteractor
:
RefreshSettingsInteractor
,
private
val
viewModelMapper
:
ViewModelMapper
,
private
val
jobSchedulerInteractor
:
JobSchedulerInteractor
,
settingsRepository
:
SettingsRepository
,
factory
:
ConnectionManagerFactory
)
{
private
val
manager
:
ConnectionManager
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
...
...
@@ -258,6 +259,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
}
if
(
state
is
State
.
Connected
)
{
jobSchedulerInteractor
.
scheduleSendingMessages
()
reloadRooms
()
updateRooms
()
}
...
...
app/src/main/java/chat/rocket/android/dagger/AppComponent.kt
View file @
2f934213
...
...
@@ -2,6 +2,7 @@ package chat.rocket.android.dagger
import
android.app.Application
import
chat.rocket.android.app.RocketChatApplication
import
chat.rocket.android.chatroom.service.MessageService
import
chat.rocket.android.dagger.module.ActivityBuilder
import
chat.rocket.android.dagger.module.AppModule
import
chat.rocket.android.dagger.module.ReceiverBuilder
...
...
@@ -29,6 +30,8 @@ interface AppComponent {
fun
inject
(
service
:
FirebaseTokenService
)
fun
inject
(
service
:
MessageService
)
/*@Component.Builder
abstract class Builder : AndroidInjector.Builder<RocketChatApplication>()*/
}
app/src/main/java/chat/rocket/android/dagger/module/AppModule.kt
View file @
2f934213
...
...
@@ -2,7 +2,10 @@ package chat.rocket.android.dagger.module
import
android.app.Application
import
android.app.NotificationManager
import
android.app.job.JobInfo
import
android.app.job.JobScheduler
import
android.arch.persistence.room.Room
import
android.content.ComponentName
import
android.content.Context
import
android.content.SharedPreferences
import
androidx.core.content.systemService
...
...
@@ -11,6 +14,7 @@ import chat.rocket.android.R
import
chat.rocket.android.app.RocketChatDatabase
import
chat.rocket.android.authentication.infraestructure.SharedPreferencesMultiServerTokenRepository
import
chat.rocket.android.authentication.infraestructure.SharedPreferencesTokenRepository
import
chat.rocket.android.chatroom.service.MessageService
import
chat.rocket.android.dagger.qualifier.ForFresco
import
chat.rocket.android.helper.FrescoAuthInterceptor
import
chat.rocket.android.helper.MessageParser
...
...
@@ -19,19 +23,17 @@ import chat.rocket.android.infrastructure.SharedPrefsLocalRepository
import
chat.rocket.android.push.GroupedPush
import
chat.rocket.android.push.PushManager
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.infraestructure.MemoryChatRoomsRepository
import
chat.rocket.android.server.infraestructure.MemoryMessagesRepository
import
chat.rocket.android.server.infraestructure.MemoryRoomRepository
import
chat.rocket.android.server.infraestructure.MemoryUsersRepository
import
chat.rocket.android.server.infraestructure.ServerDao
import
chat.rocket.android.server.infraestructure.SharedPreferencesAccountsRepository
import
chat.rocket.android.server.infraestructure.SharedPreferencesSettingsRepository
import
chat.rocket.android.server.infraestructure.SharedPrefsCurrentServerRepository
import
chat.rocket.android.server.infraestructure.*
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.RocketChatClient
import
chat.rocket.core.internal.AttachmentAdapterFactory
import
com.facebook.drawee.backends.pipeline.DraweeConfig
import
com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory
import
com.facebook.imagepipeline.core.ImagePipelineConfig
...
...
@@ -121,7 +123,7 @@ class AppModule {
@Provides
@ForFresco
@Singleton
fun
provideFrescoAuthIntercept
e
r
(
tokenRepository
:
TokenRepository
,
currentServerInteractor
:
GetCurrentServerInteractor
):
Interceptor
{
fun
provideFrescoAuthIntercept
o
r
(
tokenRepository
:
TokenRepository
,
currentServerInteractor
:
GetCurrentServerInteractor
):
Interceptor
{
return
FrescoAuthInterceptor
(
tokenRepository
,
currentServerInteractor
)
}
...
...
@@ -202,10 +204,16 @@ class AppModule {
@Provides
@Singleton
fun
provideMoshi
():
Moshi
{
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
()))
.
build
()
}
...
...
@@ -217,8 +225,9 @@ class AppModule {
@Provides
@Singleton
fun
provideMessageRepository
():
MessagesRepository
{
return
MemoryMessagesRepository
()
fun
provideMessageRepository
(
context
:
Application
,
moshi
:
Moshi
,
currentServerInteractor
:
GetCurrentServerInteractor
):
MessagesRepository
{
val
preferences
=
context
.
getSharedPreferences
(
"messages"
,
Context
.
MODE_PRIVATE
)
return
SharedPreferencesMessagesRepository
(
preferences
,
moshi
,
currentServerInteractor
)
}
@Provides
...
...
@@ -278,4 +287,22 @@ class AppModule {
getSettingsInteractor
:
GetSettingsInteractor
):
PushManager
{
return
PushManager
(
groupedPushes
,
manager
,
moshi
,
getAccountInteractor
,
getSettingsInteractor
,
context
)
}
@Provides
fun
provideJobScheduler
(
context
:
Application
):
JobScheduler
{
return
context
.
getSystemService
(
Context
.
JOB_SCHEDULER_SERVICE
)
as
JobScheduler
}
@Provides
fun
provideSendMessageJob
(
context
:
Application
):
JobInfo
{
return
JobInfo
.
Builder
(
MessageService
.
RETRY_SEND_MESSAGE_ID
,
ComponentName
(
context
,
MessageService
::
class
.
java
))
.
setRequiredNetworkType
(
JobInfo
.
NETWORK_TYPE_ANY
)
.
build
()
}
@Provides
fun
provideJobSchedulerInteractor
(
jobScheduler
:
JobScheduler
,
jobInfo
:
JobInfo
):
JobSchedulerInteractor
{
return
JobSchedulerInteractorImpl
(
jobScheduler
,
jobInfo
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/dagger/module/ServiceBuilder.kt
View file @
2f934213
package
chat.rocket.android.dagger.module
import
chat.rocket.android.chatroom.di.MessageServiceProvider
import
chat.rocket.android.chatroom.service.MessageService
import
chat.rocket.android.push.FirebaseTokenService
import
chat.rocket.android.push.GcmListenerService
import
chat.rocket.android.push.di.FirebaseTokenServiceProvider
...
...
@@ -14,4 +16,7 @@ import dagger.android.ContributesAndroidInjector
@ContributesAndroidInjector
(
modules
=
[
GcmListenerServiceProvider
::
class
])
abstract
fun
bindGcmListenerService
():
GcmListenerService
@ContributesAndroidInjector
(
modules
=
[
MessageServiceProvider
::
class
])
abstract
fun
bindMessageService
():
MessageService
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/infrastructure/LocalRepository.kt
View file @
2f934213
...
...
@@ -24,4 +24,5 @@ interface LocalRepository {
}
}
fun
LocalRepository
.
checkIfMyself
(
username
:
String
)
=
get
(
LocalRepository
.
CURRENT_USERNAME_KEY
)
==
username
\ No newline at end of file
fun
LocalRepository
.
checkIfMyself
(
username
:
String
)
=
username
()
==
username
fun
LocalRepository
.
username
()
=
get
(
LocalRepository
.
CURRENT_USERNAME_KEY
)
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/presentation/MainPresenter.kt
View file @
2f934213
...
...
@@ -23,9 +23,7 @@ import chat.rocket.core.internal.rest.logout
import
chat.rocket.core.internal.rest.me
import
chat.rocket.core.internal.rest.unregisterPushToken
import
chat.rocket.core.model.Myself
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.channels.Channel
import
kotlinx.coroutines.experimental.launch
import
timber.log.Timber
import
javax.inject.Inject
...
...
@@ -39,7 +37,7 @@ class MainPresenter @Inject constructor(
private
val
navHeaderMapper
:
NavHeaderViewModelMapper
,
private
val
saveAccountInteractor
:
SaveAccountInteractor
,
private
val
getAccountsInteractor
:
GetAccountsInteractor
,
private
val
removeAccountInterector
:
RemoveAccountIntere
ctor
,
private
val
removeAccountInteractor
:
RemoveAccountIntera
ctor
,
private
val
factory
:
RocketChatClientFactory
,
getSettingsInteractor
:
GetSettingsInteractor
,
managerFactory
:
ConnectionManagerFactory
...
...
@@ -105,7 +103,7 @@ class MainPresenter @Inject constructor(
try
{
disconnect
()
removeAccountInter
e
ctor
.
remove
(
currentServer
)
removeAccountInter
a
ctor
.
remove
(
currentServer
)
tokenRepository
.
remove
(
currentServer
)
navigator
.
toNewServer
()
}
catch
(
ex
:
Exception
)
{
...
...
app/src/main/java/chat/rocket/android/server/domain/JobSchedulerInteractor.kt
0 → 100644
View file @
2f934213
package
chat.rocket.android.server.domain
interface
JobSchedulerInteractor
{
/**
* Schedule job to retry previously failed sending messages.
*/
fun
scheduleSendingMessages
()
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/MessagesRepository.kt
View file @
2f934213
...
...
@@ -11,7 +11,7 @@ interface MessagesRepository {
*
* @return The Message object given by the id or null if message wasn't found.
*/
fun
getById
(
id
:
String
):
Message
?
suspend
fun
getById
(
id
:
String
):
Message
?
/**
* Get all messages from the current room id.
...
...
@@ -19,7 +19,7 @@ interface MessagesRepository {
* @param rid The room id.
* @return A list of Message objects for the room with given room id or an empty list.
*/
fun
getByRoomId
(
rid
:
String
):
List
<
Message
>
suspend
fun
getByRoomId
(
rid
:
String
):
List
<
Message
>
/**
* Get most recent messages up to count different users.
...
...
@@ -29,43 +29,47 @@ interface MessagesRepository {
*
* @return List of last count messages.
*/
fun
getRecentMessages
(
rid
:
String
,
count
:
Long
):
List
<
Message
>
suspend
fun
getRecentMessages
(
rid
:
String
,
count
:
Long
):
List
<
Message
>
/**
* Get all messages. Use carefully!
*
* @return All messages or an empty list.
*/
fun
getAll
():
List
<
Message
>
suspend
fun
getAll
():
List
<
Message
>
/**
* Save a single message object.
*
* @param The message object to saveAll.
*/
fun
save
(
message
:
Message
)
suspend
fun
save
(
message
:
Message
)
/**
* Save a list of messages.
*/
fun
saveAll
(
newMessages
:
List
<
Message
>)
suspend
fun
saveAll
(
newMessages
:
List
<
Message
>)
/**
* Removes all messages.
*/
fun
clear
()
suspend
fun
clear
()
/**
* Remove message by id.
*
* @param id The id of the message to remove.
*/
fun
removeById
(
id
:
String
)
suspend
fun
removeById
(
id
:
String
)
/**
* Remove all messages from a given room.
*
* @param rid The room id where messages are to be removed.
*/
fun
removeByRoomId
(
rid
:
String
)
suspend
fun
removeByRoomId
(
rid
:
String
)
suspend
fun
getAllUnsent
():
List
<
Message
>
suspend
fun
getUnsentByRoomId
(
roomId
:
String
):
List
<
Message
>
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/RemoveAccountInter
e
ctor.kt
→
app/src/main/java/chat/rocket/android/server/domain/RemoveAccountInter
a
ctor.kt
View file @
2f934213
...
...
@@ -2,7 +2,7 @@ package chat.rocket.android.server.domain
import
javax.inject.Inject
class
RemoveAccountInter
e
ctor
@Inject
constructor
(
val
repository
:
AccountsRepository
)
{
class
RemoveAccountInter
a
ctor
@Inject
constructor
(
val
repository
:
AccountsRepository
)
{
suspend
fun
remove
(
serverUrl
:
String
)
{
repository
.
remove
(
serverUrl
)
}
...
...
app/src/main/java/chat/rocket/android/server/infraestructure/JobSchedulerInteractorImpl.kt
0 → 100644
View file @
2f934213
package
chat.rocket.android.server.infraestructure
import
android.app.job.JobInfo
import
android.app.job.JobScheduler
import
chat.rocket.android.server.domain.JobSchedulerInteractor
import
timber.log.Timber
import
javax.inject.Inject
/**
* Uses the Android framework [JobScheduler].
*/
class
JobSchedulerInteractorImpl
@Inject
constructor
(
private
val
jobScheduler
:
JobScheduler
,
private
val
jobInfo
:
JobInfo
)
:
JobSchedulerInteractor
{
override
fun
scheduleSendingMessages
()
{
Timber
.
d
(
"Scheduling unsent messages to send..."
)
jobScheduler
.
schedule
(
jobInfo
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/infraestructure/MemoryMessagesRepository.kt
View file @
2f934213
...
...
@@ -2,45 +2,67 @@ package chat.rocket.android.server.infraestructure
import
chat.rocket.android.server.domain.MessagesRepository
import
chat.rocket.core.model.Message
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.withContext
class
MemoryMessagesRepository
:
MessagesRepository
{
private
val
messages
:
HashMap
<
String
,
Message
>
=
HashMap
()
override
fun
getById
(
id
:
String
):
Message
?
{
return
messages
[
id
]
override
suspend
fun
getById
(
id
:
String
):
Message
?
=
withContext
(
CommonPool
)
{
return
@withContext
messages
[
id
]
}
override
fun
getByRoomId
(
rid
:
String
):
List
<
Message
>
{
return
messages
.
filter
{
it
.
value
.
roomId
==
rid
}.
values
.
toList
()
override
suspend
fun
getByRoomId
(
rid
:
String
):
List
<
Message
>
=
withContext
(
CommonPool
)
{
return
@withContext
messages
.
filter
{
it
.
value
.
roomId
==
rid
}.
values
.
toList
()
}
override
fun
getRecentMessages
(
rid
:
String
,
count
:
Long
):
List
<
Message
>
{
return
getByRoomId
(
rid
).
sortedByDescending
{
it
.
timestamp
}
override
suspend
fun
getRecentMessages
(
rid
:
String
,
count
:
Long
):
List
<
Message
>
=
withContext
(
CommonPool
)
{
return
@withContext
getByRoomId
(
rid
).
sortedByDescending
{
it
.
timestamp
}
.
distinctBy
{
it
.
sender
}.
take
(
count
.
toInt
())
}
override
fun
getAll
():
List
<
Message
>
=
messages
.
values
.
toList
()
override
suspend
fun
getAll
():
List
<
Message
>
=
withContext
(
CommonPool
)
{
return
@withContext
messages
.
values
.
toList
()
}
override
suspend
fun
getUnsentByRoomId
(
roomId
:
String
):
List
<
Message
>
=
withContext
(
CommonPool
)
{
val
allByRoomId
=
getByRoomId
(
roomId
)
if
(
allByRoomId
.
isEmpty
())
{
return
@withContext
emptyList
<
Message
>()
}
return
@withContext
allByRoomId
.
filter
{
it
.
isTemporary
?:
false
&&
it
.
roomId
==
roomId
}
}
override
fun
save
(
message
:
Message
)
{
override
suspend
fun
getAllUnsent
():
List
<
Message
>
=
withContext
(
CommonPool
)
{
val
all
=
getAll
()
if
(
all
.
isEmpty
())
{
return
@withContext
emptyList
<
Message
>()
}
return
@withContext
all
.
filter
{
it
.
isTemporary
?:
false
}
}
override
suspend
fun
save
(
message
:
Message
)
=
withContext
(
CommonPool
)
{
messages
[
message
.
id
]
=
message
}
override
fun
saveAll
(
newMessages
:
List
<
Message
>
)
{
override
suspend
fun
saveAll
(
newMessages
:
List
<
Message
>)
=
withContext
(
CommonPool
)
{
for
(
msg
in
newMessages
)
{
messages
[
msg
.
id
]
=
msg
}
}
override
fun
clear
(
)
{
override
suspend
fun
clear
()
=
withContext
(
CommonPool
)
{
messages
.
clear
()
}
override
fun
removeById
(
id
:
String
)
{
override
suspend
fun
removeById
(
id
:
String
)
{
withContext
(
CommonPool
)
{
messages
.
remove
(
id
)
}
}
override
fun
removeByRoomId
(
rid
:
String
)
{
override
suspend
fun
removeByRoomId
(
rid
:
String
)
=
withContext
(
CommonPool
)
{
val
roomMessages
=
messages
.
filter
{
it
.
value
.
roomId
==
rid
}.
values
roomMessages
.
forEach
{
messages
.
remove
(
it
.
roomId
)
...
...
app/src/main/java/chat/rocket/android/server/infraestructure/SharedPreferencesMessagesRepository.kt
0 → 100644
View file @
2f934213
package
chat.rocket.android.server.infraestructure
import
android.content.SharedPreferences
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.MessagesRepository
import
chat.rocket.core.model.Message
import
com.squareup.moshi.Moshi
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.withContext
class
SharedPreferencesMessagesRepository
(
private
val
prefs
:
SharedPreferences
,
private
val
moshi
:
Moshi
,
private
val
currentServerInteractor
:
GetCurrentServerInteractor
)
:
MessagesRepository
{
override
suspend
fun
getById
(
id
:
String
):
Message
?
=
withContext
(
CommonPool
)
{
currentServerInteractor
.
get
()
?.
also
{
server
->
if
(
prefs
.
all
.
values
.
isEmpty
())
{
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
}
}
return
@withContext
null
}
override
suspend
fun
getByRoomId
(
rid
:
String
):
List
<
Message
>
=
withContext
(
CommonPool
)
{
currentServerInteractor
.
get
()
?.
also
{
server
->
val
adapter
=
moshi
.
adapter
<
Message
>(
Message
::
class
.
java
)
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
()
}
return
@withContext
emptyList
<
Message
>()
}
override
suspend
fun
getRecentMessages
(
rid
:
String
,
count
:
Long
):
List
<
Message
>
=
withContext
(
CommonPool
)
{
return
@withContext
getByRoomId
(
rid
).
sortedByDescending
{
it
.
timestamp
}
.
distinctBy
{
it
.
sender
}.
take
(
count
.
toInt
())
}
override
suspend
fun
getAll
():
List
<
Message
>
=
withContext
(
CommonPool
)
{
val
adapter
=
moshi
.
adapter
<
Message
>(
Message
::
class
.
java
)
if
(
prefs
.
all
.
values
.
isEmpty
())
{
return
@withContext
emptyList
<
Message
>()
}
currentServerInteractor
.
get
()
?.
also
{
server
->
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
)
{
if
(
prefs
.
all
.
values
.
isEmpty
())
{
return
@withContext
emptyList
<
Message
>()
}
currentServerInteractor
.
get
()
?.
also
{
server
->
val
values
=
prefs
.
all
.
entries
.
filter
{
it
.
key
.
startsWith
(
server
)
}
.
map
{
it
.
value
}
as
Collection
<
String
>
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
)
{
val
allByRoomId
=
getByRoomId
(
roomId
)
if
(
allByRoomId
.
isEmpty
())
{
return
@withContext
emptyList
<
Message
>()
}
return
@withContext
allByRoomId
.
filter
{
it
.
isTemporary
?:
false
}
}
override
suspend
fun
save
(
message
:
Message
)
{
withContext
(
CommonPool
)
{
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
)
{
currentServerInteractor
.
get
()
?.
also
{
val
adapter
=
moshi
.
adapter
<
Message
>(
Message
::
class
.
java
)
val
editor
=
prefs
.
edit
()
for
(
msg
in
newMessages
)
{
editor
.
putString
(
"${it}_${msg.id}"
,
adapter
.
toJson
(
msg
))
}
editor
.
apply
()
}
}
}
override
suspend
fun
clear
()
=
withContext
(
CommonPool
)
{
prefs
.
edit
().
clear
().
apply
()
}
override
suspend
fun
removeById
(
id
:
String
)
{
withContext
(
CommonPool
)
{
currentServerInteractor
.
get
()
?.
also
{
prefs
.
edit
().
putString
(
"${it}_$id"
,
null
).
apply
()
}
}
}
override
suspend
fun
removeByRoomId
(
rid
:
String
)
{
withContext
(
CommonPool
)
{
currentServerInteractor
.
get
()
?.
also
{
server
->
val
adapter
=
moshi
.
adapter
<
Message
>(
Message
::
class
.
java
)
val
editor
=
prefs
.
edit
()
prefs
.
all
.
entries
.
forEach
{
val
value
=
it
.
value
if
(
value
is
String
)
{
val
message
=
adapter
.
fromJson
(
value
)
if
(
message
?.
roomId
==
rid
)
{
editor
.
putString
(
"${server}_${message.id}"
,
null
)
}
}
}
editor
.
apply
()
}
}
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment