Commit 5320a635 authored by karthyks's avatar karthyks

refactor app module

remove unwanted imports
handle arguments using elvis operator in activities and fragments
get rid of redundant return keyword in a single block method
handle deprecated function calls
handle non null assertion operator with elvis operator
parent 1130fd04
...@@ -3,15 +3,10 @@ package chat.rocket.android.app ...@@ -3,15 +3,10 @@ package chat.rocket.android.app
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent import androidx.lifecycle.OnLifecycleEvent
import chat.rocket.android.server.domain.GetAccountInteractor
import chat.rocket.android.server.domain.GetCurrentServerInteractor import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory 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.common.model.UserStatus
import chat.rocket.core.internal.realtime.setTemporaryStatus
import kotlinx.coroutines.experimental.launch import kotlinx.coroutines.experimental.launch
import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
class AppLifecycleObserver @Inject constructor( class AppLifecycleObserver @Inject constructor(
......
import android.content.Context import android.content.Context
import chat.rocket.android.R 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.DateTimeFormatter
import org.threeten.bp.format.FormatStyle import org.threeten.bp.format.FormatStyle
import org.threeten.bp.format.TextStyle import org.threeten.bp.format.TextStyle
...@@ -53,39 +58,39 @@ object DateTimeHelper { ...@@ -53,39 +58,39 @@ object DateTimeHelper {
} }
} }
/** /**
* Returns a time from a [LocalDateTime]. * Returns a time from a [LocalDateTime].
* *
* @param localDateTime The [LocalDateTime]. * @param localDateTime The [LocalDateTime].
* @return The time from a [LocalDateTime]. * @return The time from a [LocalDateTime].
*/ */
fun getTime(localDateTime: LocalDateTime): String { fun getTime(localDateTime: LocalDateTime): String {
val formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT) val formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)
return localDateTime.toLocalTime().format(formatter).toString() return localDateTime.toLocalTime().format(formatter).toString()
} }
/** /**
* Returns a date time from a [LocalDateTime]. * Returns a date time from a [LocalDateTime].
* *
* @param localDateTime The [LocalDateTime]. * @param localDateTime The [LocalDateTime].
* @return The time from a [LocalDateTime]. * @return The time from a [LocalDateTime].
*/ */
fun getDateTime(localDateTime: LocalDateTime): String { fun getDateTime(localDateTime: LocalDateTime): String {
return formatLocalDateTime(localDateTime) return formatLocalDateTime(localDateTime)
} }
private fun formatLocalDateTime(localDateTime: LocalDateTime): String { private fun formatLocalDateTime(localDateTime: LocalDateTime): String {
val formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT) val formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)
return localDateTime.format(formatter).toString() return localDateTime.format(formatter).toString()
} }
private fun formatLocalDate(localDate: LocalDate): String { private fun formatLocalDate(localDate: LocalDate): String {
val formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM) val formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
return localDate.format(formatter).toString() return localDate.format(formatter).toString()
} }
private fun formatLocalTime(localTime: LocalTime): String { private fun formatLocalTime(localTime: LocalTime): String {
val formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT) val formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)
return localTime.format(formatter).toString() return localTime.format(formatter).toString()
} }
} }
\ No newline at end of file
...@@ -8,19 +8,16 @@ import chat.rocket.android.server.domain.MultiServerTokenRepository ...@@ -8,19 +8,16 @@ import chat.rocket.android.server.domain.MultiServerTokenRepository
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
@PerActivity @PerActivity
class SharedPreferencesMultiServerTokenRepository(private val repository: LocalRepository, class SharedPreferencesMultiServerTokenRepository(
private val moshi: Moshi private val repository: LocalRepository,
private val moshi: Moshi
) : MultiServerTokenRepository { ) : MultiServerTokenRepository {
override fun get(server: String): TokenModel? { override fun get(server: String): TokenModel? {
val token = repository.get("$TOKEN_KEY$server") val token = repository.get("$TOKEN_KEY$server")
val adapter = moshi.adapter<TokenModel>(TokenModel::class.java) val adapter = moshi.adapter<TokenModel>(TokenModel::class.java)
token?.let { return token?.let { adapter.fromJson(it) }
return adapter.fromJson(token)
}
return null
} }
override fun save(server: String, token: TokenModel) { override fun save(server: String, token: TokenModel) {
......
...@@ -39,11 +39,9 @@ internal const val REQUEST_CODE_FOR_SIGN_IN_REQUIRED = 1 ...@@ -39,11 +39,9 @@ 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_MULTIPLE_ACCOUNTS_RESOLUTION = 2
internal const val REQUEST_CODE_FOR_SAVE_RESOLUTION = 3 internal const val REQUEST_CODE_FOR_SAVE_RESOLUTION = 3
fun newInstance(serverName: String): Fragment { fun newInstance(serverName: String): Fragment = LoginFragment().apply {
return LoginFragment().apply { arguments = Bundle(1).apply {
arguments = Bundle(1).apply { putString(SERVER_NAME, serverName)
putString(SERVER_NAME, serverName)
}
} }
} }
...@@ -59,9 +57,8 @@ class LoginFragment : Fragment(), LoginView { ...@@ -59,9 +57,8 @@ class LoginFragment : Fragment(), LoginView {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
val bundle = arguments arguments?.run {
if (bundle != null) { serverName = getString(SERVER_NAME)
serverName = bundle.getString(SERVER_NAME)
} }
} }
...@@ -150,7 +147,7 @@ class LoginFragment : Fragment(), LoginView { ...@@ -150,7 +147,7 @@ class LoginFragment : Fragment(), LoginView {
override fun showGenericErrorMessage() = showMessage(R.string.msg_generic_error) override fun showGenericErrorMessage() = showMessage(R.string.msg_generic_error)
private fun setupOnClickListener() = private fun setupOnClickListener() =
ui { _ -> ui {
button_log_in.setOnClickListener { button_log_in.setOnClickListener {
presenter.authenticateWithUserAndPassword( presenter.authenticateWithUserAndPassword(
text_username_or_email.textContent, text_username_or_email.textContent,
...@@ -160,7 +157,7 @@ class LoginFragment : Fragment(), LoginView { ...@@ -160,7 +157,7 @@ class LoginFragment : Fragment(), LoginView {
} }
override fun showForgotPasswordView() { override fun showForgotPasswordView() {
ui { _ -> ui {
button_forgot_your_password.isVisible = true button_forgot_your_password.isVisible = true
button_forgot_your_password.setOnClickListener { presenter.forgotPassword() } button_forgot_your_password.setOnClickListener { presenter.forgotPassword() }
......
...@@ -88,36 +88,34 @@ fun newInstance( ...@@ -88,36 +88,34 @@ fun newInstance(
isLoginFormEnabled: Boolean, isLoginFormEnabled: Boolean,
isNewAccountCreationEnabled: Boolean, isNewAccountCreationEnabled: Boolean,
deepLinkInfo: LoginDeepLinkInfo? = null deepLinkInfo: LoginDeepLinkInfo? = null
): Fragment { ): Fragment = LoginOptionsFragment().apply {
return LoginOptionsFragment().apply { arguments = Bundle(23).apply {
arguments = Bundle(23).apply { putString(SERVER_NAME, serverName)
putString(SERVER_NAME, serverName) putString(STATE, state)
putString(STATE, state) putString(FACEBOOK_OAUTH_URL, facebookOauthUrl)
putString(FACEBOOK_OAUTH_URL, facebookOauthUrl) putString(GITHUB_OAUTH_URL, githubOauthUrl)
putString(GITHUB_OAUTH_URL, githubOauthUrl) putString(GOOGLE_OAUTH_URL, googleOauthUrl)
putString(GOOGLE_OAUTH_URL, googleOauthUrl) putString(LINKEDIN_OAUTH_URL, linkedinOauthUrl)
putString(LINKEDIN_OAUTH_URL, linkedinOauthUrl) putString(GITLAB_OAUTH_URL, gitlabOauthUrl)
putString(GITLAB_OAUTH_URL, gitlabOauthUrl) putString(WORDPRESS_OAUTH_URL, wordpressOauthUrl)
putString(WORDPRESS_OAUTH_URL, wordpressOauthUrl) putString(CAS_LOGIN_URL, casLoginUrl)
putString(CAS_LOGIN_URL, casLoginUrl) putString(CAS_TOKEN, casToken)
putString(CAS_TOKEN, casToken) putString(CAS_SERVICE_NAME, casServiceName)
putString(CAS_SERVICE_NAME, casServiceName) putInt(CAS_SERVICE_NAME_TEXT_COLOR, casServiceNameTextColor)
putInt(CAS_SERVICE_NAME_TEXT_COLOR, casServiceNameTextColor) putInt(CAS_SERVICE_BUTTON_COLOR, casServiceButtonColor)
putInt(CAS_SERVICE_BUTTON_COLOR, casServiceButtonColor) putString(CUSTOM_OAUTH_URL, customOauthUrl)
putString(CUSTOM_OAUTH_URL, customOauthUrl) putString(CUSTOM_OAUTH_SERVICE_NAME, customOauthServiceName)
putString(CUSTOM_OAUTH_SERVICE_NAME, customOauthServiceName) putInt(CUSTOM_OAUTH_SERVICE_NAME_TEXT_COLOR, customOauthServiceNameTextColor)
putInt(CUSTOM_OAUTH_SERVICE_NAME_TEXT_COLOR, customOauthServiceNameTextColor) putInt(CUSTOM_OAUTH_SERVICE_BUTTON_COLOR, customOauthServiceButtonColor)
putInt(CUSTOM_OAUTH_SERVICE_BUTTON_COLOR, customOauthServiceButtonColor) putString(SAML_URL, samlUrl)
putString(SAML_URL, samlUrl) putString(SAML_TOKEN, samlToken)
putString(SAML_TOKEN, samlToken) putString(SAML_SERVICE_NAME, samlServiceName)
putString(SAML_SERVICE_NAME, samlServiceName) putInt(SAML_SERVICE_NAME_TEXT_COLOR, samlServiceNameTextColor)
putInt(SAML_SERVICE_NAME_TEXT_COLOR, samlServiceNameTextColor) putInt(SAML_SERVICE_BUTTON_COLOR, samlServiceButtonColor)
putInt(SAML_SERVICE_BUTTON_COLOR, samlServiceButtonColor) putInt(TOTAL_SOCIAL_ACCOUNTS, totalSocialAccountsEnabled)
putInt(TOTAL_SOCIAL_ACCOUNTS, totalSocialAccountsEnabled) putBoolean(IS_LOGIN_FORM_ENABLED, isLoginFormEnabled)
putBoolean(IS_LOGIN_FORM_ENABLED, isLoginFormEnabled) putBoolean(IS_NEW_ACCOUNT_CREATION_ENABLED, isNewAccountCreationEnabled)
putBoolean(IS_NEW_ACCOUNT_CREATION_ENABLED, isNewAccountCreationEnabled) putParcelable(DEEP_LINK_INFO, deepLinkInfo)
putParcelable(DEEP_LINK_INFO, deepLinkInfo)
}
} }
} }
...@@ -157,34 +155,33 @@ class LoginOptionsFragment : Fragment(), LoginOptionsView { ...@@ -157,34 +155,33 @@ class LoginOptionsFragment : Fragment(), LoginOptionsView {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
val bundle = arguments arguments?.run {
if (bundle != null) { serverName = getString(SERVER_NAME)
serverName = bundle.getString(SERVER_NAME) state = getString(STATE)
state = bundle.getString(STATE) facebookOauthUrl = getString(FACEBOOK_OAUTH_URL)
facebookOauthUrl = bundle.getString(FACEBOOK_OAUTH_URL) githubOauthUrl = getString(GITHUB_OAUTH_URL)
githubOauthUrl = bundle.getString(GITHUB_OAUTH_URL) googleOauthUrl = getString(GOOGLE_OAUTH_URL)
googleOauthUrl = bundle.getString(GOOGLE_OAUTH_URL) linkedinOauthUrl = getString(LINKEDIN_OAUTH_URL)
linkedinOauthUrl = bundle.getString(LINKEDIN_OAUTH_URL) gitlabOauthUrl = getString(GITLAB_OAUTH_URL)
gitlabOauthUrl = bundle.getString(GITLAB_OAUTH_URL) wordpressOauthUrl = getString(WORDPRESS_OAUTH_URL)
wordpressOauthUrl = bundle.getString(WORDPRESS_OAUTH_URL) casLoginUrl = getString(CAS_LOGIN_URL)
casLoginUrl = bundle.getString(CAS_LOGIN_URL) casToken = getString(CAS_TOKEN)
casToken = bundle.getString(CAS_TOKEN) casServiceName = getString(CAS_SERVICE_NAME)
casServiceName = bundle.getString(CAS_SERVICE_NAME) casServiceNameTextColor = getInt(CAS_SERVICE_NAME_TEXT_COLOR)
casServiceNameTextColor = bundle.getInt(CAS_SERVICE_NAME_TEXT_COLOR) casServiceButtonColor = getInt(CAS_SERVICE_BUTTON_COLOR)
casServiceButtonColor = bundle.getInt(CAS_SERVICE_BUTTON_COLOR) customOauthUrl = getString(CUSTOM_OAUTH_URL)
customOauthUrl = bundle.getString(CUSTOM_OAUTH_URL) customOauthServiceName = getString(CUSTOM_OAUTH_SERVICE_NAME)
customOauthServiceName = bundle.getString(CUSTOM_OAUTH_SERVICE_NAME) customOauthServiceTextColor = getInt(CUSTOM_OAUTH_SERVICE_NAME_TEXT_COLOR)
customOauthServiceTextColor = bundle.getInt(CUSTOM_OAUTH_SERVICE_NAME_TEXT_COLOR) customOauthServiceButtonColor = getInt(CUSTOM_OAUTH_SERVICE_BUTTON_COLOR)
customOauthServiceButtonColor = bundle.getInt(CUSTOM_OAUTH_SERVICE_BUTTON_COLOR) samlUrl = getString(SAML_URL)
samlUrl = bundle.getString(SAML_URL) samlToken = getString(SAML_TOKEN)
samlToken = bundle.getString(SAML_TOKEN) samlServiceName = getString(SAML_SERVICE_NAME)
samlServiceName = bundle.getString(SAML_SERVICE_NAME) samlServiceTextColor = getInt(SAML_SERVICE_NAME_TEXT_COLOR)
samlServiceTextColor = bundle.getInt(SAML_SERVICE_NAME_TEXT_COLOR) samlServiceButtonColor = getInt(SAML_SERVICE_BUTTON_COLOR)
samlServiceButtonColor = bundle.getInt(SAML_SERVICE_BUTTON_COLOR) totalSocialAccountsEnabled = getInt(TOTAL_SOCIAL_ACCOUNTS)
totalSocialAccountsEnabled = bundle.getInt(TOTAL_SOCIAL_ACCOUNTS) isLoginFormEnabled = getBoolean(IS_LOGIN_FORM_ENABLED)
isLoginFormEnabled = bundle.getBoolean(IS_LOGIN_FORM_ENABLED) isNewAccountCreationEnabled = getBoolean(IS_NEW_ACCOUNT_CREATION_ENABLED)
isNewAccountCreationEnabled = bundle.getBoolean(IS_NEW_ACCOUNT_CREATION_ENABLED) deepLinkInfo = getParcelable(DEEP_LINK_INFO)
deepLinkInfo = bundle.getParcelable(DEEP_LINK_INFO)
} }
} }
...@@ -388,7 +385,7 @@ class LoginOptionsFragment : Fragment(), LoginOptionsView { ...@@ -388,7 +385,7 @@ class LoginOptionsFragment : Fragment(), LoginOptionsView {
} }
override fun setupExpandAccountsView() { override fun setupExpandAccountsView() {
ui { _ -> ui {
expand_more_accounts_container.isVisible = true expand_more_accounts_container.isVisible = true
var isAccountsCollapsed = true var isAccountsCollapsed = true
button_expand_collapse_accounts.setOnClickListener { button_expand_collapse_accounts.setOnClickListener {
...@@ -406,14 +403,14 @@ class LoginOptionsFragment : Fragment(), LoginOptionsView { ...@@ -406,14 +403,14 @@ class LoginOptionsFragment : Fragment(), LoginOptionsView {
} }
override fun showLoginWithEmailButton() { override fun showLoginWithEmailButton() {
ui { _ -> ui {
button_login_with_email.setOnClickListener { presenter.toLoginWithEmail() } button_login_with_email.setOnClickListener { presenter.toLoginWithEmail() }
button_login_with_email.isVisible = true button_login_with_email.isVisible = true
} }
} }
override fun showCreateNewAccountButton() { override fun showCreateNewAccountButton() {
ui { _ -> ui {
button_create_an_account.setOnClickListener { presenter.toCreateAccount() } button_create_an_account.setOnClickListener { presenter.toCreateAccount() }
button_create_an_account.isVisible = true button_create_an_account.isVisible = true
} }
......
...@@ -31,12 +31,10 @@ import javax.inject.Inject ...@@ -31,12 +31,10 @@ import javax.inject.Inject
private const val BUNDLE_USER_ID = "user_id" private const val BUNDLE_USER_ID = "user_id"
private const val BUNDLE_AUTH_TOKEN = "auth_token" private const val BUNDLE_AUTH_TOKEN = "auth_token"
fun newInstance(userId: String, authToken: String): Fragment { fun newInstance(userId: String, authToken: String): Fragment = RegisterUsernameFragment().apply {
return RegisterUsernameFragment().apply { arguments = Bundle(2).apply {
arguments = Bundle(2).apply { putString(BUNDLE_USER_ID, userId)
putString(BUNDLE_USER_ID, userId) putString(BUNDLE_AUTH_TOKEN, authToken)
putString(BUNDLE_AUTH_TOKEN, authToken)
}
} }
} }
...@@ -53,13 +51,10 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView { ...@@ -53,13 +51,10 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
val bundle = arguments arguments?.run {
if (bundle != null) { userId = getString(BUNDLE_USER_ID, "")
userId = bundle.getString(BUNDLE_USER_ID) authToken = getString(BUNDLE_AUTH_TOKEN, "")
authToken = bundle.getString(BUNDLE_AUTH_TOKEN) } ?: requireNotNull(arguments) { "no arguments supplied when the fragment was instantiated" }
} else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
}
} }
override fun onCreateView( override fun onCreateView(
......
...@@ -75,7 +75,7 @@ class SignupFragment : Fragment(), SignupView { ...@@ -75,7 +75,7 @@ class SignupFragment : Fragment(), SignupView {
} }
private fun setupOnClickListener() = private fun setupOnClickListener() =
ui { _ -> ui {
button_register.setOnClickListener { button_register.setOnClickListener {
presenter.signup( presenter.signup(
text_username.textContent, text_username.textContent,
......
...@@ -25,12 +25,10 @@ import io.reactivex.disposables.Disposable ...@@ -25,12 +25,10 @@ import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.fragment_authentication_two_fa.* import kotlinx.android.synthetic.main.fragment_authentication_two_fa.*
import javax.inject.Inject import javax.inject.Inject
fun newInstance(username: String, password: String): Fragment { fun newInstance(username: String, password: String): Fragment = TwoFAFragment().apply {
return TwoFAFragment().apply { arguments = Bundle(2).apply {
arguments = Bundle(2).apply { putString(BUNDLE_USERNAME, username)
putString(BUNDLE_USERNAME, username) putString(BUNDLE_PASSWORD, password)
putString(BUNDLE_PASSWORD, password)
}
} }
} }
...@@ -50,13 +48,10 @@ class TwoFAFragment : Fragment(), TwoFAView { ...@@ -50,13 +48,10 @@ class TwoFAFragment : Fragment(), TwoFAView {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
val bundle = arguments arguments?.run {
if (bundle != null) { username = getString(BUNDLE_USERNAME, "")
username = bundle.getString(BUNDLE_USERNAME) password = getString(BUNDLE_PASSWORD, "")
password = bundle.getString(BUNDLE_PASSWORD) } ?: requireNotNull(arguments) { "no arguments supplied when the fragment was instantiated" }
} else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
}
} }
override fun onCreateView( override fun onCreateView(
......
package chat.rocket.android.chatdetails.adapter package chat.rocket.android.chatdetails.adapter
import android.content.Context import DrawableHelper
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
......
...@@ -11,9 +11,15 @@ import chat.rocket.android.util.extensions.inflate ...@@ -11,9 +11,15 @@ import chat.rocket.android.util.extensions.inflate
class ChatDetailsAdapter: RecyclerView.Adapter<OptionViewHolder>() { class ChatDetailsAdapter: RecyclerView.Adapter<OptionViewHolder>() {
private val options: MutableList<Option> = ArrayList() 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 override fun getItemCount(): Int = options.size
......
...@@ -32,14 +32,12 @@ fun newInstance( ...@@ -32,14 +32,12 @@ fun newInstance(
chatRoomType: String, chatRoomType: String,
isSubscribed: Boolean, isSubscribed: Boolean,
disableMenu: Boolean disableMenu: Boolean
): ChatDetailsFragment { ): ChatDetailsFragment = ChatDetailsFragment().apply {
return ChatDetailsFragment().apply { arguments = Bundle(4).apply {
arguments = Bundle(4).apply { putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
putString(BUNDLE_CHAT_ROOM_ID, chatRoomId) putString(BUNDLE_CHAT_ROOM_TYPE, chatRoomType)
putString(BUNDLE_CHAT_ROOM_TYPE, chatRoomType) putBoolean(BUNDLE_IS_SUBSCRIBED, isSubscribed)
putBoolean(BUNDLE_IS_SUBSCRIBED, isSubscribed) putBoolean(BUNDLE_DISABLE_MENU, disableMenu)
putBoolean(BUNDLE_DISABLE_MENU, disableMenu)
}
} }
} }
...@@ -66,15 +64,13 @@ class ChatDetailsFragment : Fragment(), ChatDetailsView { ...@@ -66,15 +64,13 @@ class ChatDetailsFragment : Fragment(), ChatDetailsView {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
val bundle = arguments
if (bundle != null) { arguments?.run {
chatRoomId = bundle.getString(BUNDLE_CHAT_ROOM_ID) chatRoomId = getString(BUNDLE_CHAT_ROOM_ID)
chatRoomType = bundle.getString(BUNDLE_CHAT_ROOM_TYPE) chatRoomType = getString(BUNDLE_CHAT_ROOM_TYPE)
isSubscribed = bundle.getBoolean(BUNDLE_IS_SUBSCRIBED) isSubscribed = getBoolean(BUNDLE_IS_SUBSCRIBED)
disableMenu = bundle.getBoolean(BUNDLE_DISABLE_MENU) disableMenu = getBoolean(BUNDLE_DISABLE_MENU)
} else { } ?: requireNotNull(arguments) { "no arguments supplied when the fragment was instantiated" }
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
}
} }
override fun onCreateView( override fun onCreateView(
......
...@@ -5,9 +5,10 @@ import androidx.lifecycle.ViewModelProvider ...@@ -5,9 +5,10 @@ import androidx.lifecycle.ViewModelProvider
import chat.rocket.android.db.ChatRoomDao import chat.rocket.android.db.ChatRoomDao
import javax.inject.Inject 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") @Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(modelClass: Class<T>) = override fun <T : ViewModel?> create(modelClass: Class<T>) = ChatDetailsViewModel(chatRoomDao) as T
ChatDetailsViewModel(chatRoomDao) as T
} }
\ No newline at end of file
...@@ -12,7 +12,10 @@ import com.facebook.drawee.backends.pipeline.Fresco ...@@ -12,7 +12,10 @@ import com.facebook.drawee.backends.pipeline.Fresco
import kotlinx.android.synthetic.main.item_action_button.view.* import kotlinx.android.synthetic.main.item_action_button.view.*
import timber.log.Timber 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 var actions: List<Action> = actions
...@@ -62,9 +65,7 @@ class ActionsListAdapter(actions: List<Action>, var actionAttachmentOnClickListe ...@@ -62,9 +65,7 @@ class ActionsListAdapter(actions: List<Action>, var actionAttachmentOnClickListe
return ViewHolder(view) return ViewHolder(view)
} }
override fun getItemCount(): Int { override fun getItemCount(): Int = actions.size
return actions.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val action = actions[position] val action = actions[position]
......
...@@ -76,13 +76,9 @@ class ChatRoomAdapter( ...@@ -76,13 +76,9 @@ class ChatRoomAdapter(
} }
} }
override fun getItemViewType(position: Int): Int { override fun getItemViewType(position: Int): Int = dataSet[position].viewType
return dataSet[position].viewType
}
override fun getItemCount(): Int { override fun getItemCount(): Int = dataSet.size
return dataSet.size
}
override fun onBindViewHolder(holder: BaseViewHolder<*>, position: Int) { override fun onBindViewHolder(holder: BaseViewHolder<*>, position: Int) {
if (holder !is MessageViewHolder) { if (holder !is MessageViewHolder) {
...@@ -174,12 +170,12 @@ class ChatRoomAdapter( ...@@ -174,12 +170,12 @@ class ChatRoomAdapter(
Timber.d("index: $index") Timber.d("index: $index")
if (index > -1) { if (index > -1) {
dataSet[index] = message dataSet[index] = message
dataSet.forEachIndexed { index, viewModel -> dataSet.forEachIndexed { ind, viewModel ->
if (viewModel.messageId == message.messageId) { if (viewModel.messageId == message.messageId) {
if (viewModel.nextDownStreamMessage == null) { if (viewModel.nextDownStreamMessage == null) {
viewModel.reactions = message.reactions viewModel.reactions = message.reactions
} }
notifyItemChanged(index) notifyItemChanged(ind)
} }
} }
// Delete message only if current is a system message update, i.e.: Message Removed // Delete message only if current is a system message update, i.e.: Message Removed
...@@ -258,10 +254,10 @@ class ChatRoomAdapter( ...@@ -258,10 +254,10 @@ class ChatRoomAdapter(
actionSelectListener?.editMessage(roomId, id, message.message) actionSelectListener?.editMessage(roomId, id, message.message)
} }
R.id.action_message_star -> { R.id.action_message_star -> {
actionSelectListener?.toogleStar(id, !item.isChecked) actionSelectListener?.toggleStar(id, !item.isChecked)
} }
R.id.action_message_unpin -> { R.id.action_message_unpin -> {
actionSelectListener?.tooglePin(id, !item.isChecked) actionSelectListener?.togglePin(id, !item.isChecked)
} }
R.id.action_message_delete -> { R.id.action_message_delete -> {
actionSelectListener?.deleteMessage(roomId, id) actionSelectListener?.deleteMessage(roomId, id)
...@@ -298,9 +294,9 @@ class ChatRoomAdapter( ...@@ -298,9 +294,9 @@ class ChatRoomAdapter(
fun editMessage(roomId: String, messageId: String, text: String) fun editMessage(roomId: String, messageId: String, text: String)
fun toogleStar(id: String, star: Boolean) fun toggleStar(id: String, star: Boolean)
fun tooglePin(id: String, pin: Boolean) fun togglePin(id: String, pin: Boolean)
fun deleteMessage(roomId: String, id: String) fun deleteMessage(roomId: String, id: String)
......
...@@ -24,8 +24,8 @@ class RoomSuggestionsAdapter : SuggestionsAdapter<RoomSuggestionsViewHolder>("#" ...@@ -24,8 +24,8 @@ class RoomSuggestionsAdapter : SuggestionsAdapter<RoomSuggestionsViewHolder>("#"
override fun bind(item: SuggestionModel, itemClickListener: SuggestionsAdapter.ItemClickListener?) { override fun bind(item: SuggestionModel, itemClickListener: SuggestionsAdapter.ItemClickListener?) {
item as ChatRoomSuggestionUiModel item as ChatRoomSuggestionUiModel
with(itemView) { with(itemView) {
val fullname = itemView.findViewById<TextView>(R.id.text_fullname) val fullname = findViewById<TextView>(R.id.text_fullname)
val name = itemView.findViewById<TextView>(R.id.text_name) val name = findViewById<TextView>(R.id.text_name)
name.text = item.name name.text = item.name
fullname.text = item.fullName fullname.text = item.fullName
setOnClickListener { setOnClickListener {
......
...@@ -8,15 +8,14 @@ import chat.rocket.android.util.extensions.content ...@@ -8,15 +8,14 @@ import chat.rocket.android.util.extensions.content
import chat.rocket.android.util.extensions.openTabbedUrl import chat.rocket.android.util.extensions.openTabbedUrl
import kotlinx.android.synthetic.main.message_url_preview.view.* import kotlinx.android.synthetic.main.message_url_preview.view.*
class UrlPreviewViewHolder(itemView: View, class UrlPreviewViewHolder(
listener: ActionsListener, itemView: View,
reactionListener: EmojiReactionListener? = null) listener: ActionsListener,
: BaseViewHolder<UrlPreviewUiModel>(itemView, listener, reactionListener) { reactionListener: EmojiReactionListener? = null
) : BaseViewHolder<UrlPreviewUiModel>(itemView, listener, reactionListener) {
init { init {
with(itemView) { setupActionMenu(itemView.url_preview_layout)
setupActionMenu(url_preview_layout)
}
} }
override fun bindViews(data: UrlPreviewUiModel) { override fun bindViews(data: UrlPreviewUiModel) {
......
...@@ -182,8 +182,8 @@ class ChatRoomPresenter @Inject constructor( ...@@ -182,8 +182,8 @@ class ChatRoomPresenter @Inject constructor(
chatRoomId?.let { chatRoomId?.let {
manager.addRoomChannel(it, roomChangesChannel) manager.addRoomChannel(it, roomChangesChannel)
for (room in roomChangesChannel) { for (room in roomChangesChannel) {
dbManager.getRoom(room.id)?.let { dbManager.getRoom(room.id)?.let { chatRoom ->
view.onRoomUpdated(roomMapper.map(chatRoom = it, showLastMessage = true)) view.onRoomUpdated(roomMapper.map(chatRoom = chatRoom, showLastMessage = true))
} }
} }
} }
...@@ -1074,7 +1074,7 @@ class ChatRoomPresenter @Inject constructor( ...@@ -1074,7 +1074,7 @@ class ChatRoomPresenter @Inject constructor(
launchUI(strategy) { launchUI(strategy) {
try { try {
messagesRepository.getById(messageId)?.let { message -> messagesRepository.getById(messageId)?.let { message ->
getChatRoomAsync(message.roomId)?.let { chatRoom -> getChatRoomAsync(message.roomId)?.let {
val models = mapper.map(message) val models = mapper.map(message)
models.firstOrNull()?.permalink?.let { models.firstOrNull()?.permalink?.let {
view.copyToClipboard(it) view.copyToClipboard(it)
......
...@@ -31,18 +31,16 @@ fun Context.chatRoomIntent( ...@@ -31,18 +31,16 @@ fun Context.chatRoomIntent(
isCreator: Boolean = false, isCreator: Boolean = false,
isFavorite: Boolean = false, isFavorite: Boolean = false,
chatRoomMessage: String? = null chatRoomMessage: String? = null
): Intent { ): Intent = Intent(this, ChatRoomActivity::class.java).apply {
return Intent(this, ChatRoomActivity::class.java).apply { putExtra(INTENT_CHAT_ROOM_ID, chatRoomId)
putExtra(INTENT_CHAT_ROOM_ID, chatRoomId) putExtra(INTENT_CHAT_ROOM_NAME, chatRoomName)
putExtra(INTENT_CHAT_ROOM_NAME, chatRoomName) putExtra(INTENT_CHAT_ROOM_TYPE, chatRoomType)
putExtra(INTENT_CHAT_ROOM_TYPE, chatRoomType) putExtra(INTENT_CHAT_ROOM_IS_READ_ONLY, isReadOnly)
putExtra(INTENT_CHAT_ROOM_IS_READ_ONLY, isReadOnly) putExtra(INTENT_CHAT_ROOM_LAST_SEEN, chatRoomLastSeen)
putExtra(INTENT_CHAT_ROOM_LAST_SEEN, chatRoomLastSeen) putExtra(INTENT_CHAT_IS_SUBSCRIBED, isSubscribed)
putExtra(INTENT_CHAT_IS_SUBSCRIBED, isSubscribed) putExtra(INTENT_CHAT_ROOM_IS_CREATOR, isCreator)
putExtra(INTENT_CHAT_ROOM_IS_CREATOR, isCreator) putExtra(INTENT_CHAT_ROOM_IS_FAVORITE, isFavorite)
putExtra(INTENT_CHAT_ROOM_IS_FAVORITE, isFavorite) putExtra(INTENT_CHAT_ROOM_MESSAGE, chatRoomMessage)
putExtra(INTENT_CHAT_ROOM_MESSAGE, chatRoomMessage)
}
} }
private const val INTENT_CHAT_ROOM_ID = "chat_room_id" private const val INTENT_CHAT_ROOM_ID = "chat_room_id"
...@@ -81,42 +79,44 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -81,42 +79,44 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
return return
} }
val chatRoomId = intent.getStringExtra(INTENT_CHAT_ROOM_ID) with(intent) {
requireNotNull(chatRoomId) { "no chat_room_id provided in Intent extras" } 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" } 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" } 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() setupToolbar()
if (supportFragmentManager.findFragmentByTag(TAG_CHAT_ROOM_FRAGMENT) == null) { if (supportFragmentManager.findFragmentByTag(TAG_CHAT_ROOM_FRAGMENT) == null) {
addFragment(TAG_CHAT_ROOM_FRAGMENT, R.id.fragment_container) { addFragment(TAG_CHAT_ROOM_FRAGMENT, R.id.fragment_container) {
newInstance( newInstance(
chatRoomId, chatRoomId,
chatRoomName, chatRoomName,
chatRoomType, chatRoomType,
isReadOnly, isReadOnly,
chatRoomLastSeen, chatRoomLastSeen,
isSubscribed, isSubscribed,
isCreator, isCreator,
isFavorite, isFavorite,
chatRoomMessage chatRoomMessage
) )
}
} }
} }
} }
......
...@@ -111,19 +111,17 @@ fun newInstance( ...@@ -111,19 +111,17 @@ fun newInstance(
isCreator: Boolean = false, isCreator: Boolean = false,
isFavorite: Boolean = false, isFavorite: Boolean = false,
chatRoomMessage: String? = null chatRoomMessage: String? = null
): Fragment { ): Fragment = ChatRoomFragment().apply {
return ChatRoomFragment().apply { arguments = Bundle(1).apply {
arguments = Bundle(1).apply { putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
putString(BUNDLE_CHAT_ROOM_ID, chatRoomId) putString(BUNDLE_CHAT_ROOM_NAME, chatRoomName)
putString(BUNDLE_CHAT_ROOM_NAME, chatRoomName) putString(BUNDLE_CHAT_ROOM_TYPE, chatRoomType)
putString(BUNDLE_CHAT_ROOM_TYPE, chatRoomType) putBoolean(BUNDLE_IS_CHAT_ROOM_READ_ONLY, isReadOnly)
putBoolean(BUNDLE_IS_CHAT_ROOM_READ_ONLY, isReadOnly) putLong(BUNDLE_CHAT_ROOM_LAST_SEEN, chatRoomLastSeen)
putLong(BUNDLE_CHAT_ROOM_LAST_SEEN, chatRoomLastSeen) putBoolean(BUNDLE_CHAT_ROOM_IS_SUBSCRIBED, isSubscribed)
putBoolean(BUNDLE_CHAT_ROOM_IS_SUBSCRIBED, isSubscribed) putBoolean(BUNDLE_CHAT_ROOM_IS_CREATOR, isCreator)
putBoolean(BUNDLE_CHAT_ROOM_IS_CREATOR, isCreator) putBoolean(BUNDLE_CHAT_ROOM_IS_FAVORITE, isFavorite)
putBoolean(BUNDLE_CHAT_ROOM_IS_FAVORITE, isFavorite) putString(BUNDLE_CHAT_ROOM_MESSAGE, chatRoomMessage)
putString(BUNDLE_CHAT_ROOM_MESSAGE, chatRoomMessage)
}
} }
} }
...@@ -272,20 +270,17 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -272,20 +270,17 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
setHasOptionsMenu(true) setHasOptionsMenu(true)
val bundle = arguments arguments?.run {
if (bundle != null) { chatRoomId = getString(BUNDLE_CHAT_ROOM_ID, "")
chatRoomId = bundle.getString(BUNDLE_CHAT_ROOM_ID) chatRoomName = getString(BUNDLE_CHAT_ROOM_NAME, "")
chatRoomName = bundle.getString(BUNDLE_CHAT_ROOM_NAME) chatRoomType = getString(BUNDLE_CHAT_ROOM_TYPE, "")
chatRoomType = bundle.getString(BUNDLE_CHAT_ROOM_TYPE) isReadOnly = getBoolean(BUNDLE_IS_CHAT_ROOM_READ_ONLY)
isReadOnly = bundle.getBoolean(BUNDLE_IS_CHAT_ROOM_READ_ONLY) isSubscribed = getBoolean(BUNDLE_CHAT_ROOM_IS_SUBSCRIBED)
isSubscribed = bundle.getBoolean(BUNDLE_CHAT_ROOM_IS_SUBSCRIBED) chatRoomLastSeen = getLong(BUNDLE_CHAT_ROOM_LAST_SEEN)
chatRoomLastSeen = bundle.getLong(BUNDLE_CHAT_ROOM_LAST_SEEN) isCreator = getBoolean(BUNDLE_CHAT_ROOM_IS_CREATOR)
isCreator = bundle.getBoolean(BUNDLE_CHAT_ROOM_IS_CREATOR) isFavorite = getBoolean(BUNDLE_CHAT_ROOM_IS_FAVORITE)
isFavorite = bundle.getBoolean(BUNDLE_CHAT_ROOM_IS_FAVORITE) chatRoomMessage = getString(BUNDLE_CHAT_ROOM_MESSAGE)
chatRoomMessage = bundle.getString(BUNDLE_CHAT_ROOM_MESSAGE) } ?: requireNotNull(arguments) { "no arguments supplied when the fragment was instantiated" }
} else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
}
adapter = ChatRoomAdapter(chatRoomId, chatRoomType, chatRoomName, this, reactionListener = this, navigator = navigator) adapter = ChatRoomAdapter(chatRoomId, chatRoomType, chatRoomName, this, reactionListener = this, navigator = navigator)
} }
...@@ -758,21 +753,20 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -758,21 +753,20 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
ui { ui {
text_connection_status.fadeIn() text_connection_status.fadeIn()
handler.removeCallbacks(dismissStatus) handler.removeCallbacks(dismissStatus)
when (state) { text_connection_status.text = when (state) {
is State.Connected -> { is State.Connected -> {
text_connection_status.text = getString(R.string.status_connected)
handler.postDelayed(dismissStatus, 2000) 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 ...@@ -1098,7 +1092,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
presenter.editMessage(roomId, messageId, text) presenter.editMessage(roomId, messageId, text)
} }
override fun toogleStar(id: String, star: Boolean) { override fun toggleStar(id: String, star: Boolean) {
if (star) { if (star) {
presenter.starMessage(id) presenter.starMessage(id)
} else { } else {
...@@ -1106,7 +1100,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -1106,7 +1100,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
} }
override fun tooglePin(id: String, pin: Boolean) { override fun togglePin(id: String, pin: Boolean) {
if (pin) { if (pin) {
presenter.pinMessage(id) presenter.pinMessage(id)
} else { } else {
......
...@@ -416,21 +416,19 @@ class UiModelMapper @Inject constructor( ...@@ -416,21 +416,19 @@ class UiModelMapper @Inject constructor(
return fullUrl return fullUrl
} }
private fun attachmentText(text: String?, attachment: Attachment?, context: Context): String? { private fun attachmentText(text: String?, attachment: Attachment?, context: Context): String? = attachment?.run {
return if (attachment != null) { with(context) {
when { when {
attachment.imageUrl.isNotNullNorEmpty() -> context.getString(R.string.msg_preview_photo) imageUrl.isNotNullNorEmpty() -> getString(R.string.msg_preview_photo)
attachment.videoUrl.isNotNullNorEmpty() -> context.getString(R.string.msg_preview_video) videoUrl.isNotNullNorEmpty() -> getString(R.string.msg_preview_video)
attachment.audioUrl.isNotNullNorEmpty() -> context.getString(R.string.msg_preview_audio) audioUrl.isNotNullNorEmpty() -> getString(R.string.msg_preview_audio)
attachment.titleLink.isNotNullNorEmpty() && titleLink.isNotNullNorEmpty() &&
attachment.type?.contentEquals("file") == true -> type?.contentEquals("file") == true ->
context.getString(R.string.msg_preview_file) getString(R.string.msg_preview_file)
else -> text else -> text
} }
} else {
text
} }
} } ?: text
private fun attachmentDescription(attachment: Attachment): String? { private fun attachmentDescription(attachment: Attachment): String? {
return attachment.description return attachment.description
...@@ -464,11 +462,9 @@ class UiModelMapper @Inject constructor( ...@@ -464,11 +462,9 @@ class UiModelMapper @Inject constructor(
subscriptionId = chatRoom.subscriptionId) subscriptionId = chatRoom.subscriptionId)
} }
private fun mapMessagePreview(message: Message): Message { private fun mapMessagePreview(message: Message): Message = when (message.isSystemMessage()) {
return when (message.isSystemMessage()) { false -> stripMessageQuotes(message)
false -> stripMessageQuotes(message) true -> message.copy(message = getSystemMessage(message).toString())
true -> message.copy(message = getSystemMessage(message).toString())
}
} }
private fun getReactions(message: Message): List<ReactionUiModel> { private fun getReactions(message: Message): List<ReactionUiModel> {
...@@ -535,37 +531,33 @@ class UiModelMapper @Inject constructor( ...@@ -535,37 +531,33 @@ class UiModelMapper @Inject constructor(
private fun getTime(timestamp: Long) = DateTimeHelper.getTime(DateTimeHelper.getLocalDateTime(timestamp)) private fun getTime(timestamp: Long) = DateTimeHelper.getTime(DateTimeHelper.getLocalDateTime(timestamp))
private fun getContent(message: Message): CharSequence { private fun getContent(message: Message): CharSequence = when (message.isSystemMessage()) {
return when (message.isSystemMessage()) { true -> getSystemMessage(message)
true -> getSystemMessage(message) false -> parser.render(message, currentUsername)
false -> parser.render(message, currentUsername)
}
} }
private fun getSystemMessage(message: Message): CharSequence { private fun getSystemMessage(message: Message): CharSequence {
val content = when (message.type) { val content = with(context) {
//TODO: Add implementation for Welcome type. when (message.type) {
is MessageType.MessageRemoved -> context.getString(R.string.message_removed) //TODO: Add implementation for Welcome type.
is MessageType.UserJoined -> context.getString(R.string.message_user_joined_channel) is MessageType.MessageRemoved -> getString(R.string.message_removed)
is MessageType.UserLeft -> context.getString(R.string.message_user_left) is MessageType.UserJoined -> getString(R.string.message_user_joined_channel)
is MessageType.UserAdded -> context.getString(R.string.message_user_added_by, message.message, message.sender?.username) is MessageType.UserLeft -> getString(R.string.message_user_left)
is MessageType.RoomNameChanged -> context.getString(R.string.message_room_name_changed, message.message, message.sender?.username) is MessageType.UserAdded -> getString(R.string.message_user_added_by, message.message, message.sender?.username)
is MessageType.UserRemoved -> context.getString(R.string.message_user_removed_by, message.message, message.sender?.username) is MessageType.RoomNameChanged -> getString(R.string.message_room_name_changed, message.message, message.sender?.username)
is MessageType.MessagePinned -> context.getString(R.string.message_pinned) is MessageType.UserRemoved -> getString(R.string.message_user_removed_by, message.message, message.sender?.username)
is MessageType.UserMuted -> context.getString(R.string.message_muted, message.message, message.sender?.username) is MessageType.MessagePinned -> getString(R.string.message_pinned)
is MessageType.UserUnMuted -> context.getString(R.string.message_unmuted, message.message, message.sender?.username) is MessageType.UserMuted -> getString(R.string.message_muted, message.message, message.sender?.username)
is MessageType.SubscriptionRoleAdded -> context.getString(R.string.message_role_add, message.message, message.role, message.sender?.username) is MessageType.UserUnMuted -> getString(R.string.message_unmuted, message.message, message.sender?.username)
is MessageType.SubscriptionRoleRemoved -> context.getString(R.string.message_role_removed, message.message, message.role, message.sender?.username) is MessageType.SubscriptionRoleAdded -> getString(R.string.message_role_add, message.message, message.role, message.sender?.username)
is MessageType.RoomChangedPrivacy -> context.getString(R.string.message_room_changed_privacy, message.message, message.sender?.username) is MessageType.SubscriptionRoleRemoved -> getString(R.string.message_role_removed, message.message, message.role, message.sender?.username)
else -> { is MessageType.RoomChangedPrivacy -> getString(R.string.message_room_changed_privacy, message.message, message.sender?.username)
throw InvalidParameterException("Invalid message type: ${message.type}") else -> throw InvalidParameterException("Invalid message type: ${message.type}")
} }
} }
val spannableMsg = SpannableStringBuilder(content) val spannableMsg = SpannableStringBuilder(content)
spannableMsg.setSpan(StyleSpan(Typeface.ITALIC), 0, spannableMsg.length, spannableMsg.setSpan(StyleSpan(Typeface.ITALIC), 0, spannableMsg.length, 0)
0) spannableMsg.setSpan(ForegroundColorSpan(Color.GRAY), 0, spannableMsg.length, 0)
spannableMsg.setSpan(ForegroundColorSpan(Color.GRAY), 0, spannableMsg.length,
0)
return spannableMsg return spannableMsg
} }
......
...@@ -77,77 +77,71 @@ class RoomUiModelMapper( ...@@ -77,77 +77,71 @@ class RoomUiModelMapper(
return list return list
} }
private fun mapUser(user: User): RoomUiModel { private fun mapUser(user: User): RoomUiModel = with(user) {
return with(user) { val name = mapName(user.username!!, user.name)
val name = mapName(user.username!!, user.name) val status = user.status
val status = user.status val avatar = serverUrl.avatarUrl(user.username!!)
val avatar = serverUrl.avatarUrl(user.username!!) val username = user.username!!
val username = user.username!!
RoomUiModel(
RoomUiModel(
id = user.id, id = user.id,
name = name, name = name,
type = roomTypeOf(RoomType.DIRECT_MESSAGE), type = roomTypeOf(RoomType.DIRECT_MESSAGE),
avatar = avatar, avatar = avatar,
status = status, status = status,
username = username username = username
) )
}
} }
private fun mapRoom(room: Room, showLastMessage: Boolean = true): RoomUiModel { private fun mapRoom(room: Room, showLastMessage: Boolean = true): RoomUiModel = with(room) {
return with(room) { RoomUiModel(
RoomUiModel(
id = id, id = id,
name = name!!, name = name!!,
type = type, type = type,
avatar = serverUrl.avatarUrl(name!!, isGroupOrChannel = true), avatar = serverUrl.avatarUrl(name!!, isGroupOrChannel = true),
lastMessage = if (showLastMessage) { lastMessage = if (showLastMessage) {
mapLastMessage( mapLastMessage(
lastMessage?.sender?.id, lastMessage?.sender?.username, lastMessage?.sender?.id, lastMessage?.sender?.username,
lastMessage?.sender?.name, lastMessage?.message, lastMessage?.sender?.name, lastMessage?.message,
isDirectMessage = type is RoomType.DirectMessage isDirectMessage = type is RoomType.DirectMessage
) )
} else { } else {
null null
}, },
muted = muted.orEmpty(), muted = muted.orEmpty(),
writable = isChannelWritable(muted) writable = isChannelWritable(muted)
) )
}
} }
fun map(chatRoom: ChatRoom, showLastMessage: Boolean = true): RoomUiModel { fun map(chatRoom: ChatRoom, showLastMessage: Boolean = true): RoomUiModel = with(chatRoom.chatRoom) {
return with(chatRoom.chatRoom) { val isUnread = alert || unread > 0
val isUnread = alert || unread > 0 val type = roomTypeOf(type)
val type = roomTypeOf(type) val status = chatRoom.status?.let { userStatusOf(it) }
val status = chatRoom.status?.let { userStatusOf(it) } val roomName = mapName(name, fullname)
val roomName = mapName(name, fullname) val favorite = favorite
val favorite = favorite val timestamp = mapDate(lastMessageTimestamp ?: updatedAt)
val timestamp = mapDate(lastMessageTimestamp ?: updatedAt) val avatar = if (type is RoomType.DirectMessage) {
val avatar = if (type is RoomType.DirectMessage) { serverUrl.avatarUrl(name)
serverUrl.avatarUrl(name) } else {
} else { serverUrl.avatarUrl(name, isGroupOrChannel = true)
serverUrl.avatarUrl(name, isGroupOrChannel = true) }
} val unread = mapUnread(unread)
val unread = mapUnread(unread) val lastMessage = if (showLastMessage) {
val lastMessage = if (showLastMessage) { mapLastMessage(
mapLastMessage(
lastMessageUserId, lastMessageUserId,
chatRoom.lastMessageUserName, chatRoom.lastMessageUserName,
chatRoom.lastMessageUserFullName, chatRoom.lastMessageUserFullName,
lastMessageText, lastMessageText,
type is RoomType.DirectMessage type is RoomType.DirectMessage
) )
} else { } else {
null null
} }
val hasMentions = mapMentions(userMentions, groupMentions) val hasMentions = mapMentions(userMentions, groupMentions)
val open = open val open = open
val lastMessageMarkdown = val lastMessageMarkdown = lastMessage?.let { Markwon.markdown(context, it.toString()).toString() }
lastMessage?.let { Markwon.markdown(context, it.toString()).toString() }
RoomUiModel( RoomUiModel(
id = id, id = id,
name = roomName, name = roomName,
type = type, type = type,
...@@ -163,8 +157,7 @@ class RoomUiModelMapper( ...@@ -163,8 +157,7 @@ class RoomUiModelMapper(
username = if (type is RoomType.DirectMessage) name else null, username = if (type is RoomType.DirectMessage) name else null,
muted = muted.orEmpty(), muted = muted.orEmpty(),
writable = isChannelWritable(muted) writable = isChannelWritable(muted)
) )
}
} }
private fun isChannelWritable(muted: List<String>?): Boolean { private fun isChannelWritable(muted: List<String>?): Boolean {
...@@ -172,15 +165,13 @@ class RoomUiModelMapper( ...@@ -172,15 +165,13 @@ class RoomUiModelMapper(
return canWriteToReadOnlyChannels || !muted.orEmpty().contains(currentUser?.username) return canWriteToReadOnlyChannels || !muted.orEmpty().contains(currentUser?.username)
} }
private fun roomType(type: String): String { private fun roomType(type: String): String = with(context.resources) {
val resources = context.resources when (type) {
RoomType.CHANNEL -> getString(R.string.header_channel)
return when (type) { RoomType.PRIVATE_GROUP -> getString(R.string.header_private_groups)
RoomType.CHANNEL -> resources.getString(R.string.header_channel) RoomType.DIRECT_MESSAGE -> getString(R.string.header_direct_messages)
RoomType.PRIVATE_GROUP -> resources.getString(R.string.header_private_groups) RoomType.LIVECHAT -> getString(R.string.header_live_chats)
RoomType.DIRECT_MESSAGE -> resources.getString(R.string.header_direct_messages) else -> getString(R.string.header_unknown)
RoomType.LIVECHAT -> resources.getString(R.string.header_live_chats)
else -> resources.getString(R.string.header_unknown)
} }
} }
...@@ -213,13 +204,11 @@ class RoomUiModelMapper( ...@@ -213,13 +204,11 @@ class RoomUiModelMapper(
} }
} }
private fun mapUnread(unread: Long): String? { private fun mapUnread(unread: Long): String? = when (unread) {
return when (unread) { 0L -> null
0L -> null in 1..99 -> unread.toString()
in 1..99 -> unread.toString() else -> context.getString(R.string.msg_more_than_ninety_nine_unread_messages)
else -> context.getString(R.string.msg_more_than_ninety_nine_unread_messages)
}
} }
private fun mapMentions(userMentions: Long?, groupMentions: Long?): Boolean { private fun mapMentions(userMentions: Long?, groupMentions: Long?): Boolean {
......
...@@ -8,6 +8,7 @@ import androidx.core.view.isInvisible ...@@ -8,6 +8,7 @@ import androidx.core.view.isInvisible
import androidx.core.view.isVisible import androidx.core.view.isVisible
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatrooms.adapter.model.RoomUiModel 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.RoomType
import chat.rocket.common.model.UserStatus import chat.rocket.common.model.UserStatus
import kotlinx.android.synthetic.main.item_chat.view.* import kotlinx.android.synthetic.main.item_chat.view.*
...@@ -16,12 +17,12 @@ import kotlinx.android.synthetic.main.unread_messages_badge.view.* ...@@ -16,12 +17,12 @@ import kotlinx.android.synthetic.main.unread_messages_badge.view.*
class RoomViewHolder(itemView: View, private val listener: (RoomUiModel) -> Unit) : class RoomViewHolder(itemView: View, private val listener: (RoomUiModel) -> Unit) :
ViewHolder<RoomItemHolder>(itemView) { ViewHolder<RoomItemHolder>(itemView) {
private val resources: Resources = itemView.resources private val resources: Resources = itemView.resources
private val channelIcon: Drawable = resources.getDrawable(R.drawable.ic_hashtag_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) 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) 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) 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) 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) private val offlineIcon: Drawable = resources.getDrawable(R.drawable.ic_status_invisible_12dp, null)
override fun bindViews(data: RoomItemHolder) { override fun bindViews(data: RoomItemHolder) {
val room = data.data val room = data.data
...@@ -53,14 +54,14 @@ class RoomViewHolder(itemView: View, private val listener: (RoomUiModel) -> Unit ...@@ -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 = "!"
if (room.unread != null) text_total_unread_messages.text = room.unread if (room.unread != null) text_total_unread_messages.text = room.unread
if (room.mentions) 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_chat_name.setTextViewAppearance(context, R.style.ChatList_ChatName_Unread_TextView)
text_timestamp.setTextAppearance(context, R.style.ChatList_Timestamp_Unread_TextView) text_timestamp.setTextViewAppearance(context, R.style.ChatList_Timestamp_Unread_TextView)
text_last_message.setTextAppearance(context, R.style.ChatList_LastMessage_Unread_TextView) text_last_message.setTextViewAppearance(context, R.style.ChatList_LastMessage_Unread_TextView)
text_total_unread_messages.isVisible = true text_total_unread_messages.isVisible = true
} else { } else {
text_chat_name.setTextAppearance(context, R.style.ChatList_ChatName_TextView) text_chat_name.setTextViewAppearance(context, R.style.ChatList_ChatName_TextView)
text_timestamp.setTextAppearance(context, R.style.ChatList_Timestamp_TextView) text_timestamp.setTextViewAppearance(context, R.style.ChatList_Timestamp_TextView)
text_last_message.setTextAppearance(context, R.style.ChatList_LastMessage_TextView) text_last_message.setTextViewAppearance(context, R.style.ChatList_LastMessage_TextView)
text_total_unread_messages.isInvisible = true text_total_unread_messages.isInvisible = true
} }
...@@ -68,20 +69,16 @@ class RoomViewHolder(itemView: View, private val listener: (RoomUiModel) -> Unit ...@@ -68,20 +69,16 @@ class RoomViewHolder(itemView: View, private val listener: (RoomUiModel) -> Unit
} }
} }
private fun getRoomDrawable(type: RoomType): Drawable? { private fun getRoomDrawable(type: RoomType): Drawable? = when (type) {
return when (type) { is RoomType.Channel -> channelIcon
is RoomType.Channel -> channelIcon is RoomType.PrivateGroup -> groupIcon
is RoomType.PrivateGroup -> groupIcon else -> null
else -> null
}
} }
private fun getStatusDrawable(status: UserStatus): Drawable { private fun getStatusDrawable(status: UserStatus): Drawable = when (status) {
return when (status) { is UserStatus.Online -> onlineIcon
is UserStatus.Online -> onlineIcon is UserStatus.Away -> awayIcon
is UserStatus.Away -> awayIcon is UserStatus.Busy -> busyIcon
is UserStatus.Busy -> busyIcon else -> offlineIcon
else -> offlineIcon
}
} }
} }
\ No newline at end of file
...@@ -19,22 +19,20 @@ class RoomsAdapter(private val listener: (RoomUiModel) -> Unit) : ...@@ -19,22 +19,20 @@ class RoomsAdapter(private val listener: (RoomUiModel) -> Unit) :
notifyDataSetChanged() notifyDataSetChanged()
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder<*> { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder<*> = when (viewType) {
return when (viewType) { VIEW_TYPE_ROOM -> {
VIEW_TYPE_ROOM -> { val view = parent.inflate(R.layout.item_chat)
val view = parent.inflate(R.layout.item_chat) RoomViewHolder(view, listener)
RoomViewHolder(view, listener) }
} VIEW_TYPE_HEADER -> {
VIEW_TYPE_HEADER -> { val view = parent.inflate(R.layout.item_chatroom_header)
val view = parent.inflate(R.layout.item_chatroom_header) HeaderViewHolder(view)
HeaderViewHolder(view) }
} VIEW_TYPE_LOADING -> {
VIEW_TYPE_LOADING -> { val view = parent.inflate(R.layout.item_loading)
val view = parent.inflate(R.layout.item_loading) LoadingViewHolder(view)
LoadingViewHolder(view)
}
else -> throw IllegalStateException("View type must be either Room, Header or Loading")
} }
else -> throw IllegalStateException("View type must be either Room, Header or Loading")
} }
override fun getItemCount() = values.size override fun getItemCount() = values.size
...@@ -49,13 +47,11 @@ class RoomsAdapter(private val listener: (RoomUiModel) -> Unit) : ...@@ -49,13 +47,11 @@ class RoomsAdapter(private val listener: (RoomUiModel) -> Unit) :
} }
} }
override fun getItemViewType(position: Int): Int { override fun getItemViewType(position: Int): Int = when (values[position]) {
return when (values[position]) { is RoomItemHolder -> VIEW_TYPE_ROOM
is RoomItemHolder -> VIEW_TYPE_ROOM is HeaderItemHolder -> VIEW_TYPE_HEADER
is HeaderItemHolder -> VIEW_TYPE_HEADER is LoadingItemHolder -> VIEW_TYPE_LOADING
is LoadingItemHolder -> VIEW_TYPE_LOADING else -> throw IllegalStateException("View type must be either Room, Header or Loading")
else -> throw IllegalStateException("View type must be either Room, Header or Loading")
}
} }
override fun onBindViewHolder(holder: ViewHolder<*>, position: Int) { override fun onBindViewHolder(holder: ViewHolder<*>, position: Int) {
......
...@@ -69,11 +69,9 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -69,11 +69,9 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
private var progressDialog: ProgressDialog? = null private var progressDialog: ProgressDialog? = null
companion object { companion object {
fun newInstance(chatRoomId: String? = null): ChatRoomsFragment { fun newInstance(chatRoomId: String? = null): ChatRoomsFragment = ChatRoomsFragment().apply {
return ChatRoomsFragment().apply { arguments = Bundle(1).apply {
arguments = Bundle(1).apply { putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
}
} }
} }
} }
...@@ -82,9 +80,8 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -82,9 +80,8 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
setHasOptionsMenu(true) setHasOptionsMenu(true)
val bundle = arguments arguments?.run {
if (bundle != null) { chatRoomId = getString(BUNDLE_CHAT_ROOM_ID)
chatRoomId = bundle.getString(BUNDLE_CHAT_ROOM_ID)
chatRoomId.ifNotNullNotEmpty { roomId -> chatRoomId.ifNotNullNotEmpty { roomId ->
presenter.loadChatRoom(roomId) presenter.loadChatRoom(roomId)
chatRoomId = null chatRoomId = null
...@@ -320,21 +317,20 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -320,21 +317,20 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
ui { ui {
text_connection_status.fadeIn() text_connection_status.fadeIn()
handler.removeCallbacks(dismissStatus) handler.removeCallbacks(dismissStatus)
when (state) { text_connection_status.text = when (state) {
is State.Connected -> { is State.Connected -> {
text_connection_status.text = getString(R.string.status_connected)
handler.postDelayed(dismissStatus, 2000) 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)
} }
} }
} }
......
...@@ -45,9 +45,7 @@ class CreateChannelFragment : Fragment(), CreateChannelView, ActionMode.Callback ...@@ -45,9 +45,7 @@ class CreateChannelFragment : Fragment(), CreateChannelView, ActionMode.Callback
lateinit var analyticsManager: AnalyticsManager lateinit var analyticsManager: AnalyticsManager
private var actionMode: ActionMode? = null private var actionMode: ActionMode? = null
private val adapter: MembersAdapter = MembersAdapter { private val adapter: MembersAdapter = MembersAdapter {
if (it.username != null) { it.username?.run { processSelectedMember(this) }
processSelectedMember(it.username)
}
} }
private val compositeDisposable = CompositeDisposable() private val compositeDisposable = CompositeDisposable()
private var channelType: String = RoomType.CHANNEL private var channelType: String = RoomType.CHANNEL
...@@ -294,8 +292,8 @@ class CreateChannelFragment : Fragment(), CreateChannelView, ActionMode.Callback ...@@ -294,8 +292,8 @@ class CreateChannelFragment : Fragment(), CreateChannelView, ActionMode.Callback
private fun addChip(chipText: String) { private fun addChip(chipText: String) {
val chip = Chip(context) val chip = Chip(context)
chip.chipText = chipText chip.text = chipText
chip.isCloseIconEnabled = true chip.isCloseIconVisible = true
chip.setChipBackgroundColorResource(R.color.icon_grey) chip.setChipBackgroundColorResource(R.color.icon_grey)
setupChipOnCloseIconClickListener(chip) setupChipOnCloseIconClickListener(chip)
chip_group_member.addView(chip) chip_group_member.addView(chip)
...@@ -304,7 +302,7 @@ class CreateChannelFragment : Fragment(), CreateChannelView, ActionMode.Callback ...@@ -304,7 +302,7 @@ class CreateChannelFragment : Fragment(), CreateChannelView, ActionMode.Callback
private fun setupChipOnCloseIconClickListener(chip: Chip) { private fun setupChipOnCloseIconClickListener(chip: Chip) {
chip.setOnCloseIconClickListener { chip.setOnCloseIconClickListener {
removeChip(it) removeChip(it)
removeMember((it as Chip).chipText.toString()) removeMember((it as Chip).text.toString())
// whenever we remove a chip we should process the chip group visibility. // whenever we remove a chip we should process the chip group visibility.
processChipGroupVisibility() processChipGroupVisibility()
} }
......
...@@ -40,6 +40,12 @@ import kotlinx.coroutines.experimental.newSingleThreadContext ...@@ -40,6 +40,12 @@ import kotlinx.coroutines.experimental.newSingleThreadContext
import kotlinx.coroutines.experimental.withContext import kotlinx.coroutines.experimental.withContext
import timber.log.Timber import timber.log.Timber
import java.util.HashSet 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 import kotlin.system.measureTimeMillis
class DatabaseManager(val context: Application, val serverUrl: String) { class DatabaseManager(val context: Application, val serverUrl: String) {
...@@ -140,7 +146,7 @@ class DatabaseManager(val context: Application, val serverUrl: String) { ...@@ -140,7 +146,7 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
batch.forEach { batch.forEach {
when (it.type) { when (it.type) {
is Type.Removed -> toRemove.add(removeChatRoom(it.data)) 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 -> { is Type.Updated -> {
when (it.data) { when (it.data) {
is Subscription -> updateSubs[(it.data as Subscription).roomId] = it.data as Subscription is Subscription -> updateSubs[(it.data as Subscription).roomId] = it.data as Subscription
...@@ -186,16 +192,14 @@ class DatabaseManager(val context: Application, val serverUrl: String) { ...@@ -186,16 +192,14 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
} }
} }
fun processMessagesBatch(messages: List<Message>): Job { fun processMessagesBatch(messages: List<Message>): Job = launch(dbManagerContext) {
return launch(dbManagerContext) { val list = mutableListOf<Pair<MessageEntity, List<BaseMessageEntity>>>()
val list = mutableListOf<Pair<MessageEntity, List<BaseMessageEntity>>>() messages.forEach { message ->
messages.forEach { message -> val pair = createMessageEntities(message)
val pair = createMessageEntities(message) list.add(pair)
list.add(pair)
}
sendOperation(Operation.InsertMessages(list))
} }
sendOperation(Operation.InsertMessages(list))
} }
private suspend fun createMessageEntities(message: Message): Pair<MessageEntity, List<BaseMessageEntity>> { private suspend fun createMessageEntities(message: Message): Pair<MessageEntity, List<BaseMessageEntity>> {
...@@ -213,91 +217,70 @@ class DatabaseManager(val context: Application, val serverUrl: String) { ...@@ -213,91 +217,70 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
return Pair(messageEntity, list) return Pair(messageEntity, list)
} }
private fun createReactions(message: Message): List<BaseMessageEntity>? { private fun createReactions(message: Message): List<BaseMessageEntity>? = message.reactions?.run {
if (message.reactions == null || message.reactions!!.isEmpty()) { if (isNotEmpty()) {
return null val list = mutableListOf<BaseMessageEntity>()
} keys.forEach { reaction ->
get(reaction)?.let { reactionValue ->
val reactions = message.reactions!! list.add(ReactionEntity(reaction, message.id, size, reactionValue.joinToString()))
}
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()))
} }
} list
} else null
return list
} }
private fun createUrlEntities(message: Message): List<BaseMessageEntity>? { private fun createUrlEntities(message: Message): List<BaseMessageEntity>? = message.urls?.run {
if (message.urls == null || message.urls!!.isEmpty()) { if (isNotEmpty()) {
return null val list = mutableListOf<UrlEntity>()
} forEach { url ->
list.add(UrlEntity(message.id, url.url, url.parsedUrl?.host, url.meta?.title,
val list = mutableListOf<UrlEntity>() url.meta?.description, url.meta?.imageUrl))
message.urls!!.forEach { url -> }
list.add(UrlEntity(message.id, url.url, url.parsedUrl?.host, url.meta?.title, list
url.meta?.description, url.meta?.imageUrl)) } else null
}
return list
} }
private fun createChannelRelations(message: Message): List<BaseMessageEntity>? { private fun createChannelRelations(message: Message): List<BaseMessageEntity>? = message.channels?.run {
if (message.channels == null || message.channels!!.isEmpty()) { if (isNotEmpty()) {
return null val list = mutableListOf<MessageChannels>()
} forEach { channel ->
list.add(MessageChannels(message.id, channel.id, channel.name))
val list = mutableListOf<MessageChannels>() }
message.channels!!.forEach { channel -> list
list.add(MessageChannels(message.id, channel.id, channel.name)) } else null
}
return list
} }
private suspend fun createMentionRelations(message: Message): List<BaseMessageEntity>? { private suspend fun createMentionRelations(message: Message): List<BaseMessageEntity>? = message.mentions?.run {
if (message.mentions == null || message.mentions!!.isEmpty()) { if (isNotEmpty()) {
return null val list = mutableListOf<MessageMentionsRelation>()
} filterNot { user -> user.id.isNullOrEmpty() }.forEach { mention ->
insertUserIfMissing(mention)
val list = mutableListOf<MessageMentionsRelation>() list.add(MessageMentionsRelation(message.id, mention.id!!))
message.mentions!!.filterNot { user -> user.id.isNullOrEmpty() }.forEach { mention -> }
insertUserIfMissing(mention) list
list.add(MessageMentionsRelation(message.id, mention.id!!)) } else null
}
return list
} }
private suspend fun createFavoriteRelations(message: Message): List<BaseMessageEntity>? { private suspend fun createFavoriteRelations(message: Message): List<BaseMessageEntity>? = message.starred?.run {
if (message.starred == null || message.starred!!.isEmpty()) { if (isNotEmpty()) {
return null val list = mutableListOf<MessageFavoritesRelation>()
} filterNot { user -> user.id.isNullOrEmpty() }.forEach { userId ->
insertUserIfMissing(userId)
val list = mutableListOf<MessageFavoritesRelation>() list.add(MessageFavoritesRelation(message.id, userId.id!!))
message.starred!!.filterNot { user -> user.id.isNullOrEmpty() }.forEach { userId -> }
insertUserIfMissing(userId) list
list.add(MessageFavoritesRelation(message.id, userId.id!!)) } else null
}
return list
} }
private fun createAttachments(message: Message): List<BaseMessageEntity>? {
if (message.attachments == null || message.attachments!!.isEmpty()) {
return null
}
val list = ArrayList<BaseMessageEntity>(message.attachments!!.size)
message.attachments!!.forEach { attachment -> private fun createAttachments(message: Message): List<BaseMessageEntity>? = message.attachments?.run {
list.addAll(attachment.asEntity(message.id, context)) if (isNotEmpty()) {
} val list = ArrayList<BaseMessageEntity>(size)
forEach { attachment ->
return list list.addAll(attachment.asEntity(message.id, context))
}
list
} else null
} }
private suspend fun createUpdates(): List<ChatRoomEntity> { private suspend fun createUpdates(): List<ChatRoomEntity> {
...@@ -375,20 +358,15 @@ class DatabaseManager(val context: Application, val serverUrl: String) { ...@@ -375,20 +358,15 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
} }
} }
private fun mapLastMessageText(message: Message?): String? { private fun mapLastMessageText(message: Message?): String? = message?.run {
return if (message == null) { if (this.message.isEmpty() && attachments?.isNotEmpty() == true) {
null message.attachments?.let { mapAttachmentText(it[0]) }
} else { } else {
return if (message.message.isEmpty() && message.attachments?.isNotEmpty() == true) { this.message
mapAttachmentText(message.attachments!![0])
} else {
message.message
}
} }
} }
private fun mapAttachmentText(attachment: Attachment): String = private fun mapAttachmentText(attachment: Attachment): String = context.getString(R.string.msg_sent_attachment)
context.getString(R.string.msg_sent_attachment)
private suspend fun updateSubscription(data: Subscription): ChatRoomEntity? { private suspend fun updateSubscription(data: Subscription): ChatRoomEntity? {
return retryDB("getRoom(${data.roomId}") { chatRoomDao().getSync(data.roomId) }?.let { current -> return retryDB("getRoom(${data.roomId}") { chatRoomDao().getSync(data.roomId) }?.let { current ->
...@@ -431,12 +409,10 @@ class DatabaseManager(val context: Application, val serverUrl: String) { ...@@ -431,12 +409,10 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
} }
} }
private suspend fun insertChatRoom(data: BaseRoom): ChatRoomEntity? { private suspend fun insertChatRoom(data: BaseRoom): ChatRoomEntity? = when (data) {
return when (data) { is Room -> insertRoom(data)
is Room -> insertRoom(data) is Subscription -> insertSubscription(data)
is Subscription -> insertSubscription(data) else -> null
else -> null
}
} }
private suspend fun insertRoom(data: Room): ChatRoomEntity? { private suspend fun insertRoom(data: Room): ChatRoomEntity? {
......
...@@ -115,12 +115,12 @@ fun Attachment.asEntity(msgId: String, context: Context): List<BaseMessageEntity ...@@ -115,12 +115,12 @@ fun Attachment.asEntity(msgId: String, context: Context): List<BaseMessageEntity
val text = mapAttachmentText(text, attachments?.firstOrNull(), context) val text = mapAttachmentText(text, attachments?.firstOrNull(), context)
val entity = AttachmentEntity( list.add(AttachmentEntity(
_id = attachmentId, _id = attachmentId,
messageId = msgId, messageId = msgId,
title = title, title = title,
type = type, type = type,
description = description, description = description,
text = text, text = text,
titleLink = titleLink, titleLink = titleLink,
titleLinkDownload = titleLinkDownload.orFalse(), titleLinkDownload = titleLinkDownload.orFalse(),
...@@ -144,16 +144,14 @@ fun Attachment.asEntity(msgId: String, context: Context): List<BaseMessageEntity ...@@ -144,16 +144,14 @@ fun Attachment.asEntity(msgId: String, context: Context): List<BaseMessageEntity
buttonAlignment = buttonAlignment, buttonAlignment = buttonAlignment,
hasActions = actions?.isNotEmpty() == true, hasActions = actions?.isNotEmpty() == true,
hasFields = fields?.isNotEmpty() == true hasFields = fields?.isNotEmpty() == true
) ))
list.add(entity)
fields?.forEach { field -> fields?.forEach { field ->
val entity = AttachmentFieldEntity( list.add(AttachmentFieldEntity(
attachmentId = attachmentId, attachmentId = attachmentId,
title = field.title, title = field.title,
value = field.value value = field.value
) ))
list.add(entity)
} }
actions?.forEach { action -> actions?.forEach { action ->
...@@ -175,18 +173,14 @@ fun Attachment.asEntity(msgId: String, context: Context): List<BaseMessageEntity ...@@ -175,18 +173,14 @@ fun Attachment.asEntity(msgId: String, context: Context): List<BaseMessageEntity
return list return list
} }
fun mapAttachmentText(text: String?, attachment: Attachment?, context: Context): String? { fun mapAttachmentText(text: String?, attachment: Attachment?, context: Context): String? = attachment?.run {
return if (attachment != null) { when {
when { imageUrl.isNotNullNorEmpty() -> context.getString(R.string.msg_preview_photo)
attachment.imageUrl.isNotNullNorEmpty() -> context.getString(R.string.msg_preview_photo) videoUrl.isNotNullNorEmpty() -> context.getString(R.string.msg_preview_video)
attachment.videoUrl.isNotNullNorEmpty() -> context.getString(R.string.msg_preview_video) audioUrl.isNotNullNorEmpty() -> context.getString(R.string.msg_preview_audio)
attachment.audioUrl.isNotNullNorEmpty() -> context.getString(R.string.msg_preview_audio) titleLink.isNotNullNorEmpty() &&
attachment.titleLink.isNotNullNorEmpty() && type?.contentEquals("file") == true ->
attachment.type?.contentEquals("file") == true -> context.getString(R.string.msg_preview_file)
context.getString(R.string.msg_preview_file) else -> text
else -> text
}
} else {
text
} }
} } ?: text
\ No newline at end of file
...@@ -36,8 +36,7 @@ class FavoriteMessagesPresenter @Inject constructor( ...@@ -36,8 +36,7 @@ class FavoriteMessagesPresenter @Inject constructor(
try { try {
view.showLoading() view.showLoading()
dbManager.getRoom(roomId)?.let { dbManager.getRoom(roomId)?.let {
val favoriteMessages = val favoriteMessages = client.getFavoriteMessages(roomId, roomTypeOf(it.chatRoom.type), offset)
client.getFavoriteMessages(roomId, roomTypeOf(it.chatRoom.type), offset)
val messageList = mapper.map(favoriteMessages.result, asNotReversed = true) val messageList = mapper.map(favoriteMessages.result, asNotReversed = true)
view.showFavoriteMessages(messageList) view.showFavoriteMessages(messageList)
offset += 1 * 30 offset += 1 * 30
......
...@@ -25,11 +25,9 @@ import dagger.android.support.AndroidSupportInjection ...@@ -25,11 +25,9 @@ import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_favorite_messages.* import kotlinx.android.synthetic.main.fragment_favorite_messages.*
import javax.inject.Inject import javax.inject.Inject
fun newInstance(chatRoomId: String): Fragment { fun newInstance(chatRoomId: String): Fragment = FavoriteMessagesFragment().apply {
return FavoriteMessagesFragment().apply { arguments = Bundle(1).apply {
arguments = Bundle(1).apply { putString(INTENT_CHAT_ROOM_ID, chatRoomId)
putString(INTENT_CHAT_ROOM_ID, chatRoomId)
}
} }
} }
...@@ -48,12 +46,9 @@ class FavoriteMessagesFragment : Fragment(), FavoriteMessagesView { ...@@ -48,12 +46,9 @@ class FavoriteMessagesFragment : Fragment(), FavoriteMessagesView {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
val bundle = arguments arguments?.run {
if (bundle != null) { chatRoomId = getString(INTENT_CHAT_ROOM_ID, "")
chatRoomId = bundle.getString(INTENT_CHAT_ROOM_ID) } ?: requireNotNull(arguments) { "no arguments supplied when the fragment was instantiated" }
} else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
}
} }
override fun onCreateView( override fun onCreateView(
......
...@@ -30,11 +30,9 @@ import dagger.android.support.AndroidSupportInjection ...@@ -30,11 +30,9 @@ import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_files.* import kotlinx.android.synthetic.main.fragment_files.*
import javax.inject.Inject import javax.inject.Inject
fun newInstance(chatRoomId: String): Fragment { fun newInstance(chatRoomId: String): Fragment = FilesFragment().apply {
return FilesFragment().apply { arguments = Bundle(1).apply {
arguments = Bundle(1).apply { putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
}
} }
} }
...@@ -55,12 +53,9 @@ class FilesFragment : Fragment(), FilesView { ...@@ -55,12 +53,9 @@ class FilesFragment : Fragment(), FilesView {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
val bundle = arguments arguments?.run {
if (bundle != null) { chatRoomId = getString(BUNDLE_CHAT_ROOM_ID, "")
chatRoomId = bundle.getString(BUNDLE_CHAT_ROOM_ID) } ?: requireNotNull(arguments) { "no arguments supplied when the fragment was instantiated" }
} else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
}
} }
override fun onCreateView( override fun onCreateView(
......
...@@ -11,8 +11,7 @@ object AndroidPermissionsHelper { ...@@ -11,8 +11,7 @@ object AndroidPermissionsHelper {
const val WRITE_EXTERNAL_STORAGE_CODE = 1 const val WRITE_EXTERNAL_STORAGE_CODE = 1
fun checkPermission(context: Context, permission: String): Boolean { fun checkPermission(context: Context, permission: String): Boolean {
return ContextCompat.checkSelfPermission(context, permission) == return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
PackageManager.PERMISSION_GRANTED
} }
fun requestPermission(context: Activity, permission: String, requestCode: Int) { fun requestPermission(context: Activity, permission: String, requestCode: Int) {
......
...@@ -53,8 +53,8 @@ object ImageHelper { ...@@ -53,8 +53,8 @@ object ImageHelper {
) )
val toolbar = Toolbar(context).also { val toolbar = Toolbar(context).also {
it.inflateMenu(R.menu.image_actions) it.inflateMenu(R.menu.image_actions)
it.setOnMenuItemClickListener { it.setOnMenuItemClickListener { view ->
return@setOnMenuItemClickListener when (it.itemId) { return@setOnMenuItemClickListener when (view.itemId) {
R.id.action_save_image -> saveImage(context) R.id.action_save_image -> saveImage(context)
else -> true else -> true
} }
...@@ -62,20 +62,24 @@ object ImageHelper { ...@@ -62,20 +62,24 @@ object ImageHelper {
val titleSize = context.resources val titleSize = context.resources
.getDimensionPixelSize(R.dimen.viewer_toolbar_title) .getDimensionPixelSize(R.dimen.viewer_toolbar_title)
val titleTextView = TextView(context).also { val titleTextView = TextView(context).also { tv ->
it.text = imageName with(tv) {
it.setTextColor(Color.WHITE) text = imageName
it.setTextSize(TypedValue.COMPLEX_UNIT_PX, titleSize.toFloat()) setTextColor(Color.WHITE)
it.ellipsize = TextUtils.TruncateAt.END setTextSize(TypedValue.COMPLEX_UNIT_PX, titleSize.toFloat())
it.setSingleLine() ellipsize = TextUtils.TruncateAt.END
it.typeface = Typeface.DEFAULT_BOLD setSingleLine()
it.setPadding(pad) typeface = Typeface.DEFAULT_BOLD
setPadding(pad)
}
} }
val backArrowView = ImageView(context).also { val backArrowView = ImageView(context).also { imgView ->
it.setImageResource(R.drawable.ic_arrow_back_white_24dp) with(imgView) {
it.setOnClickListener { imageViewer?.onDismiss() } setImageResource(R.drawable.ic_arrow_back_white_24dp)
it.setPadding(0, pad, pad, pad) setOnClickListener { imageViewer?.onDismiss() }
setPadding(0, pad, pad, pad)
}
} }
val layoutParams = AppBarLayout.LayoutParams( val layoutParams = AppBarLayout.LayoutParams(
...@@ -88,14 +92,16 @@ object ImageHelper { ...@@ -88,14 +92,16 @@ object ImageHelper {
} }
val appBarLayout = AppBarLayout(context).also { val appBarLayout = AppBarLayout(context).also {
it.layoutParams = lparams with(it) {
it.setBackgroundColor(Color.BLACK) layoutParams = lparams
it.addView( setBackgroundColor(Color.BLACK)
toolbar, AppBarLayout.LayoutParams( addView(
AppBarLayout.LayoutParams.MATCH_PARENT, toolbar, AppBarLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT AppBarLayout.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
) )
) )
}
} }
val builder = ImageViewer.createPipelineDraweeControllerBuilder() val builder = ImageViewer.createPipelineDraweeControllerBuilder()
......
...@@ -10,8 +10,9 @@ import chat.rocket.android.util.extensions.inflate ...@@ -10,8 +10,9 @@ import chat.rocket.android.util.extensions.inflate
import kotlinx.android.synthetic.main.avatar.view.* import kotlinx.android.synthetic.main.avatar.view.*
import kotlinx.android.synthetic.main.item_member.view.* import kotlinx.android.synthetic.main.item_member.view.*
class MembersAdapter(private val listener: (MemberUiModel) -> Unit) : class MembersAdapter(
RecyclerView.Adapter<MembersAdapter.ViewHolder>() { private val listener: (MemberUiModel) -> Unit
) : RecyclerView.Adapter<MembersAdapter.ViewHolder>() {
private var dataSet: List<MemberUiModel> = ArrayList() private var dataSet: List<MemberUiModel> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MembersAdapter.ViewHolder = override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MembersAdapter.ViewHolder =
...@@ -43,7 +44,8 @@ class MembersAdapter(private val listener: (MemberUiModel) -> Unit) : ...@@ -43,7 +44,8 @@ class MembersAdapter(private val listener: (MemberUiModel) -> Unit) :
fun bind(memberUiModel: MemberUiModel, listener: (MemberUiModel) -> Unit) = with(itemView) { fun bind(memberUiModel: MemberUiModel, listener: (MemberUiModel) -> Unit) = with(itemView) {
image_avatar.setImageURI(memberUiModel.avatarUri) image_avatar.setImageURI(memberUiModel.avatarUri)
text_member.content = memberUiModel.displayName 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) } setOnClickListener { listener(memberUiModel) }
} }
} }
......
...@@ -27,11 +27,9 @@ import kotlinx.android.synthetic.main.app_bar_chat_room.* ...@@ -27,11 +27,9 @@ import kotlinx.android.synthetic.main.app_bar_chat_room.*
import kotlinx.android.synthetic.main.fragment_members.* import kotlinx.android.synthetic.main.fragment_members.*
import javax.inject.Inject import javax.inject.Inject
fun newInstance(chatRoomId: String): Fragment { fun newInstance(chatRoomId: String): Fragment = MembersFragment().apply {
return MembersFragment().apply { arguments = Bundle(1).apply {
arguments = Bundle(1).apply { putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
}
} }
} }
...@@ -52,12 +50,9 @@ class MembersFragment : Fragment(), MembersView { ...@@ -52,12 +50,9 @@ class MembersFragment : Fragment(), MembersView {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
val bundle = arguments arguments?.run {
if (bundle != null) { chatRoomId = getString(BUNDLE_CHAT_ROOM_ID, "")
chatRoomId = bundle.getString(BUNDLE_CHAT_ROOM_ID) } ?: requireNotNull(arguments) { "no arguments supplied when the fragment was instantiated" }
} else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
}
} }
override fun onCreateView( override fun onCreateView(
...@@ -80,7 +75,7 @@ class MembersFragment : Fragment(), MembersView { ...@@ -80,7 +75,7 @@ class MembersFragment : Fragment(), MembersView {
setupToolbar(total) setupToolbar(total)
if (adapter.itemCount == 0) { if (adapter.itemCount == 0) {
adapter.prependData(dataSet) adapter.prependData(dataSet)
if (dataSet.size >= 59) { // TODO Check why the API retorns the specified count -1 if (dataSet.size >= 59) { // TODO Check why the API returns the specified count -1
recycler_view.addOnScrollListener(object : recycler_view.addOnScrollListener(object :
EndlessRecyclerViewScrollListener(linearLayoutManager) { EndlessRecyclerViewScrollListener(linearLayoutManager) {
override fun onLoadMore( override fun onLoadMore(
......
...@@ -25,11 +25,9 @@ import dagger.android.support.AndroidSupportInjection ...@@ -25,11 +25,9 @@ import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_mentions.* import kotlinx.android.synthetic.main.fragment_mentions.*
import javax.inject.Inject import javax.inject.Inject
fun newInstance(chatRoomId: String): Fragment { fun newInstance(chatRoomId: String): Fragment = MentionsFragment().apply {
return MentionsFragment().apply { arguments = Bundle(1).apply {
arguments = Bundle(1).apply { putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
}
} }
} }
...@@ -48,12 +46,9 @@ class MentionsFragment : Fragment(), MentionsView { ...@@ -48,12 +46,9 @@ class MentionsFragment : Fragment(), MentionsView {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
val bundle = arguments arguments?.run {
if (bundle != null) { chatRoomId = getString(BUNDLE_CHAT_ROOM_ID, "")
chatRoomId = bundle.getString(BUNDLE_CHAT_ROOM_ID) } ?: requireNotNull(arguments) { "no arguments supplied when the fragment was instantiated" }
} else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
}
} }
override fun onCreateView( override fun onCreateView(
......
...@@ -25,11 +25,9 @@ import dagger.android.support.AndroidSupportInjection ...@@ -25,11 +25,9 @@ import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_pinned_messages.* import kotlinx.android.synthetic.main.fragment_pinned_messages.*
import javax.inject.Inject import javax.inject.Inject
fun newInstance(chatRoomId: String): Fragment { fun newInstance(chatRoomId: String): Fragment = PinnedMessagesFragment().apply {
return PinnedMessagesFragment().apply { arguments = Bundle(1).apply {
arguments = Bundle(1).apply { putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
}
} }
} }
...@@ -48,12 +46,9 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView { ...@@ -48,12 +46,9 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
val bundle = arguments arguments?.run {
if (bundle != null) { chatRoomId = getString(BUNDLE_CHAT_ROOM_ID, "")
chatRoomId = bundle.getString(BUNDLE_CHAT_ROOM_ID) } ?: requireNotNull(arguments) { "no arguments supplied when the fragment was instantiated" }
} else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
}
} }
override fun onCreateView( override fun onCreateView(
......
...@@ -94,11 +94,13 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback { ...@@ -94,11 +94,13 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
if (resultData != null && resultCode == Activity.RESULT_OK) { resultData?.run {
if (requestCode == REQUEST_CODE_FOR_PERFORM_SAF) { if (resultCode == Activity.RESULT_OK) {
presenter.updateAvatar(resultData.data) if (requestCode == REQUEST_CODE_FOR_PERFORM_SAF) {
} else if (requestCode == REQUEST_CODE_FOR_PERFORM_CAMERA) { data?.let { presenter.updateAvatar(it) }
presenter.preparePhotoAndUpdateAvatar(resultData.extras["data"] as Bitmap) } else if (requestCode == REQUEST_CODE_FOR_PERFORM_CAMERA) {
extras?.get("data")?.let { presenter.preparePhotoAndUpdateAvatar(it as Bitmap) }
}
} }
} }
} }
...@@ -203,8 +205,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback { ...@@ -203,8 +205,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
} }
private fun setupToolbar() { private fun setupToolbar() {
(activity as AppCompatActivity?)?.supportActionBar?.title = (activity as AppCompatActivity?)?.supportActionBar?.title = getString(R.string.title_profile)
getString(R.string.title_profile)
} }
private fun setupListeners() { private fun setupListeners() {
......
...@@ -12,13 +12,14 @@ import android.os.Build ...@@ -12,13 +12,14 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Parcel import android.os.Parcel
import android.os.Parcelable import android.os.Parcelable
import android.text.Html
import android.text.Spanned
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
import androidx.core.app.RemoteInput import androidx.core.app.RemoteInput
import android.text.Html
import android.text.Spanned
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.text.HtmlCompat.FROM_HTML_MODE_LEGACY
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.main.ui.MainActivity import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.server.domain.GetAccountInteractor import chat.rocket.android.server.domain.GetAccountInteractor
...@@ -303,7 +304,11 @@ class PushManager @Inject constructor( ...@@ -303,7 +304,11 @@ class PushManager @Inject constructor(
// CharSequence extensions // CharSequence extensions
private fun CharSequence.fromHtml(): Spanned { 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 // NotificationCompat.Builder extensions
...@@ -383,12 +388,12 @@ data class PushMessage( ...@@ -383,12 +388,12 @@ data class PushMessage(
) : Parcelable { ) : Parcelable {
constructor(parcel: Parcel) : this( constructor(parcel: Parcel) : this(
parcel.readString().orEmpty(),
parcel.readString().orEmpty(),
parcel.readParcelable(PushMessage::class.java.classLoader) ?: PushInfo.EMPTY,
parcel.readString(), parcel.readString(),
parcel.readString(), parcel.readString(),
parcel.readParcelable(PushMessage::class.java.classLoader), parcel.readString().orEmpty(),
parcel.readString(),
parcel.readString(),
parcel.readString(),
parcel.readString(), parcel.readString(),
parcel.readString()) parcel.readString())
...@@ -433,9 +438,9 @@ data class PushInfo @KotshiConstructor constructor( ...@@ -433,9 +438,9 @@ data class PushInfo @KotshiConstructor constructor(
} }
constructor(parcel: Parcel) : this( constructor(parcel: Parcel) : this(
parcel.readString(), parcel.readString().orEmpty(),
parcel.readString(), parcel.readString().orEmpty(),
roomTypeOf(parcel.readString()), roomTypeOf(parcel.readString().orEmpty()),
parcel.readString(), parcel.readString(),
parcel.readParcelable(PushInfo::class.java.classLoader)) parcel.readParcelable(PushInfo::class.java.classLoader))
...@@ -481,7 +486,7 @@ data class PushSender @KotshiConstructor constructor( ...@@ -481,7 +486,7 @@ data class PushSender @KotshiConstructor constructor(
val name: String? val name: String?
) : Parcelable { ) : Parcelable {
constructor(parcel: Parcel) : this( constructor(parcel: Parcel) : this(
parcel.readString(), parcel.readString().orEmpty(),
parcel.readString(), parcel.readString(),
parcel.readString()) parcel.readString())
......
...@@ -97,8 +97,8 @@ class ConnectionManager( ...@@ -97,8 +97,8 @@ class ConnectionManager(
resubscribeRooms() resubscribeRooms()
temporaryStatus?.let { status -> temporaryStatus?.let { tempStatus ->
client.setTemporaryStatus(status) client.setTemporaryStatus(tempStatus)
} }
} }
is State.Waiting -> { is State.Waiting -> {
...@@ -135,9 +135,7 @@ class ConnectionManager( ...@@ -135,9 +135,7 @@ class ConnectionManager(
if (it.type == Type.Updated) { if (it.type == Type.Updated) {
if (it.data is Room) { if (it.data is Room) {
val room = it.data as Room val room = it.data as Room
roomsChannels[it.data.id]?.let { channel -> roomsChannels[it.data.id]?.offer(room)
channel.offer(room)
}
} }
} }
} }
...@@ -231,7 +229,7 @@ class ConnectionManager( ...@@ -231,7 +229,7 @@ class ConnectionManager(
} }
private fun resubscribeRooms() { private fun resubscribeRooms() {
roomMessagesChannels.toList().map { (roomId, channel) -> roomMessagesChannels.toList().map { (roomId, _) ->
client.subscribeRoomMessages(roomId) { _, id -> client.subscribeRoomMessages(roomId) { _, id ->
Timber.d("Subscribed to $roomId: $id") Timber.d("Subscribed to $roomId: $id")
subscriptionIdMap[roomId] = id subscriptionIdMap[roomId] = id
......
...@@ -14,7 +14,6 @@ import chat.rocket.core.model.Message ...@@ -14,7 +14,6 @@ import chat.rocket.core.model.Message
import chat.rocket.core.model.Reactions import chat.rocket.core.model.Reactions
import chat.rocket.core.model.attachment.Attachment import chat.rocket.core.model.attachment.Attachment
import chat.rocket.core.model.attachment.Color 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.Field
import chat.rocket.core.model.attachment.actions.Action import chat.rocket.core.model.attachment.actions.Action
import chat.rocket.core.model.attachment.actions.ButtonAction import chat.rocket.core.model.attachment.actions.ButtonAction
...@@ -153,7 +152,7 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) { ...@@ -153,7 +152,7 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
null null
} }
val attachment = Attachment( list.add(Attachment(
title = title, title = title,
type = type, type = type,
description = description, description = description,
...@@ -179,10 +178,10 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) { ...@@ -179,10 +178,10 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
authorLink = authorLink, authorLink = authorLink,
fields = fields, fields = fields,
fallback = fallback, fallback = fallback,
buttonAlignment = if (actions != null && actions.isNotEmpty()) buttonAlignment ?: "vertical" else null, buttonAlignment = if (actions != null && actions.isNotEmpty()) buttonAlignment
?: "vertical" else null,
actions = actions actions = actions
) ))
list.add(attachment)
} }
} }
return list return list
......
...@@ -46,8 +46,8 @@ class DatabaseMessagesRepository( ...@@ -46,8 +46,8 @@ class DatabaseMessagesRepository(
dbManager.processMessagesBatch(listOf(message)).join() dbManager.processMessagesBatch(listOf(message)).join()
} }
override suspend fun saveAll(messages: List<Message>) { override suspend fun saveAll(newMessages: List<Message>) {
dbManager.processMessagesBatch(messages).join() dbManager.processMessagesBatch(newMessages).join()
} }
override suspend fun removeById(id: String) { override suspend fun removeById(id: String) {
...@@ -78,7 +78,7 @@ class DatabaseMessagesRepository( ...@@ -78,7 +78,7 @@ class DatabaseMessagesRepository(
override suspend fun getLastSyncDate(roomId: String): Long? = withContext(CommonPool) { override suspend fun getLastSyncDate(roomId: String): Long? = withContext(CommonPool) {
retryDB("getLastSync($roomId)") { retryDB("getLastSync($roomId)") {
dbManager.messageDao().getLastSync(roomId)?.let { it.timestamp } dbManager.messageDao().getLastSync(roomId)?.timestamp
} }
} }
} }
\ No newline at end of file
...@@ -14,13 +14,8 @@ class SharedPreferencesAccountsRepository( ...@@ -14,13 +14,8 @@ class SharedPreferencesAccountsRepository(
private val moshi: Moshi private val moshi: Moshi
) : AccountsRepository { ) : AccountsRepository {
override fun save(newAccount: Account) { override fun save(account: Account) {
val accounts = load() save(load().filter { item -> item.serverUrl != item.serverUrl }.toMutableList().apply { add(0, account) })
val newList = accounts.filter { account -> newAccount.serverUrl != account.serverUrl }
.toMutableList()
newList.add(0, newAccount)
save(newList)
} }
override fun load(): List<Account> { override fun load(): List<Account> {
...@@ -28,15 +23,11 @@ class SharedPreferencesAccountsRepository( ...@@ -28,15 +23,11 @@ class SharedPreferencesAccountsRepository(
val type = Types.newParameterizedType(List::class.java, Account::class.java) val type = Types.newParameterizedType(List::class.java, Account::class.java)
val adapter = moshi.adapter<List<Account>>(type) 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) { override fun remove(serverUrl: String) {
val accounts = load() save(load().filter { account -> serverUrl != account.serverUrl }.toMutableList())
val newList = accounts.filter { account -> serverUrl != account.serverUrl }
.toMutableList()
save(newList)
} }
private fun save(accounts: List<Account>) { private fun save(accounts: List<Account>) {
......
...@@ -15,8 +15,7 @@ class SharedPrefsBasicAuthRepository( ...@@ -15,8 +15,7 @@ class SharedPrefsBasicAuthRepository(
) : BasicAuthRepository { ) : BasicAuthRepository {
override fun save(basicAuth: BasicAuth) { override fun save(basicAuth: BasicAuth) {
val newList = load().filter { basicAuth -> basicAuth.host != basicAuth.host } val newList = load().filter { auth -> auth.host != auth.host }.toMutableList()
.toMutableList()
newList.add(0, basicAuth) newList.add(0, basicAuth)
save(newList) save(newList)
} }
...@@ -26,7 +25,7 @@ class SharedPrefsBasicAuthRepository( ...@@ -26,7 +25,7 @@ class SharedPrefsBasicAuthRepository(
val type = Types.newParameterizedType(List::class.java, BasicAuth::class.java) val type = Types.newParameterizedType(List::class.java, BasicAuth::class.java)
val adapter = moshi.adapter<List<BasicAuth>>(type) 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>) { private fun save(basicAuths: List<BasicAuth>) {
......
...@@ -106,18 +106,16 @@ class PasswordFragment : Fragment(), PasswordView, ActionMode.Callback { ...@@ -106,18 +106,16 @@ class PasswordFragment : Fragment(), PasswordView, ActionMode.Callback {
private fun finishActionMode() = actionMode?.finish() private fun finishActionMode() = actionMode?.finish()
private fun listenToChanges(): Disposable { private fun listenToChanges(): Disposable = Observables.combineLatest(
return Observables.combineLatest( text_new_password.asObservable(),
text_new_password.asObservable(), text_confirm_password.asObservable()
text_confirm_password.asObservable() ).subscribe {
).subscribe { val newPassword = it.first.toString()
val newPassword = it.first.toString() val newPasswordConfirmation = it.second.toString()
val newPasswordConfirmation = it.second.toString() if (newPassword.length > 5 && newPassword == newPasswordConfirmation) {
if (newPassword.length > 5 && newPassword == newPasswordConfirmation) { startActionMode()
startActionMode() } else {
} else { finishActionMode()
finishActionMode()
}
} }
} }
......
...@@ -115,8 +115,7 @@ class SettingsFragment : Fragment(), SettingsView, AdapterView.OnItemClickListen ...@@ -115,8 +115,7 @@ class SettingsFragment : Fragment(), SettingsView, AdapterView.OnItemClickListen
} }
private fun setupToolbar() { private fun setupToolbar() {
(activity as AppCompatActivity?)?.supportActionBar?.title = (activity as AppCompatActivity?)?.supportActionBar?.title = getString(R.string.title_settings)
getString(R.string.title_settings)
} }
private fun shareApp() { private fun shareApp() {
......
...@@ -40,7 +40,7 @@ class UserDetailsPresenter @Inject constructor( ...@@ -40,7 +40,7 @@ class UserDetailsPresenter @Inject constructor(
dbManager.getUser(userId)?.let { dbManager.getUser(userId)?.let {
userEntity = it userEntity = it
val avatarUrl = val avatarUrl =
userEntity.username?.let { currentServer.avatarUrl(avatar = it) } userEntity.username?.let { username -> currentServer.avatarUrl(avatar = username) }
val username = userEntity.username val username = userEntity.username
val name = userEntity.name val name = userEntity.name
val utcOffset = val utcOffset =
......
...@@ -29,11 +29,9 @@ import kotlinx.android.synthetic.main.app_bar_chat_room.* ...@@ -29,11 +29,9 @@ import kotlinx.android.synthetic.main.app_bar_chat_room.*
import kotlinx.android.synthetic.main.fragment_user_details.* import kotlinx.android.synthetic.main.fragment_user_details.*
import javax.inject.Inject import javax.inject.Inject
fun newInstance(userId: String): Fragment { fun newInstance(userId: String): Fragment = UserDetailsFragment().apply {
return UserDetailsFragment().apply { arguments = Bundle(1).apply {
arguments = Bundle(1).apply { putString(BUNDLE_USER_ID, userId)
putString(BUNDLE_USER_ID, userId)
}
} }
} }
...@@ -52,12 +50,9 @@ class UserDetailsFragment : Fragment(), UserDetailsView { ...@@ -52,12 +50,9 @@ class UserDetailsFragment : Fragment(), UserDetailsView {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
val bundle = arguments arguments?.run {
if (bundle != null) { userId = getString(BUNDLE_USER_ID, "")
userId = bundle.getString(BUNDLE_USER_ID) } ?: requireNotNull(arguments) { "no arguments supplied when the fragment was instantiated" }
} else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
}
} }
override fun onCreateView( override fun onCreateView(
......
...@@ -191,7 +191,7 @@ class HttpLoggingInterceptor constructor(private val logger: Logger) : Intercept ...@@ -191,7 +191,7 @@ class HttpLoggingInterceptor constructor(private val logger: Logger) : Intercept
val responseBody = response.body() val responseBody = response.body()
val contentLength = responseBody!!.contentLength() 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()}" val responseStr = if (response.message().isEmpty()) "" else " ${response.message()}"
logger.log("<-- ${response.code()}$responseStr ${response.request().url()}" logger.log("<-- ${response.code()}$responseStr ${response.request().url()}"
+ " (" + tookMs + "ms" + (if (!logHeaders) ", $bodySize body" else "") + ')'.toString()) + " (" + tookMs + "ms" + (if (!logHeaders) ", $bodySize body" else "") + ')'.toString())
......
...@@ -69,11 +69,8 @@ fun String.userId(userId: String?): String? { ...@@ -69,11 +69,8 @@ fun String.userId(userId: String?): String? {
return userId?.let { this.replace(it, "") } return userId?.let { this.replace(it, "") }
} }
fun String.lowercaseUrl(): String? { fun String.lowercaseUrl(): String? = HttpUrl.parse(this)?.run {
val httpUrl = HttpUrl.parse(this) newBuilder().scheme(scheme().toLowerCase()).build().toString()
val newScheme = httpUrl?.scheme()?.toLowerCase()
return httpUrl?.newBuilder()?.scheme(newScheme)?.build()?.toString()
} }
fun String?.isNotNullNorEmpty(): Boolean = this != null && this.isNotEmpty() fun String?.isNotNullNorEmpty(): Boolean = this != null && this.isNotEmpty()
......
...@@ -80,12 +80,10 @@ fun AppCompatActivity.toPreviousView() { ...@@ -80,12 +80,10 @@ fun AppCompatActivity.toPreviousView() {
} }
fun Activity.hideKeyboard() { fun Activity.hideKeyboard() {
if (currentFocus != null) { currentFocus?.run {
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager (getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).also {
imm.hideSoftInputFromWindow( it.hideSoftInputFromWindow(windowToken, InputMethodManager.RESULT_UNCHANGED_SHOWN)
currentFocus.windowToken, }
InputMethodManager.RESULT_UNCHANGED_SHOWN
)
} }
} }
......
...@@ -51,7 +51,7 @@ fun Uri.getFileSize(context: Context): Int { ...@@ -51,7 +51,7 @@ fun Uri.getFileSize(context: Context): Int {
fun Uri.getMimeType(context: Context): String { fun Uri.getMimeType(context: Context): String {
return if (scheme == ContentResolver.SCHEME_CONTENT) { return if (scheme == ContentResolver.SCHEME_CONTENT) {
context.contentResolver.getType(this) context.contentResolver?.getType(this) ?: ""
} else { } else {
val fileExtension = MimeTypeMap.getFileExtensionFromUrl(toString()) val fileExtension = MimeTypeMap.getFileExtensionFromUrl(toString())
if (fileExtension != null) { if (fileExtension != null) {
......
...@@ -27,13 +27,10 @@ class AdminPanelWebViewFragment : DaggerFragment() { ...@@ -27,13 +27,10 @@ class AdminPanelWebViewFragment : DaggerFragment() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val bundle = arguments arguments?.run {
if (bundle != null) { webPageUrl = getString(BUNDLE_WEB_PAGE_URL, "")
webPageUrl = bundle.getString(BUNDLE_WEB_PAGE_URL) userToken = getString(BUNDLE_USER_TOKEN, "")
userToken = bundle.getString(BUNDLE_USER_TOKEN) } ?: requireNotNull(arguments) { "no arguments supplied when the fragment was instantiated" }
} else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
}
} }
override fun onCreateView( override fun onCreateView(
...@@ -65,7 +62,7 @@ class AdminPanelWebViewFragment : DaggerFragment() { ...@@ -65,7 +62,7 @@ class AdminPanelWebViewFragment : DaggerFragment() {
web_view.webViewClient = object : WebViewClient() { web_view.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView, url: String) { override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url) super.onPageFinished(view, url)
ui { _ -> ui {
view_loading.hide() view_loading.hide()
web_view.evaluateJavascript("Meteor.loginWithToken('$userToken', function() { })") {} web_view.evaluateJavascript("Meteor.loginWithToken('$userToken', function() { })") {}
} }
......
...@@ -14,7 +14,7 @@ import androidx.recyclerview.widget.RecyclerView ...@@ -14,7 +14,7 @@ import androidx.recyclerview.widget.RecyclerView
* @see RecyclerView.ItemDecoration * @see RecyclerView.ItemDecoration
*/ */
class DividerItemDecoration() : RecyclerView.ItemDecoration() { class DividerItemDecoration() : RecyclerView.ItemDecoration() {
private lateinit var divider: Drawable private var divider: Drawable? = null
private var boundStart = 0 private var boundStart = 0
private var boundEnd = 0 private var boundEnd = 0
...@@ -39,10 +39,7 @@ class DividerItemDecoration() : RecyclerView.ItemDecoration() { ...@@ -39,10 +39,7 @@ class DividerItemDecoration() : RecyclerView.ItemDecoration() {
// Custom divider will be used. // Custom divider will be used.
constructor(context: Context, @DrawableRes drawableResId: Int) : this() { constructor(context: Context, @DrawableRes drawableResId: Int) : this() {
val customDrawable = ContextCompat.getDrawable(context, drawableResId) divider = ContextCompat.getDrawable(context, drawableResId)
if (customDrawable != null) {
divider = customDrawable
}
} }
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
...@@ -59,10 +56,10 @@ class DividerItemDecoration() : RecyclerView.ItemDecoration() { ...@@ -59,10 +56,10 @@ class DividerItemDecoration() : RecyclerView.ItemDecoration() {
val params = child.layoutParams as RecyclerView.LayoutParams val params = child.layoutParams as RecyclerView.LayoutParams
val top = child.bottom + params.bottomMargin val top = child.bottom + params.bottomMargin
val bottom = top + divider.intrinsicHeight val bottom = top + (divider?.intrinsicHeight ?: 0)
divider.setBounds(left, top, right, bottom) divider?.setBounds(left, top, right, bottom)
divider.draw(c) divider?.draw(c)
} }
} }
......
package chat.rocket.android.util.extension package chat.rocket.android.util.extension
import android.content.Context
import android.os.Build
import android.widget.TextView
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
fun SearchView.onQueryTextListener(queryListener: (String) -> Unit) { fun SearchView.onQueryTextListener(queryListener: (String) -> Unit) {
...@@ -14,4 +17,12 @@ fun SearchView.onQueryTextListener(queryListener: (String) -> Unit) { ...@@ -14,4 +17,12 @@ fun SearchView.onQueryTextListener(queryListener: (String) -> Unit) {
return true return true
} }
}) })
}
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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment