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
1f1391d7
Unverified
Commit
1f1391d7
authored
Mar 12, 2019
by
Filipe de Lima Brito
Committed by
GitHub
Mar 12, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2125 from karthyks/refactor/app
[REFACTOR] refactor app module
parents
1130fd04
5320a635
Changes
54
Show whitespace changes
Inline
Side-by-side
Showing
54 changed files
with
631 additions
and
753 deletions
+631
-753
AppLifecycleObserver.kt
...main/java/chat/rocket/android/app/AppLifecycleObserver.kt
+0
-5
DateTimeHelper.kt
app/src/main/java/chat/rocket/android/app/DateTimeHelper.kt
+37
-32
SharedPreferencesMultiServerTokenRepository.kt
...estructure/SharedPreferencesMultiServerTokenRepository.kt
+4
-7
LoginFragment.kt
...t/rocket/android/authentication/login/ui/LoginFragment.kt
+7
-10
LoginOptionsFragment.kt
...id/authentication/loginoptions/ui/LoginOptionsFragment.kt
+58
-61
RegisterUsernameFragment.kt
...ntication/registerusername/ui/RegisterUsernameFragment.kt
+8
-13
SignupFragment.kt
...rocket/android/authentication/signup/ui/SignupFragment.kt
+1
-1
TwoFAFragment.kt
...cket/android/authentication/twofactor/ui/TwoFAFragment.kt
+8
-13
OptionViewHolder.kt
...at/rocket/android/chatdetails/adapter/OptionViewHolder.kt
+1
-1
ChatDetailsAdapter.kt
.../chat/rocket/android/chatdetails/ui/ChatDetailsAdapter.kt
+8
-2
ChatDetailsFragment.kt
...chat/rocket/android/chatdetails/ui/ChatDetailsFragment.kt
+13
-17
ChatDetailsViewModelFactory.kt
...roid/chatdetails/viewmodel/ChatDetailsViewModelFactory.kt
+4
-3
ActionsListAdapter.kt
...hat/rocket/android/chatroom/adapter/ActionsListAdapter.kt
+5
-4
ChatRoomAdapter.kt
...a/chat/rocket/android/chatroom/adapter/ChatRoomAdapter.kt
+8
-12
RoomSuggestionsAdapter.kt
...rocket/android/chatroom/adapter/RoomSuggestionsAdapter.kt
+2
-2
UrlPreviewViewHolder.kt
...t/rocket/android/chatroom/adapter/UrlPreviewViewHolder.kt
+6
-7
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+3
-3
ChatRoomActivity.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt
+38
-38
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+35
-41
UiModelMapper.kt
...ava/chat/rocket/android/chatroom/uimodel/UiModelMapper.kt
+33
-41
RoomUiModelMapper.kt
...hat/rocket/android/chatrooms/adapter/RoomUiModelMapper.kt
+49
-60
RoomViewHolder.kt
...a/chat/rocket/android/chatrooms/adapter/RoomViewHolder.kt
+22
-25
RoomsAdapter.kt
...ava/chat/rocket/android/chatrooms/adapter/RoomsAdapter.kt
+18
-22
ChatRoomsFragment.kt
...ava/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
+16
-20
CreateChannelFragment.kt
.../rocket/android/createchannel/ui/CreateChannelFragment.kt
+4
-6
DatabaseManager.kt
app/src/main/java/chat/rocket/android/db/DatabaseManager.kt
+75
-99
Attachments.kt
...src/main/java/chat/rocket/android/db/model/Attachments.kt
+15
-21
FavoriteMessagesPresenter.kt
...avoritemessages/presentation/FavoriteMessagesPresenter.kt
+1
-2
FavoriteMessagesFragment.kt
...t/android/favoritemessages/ui/FavoriteMessagesFragment.kt
+6
-11
FilesFragment.kt
...c/main/java/chat/rocket/android/files/ui/FilesFragment.kt
+6
-11
AndroidPermissionsHelper.kt
...va/chat/rocket/android/helper/AndroidPermissionsHelper.kt
+1
-2
ImageHelper.kt
app/src/main/java/chat/rocket/android/helper/ImageHelper.kt
+27
-21
MembersAdapter.kt
...ava/chat/rocket/android/members/adapter/MembersAdapter.kt
+5
-3
MembersFragment.kt
...in/java/chat/rocket/android/members/ui/MembersFragment.kt
+7
-12
MentionsFragment.kt
.../java/chat/rocket/android/mentions/ui/MentionsFragment.kt
+6
-11
PinnedMessagesFragment.kt
...ocket/android/pinnedmessages/ui/PinnedMessagesFragment.kt
+6
-11
ProfileFragment.kt
...in/java/chat/rocket/android/profile/ui/ProfileFragment.kt
+8
-7
PushManager.kt
app/src/main/java/chat/rocket/android/push/PushManager.kt
+16
-11
ConnectionManager.kt
...ocket/android/server/infraestructure/ConnectionManager.kt
+4
-6
DatabaseMessageMapper.kt
...t/android/server/infraestructure/DatabaseMessageMapper.kt
+4
-5
DatabaseMessagesRepository.kt
...roid/server/infraestructure/DatabaseMessagesRepository.kt
+3
-3
SharedPreferencesAccountsRepository.kt
...er/infraestructure/SharedPreferencesAccountsRepository.kt
+4
-13
SharedPrefsBasicAuthRepository.kt
.../server/infraestructure/SharedPrefsBasicAuthRepository.kt
+2
-3
PasswordFragment.kt
...t/rocket/android/settings/password/ui/PasswordFragment.kt
+10
-12
SettingsFragment.kt
.../java/chat/rocket/android/settings/ui/SettingsFragment.kt
+1
-2
UserDetailsPresenter.kt
.../android/userdetails/presentation/UserDetailsPresenter.kt
+1
-1
UserDetailsFragment.kt
...chat/rocket/android/userdetails/ui/UserDetailsFragment.kt
+6
-11
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
Ui.kt
app/src/main/java/chat/rocket/android/util/extensions/Ui.kt
+4
-6
Uri.kt
app/src/main/java/chat/rocket/android/util/extensions/Uri.kt
+1
-1
AdminPanelWebViewFragment.kt
...ndroid/webview/adminpanel/ui/AdminPanelWebViewFragment.kt
+5
-8
DividerItemDecoration.kt
.../java/chat/rocket/android/widget/DividerItemDecoration.kt
+5
-8
Widget.kt
...rc/main/java/chat/rocket/android/util/extension/Widget.kt
+11
-0
No files found.
app/src/main/java/chat/rocket/android/app/AppLifecycleObserver.kt
View file @
1f1391d7
...
...
@@ -3,15 +3,10 @@ package chat.rocket.android.app
import
androidx.lifecycle.Lifecycle
import
androidx.lifecycle.LifecycleObserver
import
androidx.lifecycle.OnLifecycleEvent
import
chat.rocket.android.server.domain.GetAccountInteractor
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.UserStatus
import
chat.rocket.core.internal.realtime.setTemporaryStatus
import
kotlinx.coroutines.experimental.launch
import
timber.log.Timber
import
javax.inject.Inject
class
AppLifecycleObserver
@Inject
constructor
(
...
...
app/src/main/java/chat/rocket/android/app/DateTimeHelper.kt
View file @
1f1391d7
import
android.content.Context
import
chat.rocket.android.R
import
org.threeten.bp.*
import
org.threeten.bp.Instant
import
org.threeten.bp.LocalDate
import
org.threeten.bp.LocalDateTime
import
org.threeten.bp.LocalTime
import
org.threeten.bp.Period
import
org.threeten.bp.ZoneId
import
org.threeten.bp.format.DateTimeFormatter
import
org.threeten.bp.format.FormatStyle
import
org.threeten.bp.format.TextStyle
...
...
@@ -53,39 +58,39 @@ object DateTimeHelper {
}
}
/**
/**
* Returns a time from a [LocalDateTime].
*
* @param localDateTime The [LocalDateTime].
* @return The time from a [LocalDateTime].
*/
fun
getTime
(
localDateTime
:
LocalDateTime
):
String
{
fun
getTime
(
localDateTime
:
LocalDateTime
):
String
{
val
formatter
=
DateTimeFormatter
.
ofLocalizedTime
(
FormatStyle
.
SHORT
)
return
localDateTime
.
toLocalTime
().
format
(
formatter
).
toString
()
}
}
/**
/**
* Returns a date time from a [LocalDateTime].
*
* @param localDateTime The [LocalDateTime].
* @return The time from a [LocalDateTime].
*/
fun
getDateTime
(
localDateTime
:
LocalDateTime
):
String
{
fun
getDateTime
(
localDateTime
:
LocalDateTime
):
String
{
return
formatLocalDateTime
(
localDateTime
)
}
}
private
fun
formatLocalDateTime
(
localDateTime
:
LocalDateTime
):
String
{
private
fun
formatLocalDateTime
(
localDateTime
:
LocalDateTime
):
String
{
val
formatter
=
DateTimeFormatter
.
ofLocalizedDateTime
(
FormatStyle
.
SHORT
)
return
localDateTime
.
format
(
formatter
).
toString
()
}
}
private
fun
formatLocalDate
(
localDate
:
LocalDate
):
String
{
private
fun
formatLocalDate
(
localDate
:
LocalDate
):
String
{
val
formatter
=
DateTimeFormatter
.
ofLocalizedDate
(
FormatStyle
.
MEDIUM
)
return
localDate
.
format
(
formatter
).
toString
()
}
}
private
fun
formatLocalTime
(
localTime
:
LocalTime
):
String
{
private
fun
formatLocalTime
(
localTime
:
LocalTime
):
String
{
val
formatter
=
DateTimeFormatter
.
ofLocalizedTime
(
FormatStyle
.
SHORT
)
return
localTime
.
format
(
formatter
).
toString
()
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/infraestructure/SharedPreferencesMultiServerTokenRepository.kt
View file @
1f1391d7
...
...
@@ -8,7 +8,8 @@ import chat.rocket.android.server.domain.MultiServerTokenRepository
import
com.squareup.moshi.Moshi
@PerActivity
class
SharedPreferencesMultiServerTokenRepository
(
private
val
repository
:
LocalRepository
,
class
SharedPreferencesMultiServerTokenRepository
(
private
val
repository
:
LocalRepository
,
private
val
moshi
:
Moshi
)
:
MultiServerTokenRepository
{
...
...
@@ -16,11 +17,7 @@ class SharedPreferencesMultiServerTokenRepository(private val repository: LocalR
val
token
=
repository
.
get
(
"$TOKEN_KEY$server"
)
val
adapter
=
moshi
.
adapter
<
TokenModel
>(
TokenModel
::
class
.
java
)
token
?.
let
{
return
adapter
.
fromJson
(
token
)
}
return
null
return
token
?.
let
{
adapter
.
fromJson
(
it
)
}
}
override
fun
save
(
server
:
String
,
token
:
TokenModel
)
{
...
...
app/src/main/java/chat/rocket/android/authentication/login/ui/LoginFragment.kt
View file @
1f1391d7
...
...
@@ -39,12 +39,10 @@ internal const val REQUEST_CODE_FOR_SIGN_IN_REQUIRED = 1
internal
const
val
REQUEST_CODE_FOR_MULTIPLE_ACCOUNTS_RESOLUTION
=
2
internal
const
val
REQUEST_CODE_FOR_SAVE_RESOLUTION
=
3
fun
newInstance
(
serverName
:
String
):
Fragment
{
return
LoginFragment
().
apply
{
fun
newInstance
(
serverName
:
String
):
Fragment
=
LoginFragment
().
apply
{
arguments
=
Bundle
(
1
).
apply
{
putString
(
SERVER_NAME
,
serverName
)
}
}
}
class
LoginFragment
:
Fragment
(),
LoginView
{
...
...
@@ -59,9 +57,8 @@ class LoginFragment : Fragment(), LoginView {
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 +147,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 +157,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 @
1f1391d7
...
...
@@ -88,8 +88,7 @@ fun newInstance(
isLoginFormEnabled
:
Boolean
,
isNewAccountCreationEnabled
:
Boolean
,
deepLinkInfo
:
LoginDeepLinkInfo
?
=
null
):
Fragment
{
return
LoginOptionsFragment
().
apply
{
):
Fragment
=
LoginOptionsFragment
().
apply
{
arguments
=
Bundle
(
23
).
apply
{
putString
(
SERVER_NAME
,
serverName
)
putString
(
STATE
,
state
)
...
...
@@ -118,7 +117,6 @@ fun newInstance(
putBoolean
(
IS_NEW_ACCOUNT_CREATION_ENABLED
,
isNewAccountCreationEnabled
)
putParcelable
(
DEEP_LINK_INFO
,
deepLinkInfo
)
}
}
}
class
LoginOptionsFragment
:
Fragment
(),
LoginOptionsView
{
...
...
@@ -157,34 +155,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 +385,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 +403,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 @
1f1391d7
...
...
@@ -31,13 +31,11 @@ import javax.inject.Inject
private
const
val
BUNDLE_USER_ID
=
"user_id"
private
const
val
BUNDLE_AUTH_TOKEN
=
"auth_token"
fun
newInstance
(
userId
:
String
,
authToken
:
String
):
Fragment
{
return
RegisterUsernameFragment
().
apply
{
fun
newInstance
(
userId
:
String
,
authToken
:
String
):
Fragment
=
RegisterUsernameFragment
().
apply
{
arguments
=
Bundle
(
2
).
apply
{
putString
(
BUNDLE_USER_ID
,
userId
)
putString
(
BUNDLE_AUTH_TOKEN
,
authToken
)
}
}
}
class
RegisterUsernameFragment
:
Fragment
(),
RegisterUsernameView
{
...
...
@@ -53,13 +51,10 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView {
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 @
1f1391d7
...
...
@@ -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 @
1f1391d7
...
...
@@ -25,13 +25,11 @@ import io.reactivex.disposables.Disposable
import
kotlinx.android.synthetic.main.fragment_authentication_two_fa.*
import
javax.inject.Inject
fun
newInstance
(
username
:
String
,
password
:
String
):
Fragment
{
return
TwoFAFragment
().
apply
{
fun
newInstance
(
username
:
String
,
password
:
String
):
Fragment
=
TwoFAFragment
().
apply
{
arguments
=
Bundle
(
2
).
apply
{
putString
(
BUNDLE_USERNAME
,
username
)
putString
(
BUNDLE_PASSWORD
,
password
)
}
}
}
private
const
val
BUNDLE_USERNAME
=
"username"
...
...
@@ -50,13 +48,10 @@ class TwoFAFragment : Fragment(), TwoFAView {
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/adapter/OptionViewHolder.kt
View file @
1f1391d7
package
chat.rocket.android.chatdetails.adapter
import
android.content.Context
import
DrawableHelper
import
android.view.View
import
android.widget.ImageView
import
android.widget.TextView
...
...
app/src/main/java/chat/rocket/android/chatdetails/ui/ChatDetailsAdapter.kt
View file @
1f1391d7
...
...
@@ -11,9 +11,15 @@ import chat.rocket.android.util.extensions.inflate
class
ChatDetailsAdapter
:
RecyclerView
.
Adapter
<
OptionViewHolder
>()
{
private
val
options
:
MutableList
<
Option
>
=
ArrayList
()
override
fun
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
):
OptionViewHolder
=
OptionViewHolder
(
parent
.
inflate
(
R
.
layout
.
item_detail_option
))
override
fun
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
):
OptionViewHolder
=
OptionViewHolder
(
parent
.
inflate
(
R
.
layout
.
item_detail_option
))
override
fun
onBindViewHolder
(
holder
:
OptionViewHolder
,
position
:
Int
)
=
holder
.
bindViews
(
OptionItemHolder
(
options
[
position
]))
override
fun
onBindViewHolder
(
holder
:
OptionViewHolder
,
position
:
Int
)
=
holder
.
bindViews
(
OptionItemHolder
(
options
[
position
]))
override
fun
getItemCount
():
Int
=
options
.
size
...
...
app/src/main/java/chat/rocket/android/chatdetails/ui/ChatDetailsFragment.kt
View file @
1f1391d7
...
...
@@ -32,15 +32,13 @@ fun newInstance(
chatRoomType
:
String
,
isSubscribed
:
Boolean
,
disableMenu
:
Boolean
):
ChatDetailsFragment
{
return
ChatDetailsFragment
().
apply
{
):
ChatDetailsFragment
=
ChatDetailsFragment
().
apply
{
arguments
=
Bundle
(
4
).
apply
{
putString
(
BUNDLE_CHAT_ROOM_ID
,
chatRoomId
)
putString
(
BUNDLE_CHAT_ROOM_TYPE
,
chatRoomType
)
putBoolean
(
BUNDLE_IS_SUBSCRIBED
,
isSubscribed
)
putBoolean
(
BUNDLE_DISABLE_MENU
,
disableMenu
)
}
}
}
internal
const
val
TAG_CHAT_DETAILS_FRAGMENT
=
"ChatDetailsFragment"
...
...
@@ -66,15 +64,13 @@ 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/chatdetails/viewmodel/ChatDetailsViewModelFactory.kt
View file @
1f1391d7
...
...
@@ -5,9 +5,10 @@ import androidx.lifecycle.ViewModelProvider
import
chat.rocket.android.db.ChatRoomDao
import
javax.inject.Inject
class
ChatDetailsViewModelFactory
@Inject
constructor
(
private
val
chatRoomDao
:
ChatRoomDao
)
:
ViewModelProvider
.
NewInstanceFactory
()
{
class
ChatDetailsViewModelFactory
@Inject
constructor
(
private
val
chatRoomDao
:
ChatRoomDao
)
:
ViewModelProvider
.
NewInstanceFactory
()
{
@Suppress
(
"UNCHECKED_CAST"
)
override
fun
<
T
:
ViewModel
?
>
create
(
modelClass
:
Class
<
T
>)
=
ChatDetailsViewModel
(
chatRoomDao
)
as
T
override
fun
<
T
:
ViewModel
?
>
create
(
modelClass
:
Class
<
T
>)
=
ChatDetailsViewModel
(
chatRoomDao
)
as
T
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/adapter/ActionsListAdapter.kt
View file @
1f1391d7
...
...
@@ -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
...
...
@@ -62,9 +65,7 @@ class ActionsListAdapter(actions: List<Action>, var actionAttachmentOnClickListe
return
ViewHolder
(
view
)
}
override
fun
getItemCount
():
Int
{
return
actions
.
size
}
override
fun
getItemCount
():
Int
=
actions
.
size
override
fun
onBindViewHolder
(
holder
:
ViewHolder
,
position
:
Int
)
{
val
action
=
actions
[
position
]
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/ChatRoomAdapter.kt
View file @
1f1391d7
...
...
@@ -76,13 +76,9 @@ class ChatRoomAdapter(
}
}
override
fun
getItemViewType
(
position
:
Int
):
Int
{
return
dataSet
[
position
].
viewType
}
override
fun
getItemViewType
(
position
:
Int
):
Int
=
dataSet
[
position
].
viewType
override
fun
getItemCount
():
Int
{
return
dataSet
.
size
}
override
fun
getItemCount
():
Int
=
dataSet
.
size
override
fun
onBindViewHolder
(
holder
:
BaseViewHolder
<
*
>,
position
:
Int
)
{
if
(
holder
!
is
MessageViewHolder
)
{
...
...
@@ -174,12 +170,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
...
...
@@ -258,10 +254,10 @@ class ChatRoomAdapter(
actionSelectListener
?.
editMessage
(
roomId
,
id
,
message
.
message
)
}
R
.
id
.
action_message_star
->
{
actionSelectListener
?.
to
o
gleStar
(
id
,
!
item
.
isChecked
)
actionSelectListener
?.
to
g
gleStar
(
id
,
!
item
.
isChecked
)
}
R
.
id
.
action_message_unpin
->
{
actionSelectListener
?.
to
o
glePin
(
id
,
!
item
.
isChecked
)
actionSelectListener
?.
to
g
glePin
(
id
,
!
item
.
isChecked
)
}
R
.
id
.
action_message_delete
->
{
actionSelectListener
?.
deleteMessage
(
roomId
,
id
)
...
...
@@ -298,9 +294,9 @@ class ChatRoomAdapter(
fun
editMessage
(
roomId
:
String
,
messageId
:
String
,
text
:
String
)
fun
to
o
gleStar
(
id
:
String
,
star
:
Boolean
)
fun
to
g
gleStar
(
id
:
String
,
star
:
Boolean
)
fun
to
o
glePin
(
id
:
String
,
pin
:
Boolean
)
fun
to
g
glePin
(
id
:
String
,
pin
:
Boolean
)
fun
deleteMessage
(
roomId
:
String
,
id
:
String
)
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/RoomSuggestionsAdapter.kt
View file @
1f1391d7
...
...
@@ -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 @
1f1391d7
...
...
@@ -8,15 +8,14 @@ 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
)
{
setupActionMenu
(
url_preview_layout
)
}
setupActionMenu
(
itemView
.
url_preview_layout
)
}
override
fun
bindViews
(
data
:
UrlPreviewUiModel
)
{
...
...
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
View file @
1f1391d7
...
...
@@ -182,8 +182,8 @@ class ChatRoomPresenter @Inject constructor(
chatRoomId
?.
let
{
manager
.
addRoomChannel
(
it
,
roomChangesChannel
)
for
(
room
in
roomChangesChannel
)
{
dbManager
.
getRoom
(
room
.
id
)
?.
let
{
view
.
onRoomUpdated
(
roomMapper
.
map
(
chatRoom
=
it
,
showLastMessage
=
true
))
dbManager
.
getRoom
(
room
.
id
)
?.
let
{
chatRoom
->
view
.
onRoomUpdated
(
roomMapper
.
map
(
chatRoom
=
chatRoom
,
showLastMessage
=
true
))
}
}
}
...
...
@@ -1074,7 +1074,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 @
1f1391d7
...
...
@@ -31,8 +31,7 @@ fun Context.chatRoomIntent(
isCreator
:
Boolean
=
false
,
isFavorite
:
Boolean
=
false
,
chatRoomMessage
:
String
?
=
null
):
Intent
{
return
Intent
(
this
,
ChatRoomActivity
::
class
.
java
).
apply
{
):
Intent
=
Intent
(
this
,
ChatRoomActivity
::
class
.
java
).
apply
{
putExtra
(
INTENT_CHAT_ROOM_ID
,
chatRoomId
)
putExtra
(
INTENT_CHAT_ROOM_NAME
,
chatRoomName
)
putExtra
(
INTENT_CHAT_ROOM_TYPE
,
chatRoomType
)
...
...
@@ -42,7 +41,6 @@ fun Context.chatRoomIntent(
putExtra
(
INTENT_CHAT_ROOM_IS_CREATOR
,
isCreator
)
putExtra
(
INTENT_CHAT_ROOM_IS_FAVORITE
,
isFavorite
)
putExtra
(
INTENT_CHAT_ROOM_MESSAGE
,
chatRoomMessage
)
}
}
private
const
val
INTENT_CHAT_ROOM_ID
=
"chat_room_id"
...
...
@@ -81,26 +79,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
)
val
chatRoomMessage
=
getStringExtra
(
INTENT_CHAT_ROOM_MESSAGE
)
setupToolbar
()
...
...
@@ -120,6 +119,7 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
}
}
}
}
override
fun
onBackPressed
()
{
finishActivity
()
...
...
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
1f1391d7
...
...
@@ -111,8 +111,7 @@ fun newInstance(
isCreator
:
Boolean
=
false
,
isFavorite
:
Boolean
=
false
,
chatRoomMessage
:
String
?
=
null
):
Fragment
{
return
ChatRoomFragment
().
apply
{
):
Fragment
=
ChatRoomFragment
().
apply
{
arguments
=
Bundle
(
1
).
apply
{
putString
(
BUNDLE_CHAT_ROOM_ID
,
chatRoomId
)
putString
(
BUNDLE_CHAT_ROOM_NAME
,
chatRoomName
)
...
...
@@ -124,7 +123,6 @@ fun newInstance(
putBoolean
(
BUNDLE_CHAT_ROOM_IS_FAVORITE
,
isFavorite
)
putString
(
BUNDLE_CHAT_ROOM_MESSAGE
,
chatRoomMessage
)
}
}
}
internal
const
val
TAG_CHAT_ROOM_FRAGMENT
=
"ChatRoomFragment"
...
...
@@ -272,20 +270,17 @@ 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
)
}
...
...
@@ -758,21 +753,20 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
ui
{
text_connection_status
.
fadeIn
()
handler
.
removeCallbacks
(
dismissStatus
)
when
(
state
)
{
text_connection_status
.
text
=
when
(
state
)
{
is
State
.
Connected
->
{
text_connection_status
.
text
=
getString
(
R
.
string
.
status_connected
)
handler
.
postDelayed
(
dismissStatus
,
2000
)
getString
(
R
.
string
.
status_connected
)
}
is
State
.
Disconnected
->
getString
(
R
.
string
.
status_disconnected
)
is
State
.
Connecting
->
getString
(
R
.
string
.
status_connecting
)
is
State
.
Authenticating
->
getString
(
R
.
string
.
status_authenticating
)
is
State
.
Disconnecting
->
getString
(
R
.
string
.
status_disconnecting
)
is
State
.
Waiting
->
getString
(
R
.
string
.
status_waiting
,
state
.
seconds
)
else
->
{
handler
.
postDelayed
(
dismissStatus
,
500
)
""
}
is
State
.
Disconnected
->
text_connection_status
.
text
=
getString
(
R
.
string
.
status_disconnected
)
is
State
.
Connecting
->
text_connection_status
.
text
=
getString
(
R
.
string
.
status_connecting
)
is
State
.
Authenticating
->
text_connection_status
.
text
=
getString
(
R
.
string
.
status_authenticating
)
is
State
.
Disconnecting
->
text_connection_status
.
text
=
getString
(
R
.
string
.
status_disconnecting
)
is
State
.
Waiting
->
text_connection_status
.
text
=
getString
(
R
.
string
.
status_waiting
,
state
.
seconds
)
}
}
}
...
...
@@ -1098,7 +1092,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
presenter
.
editMessage
(
roomId
,
messageId
,
text
)
}
override
fun
to
o
gleStar
(
id
:
String
,
star
:
Boolean
)
{
override
fun
to
g
gleStar
(
id
:
String
,
star
:
Boolean
)
{
if
(
star
)
{
presenter
.
starMessage
(
id
)
}
else
{
...
...
@@ -1106,7 +1100,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
}
}
override
fun
to
o
glePin
(
id
:
String
,
pin
:
Boolean
)
{
override
fun
to
g
glePin
(
id
:
String
,
pin
:
Boolean
)
{
if
(
pin
)
{
presenter
.
pinMessage
(
id
)
}
else
{
...
...
app/src/main/java/chat/rocket/android/chatroom/uimodel/UiModelMapper.kt
View file @
1f1391d7
...
...
@@ -416,21 +416,19 @@ 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
)
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
private
fun
attachmentDescription
(
attachment
:
Attachment
):
String
?
{
return
attachment
.
description
...
...
@@ -464,12 +462,10 @@ class UiModelMapper @Inject constructor(
subscriptionId
=
chatRoom
.
subscriptionId
)
}
private
fun
mapMessagePreview
(
message
:
Message
):
Message
{
return
when
(
message
.
isSystemMessage
())
{
private
fun
mapMessagePreview
(
message
:
Message
):
Message
=
when
(
message
.
isSystemMessage
())
{
false
->
stripMessageQuotes
(
message
)
true
->
message
.
copy
(
message
=
getSystemMessage
(
message
).
toString
())
}
}
private
fun
getReactions
(
message
:
Message
):
List
<
ReactionUiModel
>
{
val
reactions
=
message
.
reactions
?.
let
{
...
...
@@ -535,37 +531,33 @@ class UiModelMapper @Inject constructor(
private
fun
getTime
(
timestamp
:
Long
)
=
DateTimeHelper
.
getTime
(
DateTimeHelper
.
getLocalDateTime
(
timestamp
))
private
fun
getContent
(
message
:
Message
):
CharSequence
{
return
when
(
message
.
isSystemMessage
())
{
private
fun
getContent
(
message
:
Message
):
CharSequence
=
when
(
message
.
isSystemMessage
())
{
true
->
getSystemMessage
(
message
)
false
->
parser
.
render
(
message
,
currentUsername
)
}
}
private
fun
getSystemMessage
(
message
:
Message
):
CharSequence
{
val
content
=
when
(
message
.
type
)
{
val
content
=
with
(
context
)
{
when
(
message
.
type
)
{
//TODO: Add implementation for Welcome type.
is
MessageType
.
MessageRemoved
->
context
.
getString
(
R
.
string
.
message_removed
)
is
MessageType
.
UserJoined
->
context
.
getString
(
R
.
string
.
message_user_joined_channel
)
is
MessageType
.
UserLeft
->
context
.
getString
(
R
.
string
.
message_user_left
)
is
MessageType
.
UserAdded
->
context
.
getString
(
R
.
string
.
message_user_added_by
,
message
.
message
,
message
.
sender
?.
username
)
is
MessageType
.
RoomNameChanged
->
context
.
getString
(
R
.
string
.
message_room_name_changed
,
message
.
message
,
message
.
sender
?.
username
)
is
MessageType
.
UserRemoved
->
context
.
getString
(
R
.
string
.
message_user_removed_by
,
message
.
message
,
message
.
sender
?.
username
)
is
MessageType
.
MessagePinned
->
context
.
getString
(
R
.
string
.
message_pinned
)
is
MessageType
.
UserMuted
->
context
.
getString
(
R
.
string
.
message_muted
,
message
.
message
,
message
.
sender
?.
username
)
is
MessageType
.
UserUnMuted
->
context
.
getString
(
R
.
string
.
message_unmuted
,
message
.
message
,
message
.
sender
?.
username
)
is
MessageType
.
SubscriptionRoleAdded
->
context
.
getString
(
R
.
string
.
message_role_add
,
message
.
message
,
message
.
role
,
message
.
sender
?.
username
)
is
MessageType
.
SubscriptionRoleRemoved
->
context
.
getString
(
R
.
string
.
message_role_removed
,
message
.
message
,
message
.
role
,
message
.
sender
?.
username
)
is
MessageType
.
RoomChangedPrivacy
->
context
.
getString
(
R
.
string
.
message_room_changed_privacy
,
message
.
message
,
message
.
sender
?.
username
)
else
->
{
throw
InvalidParameterException
(
"Invalid message type: ${message.type}"
)
is
MessageType
.
MessageRemoved
->
getString
(
R
.
string
.
message_removed
)
is
MessageType
.
UserJoined
->
getString
(
R
.
string
.
message_user_joined_channel
)
is
MessageType
.
UserLeft
->
getString
(
R
.
string
.
message_user_left
)
is
MessageType
.
UserAdded
->
getString
(
R
.
string
.
message_user_added_by
,
message
.
message
,
message
.
sender
?.
username
)
is
MessageType
.
RoomNameChanged
->
getString
(
R
.
string
.
message_room_name_changed
,
message
.
message
,
message
.
sender
?.
username
)
is
MessageType
.
UserRemoved
->
getString
(
R
.
string
.
message_user_removed_by
,
message
.
message
,
message
.
sender
?.
username
)
is
MessageType
.
MessagePinned
->
getString
(
R
.
string
.
message_pinned
)
is
MessageType
.
UserMuted
->
getString
(
R
.
string
.
message_muted
,
message
.
message
,
message
.
sender
?.
username
)
is
MessageType
.
UserUnMuted
->
getString
(
R
.
string
.
message_unmuted
,
message
.
message
,
message
.
sender
?.
username
)
is
MessageType
.
SubscriptionRoleAdded
->
getString
(
R
.
string
.
message_role_add
,
message
.
message
,
message
.
role
,
message
.
sender
?.
username
)
is
MessageType
.
SubscriptionRoleRemoved
->
getString
(
R
.
string
.
message_role_removed
,
message
.
message
,
message
.
role
,
message
.
sender
?.
username
)
is
MessageType
.
RoomChangedPrivacy
->
getString
(
R
.
string
.
message_room_changed_privacy
,
message
.
message
,
message
.
sender
?.
username
)
else
->
throw
InvalidParameterException
(
"Invalid message type: ${message.type}"
)
}
}
val
spannableMsg
=
SpannableStringBuilder
(
content
)
spannableMsg
.
setSpan
(
StyleSpan
(
Typeface
.
ITALIC
),
0
,
spannableMsg
.
length
,
0
)
spannableMsg
.
setSpan
(
ForegroundColorSpan
(
Color
.
GRAY
),
0
,
spannableMsg
.
length
,
0
)
spannableMsg
.
setSpan
(
StyleSpan
(
Typeface
.
ITALIC
),
0
,
spannableMsg
.
length
,
0
)
spannableMsg
.
setSpan
(
ForegroundColorSpan
(
Color
.
GRAY
),
0
,
spannableMsg
.
length
,
0
)
return
spannableMsg
}
...
...
app/src/main/java/chat/rocket/android/chatrooms/adapter/RoomUiModelMapper.kt
View file @
1f1391d7
...
...
@@ -77,8 +77,7 @@ class RoomUiModelMapper(
return
list
}
private
fun
mapUser
(
user
:
User
):
RoomUiModel
{
return
with
(
user
)
{
private
fun
mapUser
(
user
:
User
):
RoomUiModel
=
with
(
user
)
{
val
name
=
mapName
(
user
.
username
!!
,
user
.
name
)
val
status
=
user
.
status
val
avatar
=
serverUrl
.
avatarUrl
(
user
.
username
!!
)
...
...
@@ -93,10 +92,8 @@ class RoomUiModelMapper(
username
=
username
)
}
}
private
fun
mapRoom
(
room
:
Room
,
showLastMessage
:
Boolean
=
true
):
RoomUiModel
{
return
with
(
room
)
{
private
fun
mapRoom
(
room
:
Room
,
showLastMessage
:
Boolean
=
true
):
RoomUiModel
=
with
(
room
)
{
RoomUiModel
(
id
=
id
,
name
=
name
!!
,
...
...
@@ -115,10 +112,8 @@ class RoomUiModelMapper(
writable
=
isChannelWritable
(
muted
)
)
}
}
fun
map
(
chatRoom
:
ChatRoom
,
showLastMessage
:
Boolean
=
true
):
RoomUiModel
{
return
with
(
chatRoom
.
chatRoom
)
{
fun
map
(
chatRoom
:
ChatRoom
,
showLastMessage
:
Boolean
=
true
):
RoomUiModel
=
with
(
chatRoom
.
chatRoom
)
{
val
isUnread
=
alert
||
unread
>
0
val
type
=
roomTypeOf
(
type
)
val
status
=
chatRoom
.
status
?.
let
{
userStatusOf
(
it
)
}
...
...
@@ -144,8 +139,7 @@ class RoomUiModelMapper(
}
val
hasMentions
=
mapMentions
(
userMentions
,
groupMentions
)
val
open
=
open
val
lastMessageMarkdown
=
lastMessage
?.
let
{
Markwon
.
markdown
(
context
,
it
.
toString
()).
toString
()
}
val
lastMessageMarkdown
=
lastMessage
?.
let
{
Markwon
.
markdown
(
context
,
it
.
toString
()).
toString
()
}
RoomUiModel
(
id
=
id
,
...
...
@@ -165,22 +159,19 @@ class RoomUiModelMapper(
writable
=
isChannelWritable
(
muted
)
)
}
}
private
fun
isChannelWritable
(
muted
:
List
<
String
>?):
Boolean
{
val
canWriteToReadOnlyChannels
=
permissions
.
canPostToReadOnlyChannels
()
return
canWriteToReadOnlyChannels
||
!
muted
.
orEmpty
().
contains
(
currentUser
?.
username
)
}
private
fun
roomType
(
type
:
String
):
String
{
val
resources
=
context
.
resources
return
when
(
type
)
{
RoomType
.
CHANNEL
->
resources
.
getString
(
R
.
string
.
header_channel
)
RoomType
.
PRIVATE_GROUP
->
resources
.
getString
(
R
.
string
.
header_private_groups
)
RoomType
.
DIRECT_MESSAGE
->
resources
.
getString
(
R
.
string
.
header_direct_messages
)
RoomType
.
LIVECHAT
->
resources
.
getString
(
R
.
string
.
header_live_chats
)
else
->
resources
.
getString
(
R
.
string
.
header_unknown
)
private
fun
roomType
(
type
:
String
):
String
=
with
(
context
.
resources
)
{
when
(
type
)
{
RoomType
.
CHANNEL
->
getString
(
R
.
string
.
header_channel
)
RoomType
.
PRIVATE_GROUP
->
getString
(
R
.
string
.
header_private_groups
)
RoomType
.
DIRECT_MESSAGE
->
getString
(
R
.
string
.
header_direct_messages
)
RoomType
.
LIVECHAT
->
getString
(
R
.
string
.
header_live_chats
)
else
->
getString
(
R
.
string
.
header_unknown
)
}
}
...
...
@@ -213,14 +204,12 @@ class RoomUiModelMapper(
}
}
private
fun
mapUnread
(
unread
:
Long
):
String
?
{
return
when
(
unread
)
{
private
fun
mapUnread
(
unread
:
Long
):
String
?
=
when
(
unread
)
{
0L
->
null
in
1
..
99
->
unread
.
toString
()
else
->
context
.
getString
(
R
.
string
.
msg_more_than_ninety_nine_unread_messages
)
}
}
private
fun
mapMentions
(
userMentions
:
Long
?,
groupMentions
:
Long
?):
Boolean
{
if
(
userMentions
!=
null
&&
groupMentions
!=
null
)
{
...
...
app/src/main/java/chat/rocket/android/chatrooms/adapter/RoomViewHolder.kt
View file @
1f1391d7
...
...
@@ -8,6 +8,7 @@ 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.*
...
...
@@ -16,12 +17,12 @@ import kotlinx.android.synthetic.main.unread_messages_badge.view.*
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 +54,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
}
...
...
@@ -68,20 +69,16 @@ class RoomViewHolder(itemView: View, private val listener: (RoomUiModel) -> Unit
}
}
private
fun
getRoomDrawable
(
type
:
RoomType
):
Drawable
?
{
return
when
(
type
)
{
private
fun
getRoomDrawable
(
type
:
RoomType
):
Drawable
?
=
when
(
type
)
{
is
RoomType
.
Channel
->
channelIcon
is
RoomType
.
PrivateGroup
->
groupIcon
else
->
null
}
}
private
fun
getStatusDrawable
(
status
:
UserStatus
):
Drawable
{
return
when
(
status
)
{
private
fun
getStatusDrawable
(
status
:
UserStatus
):
Drawable
=
when
(
status
)
{
is
UserStatus
.
Online
->
onlineIcon
is
UserStatus
.
Away
->
awayIcon
is
UserStatus
.
Busy
->
busyIcon
else
->
offlineIcon
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatrooms/adapter/RoomsAdapter.kt
View file @
1f1391d7
...
...
@@ -19,8 +19,7 @@ class RoomsAdapter(private val listener: (RoomUiModel) -> Unit) :
notifyDataSetChanged
()
}
override
fun
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
):
ViewHolder
<
*
>
{
return
when
(
viewType
)
{
override
fun
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
):
ViewHolder
<
*
>
=
when
(
viewType
)
{
VIEW_TYPE_ROOM
->
{
val
view
=
parent
.
inflate
(
R
.
layout
.
item_chat
)
RoomViewHolder
(
view
,
listener
)
...
...
@@ -35,7 +34,6 @@ class RoomsAdapter(private val listener: (RoomUiModel) -> Unit) :
}
else
->
throw
IllegalStateException
(
"View type must be either Room, Header or Loading"
)
}
}
override
fun
getItemCount
()
=
values
.
size
...
...
@@ -49,14 +47,12 @@ class RoomsAdapter(private val listener: (RoomUiModel) -> Unit) :
}
}
override
fun
getItemViewType
(
position
:
Int
):
Int
{
return
when
(
values
[
position
])
{
override
fun
getItemViewType
(
position
:
Int
):
Int
=
when
(
values
[
position
])
{
is
RoomItemHolder
->
VIEW_TYPE_ROOM
is
HeaderItemHolder
->
VIEW_TYPE_HEADER
is
LoadingItemHolder
->
VIEW_TYPE_LOADING
else
->
throw
IllegalStateException
(
"View type must be either Room, Header or Loading"
)
}
}
override
fun
onBindViewHolder
(
holder
:
ViewHolder
<
*
>,
position
:
Int
)
{
if
(
holder
is
RoomViewHolder
)
{
...
...
app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
View file @
1f1391d7
...
...
@@ -69,22 +69,19 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
private
var
progressDialog
:
ProgressDialog
?
=
null
companion
object
{
fun
newInstance
(
chatRoomId
:
String
?
=
null
):
ChatRoomsFragment
{
return
ChatRoomsFragment
().
apply
{
fun
newInstance
(
chatRoomId
:
String
?
=
null
):
ChatRoomsFragment
=
ChatRoomsFragment
().
apply
{
arguments
=
Bundle
(
1
).
apply
{
putString
(
BUNDLE_CHAT_ROOM_ID
,
chatRoomId
)
}
}
}
}
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
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
...
...
@@ -320,21 +317,20 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
ui
{
text_connection_status
.
fadeIn
()
handler
.
removeCallbacks
(
dismissStatus
)
when
(
state
)
{
text_connection_status
.
text
=
when
(
state
)
{
is
State
.
Connected
->
{
text_connection_status
.
text
=
getString
(
R
.
string
.
status_connected
)
handler
.
postDelayed
(
dismissStatus
,
2000
)
getString
(
R
.
string
.
status_connected
)
}
is
State
.
Disconnected
->
getString
(
R
.
string
.
status_disconnected
)
is
State
.
Connecting
->
getString
(
R
.
string
.
status_connecting
)
is
State
.
Authenticating
->
getString
(
R
.
string
.
status_authenticating
)
is
State
.
Disconnecting
->
getString
(
R
.
string
.
status_disconnecting
)
is
State
.
Waiting
->
getString
(
R
.
string
.
status_waiting
,
state
.
seconds
)
else
->
{
handler
.
postDelayed
(
dismissStatus
,
500
)
""
}
is
State
.
Disconnected
->
text_connection_status
.
text
=
getString
(
R
.
string
.
status_disconnected
)
is
State
.
Connecting
->
text_connection_status
.
text
=
getString
(
R
.
string
.
status_connecting
)
is
State
.
Authenticating
->
text_connection_status
.
text
=
getString
(
R
.
string
.
status_authenticating
)
is
State
.
Disconnecting
->
text_connection_status
.
text
=
getString
(
R
.
string
.
status_disconnecting
)
is
State
.
Waiting
->
text_connection_status
.
text
=
getString
(
R
.
string
.
status_waiting
,
state
.
seconds
)
}
}
}
...
...
app/src/main/java/chat/rocket/android/createchannel/ui/CreateChannelFragment.kt
View file @
1f1391d7
...
...
@@ -45,9 +45,7 @@ class CreateChannelFragment : Fragment(), CreateChannelView, ActionMode.Callback
lateinit
var
analyticsManager
:
AnalyticsManager
private
var
actionMode
:
ActionMode
?
=
null
private
val
adapter
:
MembersAdapter
=
MembersAdapter
{
if
(
it
.
username
!=
null
)
{
processSelectedMember
(
it
.
username
)
}
it
.
username
?.
run
{
processSelectedMember
(
this
)
}
}
private
val
compositeDisposable
=
CompositeDisposable
()
private
var
channelType
:
String
=
RoomType
.
CHANNEL
...
...
@@ -294,8 +292,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 +302,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 @
1f1391d7
...
...
@@ -40,6 +40,12 @@ import kotlinx.coroutines.experimental.newSingleThreadContext
import
kotlinx.coroutines.experimental.withContext
import
timber.log.Timber
import
java.util.HashSet
import
kotlin.collections.ArrayList
import
kotlin.collections.HashMap
import
kotlin.collections.LinkedHashMap
import
kotlin.collections.component1
import
kotlin.collections.component2
import
kotlin.collections.set
import
kotlin.system.measureTimeMillis
class
DatabaseManager
(
val
context
:
Application
,
val
serverUrl
:
String
)
{
...
...
@@ -140,7 +146,7 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
batch
.
forEach
{
when
(
it
.
type
)
{
is
Type
.
Removed
->
toRemove
.
add
(
removeChatRoom
(
it
.
data
))
is
Type
.
Inserted
->
insertChatRoom
(
it
.
data
)
?.
let
{
toInsert
.
add
(
it
)
}
is
Type
.
Inserted
->
insertChatRoom
(
it
.
data
)
?.
let
{
room
->
toInsert
.
add
(
room
)
}
is
Type
.
Updated
->
{
when
(
it
.
data
)
{
is
Subscription
->
updateSubs
[(
it
.
data
as
Subscription
).
roomId
]
=
it
.
data
as
Subscription
...
...
@@ -186,8 +192,7 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
}
}
fun
processMessagesBatch
(
messages
:
List
<
Message
>):
Job
{
return
launch
(
dbManagerContext
)
{
fun
processMessagesBatch
(
messages
:
List
<
Message
>):
Job
=
launch
(
dbManagerContext
)
{
val
list
=
mutableListOf
<
Pair
<
MessageEntity
,
List
<
BaseMessageEntity
>>>()
messages
.
forEach
{
message
->
val
pair
=
createMessageEntities
(
message
)
...
...
@@ -196,7 +201,6 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
sendOperation
(
Operation
.
InsertMessages
(
list
))
}
}
private
suspend
fun
createMessageEntities
(
message
:
Message
):
Pair
<
MessageEntity
,
List
<
BaseMessageEntity
>>
{
val
messageEntity
=
message
.
toEntity
()
...
...
@@ -213,91 +217,70 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
return
Pair
(
messageEntity
,
list
)
}
private
fun
createReactions
(
message
:
Message
):
List
<
BaseMessageEntity
>?
{
if
(
message
.
reactions
==
null
||
message
.
reactions
!!
.
isEmpty
())
{
return
null
}
val
reactions
=
message
.
reactions
!!
private
fun
createReactions
(
message
:
Message
):
List
<
BaseMessageEntity
>?
=
message
.
reactions
?.
run
{
if
(
isNotEmpty
())
{
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
()))
keys
.
forEach
{
reaction
->
get
(
reaction
)
?.
let
{
reactionValue
->
list
.
add
(
ReactionEntity
(
reaction
,
message
.
id
,
size
,
reactionValue
.
joinToString
()))
}
}
return
list
}
private
fun
createUrlEntities
(
message
:
Message
):
List
<
BaseMessageEntity
>?
{
if
(
message
.
urls
==
null
||
message
.
urls
!!
.
isEmpty
())
{
return
null
list
}
else
null
}
private
fun
createUrlEntities
(
message
:
Message
):
List
<
BaseMessageEntity
>?
=
message
.
urls
?.
run
{
if
(
isNotEmpty
())
{
val
list
=
mutableListOf
<
UrlEntity
>()
message
.
urls
!!
.
forEach
{
url
->
forEach
{
url
->
list
.
add
(
UrlEntity
(
message
.
id
,
url
.
url
,
url
.
parsedUrl
?.
host
,
url
.
meta
?.
title
,
url
.
meta
?.
description
,
url
.
meta
?.
imageUrl
))
}
return
list
}
private
fun
createChannelRelations
(
message
:
Message
):
List
<
BaseMessageEntity
>?
{
if
(
message
.
channels
==
null
||
message
.
channels
!!
.
isEmpty
())
{
return
null
list
}
else
null
}
private
fun
createChannelRelations
(
message
:
Message
):
List
<
BaseMessageEntity
>?
=
message
.
channels
?.
run
{
if
(
isNotEmpty
())
{
val
list
=
mutableListOf
<
MessageChannels
>()
message
.
channels
!!
.
forEach
{
channel
->
forEach
{
channel
->
list
.
add
(
MessageChannels
(
message
.
id
,
channel
.
id
,
channel
.
name
))
}
return
list
}
private
suspend
fun
createMentionRelations
(
message
:
Message
):
List
<
BaseMessageEntity
>?
{
if
(
message
.
mentions
==
null
||
message
.
mentions
!!
.
isEmpty
())
{
return
null
list
}
else
null
}
private
suspend
fun
createMentionRelations
(
message
:
Message
):
List
<
BaseMessageEntity
>?
=
message
.
mentions
?.
run
{
if
(
isNotEmpty
())
{
val
list
=
mutableListOf
<
MessageMentionsRelation
>()
message
.
mentions
!!
.
filterNot
{
user
->
user
.
id
.
isNullOrEmpty
()
}.
forEach
{
mention
->
filterNot
{
user
->
user
.
id
.
isNullOrEmpty
()
}.
forEach
{
mention
->
insertUserIfMissing
(
mention
)
list
.
add
(
MessageMentionsRelation
(
message
.
id
,
mention
.
id
!!
))
}
return
list
}
private
suspend
fun
createFavoriteRelations
(
message
:
Message
):
List
<
BaseMessageEntity
>?
{
if
(
message
.
starred
==
null
||
message
.
starred
!!
.
isEmpty
())
{
return
null
list
}
else
null
}
private
suspend
fun
createFavoriteRelations
(
message
:
Message
):
List
<
BaseMessageEntity
>?
=
message
.
starred
?.
run
{
if
(
isNotEmpty
())
{
val
list
=
mutableListOf
<
MessageFavoritesRelation
>()
message
.
starred
!!
.
filterNot
{
user
->
user
.
id
.
isNullOrEmpty
()
}.
forEach
{
userId
->
filterNot
{
user
->
user
.
id
.
isNullOrEmpty
()
}.
forEach
{
userId
->
insertUserIfMissing
(
userId
)
list
.
add
(
MessageFavoritesRelation
(
message
.
id
,
userId
.
id
!!
))
}
return
list
}
private
fun
createAttachments
(
message
:
Message
):
List
<
BaseMessageEntity
>?
{
if
(
message
.
attachments
==
null
||
message
.
attachments
!!
.
isEmpty
())
{
return
null
list
}
else
null
}
val
list
=
ArrayList
<
BaseMessageEntity
>(
message
.
attachments
!!
.
size
)
message
.
attachments
!!
.
forEach
{
attachment
->
private
fun
createAttachments
(
message
:
Message
):
List
<
BaseMessageEntity
>?
=
message
.
attachments
?.
run
{
if
(
isNotEmpty
())
{
val
list
=
ArrayList
<
BaseMessageEntity
>(
size
)
forEach
{
attachment
->
list
.
addAll
(
attachment
.
asEntity
(
message
.
id
,
context
))
}
return
list
list
}
else
null
}
private
suspend
fun
createUpdates
():
List
<
ChatRoomEntity
>
{
...
...
@@ -375,20 +358,15 @@ 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
)
{
message
.
attachments
?.
let
{
mapAttachmentText
(
it
[
0
])
}
}
else
{
message
.
message
}
this
.
message
}
}
private
fun
mapAttachmentText
(
attachment
:
Attachment
):
String
=
context
.
getString
(
R
.
string
.
msg_sent_attachment
)
private
fun
mapAttachmentText
(
attachment
:
Attachment
):
String
=
context
.
getString
(
R
.
string
.
msg_sent_attachment
)
private
suspend
fun
updateSubscription
(
data
:
Subscription
):
ChatRoomEntity
?
{
return
retryDB
(
"getRoom(${data.roomId}"
)
{
chatRoomDao
().
getSync
(
data
.
roomId
)
}
?.
let
{
current
->
...
...
@@ -431,13 +409,11 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
}
}
private
suspend
fun
insertChatRoom
(
data
:
BaseRoom
):
ChatRoomEntity
?
{
return
when
(
data
)
{
private
suspend
fun
insertChatRoom
(
data
:
BaseRoom
):
ChatRoomEntity
?
=
when
(
data
)
{
is
Room
->
insertRoom
(
data
)
is
Subscription
->
insertSubscription
(
data
)
else
->
null
}
}
private
suspend
fun
insertRoom
(
data
:
Room
):
ChatRoomEntity
?
{
val
subscription
=
insertSubs
.
remove
(
data
.
id
)
...
...
app/src/main/java/chat/rocket/android/db/model/Attachments.kt
View file @
1f1391d7
...
...
@@ -115,7 +115,7 @@ fun Attachment.asEntity(msgId: String, context: Context): List<BaseMessageEntity
val
text
=
mapAttachmentText
(
text
,
attachments
?.
firstOrNull
(),
context
)
val
entity
=
AttachmentEntity
(
list
.
add
(
AttachmentEntity
(
_id
=
attachmentId
,
messageId
=
msgId
,
title
=
title
,
...
...
@@ -144,16 +144,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 +173,14 @@ 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
{
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
->
imageUrl
.
isNotNullNorEmpty
()
->
context
.
getString
(
R
.
string
.
msg_preview_photo
)
videoUrl
.
isNotNullNorEmpty
()
->
context
.
getString
(
R
.
string
.
msg_preview_video
)
audioUrl
.
isNotNullNorEmpty
()
->
context
.
getString
(
R
.
string
.
msg_preview_audio
)
titleLink
.
isNotNullNorEmpty
()
&&
type
?.
contentEquals
(
"file"
)
==
true
->
context
.
getString
(
R
.
string
.
msg_preview_file
)
else
->
text
}
}
else
{
text
}
}
}
?:
text
\ No newline at end of file
app/src/main/java/chat/rocket/android/favoritemessages/presentation/FavoriteMessagesPresenter.kt
View file @
1f1391d7
...
...
@@ -36,8 +36,7 @@ class FavoriteMessagesPresenter @Inject constructor(
try
{
view
.
showLoading
()
dbManager
.
getRoom
(
roomId
)
?.
let
{
val
favoriteMessages
=
client
.
getFavoriteMessages
(
roomId
,
roomTypeOf
(
it
.
chatRoom
.
type
),
offset
)
val
favoriteMessages
=
client
.
getFavoriteMessages
(
roomId
,
roomTypeOf
(
it
.
chatRoom
.
type
),
offset
)
val
messageList
=
mapper
.
map
(
favoriteMessages
.
result
,
asNotReversed
=
true
)
view
.
showFavoriteMessages
(
messageList
)
offset
+=
1
*
30
...
...
app/src/main/java/chat/rocket/android/favoritemessages/ui/FavoriteMessagesFragment.kt
View file @
1f1391d7
...
...
@@ -25,12 +25,10 @@ import dagger.android.support.AndroidSupportInjection
import
kotlinx.android.synthetic.main.fragment_favorite_messages.*
import
javax.inject.Inject
fun
newInstance
(
chatRoomId
:
String
):
Fragment
{
return
FavoriteMessagesFragment
().
apply
{
fun
newInstance
(
chatRoomId
:
String
):
Fragment
=
FavoriteMessagesFragment
().
apply
{
arguments
=
Bundle
(
1
).
apply
{
putString
(
INTENT_CHAT_ROOM_ID
,
chatRoomId
)
}
}
}
internal
const
val
TAG_FAVORITE_MESSAGES_FRAGMENT
=
"FavoriteMessagesFragment"
...
...
@@ -48,12 +46,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 @
1f1391d7
...
...
@@ -30,12 +30,10 @@ import dagger.android.support.AndroidSupportInjection
import
kotlinx.android.synthetic.main.fragment_files.*
import
javax.inject.Inject
fun
newInstance
(
chatRoomId
:
String
):
Fragment
{
return
FilesFragment
().
apply
{
fun
newInstance
(
chatRoomId
:
String
):
Fragment
=
FilesFragment
().
apply
{
arguments
=
Bundle
(
1
).
apply
{
putString
(
BUNDLE_CHAT_ROOM_ID
,
chatRoomId
)
}
}
}
internal
const
val
TAG_FILES_FRAGMENT
=
"FilesFragment"
...
...
@@ -55,12 +53,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/AndroidPermissionsHelper.kt
View file @
1f1391d7
...
...
@@ -11,8 +11,7 @@ object AndroidPermissionsHelper {
const
val
WRITE_EXTERNAL_STORAGE_CODE
=
1
fun
checkPermission
(
context
:
Context
,
permission
:
String
):
Boolean
{
return
ContextCompat
.
checkSelfPermission
(
context
,
permission
)
==
PackageManager
.
PERMISSION_GRANTED
return
ContextCompat
.
checkSelfPermission
(
context
,
permission
)
==
PackageManager
.
PERMISSION_GRANTED
}
fun
requestPermission
(
context
:
Activity
,
permission
:
String
,
requestCode
:
Int
)
{
...
...
app/src/main/java/chat/rocket/android/helper/ImageHelper.kt
View file @
1f1391d7
...
...
@@ -53,8 +53,8 @@ object ImageHelper {
)
val
toolbar
=
Toolbar
(
context
).
also
{
it
.
inflateMenu
(
R
.
menu
.
image_actions
)
it
.
setOnMenuItemClickListener
{
return
@setOnMenuItemClickListener
when
(
it
.
itemId
)
{
it
.
setOnMenuItemClickListener
{
view
->
return
@setOnMenuItemClickListener
when
(
view
.
itemId
)
{
R
.
id
.
action_save_image
->
saveImage
(
context
)
else
->
true
}
...
...
@@ -62,20 +62,24 @@ 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
{
it
.
setImageResource
(
R
.
drawable
.
ic_arrow_back_white_24dp
)
it
.
setOnClickListener
{
imageViewer
?.
onDismiss
()
}
it
.
setPadding
(
0
,
pad
,
pad
,
pad
)
val
backArrowView
=
ImageView
(
context
).
also
{
imgView
->
with
(
imgView
)
{
setImageResource
(
R
.
drawable
.
ic_arrow_back_white_24dp
)
setOnClickListener
{
imageViewer
?.
onDismiss
()
}
setPadding
(
0
,
pad
,
pad
,
pad
)
}
}
val
layoutParams
=
AppBarLayout
.
LayoutParams
(
...
...
@@ -88,15 +92,17 @@ object ImageHelper {
}
val
appBarLayout
=
AppBarLayout
(
context
).
also
{
it
.
layoutParams
=
lparams
it
.
setBackgroundColor
(
Color
.
BLACK
)
it
.
addView
(
with
(
it
)
{
layoutParams
=
lparams
setBackgroundColor
(
Color
.
BLACK
)
addView
(
toolbar
,
AppBarLayout
.
LayoutParams
(
AppBarLayout
.
LayoutParams
.
MATCH_PARENT
,
ViewGroup
.
LayoutParams
.
WRAP_CONTENT
)
)
}
}
val
builder
=
ImageViewer
.
createPipelineDraweeControllerBuilder
()
.
setImageRequest
(
request
)
...
...
app/src/main/java/chat/rocket/android/members/adapter/MembersAdapter.kt
View file @
1f1391d7
...
...
@@ -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 @
1f1391d7
...
...
@@ -27,12 +27,10 @@ import kotlinx.android.synthetic.main.app_bar_chat_room.*
import
kotlinx.android.synthetic.main.fragment_members.*
import
javax.inject.Inject
fun
newInstance
(
chatRoomId
:
String
):
Fragment
{
return
MembersFragment
().
apply
{
fun
newInstance
(
chatRoomId
:
String
):
Fragment
=
MembersFragment
().
apply
{
arguments
=
Bundle
(
1
).
apply
{
putString
(
BUNDLE_CHAT_ROOM_ID
,
chatRoomId
)
}
}
}
internal
const
val
TAG_MEMBERS_FRAGMENT
=
"MembersFragment"
...
...
@@ -52,12 +50,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 +75,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 @
1f1391d7
...
...
@@ -25,12 +25,10 @@ import dagger.android.support.AndroidSupportInjection
import
kotlinx.android.synthetic.main.fragment_mentions.*
import
javax.inject.Inject
fun
newInstance
(
chatRoomId
:
String
):
Fragment
{
return
MentionsFragment
().
apply
{
fun
newInstance
(
chatRoomId
:
String
):
Fragment
=
MentionsFragment
().
apply
{
arguments
=
Bundle
(
1
).
apply
{
putString
(
BUNDLE_CHAT_ROOM_ID
,
chatRoomId
)
}
}
}
internal
const
val
TAG_MENTIONS_FRAGMENT
=
"MentionsFragment"
...
...
@@ -48,12 +46,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 @
1f1391d7
...
...
@@ -25,12 +25,10 @@ import dagger.android.support.AndroidSupportInjection
import
kotlinx.android.synthetic.main.fragment_pinned_messages.*
import
javax.inject.Inject
fun
newInstance
(
chatRoomId
:
String
):
Fragment
{
return
PinnedMessagesFragment
().
apply
{
fun
newInstance
(
chatRoomId
:
String
):
Fragment
=
PinnedMessagesFragment
().
apply
{
arguments
=
Bundle
(
1
).
apply
{
putString
(
BUNDLE_CHAT_ROOM_ID
,
chatRoomId
)
}
}
}
internal
const
val
TAG_PINNED_MESSAGES_FRAGMENT
=
"PinnedMessagesFragment"
...
...
@@ -48,12 +46,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 @
1f1391d7
...
...
@@ -94,11 +94,13 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
}
override
fun
onActivityResult
(
requestCode
:
Int
,
resultCode
:
Int
,
resultData
:
Intent
?)
{
if
(
resultData
!=
null
&&
resultCode
==
Activity
.
RESULT_OK
)
{
resultData
?.
run
{
if
(
resultCode
==
Activity
.
RESULT_OK
)
{
if
(
requestCode
==
REQUEST_CODE_FOR_PERFORM_SAF
)
{
presenter
.
updateAvatar
(
resultData
.
data
)
data
?.
let
{
presenter
.
updateAvatar
(
it
)
}
}
else
if
(
requestCode
==
REQUEST_CODE_FOR_PERFORM_CAMERA
)
{
presenter
.
preparePhotoAndUpdateAvatar
(
resultData
.
extras
[
"data"
]
as
Bitmap
)
extras
?.
get
(
"data"
)
?.
let
{
presenter
.
preparePhotoAndUpdateAvatar
(
it
as
Bitmap
)
}
}
}
}
}
...
...
@@ -203,8 +205,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
}
private
fun
setupToolbar
()
{
(
activity
as
AppCompatActivity
?)
?.
supportActionBar
?.
title
=
getString
(
R
.
string
.
title_profile
)
(
activity
as
AppCompatActivity
?)
?.
supportActionBar
?.
title
=
getString
(
R
.
string
.
title_profile
)
}
private
fun
setupListeners
()
{
...
...
app/src/main/java/chat/rocket/android/push/PushManager.kt
View file @
1f1391d7
...
...
@@ -12,13 +12,14 @@ import android.os.Build
import
android.os.Bundle
import
android.os.Parcel
import
android.os.Parcelable
import
android.text.Html
import
android.text.Spanned
import
androidx.annotation.RequiresApi
import
androidx.core.app.NotificationCompat
import
androidx.core.app.NotificationManagerCompat
import
androidx.core.app.RemoteInput
import
android.text.Html
import
android.text.Spanned
import
androidx.core.content.ContextCompat
import
androidx.core.text.HtmlCompat.FROM_HTML_MODE_LEGACY
import
chat.rocket.android.R
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.server.domain.GetAccountInteractor
...
...
@@ -303,7 +304,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
,
FROM_HTML_MODE_LEGACY
,
null
,
null
)
}
else
{
Html
.
fromHtml
(
this
as
String
)
}
}
// NotificationCompat.Builder extensions
...
...
@@ -383,12 +388,12 @@ data class PushMessage(
)
:
Parcelable
{
constructor
(
parcel
:
Parcel
)
:
this
(
parcel
.
readString
().
orEmpty
(),
parcel
.
readString
().
orEmpty
(),
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
().
orEmpty
(),
parcel
.
readString
(),
parcel
.
readString
())
...
...
@@ -433,9 +438,9 @@ data class PushInfo @KotshiConstructor constructor(
}
constructor
(
parcel
:
Parcel
)
:
this
(
parcel
.
readString
(),
parcel
.
readString
(),
roomTypeOf
(
parcel
.
readString
()),
parcel
.
readString
()
.
orEmpty
()
,
parcel
.
readString
()
.
orEmpty
()
,
roomTypeOf
(
parcel
.
readString
()
.
orEmpty
()
),
parcel
.
readString
(),
parcel
.
readParcelable
(
PushInfo
::
class
.
java
.
classLoader
))
...
...
@@ -481,7 +486,7 @@ data class PushSender @KotshiConstructor constructor(
val
name
:
String
?
)
:
Parcelable
{
constructor
(
parcel
:
Parcel
)
:
this
(
parcel
.
readString
(),
parcel
.
readString
()
.
orEmpty
()
,
parcel
.
readString
(),
parcel
.
readString
())
...
...
app/src/main/java/chat/rocket/android/server/infraestructure/ConnectionManager.kt
View file @
1f1391d7
...
...
@@ -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
->
{
...
...
@@ -135,9 +135,7 @@ class ConnectionManager(
if
(
it
.
type
==
Type
.
Updated
)
{
if
(
it
.
data
is
Room
)
{
val
room
=
it
.
data
as
Room
roomsChannels
[
it
.
data
.
id
]
?.
let
{
channel
->
channel
.
offer
(
room
)
}
roomsChannels
[
it
.
data
.
id
]
?.
offer
(
room
)
}
}
}
...
...
@@ -231,7 +229,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 @
1f1391d7
...
...
@@ -14,7 +14,6 @@ import chat.rocket.core.model.Message
import
chat.rocket.core.model.Reactions
import
chat.rocket.core.model.attachment.Attachment
import
chat.rocket.core.model.attachment.Color
import
chat.rocket.core.model.attachment.DEFAULT_COLOR_STR
import
chat.rocket.core.model.attachment.Field
import
chat.rocket.core.model.attachment.actions.Action
import
chat.rocket.core.model.attachment.actions.ButtonAction
...
...
@@ -153,7 +152,7 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
null
}
val
attachment
=
Attachment
(
list
.
add
(
Attachment
(
title
=
title
,
type
=
type
,
description
=
description
,
...
...
@@ -179,10 +178,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 @
1f1391d7
...
...
@@ -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 @
1f1391d7
...
...
@@ -14,13 +14,8 @@ class SharedPreferencesAccountsRepository(
private
val
moshi
:
Moshi
)
:
AccountsRepository
{
override
fun
save
(
newAccount
:
Account
)
{
val
accounts
=
load
()
val
newList
=
accounts
.
filter
{
account
->
newAccount
.
serverUrl
!=
account
.
serverUrl
}
.
toMutableList
()
newList
.
add
(
0
,
newAccount
)
save
(
newList
)
override
fun
save
(
account
:
Account
)
{
save
(
load
().
filter
{
item
->
item
.
serverUrl
!=
item
.
serverUrl
}.
toMutableList
().
apply
{
add
(
0
,
account
)
})
}
override
fun
load
():
List
<
Account
>
{
...
...
@@ -28,15 +23,11 @@ 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
json
?.
let
{
adapter
.
fromJson
(
it
)
?:
emptyList
()
}
?:
emptyList
()
}
override
fun
remove
(
serverUrl
:
String
)
{
val
accounts
=
load
()
val
newList
=
accounts
.
filter
{
account
->
serverUrl
!=
account
.
serverUrl
}
.
toMutableList
()
save
(
newList
)
save
(
load
().
filter
{
account
->
serverUrl
!=
account
.
serverUrl
}.
toMutableList
())
}
private
fun
save
(
accounts
:
List
<
Account
>)
{
...
...
app/src/main/java/chat/rocket/android/server/infraestructure/SharedPrefsBasicAuthRepository.kt
View file @
1f1391d7
...
...
@@ -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
{
auth
->
auth
.
host
!=
auth
.
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
json
?.
let
{
adapter
.
fromJson
(
it
)
?:
emptyList
()
}
?:
emptyList
()
}
private
fun
save
(
basicAuths
:
List
<
BasicAuth
>)
{
...
...
app/src/main/java/chat/rocket/android/settings/password/ui/PasswordFragment.kt
View file @
1f1391d7
...
...
@@ -106,8 +106,7 @@ class PasswordFragment : Fragment(), PasswordView, ActionMode.Callback {
private
fun
finishActionMode
()
=
actionMode
?.
finish
()
private
fun
listenToChanges
():
Disposable
{
return
Observables
.
combineLatest
(
private
fun
listenToChanges
():
Disposable
=
Observables
.
combineLatest
(
text_new_password
.
asObservable
(),
text_confirm_password
.
asObservable
()
).
subscribe
{
...
...
@@ -119,7 +118,6 @@ class PasswordFragment : Fragment(), PasswordView, ActionMode.Callback {
finishActionMode
()
}
}
}
private
fun
startActionMode
()
{
if
(
actionMode
==
null
)
{
...
...
app/src/main/java/chat/rocket/android/settings/ui/SettingsFragment.kt
View file @
1f1391d7
...
...
@@ -115,8 +115,7 @@ class SettingsFragment : Fragment(), SettingsView, AdapterView.OnItemClickListen
}
private
fun
setupToolbar
()
{
(
activity
as
AppCompatActivity
?)
?.
supportActionBar
?.
title
=
getString
(
R
.
string
.
title_settings
)
(
activity
as
AppCompatActivity
?)
?.
supportActionBar
?.
title
=
getString
(
R
.
string
.
title_settings
)
}
private
fun
shareApp
()
{
...
...
app/src/main/java/chat/rocket/android/userdetails/presentation/UserDetailsPresenter.kt
View file @
1f1391d7
...
...
@@ -40,7 +40,7 @@ class UserDetailsPresenter @Inject constructor(
dbManager
.
getUser
(
userId
)
?.
let
{
userEntity
=
it
val
avatarUrl
=
userEntity
.
username
?.
let
{
currentServer
.
avatarUrl
(
avatar
=
it
)
}
userEntity
.
username
?.
let
{
username
->
currentServer
.
avatarUrl
(
avatar
=
username
)
}
val
username
=
userEntity
.
username
val
name
=
userEntity
.
name
val
utcOffset
=
...
...
app/src/main/java/chat/rocket/android/userdetails/ui/UserDetailsFragment.kt
View file @
1f1391d7
...
...
@@ -29,12 +29,10 @@ import kotlinx.android.synthetic.main.app_bar_chat_room.*
import
kotlinx.android.synthetic.main.fragment_user_details.*
import
javax.inject.Inject
fun
newInstance
(
userId
:
String
):
Fragment
{
return
UserDetailsFragment
().
apply
{
fun
newInstance
(
userId
:
String
):
Fragment
=
UserDetailsFragment
().
apply
{
arguments
=
Bundle
(
1
).
apply
{
putString
(
BUNDLE_USER_ID
,
userId
)
}
}
}
internal
const
val
TAG_USER_DETAILS_FRAGMENT
=
"UserDetailsFragment"
...
...
@@ -52,12 +50,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 @
1f1391d7
...
...
@@ -191,7 +191,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 @
1f1391d7
...
...
@@ -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/util/extensions/Ui.kt
View file @
1f1391d7
...
...
@@ -80,12 +80,10 @@ fun AppCompatActivity.toPreviousView() {
}
fun
Activity
.
hideKeyboard
()
{
if
(
currentFocus
!=
null
)
{
val
imm
=
getSystemService
(
Context
.
INPUT_METHOD_SERVICE
)
as
InputMethodManager
imm
.
hideSoftInputFromWindow
(
currentFocus
.
windowToken
,
InputMethodManager
.
RESULT_UNCHANGED_SHOWN
)
currentFocus
?.
run
{
(
getSystemService
(
Context
.
INPUT_METHOD_SERVICE
)
as
InputMethodManager
).
also
{
it
.
hideSoftInputFromWindow
(
windowToken
,
InputMethodManager
.
RESULT_UNCHANGED_SHOWN
)
}
}
}
...
...
app/src/main/java/chat/rocket/android/util/extensions/Uri.kt
View file @
1f1391d7
...
...
@@ -51,7 +51,7 @@ fun Uri.getFileSize(context: Context): Int {
fun
Uri
.
getMimeType
(
context
:
Context
):
String
{
return
if
(
scheme
==
ContentResolver
.
SCHEME_CONTENT
)
{
context
.
contentResolver
.
getType
(
this
)
context
.
contentResolver
?.
getType
(
this
)
?:
""
}
else
{
val
fileExtension
=
MimeTypeMap
.
getFileExtensionFromUrl
(
toString
())
if
(
fileExtension
!=
null
)
{
...
...
app/src/main/java/chat/rocket/android/webview/adminpanel/ui/AdminPanelWebViewFragment.kt
View file @
1f1391d7
...
...
@@ -27,13 +27,10 @@ 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 +62,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 @
1f1391d7
...
...
@@ -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
...
...
@@ -39,10 +39,7 @@ class DividerItemDecoration() : RecyclerView.ItemDecoration() {
// Custom divider will be used.
constructor
(
context
:
Context
,
@DrawableRes
drawableResId
:
Int
)
:
this
()
{
val
customDrawable
=
ContextCompat
.
getDrawable
(
context
,
drawableResId
)
if
(
customDrawable
!=
null
)
{
divider
=
customDrawable
}
divider
=
ContextCompat
.
getDrawable
(
context
,
drawableResId
)
}
override
fun
onDraw
(
c
:
Canvas
,
parent
:
RecyclerView
,
state
:
RecyclerView
.
State
)
{
...
...
@@ -59,10 +56,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 @
1f1391d7
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