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
ca4056e3
Unverified
Commit
ca4056e3
authored
Mar 11, 2019
by
Filipe de Lima Brito
Committed by
GitHub
Mar 11, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2093 from karthyks/refactor/app-module
[REFACTOR] Handle nullable on arguments extra
parents
99f75dd6
d5a5a9be
Changes
43
Show whitespace changes
Inline
Side-by-side
Showing
43 changed files
with
292 additions
and
318 deletions
+292
-318
LoginFragment.kt
...t/rocket/android/authentication/login/ui/LoginFragment.kt
+4
-6
LoginOptionsFragment.kt
...id/authentication/loginoptions/ui/LoginOptionsFragment.kt
+30
-31
RegisterUsernameFragment.kt
...ntication/registerusername/ui/RegisterUsernameFragment.kt
+4
-8
SignupFragment.kt
...rocket/android/authentication/signup/ui/SignupFragment.kt
+1
-1
TwoFAFragment.kt
...cket/android/authentication/twofactor/ui/TwoFAFragment.kt
+4
-8
ChatDetailsFragment.kt
...chat/rocket/android/chatdetails/ui/ChatDetailsFragment.kt
+6
-9
MessageInfoFragment.kt
.../rocket/android/chatinformation/ui/MessageInfoFragment.kt
+3
-6
ActionsListAdapter.kt
...hat/rocket/android/chatroom/adapter/ActionsListAdapter.kt
+4
-1
ChatRoomAdapter.kt
...a/chat/rocket/android/chatroom/adapter/ChatRoomAdapter.kt
+2
-2
RoomSuggestionsAdapter.kt
...rocket/android/chatroom/adapter/RoomSuggestionsAdapter.kt
+2
-2
UrlPreviewViewHolder.kt
...t/rocket/android/chatroom/adapter/UrlPreviewViewHolder.kt
+5
-4
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+1
-1
ChatRoomActivity.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt
+29
-27
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+12
-14
Dialog.kt
app/src/main/java/chat/rocket/android/chatroom/ui/Dialog.kt
+16
-22
UiModelMapper.kt
...ava/chat/rocket/android/chatroom/uimodel/UiModelMapper.kt
+11
-14
RoomViewHolder.kt
...a/chat/rocket/android/chatrooms/adapter/RoomViewHolder.kt
+17
-14
RoomsAdapter.kt
...ava/chat/rocket/android/chatrooms/adapter/RoomsAdapter.kt
+1
-2
ChatRoomsFragment.kt
...ava/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
+6
-7
CreateChannelFragment.kt
.../rocket/android/createchannel/ui/CreateChannelFragment.kt
+3
-3
DatabaseManager.kt
app/src/main/java/chat/rocket/android/db/DatabaseManager.kt
+6
-10
Attachments.kt
...src/main/java/chat/rocket/android/db/model/Attachments.kt
+14
-23
FavoriteMessagesFragment.kt
...t/android/favoritemessages/ui/FavoriteMessagesFragment.kt
+3
-6
FilesFragment.kt
...c/main/java/chat/rocket/android/files/ui/FilesFragment.kt
+3
-6
ImageHelper.kt
app/src/main/java/chat/rocket/android/helper/ImageHelper.kt
+16
-14
MembersAdapter.kt
...ava/chat/rocket/android/members/adapter/MembersAdapter.kt
+5
-3
MembersFragment.kt
...in/java/chat/rocket/android/members/ui/MembersFragment.kt
+4
-7
MentionsFragment.kt
.../java/chat/rocket/android/mentions/ui/MentionsFragment.kt
+3
-6
PinnedMessagesFragment.kt
...ocket/android/pinnedmessages/ui/PinnedMessagesFragment.kt
+3
-6
ProfileFragment.kt
...in/java/chat/rocket/android/profile/ui/ProfileFragment.kt
+6
-2
PushManager.kt
app/src/main/java/chat/rocket/android/push/PushManager.kt
+24
-12
ConnectionManager.kt
...ocket/android/server/infraestructure/ConnectionManager.kt
+3
-3
DatabaseMessageMapper.kt
...t/android/server/infraestructure/DatabaseMessageMapper.kt
+4
-4
DatabaseMessagesRepository.kt
...roid/server/infraestructure/DatabaseMessagesRepository.kt
+3
-3
SharedPreferencesAccountsRepository.kt
...er/infraestructure/SharedPreferencesAccountsRepository.kt
+4
-4
SharedPrefsBasicAuthRepository.kt
.../server/infraestructure/SharedPrefsBasicAuthRepository.kt
+2
-3
ChangeServerPresenter.kt
...cket/android/server/presentation/ChangeServerPresenter.kt
+1
-0
UserDetailsFragment.kt
...chat/rocket/android/userdetails/ui/UserDetailsFragment.kt
+3
-6
HttpLoggingInterceptor.kt
...n/java/chat/rocket/android/util/HttpLoggingInterceptor.kt
+1
-1
String.kt
...c/main/java/chat/rocket/android/util/extensions/String.kt
+2
-5
AdminPanelWebViewFragment.kt
...ndroid/webview/adminpanel/ui/AdminPanelWebViewFragment.kt
+6
-8
DividerItemDecoration.kt
.../java/chat/rocket/android/widget/DividerItemDecoration.kt
+4
-4
Widget.kt
...rc/main/java/chat/rocket/android/util/extension/Widget.kt
+11
-0
No files found.
app/src/main/java/chat/rocket/android/authentication/login/ui/LoginFragment.kt
View file @
ca4056e3
...
...
@@ -58,10 +58,8 @@ class LoginFragment : Fragment(), LoginView {
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
serverName
=
bundle
.
getString
(
SERVER_NAME
)
arguments
?.
run
{
serverName
=
getString
(
SERVER_NAME
)
}
}
...
...
@@ -150,7 +148,7 @@ class LoginFragment : Fragment(), LoginView {
override
fun
showGenericErrorMessage
()
=
showMessage
(
R
.
string
.
msg_generic_error
)
private
fun
setupOnClickListener
()
=
ui
{
_
->
ui
{
button_log_in
.
setOnClickListener
{
presenter
.
authenticateWithUserAndPassword
(
text_username_or_email
.
textContent
,
...
...
@@ -160,7 +158,7 @@ class LoginFragment : Fragment(), LoginView {
}
override
fun
showForgotPasswordView
()
{
ui
{
_
->
ui
{
button_forgot_your_password
.
isVisible
=
true
button_forgot_your_password
.
setOnClickListener
{
presenter
.
forgotPassword
()
}
...
...
app/src/main/java/chat/rocket/android/authentication/loginoptions/ui/LoginOptionsFragment.kt
View file @
ca4056e3
...
...
@@ -157,34 +157,33 @@ class LoginOptionsFragment : Fragment(), LoginOptionsView {
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
serverName
=
bundle
.
getString
(
SERVER_NAME
)
state
=
bundle
.
getString
(
STATE
)
facebookOauthUrl
=
bundle
.
getString
(
FACEBOOK_OAUTH_URL
)
githubOauthUrl
=
bundle
.
getString
(
GITHUB_OAUTH_URL
)
googleOauthUrl
=
bundle
.
getString
(
GOOGLE_OAUTH_URL
)
linkedinOauthUrl
=
bundle
.
getString
(
LINKEDIN_OAUTH_URL
)
gitlabOauthUrl
=
bundle
.
getString
(
GITLAB_OAUTH_URL
)
wordpressOauthUrl
=
bundle
.
getString
(
WORDPRESS_OAUTH_URL
)
casLoginUrl
=
bundle
.
getString
(
CAS_LOGIN_URL
)
casToken
=
bundle
.
getString
(
CAS_TOKEN
)
casServiceName
=
bundle
.
getString
(
CAS_SERVICE_NAME
)
casServiceNameTextColor
=
bundle
.
getInt
(
CAS_SERVICE_NAME_TEXT_COLOR
)
casServiceButtonColor
=
bundle
.
getInt
(
CAS_SERVICE_BUTTON_COLOR
)
customOauthUrl
=
bundle
.
getString
(
CUSTOM_OAUTH_URL
)
customOauthServiceName
=
bundle
.
getString
(
CUSTOM_OAUTH_SERVICE_NAME
)
customOauthServiceTextColor
=
bundle
.
getInt
(
CUSTOM_OAUTH_SERVICE_NAME_TEXT_COLOR
)
customOauthServiceButtonColor
=
bundle
.
getInt
(
CUSTOM_OAUTH_SERVICE_BUTTON_COLOR
)
samlUrl
=
bundle
.
getString
(
SAML_URL
)
samlToken
=
bundle
.
getString
(
SAML_TOKEN
)
samlServiceName
=
bundle
.
getString
(
SAML_SERVICE_NAME
)
samlServiceTextColor
=
bundle
.
getInt
(
SAML_SERVICE_NAME_TEXT_COLOR
)
samlServiceButtonColor
=
bundle
.
getInt
(
SAML_SERVICE_BUTTON_COLOR
)
totalSocialAccountsEnabled
=
bundle
.
getInt
(
TOTAL_SOCIAL_ACCOUNTS
)
isLoginFormEnabled
=
bundle
.
getBoolean
(
IS_LOGIN_FORM_ENABLED
)
isNewAccountCreationEnabled
=
bundle
.
getBoolean
(
IS_NEW_ACCOUNT_CREATION_ENABLED
)
deepLinkInfo
=
bundle
.
getParcelable
(
DEEP_LINK_INFO
)
arguments
?.
run
{
serverName
=
getString
(
SERVER_NAME
)
state
=
getString
(
STATE
)
facebookOauthUrl
=
getString
(
FACEBOOK_OAUTH_URL
)
githubOauthUrl
=
getString
(
GITHUB_OAUTH_URL
)
googleOauthUrl
=
getString
(
GOOGLE_OAUTH_URL
)
linkedinOauthUrl
=
getString
(
LINKEDIN_OAUTH_URL
)
gitlabOauthUrl
=
getString
(
GITLAB_OAUTH_URL
)
wordpressOauthUrl
=
getString
(
WORDPRESS_OAUTH_URL
)
casLoginUrl
=
getString
(
CAS_LOGIN_URL
)
casToken
=
getString
(
CAS_TOKEN
)
casServiceName
=
getString
(
CAS_SERVICE_NAME
)
casServiceNameTextColor
=
getInt
(
CAS_SERVICE_NAME_TEXT_COLOR
)
casServiceButtonColor
=
getInt
(
CAS_SERVICE_BUTTON_COLOR
)
customOauthUrl
=
getString
(
CUSTOM_OAUTH_URL
)
customOauthServiceName
=
getString
(
CUSTOM_OAUTH_SERVICE_NAME
)
customOauthServiceTextColor
=
getInt
(
CUSTOM_OAUTH_SERVICE_NAME_TEXT_COLOR
)
customOauthServiceButtonColor
=
getInt
(
CUSTOM_OAUTH_SERVICE_BUTTON_COLOR
)
samlUrl
=
getString
(
SAML_URL
)
samlToken
=
getString
(
SAML_TOKEN
)
samlServiceName
=
getString
(
SAML_SERVICE_NAME
)
samlServiceTextColor
=
getInt
(
SAML_SERVICE_NAME_TEXT_COLOR
)
samlServiceButtonColor
=
getInt
(
SAML_SERVICE_BUTTON_COLOR
)
totalSocialAccountsEnabled
=
getInt
(
TOTAL_SOCIAL_ACCOUNTS
)
isLoginFormEnabled
=
getBoolean
(
IS_LOGIN_FORM_ENABLED
)
isNewAccountCreationEnabled
=
getBoolean
(
IS_NEW_ACCOUNT_CREATION_ENABLED
)
deepLinkInfo
=
getParcelable
(
DEEP_LINK_INFO
)
}
}
...
...
@@ -388,7 +387,7 @@ class LoginOptionsFragment : Fragment(), LoginOptionsView {
}
override
fun
setupExpandAccountsView
()
{
ui
{
_
->
ui
{
expand_more_accounts_container
.
isVisible
=
true
var
isAccountsCollapsed
=
true
button_expand_collapse_accounts
.
setOnClickListener
{
...
...
@@ -406,14 +405,14 @@ class LoginOptionsFragment : Fragment(), LoginOptionsView {
}
override
fun
showLoginWithEmailButton
()
{
ui
{
_
->
ui
{
button_login_with_email
.
setOnClickListener
{
presenter
.
toLoginWithEmail
()
}
button_login_with_email
.
isVisible
=
true
}
}
override
fun
showCreateNewAccountButton
()
{
ui
{
_
->
ui
{
button_create_an_account
.
setOnClickListener
{
presenter
.
toCreateAccount
()
}
button_create_an_account
.
isVisible
=
true
}
...
...
app/src/main/java/chat/rocket/android/authentication/registerusername/ui/RegisterUsernameFragment.kt
View file @
ca4056e3
...
...
@@ -52,14 +52,10 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView {
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
userId
=
bundle
.
getString
(
BUNDLE_USER_ID
)
authToken
=
bundle
.
getString
(
BUNDLE_AUTH_TOKEN
)
}
else
{
requireNotNull
(
bundle
)
{
"no arguments supplied when the fragment was instantiated"
}
}
arguments
?.
run
{
userId
=
getString
(
BUNDLE_USER_ID
,
""
)
authToken
=
getString
(
BUNDLE_AUTH_TOKEN
,
""
)
}
?:
requireNotNull
(
arguments
)
{
"no arguments supplied when the fragment was instantiated"
}
}
override
fun
onCreateView
(
...
...
app/src/main/java/chat/rocket/android/authentication/signup/ui/SignupFragment.kt
View file @
ca4056e3
...
...
@@ -75,7 +75,7 @@ class SignupFragment : Fragment(), SignupView {
}
private
fun
setupOnClickListener
()
=
ui
{
_
->
ui
{
button_register
.
setOnClickListener
{
presenter
.
signup
(
text_username
.
textContent
,
...
...
app/src/main/java/chat/rocket/android/authentication/twofactor/ui/TwoFAFragment.kt
View file @
ca4056e3
...
...
@@ -49,14 +49,10 @@ class TwoFAFragment : Fragment(), TwoFAView {
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
username
=
bundle
.
getString
(
BUNDLE_USERNAME
)
password
=
bundle
.
getString
(
BUNDLE_PASSWORD
)
}
else
{
requireNotNull
(
bundle
)
{
"no arguments supplied when the fragment was instantiated"
}
}
arguments
?.
run
{
username
=
getString
(
BUNDLE_USERNAME
,
""
)
password
=
getString
(
BUNDLE_PASSWORD
,
""
)
}
?:
requireNotNull
(
arguments
)
{
"no arguments supplied when the fragment was instantiated"
}
}
override
fun
onCreateView
(
...
...
app/src/main/java/chat/rocket/android/chatdetails/ui/ChatDetailsFragment.kt
View file @
ca4056e3
...
...
@@ -66,15 +66,12 @@ class ChatDetailsFragment : Fragment(), ChatDetailsView {
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
chatRoomId
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_ID
)
chatRoomType
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_TYPE
)
isSubscribed
=
bundle
.
getBoolean
(
BUNDLE_IS_SUBSCRIBED
)
disableMenu
=
bundle
.
getBoolean
(
BUNDLE_DISABLE_MENU
)
}
else
{
requireNotNull
(
bundle
)
{
"no arguments supplied when the fragment was instantiated"
}
}
arguments
?.
run
{
chatRoomId
=
getString
(
BUNDLE_CHAT_ROOM_ID
)
chatRoomType
=
getString
(
BUNDLE_CHAT_ROOM_TYPE
)
isSubscribed
=
getBoolean
(
BUNDLE_IS_SUBSCRIBED
)
disableMenu
=
getBoolean
(
BUNDLE_DISABLE_MENU
)
}
?:
requireNotNull
(
arguments
)
{
"no arguments supplied when the fragment was instantiated"
}
}
override
fun
onCreateView
(
...
...
app/src/main/java/chat/rocket/android/chatinformation/ui/MessageInfoFragment.kt
View file @
ca4056e3
...
...
@@ -46,12 +46,9 @@ class MessageInfoFragment : Fragment(), MessageInfoView {
AndroidSupportInjection
.
inject
(
this
)
setHasOptionsMenu
(
true
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
messageId
=
bundle
.
getString
(
BUNDLE_MESSAGE_ID
)
}
else
{
requireNotNull
(
bundle
)
{
"no arguments supplied when the fragment was instantiated"
}
}
arguments
?.
run
{
messageId
=
getString
(
BUNDLE_MESSAGE_ID
,
""
)
}
?:
requireNotNull
(
arguments
)
{
"no arguments supplied when the fragment was instantiated"
}
}
override
fun
onCreateView
(
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/ActionsListAdapter.kt
View file @
ca4056e3
...
...
@@ -12,7 +12,10 @@ import com.facebook.drawee.backends.pipeline.Fresco
import
kotlinx.android.synthetic.main.item_action_button.view.*
import
timber.log.Timber
class
ActionsListAdapter
(
actions
:
List
<
Action
>,
var
actionAttachmentOnClickListener
:
ActionAttachmentOnClickListener
)
:
RecyclerView
.
Adapter
<
ActionsListAdapter
.
ViewHolder
>()
{
class
ActionsListAdapter
(
actions
:
List
<
Action
>,
var
actionAttachmentOnClickListener
:
ActionAttachmentOnClickListener
)
:
RecyclerView
.
Adapter
<
ActionsListAdapter
.
ViewHolder
>()
{
var
actions
:
List
<
Action
>
=
actions
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/ChatRoomAdapter.kt
View file @
ca4056e3
...
...
@@ -174,12 +174,12 @@ class ChatRoomAdapter(
Timber
.
d
(
"index: $index"
)
if
(
index
>
-
1
)
{
dataSet
[
index
]
=
message
dataSet
.
forEachIndexed
{
ind
ex
,
viewModel
->
dataSet
.
forEachIndexed
{
ind
,
viewModel
->
if
(
viewModel
.
messageId
==
message
.
messageId
)
{
if
(
viewModel
.
nextDownStreamMessage
==
null
)
{
viewModel
.
reactions
=
message
.
reactions
}
notifyItemChanged
(
ind
ex
)
notifyItemChanged
(
ind
)
}
}
// Delete message only if current is a system message update, i.e.: Message Removed
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/RoomSuggestionsAdapter.kt
View file @
ca4056e3
...
...
@@ -24,8 +24,8 @@ class RoomSuggestionsAdapter : SuggestionsAdapter<RoomSuggestionsViewHolder>("#"
override
fun
bind
(
item
:
SuggestionModel
,
itemClickListener
:
SuggestionsAdapter
.
ItemClickListener
?)
{
item
as
ChatRoomSuggestionUiModel
with
(
itemView
)
{
val
fullname
=
itemView
.
findViewById
<
TextView
>(
R
.
id
.
text_fullname
)
val
name
=
itemView
.
findViewById
<
TextView
>(
R
.
id
.
text_name
)
val
fullname
=
findViewById
<
TextView
>(
R
.
id
.
text_fullname
)
val
name
=
findViewById
<
TextView
>(
R
.
id
.
text_name
)
name
.
text
=
item
.
name
fullname
.
text
=
item
.
fullName
setOnClickListener
{
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/UrlPreviewViewHolder.kt
View file @
ca4056e3
...
...
@@ -8,10 +8,11 @@ import chat.rocket.android.util.extensions.content
import
chat.rocket.android.util.extensions.openTabbedUrl
import
kotlinx.android.synthetic.main.message_url_preview.view.*
class
UrlPreviewViewHolder
(
itemView
:
View
,
class
UrlPreviewViewHolder
(
itemView
:
View
,
listener
:
ActionsListener
,
reactionListener
:
EmojiReactionListener
?
=
null
)
:
BaseViewHolder
<
UrlPreviewUiModel
>(
itemView
,
listener
,
reactionListener
)
{
reactionListener
:
EmojiReactionListener
?
=
null
)
:
BaseViewHolder
<
UrlPreviewUiModel
>(
itemView
,
listener
,
reactionListener
)
{
init
{
with
(
itemView
)
{
...
...
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
View file @
ca4056e3
...
...
@@ -1072,7 +1072,7 @@ class ChatRoomPresenter @Inject constructor(
launchUI
(
strategy
)
{
try
{
messagesRepository
.
getById
(
messageId
)
?.
let
{
message
->
getChatRoomAsync
(
message
.
roomId
)
?.
let
{
chatRoom
->
getChatRoomAsync
(
message
.
roomId
)
?.
let
{
val
models
=
mapper
.
map
(
message
)
models
.
firstOrNull
()
?.
permalink
?.
let
{
view
.
copyToClipboard
(
it
)
...
...
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt
View file @
ca4056e3
...
...
@@ -81,28 +81,27 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
return
}
val
chatRoomId
=
intent
.
getStringExtra
(
INTENT_CHAT_ROOM_ID
)
with
(
intent
)
{
val
chatRoomId
=
getStringExtra
(
INTENT_CHAT_ROOM_ID
)
requireNotNull
(
chatRoomId
)
{
"no chat_room_id provided in Intent extras"
}
val
chatRoomName
=
intent
.
getStringExtra
(
INTENT_CHAT_ROOM_NAME
)
val
chatRoomName
=
getStringExtra
(
INTENT_CHAT_ROOM_NAME
)
requireNotNull
(
chatRoomName
)
{
"no chat_room_name provided in Intent extras"
}
val
chatRoomType
=
intent
.
getStringExtra
(
INTENT_CHAT_ROOM_TYPE
)
val
chatRoomType
=
getStringExtra
(
INTENT_CHAT_ROOM_TYPE
)
requireNotNull
(
chatRoomType
)
{
"no chat_room_type provided in Intent extras"
}
val
isReadOnly
=
intent
.
getBooleanExtra
(
INTENT_CHAT_ROOM_IS_READ_ONLY
,
true
)
val
isReadOnly
=
getBooleanExtra
(
INTENT_CHAT_ROOM_IS_READ_ONLY
,
true
)
val
isCreator
=
intent
.
getBooleanExtra
(
INTENT_CHAT_ROOM_IS_CREATOR
,
false
)
val
isCreator
=
getBooleanExtra
(
INTENT_CHAT_ROOM_IS_CREATOR
,
false
)
val
isFavorite
=
intent
.
getBooleanExtra
(
INTENT_CHAT_ROOM_IS_FAVORITE
,
false
)
val
isFavorite
=
getBooleanExtra
(
INTENT_CHAT_ROOM_IS_FAVORITE
,
false
)
val
chatRoomLastSeen
=
intent
.
getLongExtra
(
INTENT_CHAT_ROOM_LAST_SEEN
,
-
1
)
val
chatRoomLastSeen
=
getLongExtra
(
INTENT_CHAT_ROOM_LAST_SEEN
,
-
1
)
val
isSubscribed
=
intent
.
getBooleanExtra
(
INTENT_CHAT_IS_SUBSCRIBED
,
true
)
val
isSubscribed
=
getBooleanExtra
(
INTENT_CHAT_IS_SUBSCRIBED
,
true
)
val
chatRoomMessage
=
intent
.
getStringExtra
(
INTENT_CHAT_ROOM_MESSAGE
)
setupToolbar
()
val
chatRoomMessage
=
getStringExtra
(
INTENT_CHAT_ROOM_MESSAGE
)
if
(
supportFragmentManager
.
findFragmentByTag
(
TAG_CHAT_ROOM_FRAGMENT
)
==
null
)
{
addFragment
(
TAG_CHAT_ROOM_FRAGMENT
,
R
.
id
.
fragment_container
)
{
...
...
@@ -121,6 +120,9 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
}
}
setupToolbar
()
}
override
fun
onBackPressed
()
{
finishActivity
()
}
...
...
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
ca4056e3
...
...
@@ -273,20 +273,18 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
AndroidSupportInjection
.
inject
(
this
)
setHasOptionsMenu
(
true
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
chatRoomId
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_ID
)
chatRoomName
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_NAME
)
chatRoomType
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_TYPE
)
isReadOnly
=
bundle
.
getBoolean
(
BUNDLE_IS_CHAT_ROOM_READ_ONLY
)
isSubscribed
=
bundle
.
getBoolean
(
BUNDLE_CHAT_ROOM_IS_SUBSCRIBED
)
chatRoomLastSeen
=
bundle
.
getLong
(
BUNDLE_CHAT_ROOM_LAST_SEEN
)
isCreator
=
bundle
.
getBoolean
(
BUNDLE_CHAT_ROOM_IS_CREATOR
)
isFavorite
=
bundle
.
getBoolean
(
BUNDLE_CHAT_ROOM_IS_FAVORITE
)
chatRoomMessage
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_MESSAGE
)
}
else
{
requireNotNull
(
bundle
)
{
"no arguments supplied when the fragment was instantiated"
}
}
arguments
?.
run
{
chatRoomId
=
getString
(
BUNDLE_CHAT_ROOM_ID
,
""
)
chatRoomName
=
getString
(
BUNDLE_CHAT_ROOM_NAME
,
""
)
chatRoomType
=
getString
(
BUNDLE_CHAT_ROOM_TYPE
,
""
)
isReadOnly
=
getBoolean
(
BUNDLE_IS_CHAT_ROOM_READ_ONLY
)
isSubscribed
=
getBoolean
(
BUNDLE_CHAT_ROOM_IS_SUBSCRIBED
)
chatRoomLastSeen
=
getLong
(
BUNDLE_CHAT_ROOM_LAST_SEEN
)
isCreator
=
getBoolean
(
BUNDLE_CHAT_ROOM_IS_CREATOR
)
isFavorite
=
getBoolean
(
BUNDLE_CHAT_ROOM_IS_FAVORITE
)
chatRoomMessage
=
getString
(
BUNDLE_CHAT_ROOM_MESSAGE
)
}
?:
requireNotNull
(
arguments
)
{
"no arguments supplied when the fragment was instantiated"
}
adapter
=
ChatRoomAdapter
(
chatRoomId
,
chatRoomType
,
chatRoomName
,
this
,
reactionListener
=
this
,
navigator
=
navigator
)
}
...
...
app/src/main/java/chat/rocket/android/chatroom/ui/Dialog.kt
View file @
ca4056e3
...
...
@@ -8,8 +8,7 @@ import chat.rocket.android.emoji.internal.GlideApp
import
chat.rocket.android.util.extensions.getFileName
import
chat.rocket.android.util.extensions.getMimeType
import
chat.rocket.common.util.ifNull
import
com.bumptech.glide.request.target.SimpleTarget
import
com.bumptech.glide.request.transition.Transition
import
com.bumptech.glide.request.target.ImageViewTarget
fun
ChatRoomFragment
.
showFileAttachmentDialog
(
uri
:
Uri
)
{
imagePreview
.
isVisible
=
false
...
...
@@ -25,23 +24,18 @@ fun ChatRoomFragment.showFileAttachmentDialog(uri: Uri) {
when
{
mimeType
.
startsWith
(
"image"
)
->
{
if
(
mimeType
.
contains
(
"gif"
))
{
GlideApp
.
with
(
context
)
GlideApp
.
with
(
context
)
.
asGif
()
.
load
(
uri
)
.
fitCenter
()
.
into
(
imagePreview
)
}
else
{
GlideApp
.
with
(
context
)
GlideApp
.
with
(
context
)
.
asBitmap
()
.
load
(
uri
)
.
fitCenter
()
.
into
(
object
:
SimpleTarget
<
Bitmap
>()
{
override
fun
onResourceReady
(
resource
:
Bitmap
,
transition
:
Transition
<
in
Bitmap
>?
)
{
.
into
(
object
:
ImageViewTarget
<
Bitmap
>(
imagePreview
)
{
override
fun
setResource
(
resource
:
Bitmap
?)
{
bitmap
=
resource
imagePreview
.
setImageBitmap
(
resource
)
}
...
...
app/src/main/java/chat/rocket/android/chatroom/uimodel/UiModelMapper.kt
View file @
ca4056e3
...
...
@@ -416,21 +416,18 @@ class UiModelMapper @Inject constructor(
return
fullUrl
}
private
fun
attachmentText
(
text
:
String
?,
attachment
:
Attachment
?,
context
:
Context
):
String
?
{
return
if
(
attachment
!=
null
)
{
private
fun
attachmentText
(
text
:
String
?,
attachment
:
Attachment
?,
context
:
Context
):
String
?
=
attachment
?.
run
{
with
(
context
)
{
when
{
attachment
.
imageUrl
.
isNotNullNorEmpty
()
->
context
.
getString
(
R
.
string
.
msg_preview_photo
)
attachment
.
videoUrl
.
isNotNullNorEmpty
()
->
context
.
getString
(
R
.
string
.
msg_preview_video
)
attachment
.
audioUrl
.
isNotNullNorEmpty
()
->
context
.
getString
(
R
.
string
.
msg_preview_audio
)
attachment
.
titleLink
.
isNotNullNorEmpty
()
&&
attachment
.
type
?.
contentEquals
(
"file"
)
==
true
->
context
.
getString
(
R
.
string
.
msg_preview_file
)
imageUrl
.
isNotNullNorEmpty
()
->
getString
(
R
.
string
.
msg_preview_photo
)
videoUrl
.
isNotNullNorEmpty
()
->
getString
(
R
.
string
.
msg_preview_video
)
audioUrl
.
isNotNullNorEmpty
()
->
getString
(
R
.
string
.
msg_preview_audio
)
titleLink
.
isNotNullNorEmpty
()
&&
type
?.
contentEquals
(
"file"
)
==
true
->
getString
(
R
.
string
.
msg_preview_file
)
else
->
text
}
}
else
{
text
}
}
}
?:
text
private
fun
attachmentDescription
(
attachment
:
Attachment
):
String
?
{
return
attachment
.
description
...
...
app/src/main/java/chat/rocket/android/chatrooms/adapter/RoomViewHolder.kt
View file @
ca4056e3
...
...
@@ -8,20 +8,23 @@ import androidx.core.view.isInvisible
import
androidx.core.view.isVisible
import
chat.rocket.android.R
import
chat.rocket.android.chatrooms.adapter.model.RoomUiModel
import
chat.rocket.android.util.extension.setTextViewAppearance
import
chat.rocket.common.model.RoomType
import
chat.rocket.common.model.UserStatus
import
kotlinx.android.synthetic.main.item_chat.view.*
import
kotlinx.android.synthetic.main.unread_messages_badge.view.*
class
RoomViewHolder
(
itemView
:
View
,
private
val
listener
:
(
RoomUiModel
)
->
Unit
)
:
ViewHolder
<
RoomItemHolder
>(
itemView
)
{
class
RoomViewHolder
(
itemView
:
View
,
private
val
listener
:
(
RoomUiModel
)
->
Unit
)
:
ViewHolder
<
RoomItemHolder
>(
itemView
)
{
private
val
resources
:
Resources
=
itemView
.
resources
private
val
channelIcon
:
Drawable
=
resources
.
getDrawable
(
R
.
drawable
.
ic_hashtag_12dp
)
private
val
groupIcon
:
Drawable
=
resources
.
getDrawable
(
R
.
drawable
.
ic_lock_12_dp
)
private
val
onlineIcon
:
Drawable
=
resources
.
getDrawable
(
R
.
drawable
.
ic_status_online_12dp
)
private
val
awayIcon
:
Drawable
=
resources
.
getDrawable
(
R
.
drawable
.
ic_status_away_12dp
)
private
val
busyIcon
:
Drawable
=
resources
.
getDrawable
(
R
.
drawable
.
ic_status_busy_12dp
)
private
val
offlineIcon
:
Drawable
=
resources
.
getDrawable
(
R
.
drawable
.
ic_status_invisible_12dp
)
private
val
channelIcon
:
Drawable
=
resources
.
getDrawable
(
R
.
drawable
.
ic_hashtag_12dp
,
null
)
private
val
groupIcon
:
Drawable
=
resources
.
getDrawable
(
R
.
drawable
.
ic_lock_12_dp
,
null
)
private
val
onlineIcon
:
Drawable
=
resources
.
getDrawable
(
R
.
drawable
.
ic_status_online_12dp
,
null
)
private
val
awayIcon
:
Drawable
=
resources
.
getDrawable
(
R
.
drawable
.
ic_status_away_12dp
,
null
)
private
val
busyIcon
:
Drawable
=
resources
.
getDrawable
(
R
.
drawable
.
ic_status_busy_12dp
,
null
)
private
val
offlineIcon
:
Drawable
=
resources
.
getDrawable
(
R
.
drawable
.
ic_status_invisible_12dp
,
null
)
override
fun
bindViews
(
data
:
RoomItemHolder
)
{
val
room
=
data
.
data
...
...
@@ -53,14 +56,14 @@ class RoomViewHolder(itemView: View, private val listener: (RoomUiModel) -> Unit
if
(
room
.
unread
==
null
)
text_total_unread_messages
.
text
=
"!"
if
(
room
.
unread
!=
null
)
text_total_unread_messages
.
text
=
room
.
unread
if
(
room
.
mentions
)
text_total_unread_messages
.
text
=
"@${room.unread}"
text_chat_name
.
setTextAppearance
(
context
,
R
.
style
.
ChatList_ChatName_Unread_TextView
)
text_timestamp
.
setTextAppearance
(
context
,
R
.
style
.
ChatList_Timestamp_Unread_TextView
)
text_last_message
.
setTextAppearance
(
context
,
R
.
style
.
ChatList_LastMessage_Unread_TextView
)
text_chat_name
.
setText
View
Appearance
(
context
,
R
.
style
.
ChatList_ChatName_Unread_TextView
)
text_timestamp
.
setText
View
Appearance
(
context
,
R
.
style
.
ChatList_Timestamp_Unread_TextView
)
text_last_message
.
setText
View
Appearance
(
context
,
R
.
style
.
ChatList_LastMessage_Unread_TextView
)
text_total_unread_messages
.
isVisible
=
true
}
else
{
text_chat_name
.
setTextAppearance
(
context
,
R
.
style
.
ChatList_ChatName_TextView
)
text_timestamp
.
setTextAppearance
(
context
,
R
.
style
.
ChatList_Timestamp_TextView
)
text_last_message
.
setTextAppearance
(
context
,
R
.
style
.
ChatList_LastMessage_TextView
)
text_chat_name
.
setText
View
Appearance
(
context
,
R
.
style
.
ChatList_ChatName_TextView
)
text_timestamp
.
setText
View
Appearance
(
context
,
R
.
style
.
ChatList_Timestamp_TextView
)
text_last_message
.
setText
View
Appearance
(
context
,
R
.
style
.
ChatList_LastMessage_TextView
)
text_total_unread_messages
.
isInvisible
=
true
}
...
...
app/src/main/java/chat/rocket/android/chatrooms/adapter/RoomsAdapter.kt
View file @
ca4056e3
...
...
@@ -6,8 +6,7 @@ import chat.rocket.android.R
import
chat.rocket.android.chatrooms.adapter.model.RoomUiModel
import
chat.rocket.android.util.extensions.inflate
class
RoomsAdapter
(
private
val
listener
:
(
RoomUiModel
)
->
Unit
)
:
RecyclerView
.
Adapter
<
ViewHolder
<*>>()
{
class
RoomsAdapter
(
private
val
listener
:
(
RoomUiModel
)
->
Unit
)
:
RecyclerView
.
Adapter
<
ViewHolder
<*>>()
{
init
{
setHasStableIds
(
true
)
...
...
app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
View file @
ca4056e3
...
...
@@ -82,9 +82,8 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
setHasOptionsMenu
(
true
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
chatRoomId
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_ID
)
arguments
?.
run
{
chatRoomId
=
getString
(
BUNDLE_CHAT_ROOM_ID
)
chatRoomId
.
ifNotNullNotEmpty
{
roomId
->
presenter
.
loadChatRoom
(
roomId
)
chatRoomId
=
null
...
...
@@ -132,10 +131,10 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
recycler_view
.
adapter
=
adapter
viewModel
.
getChatRooms
().
observe
(
viewLifecycleOwner
,
Observer
{
rooms
->
rooms
?.
let
{
Timber
.
d
(
"Got items: $it"
)
adapter
.
values
=
it
if
(
roo
ms
.
isNotEmpty
())
{
rooms
?.
let
{
items
->
Timber
.
d
(
"Got items: $it
ems
"
)
adapter
.
values
=
it
ems
if
(
ite
ms
.
isNotEmpty
())
{
text_no_data_to_display
.
isVisible
=
false
}
}
...
...
app/src/main/java/chat/rocket/android/createchannel/ui/CreateChannelFragment.kt
View file @
ca4056e3
...
...
@@ -294,8 +294,8 @@ class CreateChannelFragment : Fragment(), CreateChannelView, ActionMode.Callback
private
fun
addChip
(
chipText
:
String
)
{
val
chip
=
Chip
(
context
)
chip
.
chipT
ext
=
chipText
chip
.
isCloseIcon
Enabled
=
true
chip
.
t
ext
=
chipText
chip
.
isCloseIcon
Visible
=
true
chip
.
setChipBackgroundColorResource
(
R
.
color
.
icon_grey
)
setupChipOnCloseIconClickListener
(
chip
)
chip_group_member
.
addView
(
chip
)
...
...
@@ -304,7 +304,7 @@ class CreateChannelFragment : Fragment(), CreateChannelView, ActionMode.Callback
private
fun
setupChipOnCloseIconClickListener
(
chip
:
Chip
)
{
chip
.
setOnCloseIconClickListener
{
removeChip
(
it
)
removeMember
((
it
as
Chip
).
chipT
ext
.
toString
())
removeMember
((
it
as
Chip
).
t
ext
.
toString
())
// whenever we remove a chip we should process the chip group visibility.
processChipGroupVisibility
()
}
...
...
app/src/main/java/chat/rocket/android/db/DatabaseManager.kt
View file @
ca4056e3
...
...
@@ -223,8 +223,8 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
val
list
=
mutableListOf
<
BaseMessageEntity
>()
reactions
.
keys
.
forEach
{
reaction
->
val
users
=
reactions
[
reaction
]
users
?.
let
{
users
->
list
.
add
(
ReactionEntity
(
reaction
,
message
.
id
,
users
.
size
,
users
.
joinToString
()))
users
?.
let
{
list
.
add
(
ReactionEntity
(
reaction
,
message
.
id
,
it
.
size
,
it
.
joinToString
()))
}
}
...
...
@@ -375,15 +375,11 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
}
}
private
fun
mapLastMessageText
(
message
:
Message
?):
String
?
{
return
if
(
message
==
null
)
{
null
}
else
{
return
if
(
message
.
message
.
isEmpty
()
&&
message
.
attachments
?.
isNotEmpty
()
==
true
)
{
mapAttachmentText
(
message
.
attachments
!!
[
0
])
private
fun
mapLastMessageText
(
message
:
Message
?):
String
?
=
message
?.
run
{
if
(
this
.
message
.
isEmpty
()
&&
attachments
?.
isNotEmpty
()
==
true
)
{
mapAttachmentText
(
attachments
!!
[
0
])
}
else
{
message
.
message
}
this
.
message
}
}
...
...
app/src/main/java/chat/rocket/android/db/model/Attachments.kt
View file @
ca4056e3
package
chat.rocket.android.db.model
import
android.content.Context
import
androidx.room.ColumnInfo
import
androidx.room.Entity
import
androidx.room.ForeignKey
import
androidx.room.Index
import
androidx.room.PrimaryKey
import
androidx.room.*
import
chat.rocket.android.R
import
chat.rocket.android.util.extension.orFalse
import
chat.rocket.android.util.extensions.isNotNullNorEmpty
...
...
@@ -114,8 +110,7 @@ fun Attachment.asEntity(msgId: String, context: Context): List<BaseMessageEntity
val
list
=
mutableListOf
<
BaseMessageEntity
>()
val
text
=
mapAttachmentText
(
text
,
attachments
?.
firstOrNull
(),
context
)
val
entity
=
AttachmentEntity
(
list
.
add
(
AttachmentEntity
(
_id
=
attachmentId
,
messageId
=
msgId
,
title
=
title
,
...
...
@@ -144,16 +139,14 @@ fun Attachment.asEntity(msgId: String, context: Context): List<BaseMessageEntity
buttonAlignment
=
buttonAlignment
,
hasActions
=
actions
?.
isNotEmpty
()
==
true
,
hasFields
=
fields
?.
isNotEmpty
()
==
true
)
list
.
add
(
entity
)
))
fields
?.
forEach
{
field
->
val
entity
=
AttachmentFieldEntity
(
list
.
add
(
AttachmentFieldEntity
(
attachmentId
=
attachmentId
,
title
=
field
.
title
,
value
=
field
.
value
)
list
.
add
(
entity
)
))
}
actions
?.
forEach
{
action
->
...
...
@@ -175,18 +168,16 @@ fun Attachment.asEntity(msgId: String, context: Context): List<BaseMessageEntity
return
list
}
fun
mapAttachmentText
(
text
:
String
?,
attachment
:
Attachment
?,
context
:
Context
):
String
?
{
return
if
(
attachment
!=
null
)
{
fun
mapAttachmentText
(
text
:
String
?,
attachment
:
Attachment
?,
context
:
Context
):
String
?
=
attachment
?.
run
{
with
(
context
)
{
when
{
attachment
.
imageUrl
.
isNotNullNorEmpty
()
->
context
.
getString
(
R
.
string
.
msg_preview_photo
)
attachment
.
videoUrl
.
isNotNullNorEmpty
()
->
context
.
getString
(
R
.
string
.
msg_preview_video
)
a
ttachment
.
audioUrl
.
isNotNullNorEmpty
()
->
context
.
getString
(
R
.
string
.
msg_preview_audio
)
attachment
.
titleLink
.
isNotNullNorEmpty
()
&&
attachment
.
type
?.
contentEquals
(
"file"
)
==
true
->
context
.
getString
(
R
.
string
.
msg_preview_file
)
imageUrl
.
isNotNullNorEmpty
()
->
getString
(
R
.
string
.
msg_preview_photo
)
videoUrl
.
isNotNullNorEmpty
()
->
getString
(
R
.
string
.
msg_preview_video
)
a
udioUrl
.
isNotNullNorEmpty
()
->
getString
(
R
.
string
.
msg_preview_audio
)
titleLink
.
isNotNullNorEmpty
()
&&
type
?.
contentEquals
(
"file"
)
==
true
->
getString
(
R
.
string
.
msg_preview_file
)
else
->
text
}
}
else
{
text
}
}
?:
text
}
app/src/main/java/chat/rocket/android/favoritemessages/ui/FavoriteMessagesFragment.kt
View file @
ca4056e3
...
...
@@ -48,12 +48,9 @@ class FavoriteMessagesFragment : Fragment(), FavoriteMessagesView {
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
chatRoomId
=
bundle
.
getString
(
INTENT_CHAT_ROOM_ID
)
}
else
{
requireNotNull
(
bundle
)
{
"no arguments supplied when the fragment was instantiated"
}
}
arguments
?.
run
{
chatRoomId
=
getString
(
INTENT_CHAT_ROOM_ID
,
""
)
}
?:
requireNotNull
(
arguments
)
{
"no arguments supplied when the fragment was instantiated"
}
}
override
fun
onCreateView
(
...
...
app/src/main/java/chat/rocket/android/files/ui/FilesFragment.kt
View file @
ca4056e3
...
...
@@ -55,12 +55,9 @@ class FilesFragment : Fragment(), FilesView {
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
chatRoomId
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_ID
)
}
else
{
requireNotNull
(
bundle
)
{
"no arguments supplied when the fragment was instantiated"
}
}
arguments
?.
run
{
chatRoomId
=
getString
(
BUNDLE_CHAT_ROOM_ID
,
""
)
}
?:
requireNotNull
(
arguments
)
{
"no arguments supplied when the fragment was instantiated"
}
}
override
fun
onCreateView
(
...
...
app/src/main/java/chat/rocket/android/helper/ImageHelper.kt
View file @
ca4056e3
...
...
@@ -51,10 +51,10 @@ object ImageHelper {
ViewGroup
.
LayoutParams
.
MATCH_PARENT
,
ViewGroup
.
LayoutParams
.
WRAP_CONTENT
)
val
toolbar
=
Toolbar
(
context
).
also
{
it
.
inflateMenu
(
R
.
menu
.
image_actions
)
it
.
setOnMenuItemClickListener
{
return
@setOnMenuItemClickListener
when
(
it
.
itemId
)
{
val
toolbar
=
Toolbar
(
context
).
also
{
toolbar
->
toolbar
.
inflateMenu
(
R
.
menu
.
image_actions
)
toolbar
.
setOnMenuItemClickListener
{
view
->
return
@setOnMenuItemClickListener
when
(
view
.
itemId
)
{
R
.
id
.
action_save_image
->
saveImage
(
context
)
else
->
true
}
...
...
@@ -62,14 +62,16 @@ object ImageHelper {
val
titleSize
=
context
.
resources
.
getDimensionPixelSize
(
R
.
dimen
.
viewer_toolbar_title
)
val
titleTextView
=
TextView
(
context
).
also
{
it
.
text
=
imageName
it
.
setTextColor
(
Color
.
WHITE
)
it
.
setTextSize
(
TypedValue
.
COMPLEX_UNIT_PX
,
titleSize
.
toFloat
())
it
.
ellipsize
=
TextUtils
.
TruncateAt
.
END
it
.
setSingleLine
()
it
.
typeface
=
Typeface
.
DEFAULT_BOLD
it
.
setPadding
(
pad
)
val
titleTextView
=
TextView
(
context
).
also
{
tv
->
with
(
tv
)
{
text
=
imageName
setTextColor
(
Color
.
WHITE
)
setTextSize
(
TypedValue
.
COMPLEX_UNIT_PX
,
titleSize
.
toFloat
())
ellipsize
=
TextUtils
.
TruncateAt
.
END
setSingleLine
()
typeface
=
Typeface
.
DEFAULT_BOLD
setPadding
(
pad
)
}
}
val
backArrowView
=
ImageView
(
context
).
also
{
...
...
@@ -83,8 +85,8 @@ object ImageHelper {
AppBarLayout
.
LayoutParams
.
WRAP_CONTENT
)
it
.
addView
(
backArrowView
,
layoutParams
)
it
.
addView
(
titleTextView
,
layoutParams
)
toolbar
.
addView
(
backArrowView
,
layoutParams
)
toolbar
.
addView
(
titleTextView
,
layoutParams
)
}
val
appBarLayout
=
AppBarLayout
(
context
).
also
{
...
...
app/src/main/java/chat/rocket/android/members/adapter/MembersAdapter.kt
View file @
ca4056e3
...
...
@@ -10,8 +10,9 @@ import chat.rocket.android.util.extensions.inflate
import
kotlinx.android.synthetic.main.avatar.view.*
import
kotlinx.android.synthetic.main.item_member.view.*
class
MembersAdapter
(
private
val
listener
:
(
MemberUiModel
)
->
Unit
)
:
RecyclerView
.
Adapter
<
MembersAdapter
.
ViewHolder
>()
{
class
MembersAdapter
(
private
val
listener
:
(
MemberUiModel
)
->
Unit
)
:
RecyclerView
.
Adapter
<
MembersAdapter
.
ViewHolder
>()
{
private
var
dataSet
:
List
<
MemberUiModel
>
=
ArrayList
()
override
fun
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
):
MembersAdapter
.
ViewHolder
=
...
...
@@ -43,7 +44,8 @@ class MembersAdapter(private val listener: (MemberUiModel) -> Unit) :
fun
bind
(
memberUiModel
:
MemberUiModel
,
listener
:
(
MemberUiModel
)
->
Unit
)
=
with
(
itemView
)
{
image_avatar
.
setImageURI
(
memberUiModel
.
avatarUri
)
text_member
.
content
=
memberUiModel
.
displayName
text_member
.
setCompoundDrawablesRelativeWithIntrinsicBounds
(
DrawableHelper
.
getUserStatusDrawable
(
memberUiModel
.
status
,
context
),
null
,
null
,
null
)
text_member
.
setCompoundDrawablesRelativeWithIntrinsicBounds
(
DrawableHelper
.
getUserStatusDrawable
(
memberUiModel
.
status
,
context
),
null
,
null
,
null
)
setOnClickListener
{
listener
(
memberUiModel
)
}
}
}
...
...
app/src/main/java/chat/rocket/android/members/ui/MembersFragment.kt
View file @
ca4056e3
...
...
@@ -52,12 +52,9 @@ class MembersFragment : Fragment(), MembersView {
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
chatRoomId
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_ID
)
}
else
{
requireNotNull
(
bundle
)
{
"no arguments supplied when the fragment was instantiated"
}
}
arguments
?.
run
{
chatRoomId
=
getString
(
BUNDLE_CHAT_ROOM_ID
,
""
)
}
?:
requireNotNull
(
arguments
)
{
"no arguments supplied when the fragment was instantiated"
}
}
override
fun
onCreateView
(
...
...
@@ -80,7 +77,7 @@ class MembersFragment : Fragment(), MembersView {
setupToolbar
(
total
)
if
(
adapter
.
itemCount
==
0
)
{
adapter
.
prependData
(
dataSet
)
if
(
dataSet
.
size
>=
59
)
{
// TODO Check why the API ret
o
rns the specified count -1
if
(
dataSet
.
size
>=
59
)
{
// TODO Check why the API ret
u
rns the specified count -1
recycler_view
.
addOnScrollListener
(
object
:
EndlessRecyclerViewScrollListener
(
linearLayoutManager
)
{
override
fun
onLoadMore
(
...
...
app/src/main/java/chat/rocket/android/mentions/ui/MentionsFragment.kt
View file @
ca4056e3
...
...
@@ -48,12 +48,9 @@ class MentionsFragment : Fragment(), MentionsView {
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
chatRoomId
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_ID
)
}
else
{
requireNotNull
(
bundle
)
{
"no arguments supplied when the fragment was instantiated"
}
}
arguments
?.
run
{
chatRoomId
=
getString
(
BUNDLE_CHAT_ROOM_ID
,
""
)
}
?:
requireNotNull
(
arguments
)
{
"no arguments supplied when the fragment was instantiated"
}
}
override
fun
onCreateView
(
...
...
app/src/main/java/chat/rocket/android/pinnedmessages/ui/PinnedMessagesFragment.kt
View file @
ca4056e3
...
...
@@ -48,12 +48,9 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
chatRoomId
=
bundle
.
getString
(
BUNDLE_CHAT_ROOM_ID
)
}
else
{
requireNotNull
(
bundle
)
{
"no arguments supplied when the fragment was instantiated"
}
}
arguments
?.
run
{
chatRoomId
=
getString
(
BUNDLE_CHAT_ROOM_ID
,
""
)
}
?:
requireNotNull
(
arguments
)
{
"no arguments supplied when the fragment was instantiated"
}
}
override
fun
onCreateView
(
...
...
app/src/main/java/chat/rocket/android/profile/ui/ProfileFragment.kt
View file @
ca4056e3
...
...
@@ -96,9 +96,13 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
override
fun
onActivityResult
(
requestCode
:
Int
,
resultCode
:
Int
,
resultData
:
Intent
?)
{
if
(
resultData
!=
null
&&
resultCode
==
Activity
.
RESULT_OK
)
{
if
(
requestCode
==
REQUEST_CODE_FOR_PERFORM_SAF
)
{
presenter
.
updateAvatar
(
resultData
.
data
)
resultData
.
data
?.
let
{
presenter
.
updateAvatar
(
it
)
}
}
else
if
(
requestCode
==
REQUEST_CODE_FOR_PERFORM_CAMERA
)
{
presenter
.
preparePhotoAndUpdateAvatar
(
resultData
.
extras
[
"data"
]
as
Bitmap
)
resultData
.
extras
?.
get
(
"data"
)
?.
let
{
presenter
.
preparePhotoAndUpdateAvatar
(
it
as
Bitmap
)
}
}
}
}
...
...
app/src/main/java/chat/rocket/android/push/PushManager.kt
View file @
ca4056e3
...
...
@@ -186,7 +186,7 @@ class PushManager @Inject constructor(
.
setGroupSummary
(
false
)
if
(
style
==
null
||
"inbox"
==
style
)
{
val
pushMessageList
=
groupedPushes
.
hostToPushMessageList
.
get
(
host
)
val
pushMessageList
=
groupedPushes
.
hostToPushMessageList
[
host
]
if
(
pushMessageList
!=
null
)
{
val
userMessages
=
pushMessageList
.
filter
{
...
...
@@ -230,7 +230,10 @@ class PushManager @Inject constructor(
}
@RequiresApi
(
Build
.
VERSION_CODES
.
O
)
private
fun
createBaseNotificationBuilder
(
pushMessage
:
PushMessage
,
grouped
:
Boolean
=
false
):
NotificationCompat
.
Builder
{
private
fun
createBaseNotificationBuilder
(
pushMessage
:
PushMessage
,
grouped
:
Boolean
=
false
):
NotificationCompat
.
Builder
{
return
with
(
pushMessage
)
{
val
id
=
notificationId
.
toInt
()
val
host
=
info
.
host
...
...
@@ -295,7 +298,12 @@ class PushManager @Inject constructor(
return
PendingIntent
.
getBroadcast
(
context
,
pushMessage
.
notificationId
.
toInt
(),
deleteIntent
,
PendingIntent
.
FLAG_UPDATE_CURRENT
)
}
private
fun
getContentIntent
(
context
:
Context
,
notificationId
:
Int
,
pushMessage
:
PushMessage
,
grouped
:
Boolean
=
false
):
PendingIntent
{
private
fun
getContentIntent
(
context
:
Context
,
notificationId
:
Int
,
pushMessage
:
PushMessage
,
grouped
:
Boolean
=
false
):
PendingIntent
{
val
roomId
=
if
(!
grouped
)
pushMessage
.
info
.
roomId
else
null
val
notificationIntent
=
context
.
changeServerIntent
(
pushMessage
.
info
.
host
,
chatRoomId
=
roomId
)
return
PendingIntent
.
getActivity
(
context
,
random
.
nextInt
(),
notificationIntent
,
PendingIntent
.
FLAG_UPDATE_CURRENT
)
...
...
@@ -303,7 +311,11 @@ class PushManager @Inject constructor(
// CharSequence extensions
private
fun
CharSequence
.
fromHtml
():
Spanned
{
return
Html
.
fromHtml
(
this
as
String
)
return
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
N
)
{
Html
.
fromHtml
(
this
as
String
,
Html
.
FROM_HTML_MODE_LEGACY
)
}
else
{
Html
.
fromHtml
(
this
as
String
)
}
}
// NotificationCompat.Builder extensions
...
...
@@ -383,12 +395,12 @@ data class PushMessage(
)
:
Parcelable
{
constructor
(
parcel
:
Parcel
)
:
this
(
parcel
.
readString
()
?:
""
,
parcel
.
readString
()
?:
""
,
parcel
.
readParcelable
(
PushMessage
::
class
.
java
.
classLoader
)
?:
PushInfo
.
EMPTY
,
parcel
.
readString
(),
parcel
.
readString
(),
parcel
.
readParcelable
(
PushMessage
::
class
.
java
.
classLoader
),
parcel
.
readString
(),
parcel
.
readString
(),
parcel
.
readString
(),
parcel
.
readString
()
?:
""
,
parcel
.
readString
(),
parcel
.
readString
())
...
...
@@ -433,9 +445,9 @@ data class PushInfo @KotshiConstructor constructor(
}
constructor
(
parcel
:
Parcel
)
:
this
(
parcel
.
readString
(),
parcel
.
readString
(),
roomTypeOf
(
parcel
.
readString
()),
parcel
.
readString
()
!!
,
parcel
.
readString
()
!!
,
roomTypeOf
(
parcel
.
readString
()
!!
),
parcel
.
readString
(),
parcel
.
readParcelable
(
PushInfo
::
class
.
java
.
classLoader
))
...
...
@@ -481,7 +493,7 @@ data class PushSender @KotshiConstructor constructor(
val
name
:
String
?
)
:
Parcelable
{
constructor
(
parcel
:
Parcel
)
:
this
(
parcel
.
readString
(),
parcel
.
readString
()
!!
,
parcel
.
readString
(),
parcel
.
readString
())
...
...
app/src/main/java/chat/rocket/android/server/infraestructure/ConnectionManager.kt
View file @
ca4056e3
...
...
@@ -97,8 +97,8 @@ class ConnectionManager(
resubscribeRooms
()
temporaryStatus
?.
let
{
s
tatus
->
client
.
setTemporaryStatus
(
s
tatus
)
temporaryStatus
?.
let
{
tempS
tatus
->
client
.
setTemporaryStatus
(
tempS
tatus
)
}
}
is
State
.
Waiting
->
{
...
...
@@ -231,7 +231,7 @@ class ConnectionManager(
}
private
fun
resubscribeRooms
()
{
roomMessagesChannels
.
toList
().
map
{
(
roomId
,
channel
)
->
roomMessagesChannels
.
toList
().
map
{
(
roomId
,
_
)
->
client
.
subscribeRoomMessages
(
roomId
)
{
_
,
id
->
Timber
.
d
(
"Subscribed to $roomId: $id"
)
subscriptionIdMap
[
roomId
]
=
id
...
...
app/src/main/java/chat/rocket/android/server/infraestructure/DatabaseMessageMapper.kt
View file @
ca4056e3
...
...
@@ -153,7 +153,7 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
null
}
val
attachment
=
Attachment
(
list
.
add
(
Attachment
(
title
=
title
,
type
=
type
,
description
=
description
,
...
...
@@ -179,10 +179,10 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
authorLink
=
authorLink
,
fields
=
fields
,
fallback
=
fallback
,
buttonAlignment
=
if
(
actions
!=
null
&&
actions
.
isNotEmpty
())
buttonAlignment
?:
"vertical"
else
null
,
buttonAlignment
=
if
(
actions
!=
null
&&
actions
.
isNotEmpty
())
buttonAlignment
?:
"vertical"
else
null
,
actions
=
actions
)
list
.
add
(
attachment
)
))
}
}
return
list
...
...
app/src/main/java/chat/rocket/android/server/infraestructure/DatabaseMessagesRepository.kt
View file @
ca4056e3
...
...
@@ -46,8 +46,8 @@ class DatabaseMessagesRepository(
dbManager
.
processMessagesBatch
(
listOf
(
message
)).
join
()
}
override
suspend
fun
saveAll
(
m
essages
:
List
<
Message
>)
{
dbManager
.
processMessagesBatch
(
m
essages
).
join
()
override
suspend
fun
saveAll
(
newM
essages
:
List
<
Message
>)
{
dbManager
.
processMessagesBatch
(
newM
essages
).
join
()
}
override
suspend
fun
removeById
(
id
:
String
)
{
...
...
@@ -78,7 +78,7 @@ class DatabaseMessagesRepository(
override
suspend
fun
getLastSyncDate
(
roomId
:
String
):
Long
?
=
withContext
(
CommonPool
)
{
retryDB
(
"getLastSync($roomId)"
)
{
dbManager
.
messageDao
().
getLastSync
(
roomId
)
?.
let
{
it
.
timestamp
}
dbManager
.
messageDao
().
getLastSync
(
roomId
)
?.
timestamp
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/infraestructure/SharedPreferencesAccountsRepository.kt
View file @
ca4056e3
...
...
@@ -14,12 +14,12 @@ class SharedPreferencesAccountsRepository(
private
val
moshi
:
Moshi
)
:
AccountsRepository
{
override
fun
save
(
newA
ccount
:
Account
)
{
override
fun
save
(
a
ccount
:
Account
)
{
val
accounts
=
load
()
val
newList
=
accounts
.
filter
{
account
->
newA
ccount
.
serverUrl
!=
account
.
serverUrl
}
val
newList
=
accounts
.
filter
{
account
->
a
ccount
.
serverUrl
!=
account
.
serverUrl
}
.
toMutableList
()
newList
.
add
(
0
,
newA
ccount
)
newList
.
add
(
0
,
a
ccount
)
save
(
newList
)
}
...
...
@@ -28,7 +28,7 @@ class SharedPreferencesAccountsRepository(
val
type
=
Types
.
newParameterizedType
(
List
::
class
.
java
,
Account
::
class
.
java
)
val
adapter
=
moshi
.
adapter
<
List
<
Account
>>(
type
)
return
adapter
.
fromJson
(
json
)
?:
emptyList
()
return
if
(
json
==
null
)
emptyList
()
else
adapter
.
fromJson
(
json
)
?:
emptyList
()
}
override
fun
remove
(
serverUrl
:
String
)
{
...
...
app/src/main/java/chat/rocket/android/server/infraestructure/SharedPrefsBasicAuthRepository.kt
View file @
ca4056e3
...
...
@@ -15,8 +15,7 @@ class SharedPrefsBasicAuthRepository(
)
:
BasicAuthRepository
{
override
fun
save
(
basicAuth
:
BasicAuth
)
{
val
newList
=
load
().
filter
{
basicAuth
->
basicAuth
.
host
!=
basicAuth
.
host
}
.
toMutableList
()
val
newList
=
load
().
filter
{
item
->
item
.
host
!=
item
.
host
}.
toMutableList
()
newList
.
add
(
0
,
basicAuth
)
save
(
newList
)
}
...
...
@@ -26,7 +25,7 @@ class SharedPrefsBasicAuthRepository(
val
type
=
Types
.
newParameterizedType
(
List
::
class
.
java
,
BasicAuth
::
class
.
java
)
val
adapter
=
moshi
.
adapter
<
List
<
BasicAuth
>>(
type
)
return
adapter
.
fromJson
(
json
)
?:
emptyList
()
return
if
(
json
==
null
)
emptyList
()
else
adapter
.
fromJson
(
json
)
?:
emptyList
()
}
private
fun
save
(
basicAuths
:
List
<
BasicAuth
>)
{
...
...
app/src/main/java/chat/rocket/android/server/presentation/ChangeServerPresenter.kt
View file @
ca4056e3
...
...
@@ -51,6 +51,7 @@ class ChangeServerPresenter @Inject constructor(
val
settings
=
settingsRepository
.
get
(
serverUrl
)
if
(
settings
==
null
)
{
// TODO - reload settings...
// settingsRepository returns non nullable settings
}
// Call disconnect on the old url if any...
...
...
app/src/main/java/chat/rocket/android/userdetails/ui/UserDetailsFragment.kt
View file @
ca4056e3
...
...
@@ -52,12 +52,9 @@ class UserDetailsFragment : Fragment(), UserDetailsView {
super
.
onCreate
(
savedInstanceState
)
AndroidSupportInjection
.
inject
(
this
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
userId
=
bundle
.
getString
(
BUNDLE_USER_ID
)
}
else
{
requireNotNull
(
bundle
)
{
"no arguments supplied when the fragment was instantiated"
}
}
arguments
?.
run
{
userId
=
getString
(
BUNDLE_USER_ID
,
""
)
}
?:
requireNotNull
(
arguments
)
{
"no arguments supplied when the fragment was instantiated"
}
}
override
fun
onCreateView
(
...
...
app/src/main/java/chat/rocket/android/util/HttpLoggingInterceptor.kt
View file @
ca4056e3
...
...
@@ -193,7 +193,7 @@ class HttpLoggingInterceptor constructor(private val logger: Logger) : Intercept
val
responseBody
=
response
.
body
()
val
contentLength
=
responseBody
!!
.
contentLength
()
val
bodySize
=
if
(
contentLength
!=
-
1L
)
contentLength
.
toString
()
+
"
-byte"
else
"unknown-length"
val
bodySize
=
if
(
contentLength
!=
-
1L
)
"$contentLength
-byte"
else
"unknown-length"
val
responseStr
=
if
(
response
.
message
().
isEmpty
())
""
else
" ${response.message()}"
logger
.
log
(
"<-- ${response.code()}$responseStr ${response.request().url()}"
+
" ("
+
tookMs
+
"ms"
+
(
if
(!
logHeaders
)
", $bodySize body"
else
""
)
+
')'
.
toString
())
...
...
app/src/main/java/chat/rocket/android/util/extensions/String.kt
View file @
ca4056e3
...
...
@@ -69,11 +69,8 @@ fun String.userId(userId: String?): String? {
return
userId
?.
let
{
this
.
replace
(
it
,
""
)
}
}
fun
String
.
lowercaseUrl
():
String
?
{
val
httpUrl
=
HttpUrl
.
parse
(
this
)
val
newScheme
=
httpUrl
?.
scheme
()
?.
toLowerCase
()
return
httpUrl
?.
newBuilder
()
?.
scheme
(
newScheme
)
?.
build
()
?.
toString
()
fun
String
.
lowercaseUrl
():
String
?
=
HttpUrl
.
parse
(
this
)
?.
run
{
newBuilder
().
scheme
(
scheme
().
toLowerCase
()).
build
().
toString
()
}
fun
String
?.
isNotNullNorEmpty
():
Boolean
=
this
!=
null
&&
this
.
isNotEmpty
()
...
...
app/src/main/java/chat/rocket/android/webview/adminpanel/ui/AdminPanelWebViewFragment.kt
View file @
ca4056e3
...
...
@@ -27,13 +27,11 @@ class AdminPanelWebViewFragment : DaggerFragment() {
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
val
bundle
=
arguments
if
(
bundle
!=
null
)
{
webPageUrl
=
bundle
.
getString
(
BUNDLE_WEB_PAGE_URL
)
userToken
=
bundle
.
getString
(
BUNDLE_USER_TOKEN
)
}
else
{
requireNotNull
(
bundle
)
{
"no arguments supplied when the fragment was instantiated"
}
}
arguments
?.
run
{
webPageUrl
=
getString
(
BUNDLE_WEB_PAGE_URL
,
""
)
userToken
=
getString
(
BUNDLE_USER_TOKEN
,
""
)
}
?:
requireNotNull
(
arguments
)
{
"no arguments supplied when the fragment was instantiated"
}
}
override
fun
onCreateView
(
...
...
@@ -65,7 +63,7 @@ class AdminPanelWebViewFragment : DaggerFragment() {
web_view
.
webViewClient
=
object
:
WebViewClient
()
{
override
fun
onPageFinished
(
view
:
WebView
,
url
:
String
)
{
super
.
onPageFinished
(
view
,
url
)
ui
{
_
->
ui
{
view_loading
.
hide
()
web_view
.
evaluateJavascript
(
"Meteor.loginWithToken('$userToken', function() { })"
)
{}
}
...
...
app/src/main/java/chat/rocket/android/widget/DividerItemDecoration.kt
View file @
ca4056e3
...
...
@@ -14,7 +14,7 @@ import androidx.recyclerview.widget.RecyclerView
* @see RecyclerView.ItemDecoration
*/
class
DividerItemDecoration
()
:
RecyclerView
.
ItemDecoration
()
{
private
lateinit
var
divider
:
Drawable
private
var
divider
:
Drawable
?
=
null
private
var
boundStart
=
0
private
var
boundEnd
=
0
...
...
@@ -59,10 +59,10 @@ class DividerItemDecoration() : RecyclerView.ItemDecoration() {
val
params
=
child
.
layoutParams
as
RecyclerView
.
LayoutParams
val
top
=
child
.
bottom
+
params
.
bottomMargin
val
bottom
=
top
+
divider
.
intrinsicHeight
val
bottom
=
top
+
(
divider
?.
intrinsicHeight
?:
0
)
divider
.
setBounds
(
left
,
top
,
right
,
bottom
)
divider
.
draw
(
c
)
divider
?
.
setBounds
(
left
,
top
,
right
,
bottom
)
divider
?
.
draw
(
c
)
}
}
...
...
util/src/main/java/chat/rocket/android/util/extension/Widget.kt
View file @
ca4056e3
package
chat.rocket.android.util.extension
import
android.content.Context
import
android.os.Build
import
android.widget.TextView
import
androidx.appcompat.widget.SearchView
fun
SearchView
.
onQueryTextListener
(
queryListener
:
(
String
)
->
Unit
)
{
...
...
@@ -15,3 +18,11 @@ fun SearchView.onQueryTextListener(queryListener: (String) -> Unit) {
}
})
}
fun
TextView
.
setTextViewAppearance
(
context
:
Context
,
style
:
Int
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
M
)
{
setTextAppearance
(
style
)
}
else
{
setTextAppearance
(
context
,
style
)
}
}
\ 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