diff --git a/app/build.gradle b/app/build.gradle
index 9bfe286740..c8a2a36f39 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -105,6 +105,7 @@ dependencies {
implementation project(':util')
implementation project(':core')
implementation project(':suggestions')
+ implementation project(':themelibrary')
implementation libraries.kotlin
implementation libraries.coroutinesCore
@@ -121,6 +122,9 @@ dependencies {
implementation libraries.dagger
implementation libraries.daggerSupport
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ implementation 'androidx.appcompat:appcompat:1.0.2'
+ implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
kapt libraries.daggerProcessor
kapt libraries.daggerAndroidApt
@@ -180,6 +184,7 @@ dependencies {
testImplementation libraries.truth
androidTestImplementation libraries.espressoCore
androidTestImplementation libraries.espressoIntents
+ implementation 'com.google.code.gson:gson:2.8.5'
}
androidExtensions {
@@ -200,4 +205,4 @@ task compileSdk(type: Exec) {
preBuild.dependsOn compileSdk
if (isPlay) {
apply plugin: 'com.google.gms.google-services'
-}
\ No newline at end of file
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 4aad7ac636..69c78f40d5 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -19,23 +19,21 @@
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
+ android:theme="@style/AppTheme"
tools:replace="android:name">
-
+
-
-
@@ -45,7 +43,6 @@
-
-
-
+ />
-
-
-
-
-
-
-
-
+ android:name=".thememanager.ui.ThemesActivity"
+ android:windowSoftInputMode="adjustResize|stateAlwaysHidden" />
+
+
-
+
+
\ No newline at end of file
diff --git a/app/src/main/java/chat/rocket/android/app/DrawableHelper.kt b/app/src/main/java/chat/rocket/android/app/DrawableHelper.kt
index 8b3220472c..e1e9a73257 100644
--- a/app/src/main/java/chat/rocket/android/app/DrawableHelper.kt
+++ b/app/src/main/java/chat/rocket/android/app/DrawableHelper.kt
@@ -142,6 +142,16 @@ object DrawableHelper {
textView.setCompoundDrawablesWithIntrinsicBounds(startDrawable, null, endDrawable, null)
}
+ /**
+ * Compounds a Drawable (to appear on top of a text) into a TextView.
+ *
+ * @param textView The TextView.
+ * @param drawable The Drawable.
+ * @see compoundDrawables
+ */
+ fun compoundTopDrawable(textView: TextView, drawable: Drawable) =
+ textView.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null)
+
/**
* Returns the user status drawable.
*
diff --git a/app/src/main/java/chat/rocket/android/authentication/login/ui/LoginFragment.kt b/app/src/main/java/chat/rocket/android/authentication/login/ui/LoginFragment.kt
index 98169b957d..8a7a945cff 100644
--- a/app/src/main/java/chat/rocket/android/authentication/login/ui/LoginFragment.kt
+++ b/app/src/main/java/chat/rocket/android/authentication/login/ui/LoginFragment.kt
@@ -20,17 +20,15 @@ import chat.rocket.android.helper.getCredentials
import chat.rocket.android.helper.hasCredentialsSupport
import chat.rocket.android.helper.requestStoredCredentials
import chat.rocket.android.helper.saveCredentials
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extension.asObservable
-import chat.rocket.android.util.extensions.clearLightStatusBar
-import chat.rocket.android.util.extensions.inflate
-import chat.rocket.android.util.extensions.showToast
-import chat.rocket.android.util.extensions.textContent
-import chat.rocket.android.util.extensions.ui
+import chat.rocket.android.util.extensions.*
import dagger.android.support.AndroidSupportInjection
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.Observables
import kotlinx.android.synthetic.main.app_bar.*
import kotlinx.android.synthetic.main.fragment_authentication_log_in.*
+import kotlinx.android.synthetic.main.fragment_authentication_log_in.view_loading
import javax.inject.Inject
private const val SERVER_NAME = "server_name"
@@ -73,6 +71,11 @@ class LoginFragment : Fragment(), LoginView {
setupToolbar()
presenter.setupView()
subscribeEditTexts()
+
+// if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
+ tintEditTextDrawableStart()
+// }
+
setupOnClickListener()
analyticsManager.logScreenView(ScreenViewEvent.Login)
}
@@ -111,7 +114,7 @@ class LoginFragment : Fragment(), LoginView {
private fun setupToolbar() {
with(activity as AuthenticationActivity) {
- this.clearLightStatusBar()
+ view?.let {this.clearInvisibleStatusBar(it)}
toolbar.isVisible = true
toolbar.title = serverName?.replace(getString(R.string.default_protocol), "")
}
@@ -167,7 +170,7 @@ class LoginFragment : Fragment(), LoginView {
override fun enableButtonLogin() {
context?.let {
ViewCompat.setBackgroundTintList(
- button_log_in, ContextCompat.getColorStateList(it, R.color.colorAccent)
+ button_log_in, ContextCompat.getColorStateList(it, ThemeUtil.getThemeColorResource(R.attr.colorAccent))
)
button_log_in.isEnabled = true
}
@@ -178,7 +181,7 @@ class LoginFragment : Fragment(), LoginView {
context?.let {
ViewCompat.setBackgroundTintList(
button_log_in,
- ContextCompat.getColorStateList(it, R.color.colorAuthenticationButtonDisabled)
+ ContextCompat.getColorStateList(it, ThemeUtil.getThemeColorResource(R.attr.colorButtonDisabled))
)
button_log_in.isEnabled = false
}
@@ -187,9 +190,7 @@ class LoginFragment : Fragment(), LoginView {
override fun enableButtonForgetPassword() {
context?.let {
button_forgot_your_password.isEnabled = true
- button_forgot_your_password.setTextColor(
- ContextCompat.getColorStateList(it, R.color.colorAccent)
- )
+ button_forgot_your_password.setTextColor(ThemeUtil.getThemeColor(R.attr.colorAccent))
}
}
@@ -197,7 +198,7 @@ class LoginFragment : Fragment(), LoginView {
context?.let {
button_forgot_your_password.isEnabled = false
button_forgot_your_password.setTextColor(
- ContextCompat.getColorStateList(it, R.color.colorAuthenticationButtonDisabled)
+ ContextCompat.getColorStateList(it, ThemeUtil.getThemeColorResource(R.attr.colorButtonDisabled))
)
}
}
@@ -253,4 +254,15 @@ class LoginFragment : Fragment(), LoginView {
text_password.isEnabled = false
}
}
+
+ private fun tintEditTextDrawableStart() {
+ ui {
+ val atDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_at_black_20dp, it)
+ val keyDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_key_black_20dp, it)
+ val drawables = arrayOf(atDrawable, keyDrawable)
+ DrawableHelper.wrapDrawables(drawables)
+ DrawableHelper.tintDrawables(drawables, it, ThemeUtil.getThemeColorResource(R.attr.colorDrawableStrongTint))
+ DrawableHelper.compoundDrawables( arrayOf(text_username_or_email, text_password), drawables)
+ }
+ }
}
diff --git a/app/src/main/java/chat/rocket/android/authentication/loginoptions/ui/LoginOptionsFragment.kt b/app/src/main/java/chat/rocket/android/authentication/loginoptions/ui/LoginOptionsFragment.kt
index 4d317c817c..c4498dc4a7 100644
--- a/app/src/main/java/chat/rocket/android/authentication/loginoptions/ui/LoginOptionsFragment.kt
+++ b/app/src/main/java/chat/rocket/android/authentication/loginoptions/ui/LoginOptionsFragment.kt
@@ -213,9 +213,14 @@ class LoginOptionsFragment : Fragment(), LoginOptionsView {
private fun setupToolbar() {
with(activity as AuthenticationActivity) {
- this.clearLightStatusBar()
+ view?.let {this.clearInvisibleStatusBar(it)}
toolbar.isVisible = true
toolbar.title = serverName?.replace(getString(R.string.default_protocol), "")
+ val overflowIcon = toolbar.overflowIcon
+ overflowIcon?.let{
+ val wrappedDrawable = DrawableHelper.wrapDrawable(it)
+ DrawableHelper.tintDrawable(wrappedDrawable, this, R.color.colorWhite)
+ }
}
}
diff --git a/app/src/main/java/chat/rocket/android/authentication/onboarding/ui/OnBoardingFragment.kt b/app/src/main/java/chat/rocket/android/authentication/onboarding/ui/OnBoardingFragment.kt
index c2e1a10603..d1c2906a0d 100644
--- a/app/src/main/java/chat/rocket/android/authentication/onboarding/ui/OnBoardingFragment.kt
+++ b/app/src/main/java/chat/rocket/android/authentication/onboarding/ui/OnBoardingFragment.kt
@@ -12,10 +12,7 @@ import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.authentication.onboarding.presentation.OnBoardingPresenter
import chat.rocket.android.authentication.onboarding.presentation.OnBoardingView
import chat.rocket.android.authentication.ui.AuthenticationActivity
-import chat.rocket.android.util.extensions.inflate
-import chat.rocket.android.util.extensions.setLightStatusBar
-import chat.rocket.android.util.extensions.showToast
-import chat.rocket.android.util.extensions.ui
+import chat.rocket.android.util.extensions.*
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.app_bar.*
import kotlinx.android.synthetic.main.fragment_authentication_on_boarding.*
@@ -48,7 +45,7 @@ class OnBoardingFragment : Fragment(), OnBoardingView {
private fun setupToolbar() {
with(activity as AuthenticationActivity) {
- view?.let { this.setLightStatusBar(it) }
+ view?.let { this.setInvisibleStatusBar(it) }
toolbar.isVisible = false
}
}
diff --git a/app/src/main/java/chat/rocket/android/authentication/registerusername/ui/RegisterUsernameFragment.kt b/app/src/main/java/chat/rocket/android/authentication/registerusername/ui/RegisterUsernameFragment.kt
index 0ddd217bd4..f51922f1d4 100644
--- a/app/src/main/java/chat/rocket/android/authentication/registerusername/ui/RegisterUsernameFragment.kt
+++ b/app/src/main/java/chat/rocket/android/authentication/registerusername/ui/RegisterUsernameFragment.kt
@@ -1,7 +1,6 @@
package chat.rocket.android.authentication.registerusername.ui
import DrawableHelper
-import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -15,6 +14,7 @@ import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.authentication.registerusername.presentation.RegisterUsernamePresenter
import chat.rocket.android.authentication.registerusername.presentation.RegisterUsernameView
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showKeyboard
@@ -71,9 +71,9 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView {
showKeyboard(text_username)
}
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
+// if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
tintEditTextDrawableStart()
- }
+// }
setupOnClickListener()
subscribeEditText()
@@ -89,7 +89,7 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView {
override fun enableButtonUseThisUsername() {
context?.let {
ViewCompat.setBackgroundTintList(
- button_use_this_username, ContextCompat.getColorStateList(it, R.color.colorAccent)
+ button_use_this_username, ContextCompat.getColorStateList(it, ThemeUtil.getThemeColorResource(R.attr.colorAccent))
)
button_use_this_username.isEnabled = true
}
@@ -99,7 +99,7 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView {
context?.let {
ViewCompat.setBackgroundTintList(
button_use_this_username,
- ContextCompat.getColorStateList(it, R.color.colorAuthenticationButtonDisabled)
+ ContextCompat.getColorStateList(it, ThemeUtil.getThemeColorResource(R.attr.colorButtonDisabled))
)
button_use_this_username.isEnabled = false
}
@@ -139,7 +139,7 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView {
ui {
val atDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_at_black_20dp, it)
DrawableHelper.wrapDrawable(atDrawable)
- DrawableHelper.tintDrawable(atDrawable, it, R.color.colorDrawableTintGrey)
+ DrawableHelper.tintDrawable(atDrawable, it, ThemeUtil.getThemeColorResource(R.attr.colorDrawableStrongTint))
DrawableHelper.compoundStartDrawable(text_username, atDrawable)
}
}
diff --git a/app/src/main/java/chat/rocket/android/authentication/resetpassword/ui/ResetPasswordFragment.kt b/app/src/main/java/chat/rocket/android/authentication/resetpassword/ui/ResetPasswordFragment.kt
index 61b5d09c25..ccf5b601ed 100644
--- a/app/src/main/java/chat/rocket/android/authentication/resetpassword/ui/ResetPasswordFragment.kt
+++ b/app/src/main/java/chat/rocket/android/authentication/resetpassword/ui/ResetPasswordFragment.kt
@@ -13,6 +13,7 @@ import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.authentication.resetpassword.presentation.ResetPasswordPresenter
import chat.rocket.android.authentication.resetpassword.presentation.ResetPasswordView
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.isEmail
@@ -55,6 +56,10 @@ class ResetPasswordFragment : Fragment(), ResetPasswordView {
showKeyboard(text_email)
}
+// if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
+ tintEditTextDrawableStart()
+// }
+
setupOnClickListener()
subscribeEditText()
@@ -74,7 +79,7 @@ class ResetPasswordFragment : Fragment(), ResetPasswordView {
override fun enableButtonConnect() {
context?.let {
ViewCompat.setBackgroundTintList(
- button_reset_password, ContextCompat.getColorStateList(it, R.color.colorAccent)
+ button_reset_password, ContextCompat.getColorStateList(it, ThemeUtil.getThemeColorResource(R.attr.colorAccent))
)
button_reset_password.isEnabled = true
}
@@ -84,7 +89,7 @@ class ResetPasswordFragment : Fragment(), ResetPasswordView {
context?.let {
ViewCompat.setBackgroundTintList(
button_reset_password,
- ContextCompat.getColorStateList(it, R.color.colorAuthenticationButtonDisabled)
+ ContextCompat.getColorStateList(it, ThemeUtil.getThemeColorResource(R.attr.colorButtonDisabled))
)
button_reset_password.isEnabled = false
}
@@ -147,4 +152,13 @@ class ResetPasswordFragment : Fragment(), ResetPasswordView {
}
private fun unsubscribeEditText() = emailAddressDisposable.dispose()
+
+ private fun tintEditTextDrawableStart() {
+ ui {
+ val atDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_email_black_20dp, it)
+ DrawableHelper.wrapDrawable(atDrawable)
+ DrawableHelper.tintDrawable(atDrawable, it, ThemeUtil.getThemeColorResource(R.attr.colorDrawableStrongTint))
+ DrawableHelper.compoundStartDrawable(text_email, atDrawable)
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/chat/rocket/android/authentication/server/ui/ServerFragment.kt b/app/src/main/java/chat/rocket/android/authentication/server/ui/ServerFragment.kt
index eb8668ac58..89d483ed5b 100644
--- a/app/src/main/java/chat/rocket/android/authentication/server/ui/ServerFragment.kt
+++ b/app/src/main/java/chat/rocket/android/authentication/server/ui/ServerFragment.kt
@@ -25,15 +25,9 @@ import chat.rocket.android.authentication.server.presentation.ServerPresenter
import chat.rocket.android.authentication.server.presentation.ServerView
import chat.rocket.android.authentication.ui.AuthenticationActivity
import chat.rocket.android.helper.KeyboardHelper
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extension.asObservable
-import chat.rocket.android.util.extensions.hintContent
-import chat.rocket.android.util.extensions.inflate
-import chat.rocket.android.util.extensions.isValidUrl
-import chat.rocket.android.util.extensions.sanitize
-import chat.rocket.android.util.extensions.setLightStatusBar
-import chat.rocket.android.util.extensions.showToast
-import chat.rocket.android.util.extensions.textContent
-import chat.rocket.android.util.extensions.ui
+import chat.rocket.android.util.extensions.*
import chat.rocket.common.util.ifNull
import dagger.android.support.AndroidSupportInjection
import io.reactivex.disposables.Disposable
@@ -113,17 +107,19 @@ class ServerFragment : Fragment(), ServerView {
private fun setupToolbar() {
with(activity as AuthenticationActivity) {
- view?.let { setLightStatusBar(it) }
+ view?.let { setInvisibleStatusBar(it) }
toolbar.isVisible = false
}
}
private fun setupSpinner() {
context?.let {
- spinner_server_protocol.adapter = ArrayAdapter(
- it,
- android.R.layout.simple_dropdown_item_1line, arrayOf("https://", "http://")
+ val adapter = ArrayAdapter(
+ it,
+ android.R.layout.simple_dropdown_item_1line, arrayOf("https://", "http://")
)
+ adapter.setDropDownViewResource(R.layout.spinner_dropdown_item)
+ spinner_server_protocol.adapter = adapter
spinner_server_protocol.onItemSelectedListener =
object : AdapterView.OnItemSelectedListener {
@@ -159,7 +155,7 @@ class ServerFragment : Fragment(), ServerView {
override fun enableButtonConnect() {
context?.let {
ViewCompat.setBackgroundTintList(
- button_connect, ContextCompat.getColorStateList(it, R.color.colorAccent)
+ button_connect, ContextCompat.getColorStateList(it, ThemeUtil.getThemeColorResource(R.attr.colorAccent))
)
button_connect.isEnabled = true
}
@@ -169,7 +165,7 @@ class ServerFragment : Fragment(), ServerView {
context?.let {
ViewCompat.setBackgroundTintList(
button_connect,
- ContextCompat.getColorStateList(it, R.color.colorAuthenticationButtonDisabled)
+ ContextCompat.getColorStateList(it, ThemeUtil.getThemeColorResource(R.attr.colorButtonDisabled))
)
button_connect.isEnabled = false
}
@@ -282,7 +278,7 @@ class ServerFragment : Fragment(), ServerView {
private fun addDomain() {
val cursorPosition = text_server_url.length()
text_server_url.append(SpannableStringBuilder()
- .color(R.color.colorAuthenticationSecondaryText) { append("rocket.chat") })
+ .color(ThemeUtil.getThemeColorResource(R.attr.colorDescriptiveText)) { append("rocket.chat") })
text_server_url.setSelection(cursorPosition)
appendedText = text_server_url.text.toString()
isDomainAppended = true
diff --git a/app/src/main/java/chat/rocket/android/authentication/signup/ui/SignupFragment.kt b/app/src/main/java/chat/rocket/android/authentication/signup/ui/SignupFragment.kt
index fcf39174fb..3c6dff7d9d 100644
--- a/app/src/main/java/chat/rocket/android/authentication/signup/ui/SignupFragment.kt
+++ b/app/src/main/java/chat/rocket/android/authentication/signup/ui/SignupFragment.kt
@@ -15,7 +15,9 @@ import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.authentication.signup.presentation.SignupPresenter
import chat.rocket.android.authentication.signup.presentation.SignupView
+import chat.rocket.android.authentication.ui.AuthenticationActivity
import chat.rocket.android.helper.saveCredentials
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.isEmail
@@ -54,6 +56,7 @@ class SignupFragment : Fragment(), SignupView {
super.onViewCreated(view, savedInstanceState)
subscribeEditTexts()
+ tintEditTextDrawableStart()
setupOnClickListener()
analyticsManager.logScreenView(ScreenViewEvent.SignUp)
@@ -89,7 +92,7 @@ class SignupFragment : Fragment(), SignupView {
override fun enableButtonRegister() {
context?.let {
ViewCompat.setBackgroundTintList(
- button_register, ContextCompat.getColorStateList(it, R.color.colorAccent)
+ button_register, ContextCompat.getColorStateList(it, ThemeUtil.getThemeColorResource(R.attr.colorAccent))
)
button_register.isEnabled = true
}
@@ -100,7 +103,7 @@ class SignupFragment : Fragment(), SignupView {
context?.let {
ViewCompat.setBackgroundTintList(
button_register,
- ContextCompat.getColorStateList(it, R.color.colorAuthenticationButtonDisabled)
+ ContextCompat.getColorStateList(it, ThemeUtil.getThemeColorResource(R.attr.colorButtonDisabled))
)
button_register.isEnabled = false
}
@@ -180,4 +183,22 @@ class SignupFragment : Fragment(), SignupView {
text_password.isEnabled = false
text_email.isEnabled = false
}
+
+ private fun tintEditTextDrawableStart() {
+ (activity as AuthenticationActivity).apply {
+ val personDrawable =
+ DrawableHelper.getDrawableFromId(R.drawable.ic_person_black_20dp, this)
+ val atDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_at_black_20dp, this)
+ val keyDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_key_black_20dp, this)
+ val emailDrawable =
+ DrawableHelper.getDrawableFromId(R.drawable.ic_email_black_20dp, this)
+
+ val drawables = arrayOf(personDrawable, atDrawable, keyDrawable, emailDrawable)
+ DrawableHelper.wrapDrawables(drawables)
+ DrawableHelper.tintDrawables(drawables, this, ThemeUtil.getThemeColorResource(R.attr.colorDrawableStrongTint))
+ DrawableHelper.compoundDrawables(
+ arrayOf(text_name, text_username, text_password, text_email), drawables
+ )
+ }
+ }
}
diff --git a/app/src/main/java/chat/rocket/android/authentication/twofactor/ui/TwoFAFragment.kt b/app/src/main/java/chat/rocket/android/authentication/twofactor/ui/TwoFAFragment.kt
index 7f01393176..288111ba85 100644
--- a/app/src/main/java/chat/rocket/android/authentication/twofactor/ui/TwoFAFragment.kt
+++ b/app/src/main/java/chat/rocket/android/authentication/twofactor/ui/TwoFAFragment.kt
@@ -15,6 +15,7 @@ import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.authentication.twofactor.presentation.TwoFAPresenter
import chat.rocket.android.authentication.twofactor.presentation.TwoFAView
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast
@@ -86,7 +87,7 @@ class TwoFAFragment : Fragment(), TwoFAView {
override fun enableButtonConfirm() {
context?.let {
ViewCompat.setBackgroundTintList(
- button_confirm, ContextCompat.getColorStateList(it, R.color.colorAccent)
+ button_confirm, ContextCompat.getColorStateList(it, ThemeUtil.getThemeColorResource(R.attr.colorAccent))
)
button_confirm.isEnabled = true
}
@@ -96,7 +97,7 @@ class TwoFAFragment : Fragment(), TwoFAView {
context?.let {
ViewCompat.setBackgroundTintList(
button_confirm,
- ContextCompat.getColorStateList(it, R.color.colorAuthenticationButtonDisabled)
+ ContextCompat.getColorStateList(it, ThemeUtil.getThemeColorResource(R.attr.colorButtonDisabled))
)
button_confirm.isEnabled = false
}
diff --git a/app/src/main/java/chat/rocket/android/authentication/ui/AuthenticationActivity.kt b/app/src/main/java/chat/rocket/android/authentication/ui/AuthenticationActivity.kt
index 36bfcfcfea..b82daa7753 100644
--- a/app/src/main/java/chat/rocket/android/authentication/ui/AuthenticationActivity.kt
+++ b/app/src/main/java/chat/rocket/android/authentication/ui/AuthenticationActivity.kt
@@ -11,6 +11,8 @@ import androidx.fragment.app.Fragment
import chat.rocket.android.R
import chat.rocket.android.authentication.domain.model.DeepLinkInfo
import chat.rocket.android.authentication.presentation.AuthenticationPresenter
+import chat.rocket.android.thememanager.BaseActivity
+import chat.rocket.android.util.extensions.addFragment
import chat.rocket.android.dynamiclinks.DynamicLinksForFirebase
import chat.rocket.android.util.extensions.getDeepLinkInfo
import chat.rocket.android.util.extensions.isDynamicLink
@@ -23,7 +25,7 @@ import dagger.android.support.HasSupportFragmentInjector
import kotlinx.android.synthetic.main.app_bar.*
import javax.inject.Inject
-class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector {
+class AuthenticationActivity : BaseActivity(), HasSupportFragmentInjector {
@Inject
lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector
@Inject
diff --git a/app/src/main/java/chat/rocket/android/chatdetails/adapter/OptionViewHolder.kt b/app/src/main/java/chat/rocket/android/chatdetails/adapter/OptionViewHolder.kt
index a9cec0d045..0e3a029385 100644
--- a/app/src/main/java/chat/rocket/android/chatdetails/adapter/OptionViewHolder.kt
+++ b/app/src/main/java/chat/rocket/android/chatdetails/adapter/OptionViewHolder.kt
@@ -7,6 +7,7 @@ import android.widget.TextView
import chat.rocket.android.R
import chat.rocket.android.chatdetails.domain.Option
import chat.rocket.android.chatrooms.adapter.ViewHolder
+import chat.rocket.android.thememanager.util.ThemeUtil
import kotlinx.android.synthetic.main.item_detail_option.view.*
class OptionViewHolder(
@@ -24,7 +25,7 @@ class OptionViewHolder(
val drawable = DrawableHelper.getDrawableFromId(option.icon, itemView.context)
drawable.let { image ->
val mutateDrawable = DrawableHelper.wrapDrawable(image).mutate()
- DrawableHelper.tintDrawable(mutateDrawable, itemView.context, R.color.colorPrimaryText)
+ DrawableHelper.tintDrawable(mutateDrawable, itemView.context, ThemeUtil.getThemeColorResource(R.attr.colorPrimaryText))
view.setImageDrawable(mutateDrawable)
}
}
diff --git a/app/src/main/java/chat/rocket/android/chatdetails/ui/ChatDetailsFragment.kt b/app/src/main/java/chat/rocket/android/chatdetails/ui/ChatDetailsFragment.kt
index f14ac6d5c0..f3ec7182cb 100644
--- a/app/src/main/java/chat/rocket/android/chatdetails/ui/ChatDetailsFragment.kt
+++ b/app/src/main/java/chat/rocket/android/chatdetails/ui/ChatDetailsFragment.kt
@@ -21,6 +21,7 @@ import chat.rocket.android.chatdetails.viewmodel.ChatDetailsViewModelFactory
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.server.domain.CurrentServerRepository
import chat.rocket.android.server.domain.GetSettingsInteractor
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui
@@ -188,13 +189,13 @@ class ChatDetailsFragment : Fragment(), ChatDetailsView {
is RoomType.PrivateGroup -> {
DrawableHelper.getDrawableFromId(R.drawable.ic_lock_black_12_dp, context!!)
}
- else -> null
+ else -> DrawableHelper.getDrawableFromId(R.drawable.ic_hashtag_black_12dp, context!!)
}
drawable?.let {
val wrappedDrawable = DrawableHelper.wrapDrawable(it)
val mutableDrawable = wrappedDrawable.mutate()
- DrawableHelper.tintDrawable(mutableDrawable, context!!, R.color.colorPrimary)
+ DrawableHelper.tintDrawable(mutableDrawable, context!!, ThemeUtil.getThemeColorResource(R.attr.colorMessageText))
DrawableHelper.compoundStartDrawable(name, mutableDrawable)
}
}
diff --git a/app/src/main/java/chat/rocket/android/chatinformation/ui/MessageInfoActivity.kt b/app/src/main/java/chat/rocket/android/chatinformation/ui/MessageInfoActivity.kt
index 92fd1e9b09..88af23ec0c 100644
--- a/app/src/main/java/chat/rocket/android/chatinformation/ui/MessageInfoActivity.kt
+++ b/app/src/main/java/chat/rocket/android/chatinformation/ui/MessageInfoActivity.kt
@@ -6,6 +6,8 @@ import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import chat.rocket.android.R
+import chat.rocket.android.thememanager.BaseActivity
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extensions.addFragment
import chat.rocket.android.util.extensions.textContent
import dagger.android.AndroidInjection
@@ -23,7 +25,7 @@ fun Context.messageInformationIntent(messageId: String): Intent {
private const val INTENT_MESSAGE_ID = "message_id"
-class MessageInfoActivity : AppCompatActivity(), HasSupportFragmentInjector {
+class MessageInfoActivity : BaseActivity(), HasSupportFragmentInjector {
@Inject
lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector
@@ -45,6 +47,7 @@ class MessageInfoActivity : AppCompatActivity(), HasSupportFragmentInjector {
private fun setupToolbar() {
text_toolbar_title.textContent = getString(R.string.message_information_title)
+ toolbar.setBackgroundColor(ThemeUtil.getThemeColor(R.attr.colorPrimary))
setSupportActionBar(toolbar)
supportActionBar?.setDisplayShowTitleEnabled(false)
toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp)
diff --git a/app/src/main/java/chat/rocket/android/chatroom/adapter/AttachmentViewHolder.kt b/app/src/main/java/chat/rocket/android/chatroom/adapter/AttachmentViewHolder.kt
index 2c5ed9fdb8..ad4e21c3e6 100644
--- a/app/src/main/java/chat/rocket/android/chatroom/adapter/AttachmentViewHolder.kt
+++ b/app/src/main/java/chat/rocket/android/chatroom/adapter/AttachmentViewHolder.kt
@@ -15,6 +15,7 @@ import chat.rocket.android.chatroom.uimodel.AttachmentUiModel
import chat.rocket.android.emoji.EmojiReactionListener
import chat.rocket.android.helper.ImageHelper
import chat.rocket.android.player.PlayerActivity
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extensions.content
import chat.rocket.android.util.extensions.isVisible
import chat.rocket.android.util.extensions.openTabbedUrl
@@ -42,7 +43,7 @@ class AttachmentViewHolder(
itemView.play_button
)
- private val quoteBarColor = ContextCompat.getColor(itemView.context, R.color.quoteBar)
+ private val quoteBarColor = ThemeUtil.getThemeColor(R.attr.colorQuoteBar)
init {
with(itemView) {
@@ -80,6 +81,7 @@ class AttachmentViewHolder(
text_author_name.isVisible = data.hasAuthorLink && data.hasAuthorName
if (data.hasAuthorLink && data.hasAuthorName) {
bindAuthorLink(data)
+ text_author_name.setTextColor(ThemeUtil.getThemeColor(R.attr.colorAccent))
}
// If not media or message, show the text with quote bar
diff --git a/app/src/main/java/chat/rocket/android/chatroom/adapter/MessageReactionsAdapter.kt b/app/src/main/java/chat/rocket/android/chatroom/adapter/MessageReactionsAdapter.kt
index 87da4d9576..699bff866a 100644
--- a/app/src/main/java/chat/rocket/android/chatroom/adapter/MessageReactionsAdapter.kt
+++ b/app/src/main/java/chat/rocket/android/chatroom/adapter/MessageReactionsAdapter.kt
@@ -14,6 +14,7 @@ import chat.rocket.android.emoji.EmojiKeyboardListener
import chat.rocket.android.emoji.EmojiPickerPopup
import chat.rocket.android.emoji.EmojiReactionListener
import chat.rocket.android.infrastructure.LocalRepository
+import chat.rocket.android.thememanager.util.ThemeUtil
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.item_reaction.view.*
import java.util.concurrent.CopyOnWriteArrayList
@@ -114,7 +115,7 @@ class MessageReactionsAdapter : RecyclerView.Adapter()
val myself = localRepository.get(LocalRepository.CURRENT_USERNAME_KEY)
if (reaction.usernames.contains(myself)) {
val context = itemView.context
- text_count.setTextColor(ContextCompat.getColor(context, R.color.colorAccent))
+ text_count.setTextColor(ThemeUtil.getThemeColor(R.attr.colorAccent))
}
text_count.text = reaction.count.toString()
diff --git a/app/src/main/java/chat/rocket/android/chatroom/adapter/MessageViewHolder.kt b/app/src/main/java/chat/rocket/android/chatroom/adapter/MessageViewHolder.kt
index 3c084461f5..e46c56aa05 100644
--- a/app/src/main/java/chat/rocket/android/chatroom/adapter/MessageViewHolder.kt
+++ b/app/src/main/java/chat/rocket/android/chatroom/adapter/MessageViewHolder.kt
@@ -6,10 +6,12 @@ import android.text.Spannable
import android.text.method.LinkMovementMethod
import android.text.style.ImageSpan
import android.view.View
+import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import chat.rocket.android.R
import chat.rocket.android.chatroom.uimodel.MessageUiModel
import chat.rocket.android.emoji.EmojiReactionListener
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.core.model.MessageType
import chat.rocket.core.model.isSystemMessage
import com.bumptech.glide.load.resource.gif.GifDrawable
@@ -52,12 +54,14 @@ class MessageViewHolder(
}
text_content.text_content.text = data.content
+ text_content.setLinkTextColor(ThemeUtil.getThemeColor(R.attr.colorAccent))
button_join_video_call.isVisible = data.message.type is MessageType.JitsiCallStarted
button_join_video_call.setOnClickListener { joinVideoCallListener(it) }
image_avatar.setImageURI(data.avatar)
- text_content.setTextColor(if (data.isTemporary) Color.GRAY else Color.BLACK)
+ text_content.setTextColor(if (data.isTemporary) ThemeUtil.getThemeColor(R.attr.colorControlText)
+ else ThemeUtil.getThemeColor(R.attr.colorPrimaryText))
data.message.let {
text_edit_indicator.isVisible = !it.isSystemMessage() && it.editedBy != null
diff --git a/app/src/main/java/chat/rocket/android/chatroom/adapter/UrlPreviewViewHolder.kt b/app/src/main/java/chat/rocket/android/chatroom/adapter/UrlPreviewViewHolder.kt
index 16aaac7dd1..cf0c8c6400 100644
--- a/app/src/main/java/chat/rocket/android/chatroom/adapter/UrlPreviewViewHolder.kt
+++ b/app/src/main/java/chat/rocket/android/chatroom/adapter/UrlPreviewViewHolder.kt
@@ -2,8 +2,10 @@ package chat.rocket.android.chatroom.adapter
import android.view.View
import androidx.core.view.isVisible
+import chat.rocket.android.R
import chat.rocket.android.chatroom.uimodel.UrlPreviewUiModel
import chat.rocket.android.emoji.EmojiReactionListener
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extensions.content
import chat.rocket.android.util.extensions.openTabbedUrl
import kotlinx.android.synthetic.main.message_url_preview.view.*
@@ -30,6 +32,8 @@ class UrlPreviewViewHolder(
text_title.content = data.title
text_description.content = data.description ?: ""
+ text_title.setTextColor(ThemeUtil.getThemeColor(R.attr.colorAccent))
+
url_preview_layout.setOnClickListener(onClickListener)
text_host.setOnClickListener(onClickListener)
text_title.setOnClickListener(onClickListener)
diff --git a/app/src/main/java/chat/rocket/android/chatroom/ui/ActionSnackbar.kt b/app/src/main/java/chat/rocket/android/chatroom/ui/ActionSnackbar.kt
index 1fc5673756..5d38a915d5 100644
--- a/app/src/main/java/chat/rocket/android/chatroom/ui/ActionSnackbar.kt
+++ b/app/src/main/java/chat/rocket/android/chatroom/ui/ActionSnackbar.kt
@@ -11,6 +11,7 @@ import androidx.core.view.ViewCompat
import androidx.core.view.setPadding
import chat.rocket.android.R
import chat.rocket.android.helper.MessageParser
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extensions.content
import com.google.android.material.snackbar.BaseTransientBottomBar
import kotlinx.android.synthetic.main.message_action_bar.view.*
@@ -28,7 +29,7 @@ class ActionSnackbar private constructor(
val actionSnackbar = ActionSnackbar(parentViewGroup, view, CallbackImpl(view))
with(view) {
actionSnackbar.getView().setPadding(0)
- actionSnackbar.getView().setBackgroundColor(ContextCompat.getColor(context, R.color.colorWhite))
+ actionSnackbar.getView().setBackgroundColor(ThemeUtil.getThemeColor(android.R.attr.colorBackground))
actionSnackbar.parser = parser
actionSnackbar.messageTextView = text_view_action_text
actionSnackbar.titleTextView = text_view_action_title
diff --git a/app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt b/app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt
index 2af6fb6f95..8fa3e2eb5b 100644
--- a/app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt
+++ b/app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt
@@ -12,6 +12,7 @@ import chat.rocket.android.R
import chat.rocket.android.chatroom.presentation.ChatRoomNavigator
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.infrastructure.ConnectionManagerFactory
+import chat.rocket.android.thememanager.BaseActivity
import chat.rocket.android.util.extensions.addFragment
import chat.rocket.android.util.extensions.textContent
import dagger.android.AndroidInjection
@@ -53,7 +54,7 @@ private const val INTENT_CHAT_ROOM_LAST_SEEN = "chat_room_last_seen"
private const val INTENT_CHAT_IS_SUBSCRIBED = "is_chat_room_subscribed"
private const val INTENT_CHAT_ROOM_MESSAGE = "chat_room_message"
-class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
+class ChatRoomActivity : BaseActivity(), HasSupportFragmentInjector {
@Inject
lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector
// TODO - workaround for now... We will move to a single activity
diff --git a/app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt b/app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
index 72f123b008..82d5e0e160 100644
--- a/app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+++ b/app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
@@ -23,6 +23,7 @@ import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.appcompat.app.AlertDialog
+import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import androidx.core.text.bold
import androidx.core.view.isVisible
@@ -72,20 +73,12 @@ import chat.rocket.android.helper.AndroidPermissionsHelper.getCameraPermission
import chat.rocket.android.helper.AndroidPermissionsHelper.getWriteExternalStoragePermission
import chat.rocket.android.helper.AndroidPermissionsHelper.hasCameraPermission
import chat.rocket.android.helper.AndroidPermissionsHelper.hasWriteExternalStoragePermission
+import chat.rocket.android.main.ui.MainActivity
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extension.createImageFile
import chat.rocket.android.util.extension.orFalse
-import chat.rocket.android.util.extensions.circularRevealOrUnreveal
-import chat.rocket.android.util.extensions.clearLightStatusBar
-import chat.rocket.android.util.extensions.fadeIn
-import chat.rocket.android.util.extensions.fadeOut
-import chat.rocket.android.util.extensions.hideKeyboard
-import chat.rocket.android.util.extensions.inflate
-import chat.rocket.android.util.extensions.isNotNullNorEmpty
-import chat.rocket.android.util.extensions.rotateBy
-import chat.rocket.android.util.extensions.showToast
-import chat.rocket.android.util.extensions.textContent
-import chat.rocket.android.util.extensions.ui
+import chat.rocket.android.util.extensions.*
import chat.rocket.common.model.RoomType
import chat.rocket.common.model.roomTypeOf
import chat.rocket.core.internal.realtime.socket.model.State
@@ -334,10 +327,24 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
}
getDraftMessage()
subscribeComposeTextMessage()
-
+ tintMessageAttachmentOptionDrawables()
analyticsManager.logScreenView(ScreenViewEvent.ChatRoom)
}
+ private fun tintMessageAttachmentOptionDrawables() {
+ (activity as ChatRoomActivity).apply {
+ val cameraDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_camera_24dp, this)
+ val filesDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_files_24dp, this)
+ val drawingDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_gesture_black_24dp, this)
+ val drawables = arrayOf(cameraDrawable, filesDrawable, drawingDrawable)
+ DrawableHelper.wrapDrawables(drawables)
+ DrawableHelper.tintDrawables(drawables, this, ThemeUtil.getThemeColorResource(R.attr.colorAccent))
+ DrawableHelper.compoundDrawables(
+ arrayOf(button_take_a_photo, button_attach_a_file, button_drawing), drawables
+ )
+ }
+ }
+
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
text_message.addTextChangedListener(EmojiKeyboardPopup.EmojiTextWatcher(text_message))
@@ -1172,9 +1179,10 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
private fun setupToolbar(toolbarTitle: String) {
with(activity as ChatRoomActivity) {
- this.clearLightStatusBar()
+ view?.let {this.clearInvisibleStatusBar(it)}
this.setupToolbarTitle(toolbarTitle)
toolbar.isVisible = true
+ toolbar.setBackgroundColor(ThemeUtil.getThemeColor(R.attr.colorPrimary))
}
}
diff --git a/app/src/main/java/chat/rocket/android/chatroom/ui/bottomsheet/MessageActionsBottomSheet.kt b/app/src/main/java/chat/rocket/android/chatroom/ui/bottomsheet/MessageActionsBottomSheet.kt
index 4f51f1d6da..c8d1cf6ab1 100644
--- a/app/src/main/java/chat/rocket/android/chatroom/ui/bottomsheet/MessageActionsBottomSheet.kt
+++ b/app/src/main/java/chat/rocket/android/chatroom/ui/bottomsheet/MessageActionsBottomSheet.kt
@@ -1,5 +1,6 @@
package chat.rocket.android.chatroom.ui.bottomsheet
+import android.graphics.drawable.Drawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.MenuItem
@@ -8,6 +9,7 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R
+import chat.rocket.android.thememanager.util.ThemeUtil
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.android.synthetic.main.message_action_item.view.*
import kotlinx.android.synthetic.main.message_bottomsheet.*
@@ -15,8 +17,18 @@ import kotlinx.android.synthetic.main.message_bottomsheet.*
class MessageActionsBottomSheet : BottomSheetDialogFragment() {
private val adapter = MessageActionAdapter()
+ private val addReactionDrawable by lazy {
+ DrawableHelper.getDrawableFromId(R.drawable.ic_add_reaction, requireContext())
+ }
+ private val pinDrawable by lazy {
+ DrawableHelper.getDrawableFromId(R.drawable.ic_action_message_pin_24dp, requireContext())
+ }
+ private val infoDrawable by lazy {
+ DrawableHelper.getDrawableFromId(R.drawable.ic_action_message_info_outline_24dp, requireContext())
+ }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
+ tintDrawable()
return inflater.inflate(R.layout.message_bottomsheet, container, false)
}
@@ -73,4 +85,11 @@ class MessageActionsBottomSheet : BottomSheetDialogFragment() {
}
}
}
+
+ private fun tintDrawable() {
+ context?.let {
+ val drawables = arrayOf(addReactionDrawable, pinDrawable, infoDrawable)
+ DrawableHelper.tintDrawables(drawables, it, ThemeUtil.getThemeColorResource(R.attr.colorDescriptiveText))
+ }
+ }
}
diff --git a/app/src/main/java/chat/rocket/android/chatrooms/adapter/RoomViewHolder.kt b/app/src/main/java/chat/rocket/android/chatrooms/adapter/RoomViewHolder.kt
index 9a4da09a36..5a50717a16 100644
--- a/app/src/main/java/chat/rocket/android/chatrooms/adapter/RoomViewHolder.kt
+++ b/app/src/main/java/chat/rocket/android/chatrooms/adapter/RoomViewHolder.kt
@@ -9,6 +9,7 @@ import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import chat.rocket.android.R
import chat.rocket.android.chatrooms.adapter.model.RoomUiModel
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extension.setTextViewAppearance
import chat.rocket.common.model.RoomType
import chat.rocket.common.model.UserStatus
@@ -43,7 +44,9 @@ class RoomViewHolder(itemView: View, private val listener: (RoomUiModel) -> Unit
} else if (room.status != null && room.type is RoomType.DirectMessage) {
image_chat_icon.setImageDrawable(getStatusDrawable(room.status))
} else {
- image_chat_icon.setImageDrawable(getRoomDrawable(room.type))
+ val drawable = getRoomDrawable(room.type)
+ DrawableHelper.tintDrawable(drawable!!, context, ThemeUtil.getThemeColorResource(R.attr.colorDescriptiveText))
+ image_chat_icon.setImageDrawable(drawable)
}
if (room.lastMessage != null) {
diff --git a/app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt b/app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
index 315ef9a1a5..9d6d48dc54 100644
--- a/app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
+++ b/app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
@@ -31,6 +31,7 @@ import chat.rocket.android.chatrooms.viewmodel.LoadingState
import chat.rocket.android.chatrooms.viewmodel.Query
import chat.rocket.android.servers.ui.ServersBottomSheetFragment
import chat.rocket.android.sortingandgrouping.ui.SortingAndGroupingBottomSheetFragment
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extension.onQueryTextListener
import chat.rocket.android.util.extensions.fadeIn
import chat.rocket.android.util.extensions.fadeOut
@@ -111,6 +112,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
viewModel = ViewModelProviders.of(this, factory).get(ChatRoomsViewModel::class.java)
subscribeUi()
+ tintSortByDrawable()
deepLinkInfo?.let {
processDeepLink(it)
@@ -122,6 +124,15 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
analyticsManager.logScreenView(ScreenViewEvent.ChatRooms)
}
+ private fun tintSortByDrawable() {
+ ui {
+ val sortByDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_group_by_type_20dp, it)
+ DrawableHelper.wrapDrawable(sortByDrawable)
+ DrawableHelper.tintDrawable(sortByDrawable, it, ThemeUtil.getThemeColorResource(R.attr.colorSubHeaderText))
+ DrawableHelper.compoundEndDrawable(text_sort_by, sortByDrawable)
+ }
+ }
+
override fun setupToolbar(serverName: String) {
with((activity as AppCompatActivity)) {
with(toolbar) {
diff --git a/app/src/main/java/chat/rocket/android/createchannel/ui/CreateChannelFragment.kt b/app/src/main/java/chat/rocket/android/createchannel/ui/CreateChannelFragment.kt
index 966ddb6ef7..4ab093da1c 100644
--- a/app/src/main/java/chat/rocket/android/createchannel/ui/CreateChannelFragment.kt
+++ b/app/src/main/java/chat/rocket/android/createchannel/ui/CreateChannelFragment.kt
@@ -20,6 +20,7 @@ import chat.rocket.android.createchannel.presentation.CreateChannelPresenter
import chat.rocket.android.createchannel.presentation.CreateChannelView
import chat.rocket.android.members.adapter.MembersAdapter
import chat.rocket.android.members.uimodel.MemberUiModel
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast
@@ -284,7 +285,8 @@ class CreateChannelFragment : Fragment(), CreateChannelView, ActionMode.Callback
val chip = Chip(context)
chip.text = chipText
chip.isCloseIconVisible = true
- chip.setChipBackgroundColorResource(R.color.icon_grey)
+ chip.setChipBackgroundColorResource(ThemeUtil.getThemeColorResource(R.attr.colorButtonDisabled))
+ chip.setTextColor(ThemeUtil.getThemeColor(R.attr.colorPrimaryText))
setupChipOnCloseIconClickListener(chip)
chip_group_member.addView(chip)
}
diff --git a/app/src/main/java/chat/rocket/android/dagger/module/ActivityBuilder.kt b/app/src/main/java/chat/rocket/android/dagger/module/ActivityBuilder.kt
index d9c4919c3b..116eec852c 100644
--- a/app/src/main/java/chat/rocket/android/dagger/module/ActivityBuilder.kt
+++ b/app/src/main/java/chat/rocket/android/dagger/module/ActivityBuilder.kt
@@ -38,10 +38,15 @@ import chat.rocket.android.settings.di.SettingsFragmentProvider
import chat.rocket.android.settings.password.di.PasswordFragmentProvider
import chat.rocket.android.settings.password.ui.PasswordActivity
import chat.rocket.android.sortingandgrouping.di.SortingAndGroupingBottomSheetFragmentProvider
+import chat.rocket.android.thememanager.BaseActivity
+import chat.rocket.android.thememanager.di.BaseActivityModule
+import chat.rocket.android.thememanager.ui.ThemesActivity
import chat.rocket.android.userdetails.di.UserDetailsFragmentProvider
import chat.rocket.android.videoconference.di.VideoConferenceModule
import chat.rocket.android.videoconference.ui.VideoConferenceActivity
import chat.rocket.android.webview.adminpanel.di.AdminPanelWebViewFragmentProvider
+import chat.rocket.android.webview.oauth.ui.OauthWebViewActivity
+import chat.rocket.android.webview.ui.WebViewActivity
import dagger.Module
import dagger.android.ContributesAndroidInjector
@@ -50,7 +55,8 @@ abstract class ActivityBuilder {
@PerActivity
@ContributesAndroidInjector(
- modules = [AuthenticationModule::class,
+ modules = [BaseActivityModule::class,
+ AuthenticationModule::class,
OnBoardingFragmentProvider::class,
ServerFragmentProvider::class,
LoginOptionsFragmentProvider::class,
@@ -65,7 +71,8 @@ abstract class ActivityBuilder {
@PerActivity
@ContributesAndroidInjector(
- modules = [MainModule::class,
+ modules = [BaseActivityModule::class,
+ MainModule::class,
ChatRoomsFragmentProvider::class,
ServersBottomSheetFragmentProvider::class,
SortingAndGroupingBottomSheetFragmentProvider::class,
@@ -80,7 +87,8 @@ abstract class ActivityBuilder {
@PerActivity
@ContributesAndroidInjector(
- modules = [ChatRoomModule::class,
+ modules = [ BaseActivityModule::class,
+ ChatRoomModule::class,
ChatRoomFragmentProvider::class,
UserDetailsFragmentProvider::class,
ChatDetailsFragmentProvider::class,
@@ -95,22 +103,38 @@ abstract class ActivityBuilder {
abstract fun bindChatRoomActivity(): ChatRoomActivity
@PerActivity
- @ContributesAndroidInjector(modules = [PasswordFragmentProvider::class])
+ @ContributesAndroidInjector(modules = [(BaseActivityModule::class)])
+ abstract fun bindBaseActivity(): BaseActivity
+
+ @PerActivity
+ @ContributesAndroidInjector(modules = [(BaseActivityModule::class)])
+ abstract fun bindThemesActivity(): ThemesActivity
+
+ @PerActivity
+ @ContributesAndroidInjector(modules = [(BaseActivityModule::class)])
+ abstract fun OauthWebViewActivity(): OauthWebViewActivity
+
+ @PerActivity
+ @ContributesAndroidInjector(modules = [(BaseActivityModule::class)])
+ abstract fun bindWebViewActivity(): WebViewActivity
+
+ @PerActivity
+ @ContributesAndroidInjector(modules = [PasswordFragmentProvider::class, BaseActivityModule::class])
abstract fun bindPasswordActivity(): PasswordActivity
@PerActivity
- @ContributesAndroidInjector(modules = [ChangeServerModule::class])
+ @ContributesAndroidInjector(modules = [ChangeServerModule::class, BaseActivityModule::class])
abstract fun bindChangeServerActivity(): ChangeServerActivity
@PerActivity
- @ContributesAndroidInjector(modules = [MessageInfoFragmentProvider::class])
+ @ContributesAndroidInjector(modules = [MessageInfoFragmentProvider::class, BaseActivityModule::class])
abstract fun bindMessageInfoActiviy(): MessageInfoActivity
@PerActivity
- @ContributesAndroidInjector(modules = [DrawModule::class])
+ @ContributesAndroidInjector(modules = [DrawModule::class, BaseActivityModule::class])
abstract fun bindDrawingActivity(): DrawingActivity
@PerActivity
- @ContributesAndroidInjector(modules = [VideoConferenceModule::class])
+ @ContributesAndroidInjector(modules = [VideoConferenceModule::class, BaseActivityModule::class])
abstract fun bindVideoConferenceActivity(): VideoConferenceActivity
}
diff --git a/app/src/main/java/chat/rocket/android/dagger/module/AppModule.kt b/app/src/main/java/chat/rocket/android/dagger/module/AppModule.kt
index d9e1b1afaf..0112d53399 100644
--- a/app/src/main/java/chat/rocket/android/dagger/module/AppModule.kt
+++ b/app/src/main/java/chat/rocket/android/dagger/module/AppModule.kt
@@ -60,6 +60,7 @@ import chat.rocket.android.server.infrastructure.SharedPrefsBasicAuthRepository
import chat.rocket.android.server.infrastructure.SharedPrefsConnectingServerRepository
import chat.rocket.android.server.infrastructure.SharedPrefsCurrentServerRepository
import chat.rocket.android.server.infrastructure.SharedPrefsSortingAndGroupingRepository
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.AppJsonAdapterFactory
import chat.rocket.android.util.BasicAuthenticatorInterceptor
import chat.rocket.android.util.HttpLoggingInterceptor
@@ -293,7 +294,7 @@ class AppModule {
.theme(
SpannableTheme.builder()
.blockMargin(0)
- .linkColor(res.getColor(R.color.colorAccent))
+ .linkColor(ThemeUtil.getThemeColor(R.attr.colorAccent))
.build()
)
.build()
diff --git a/app/src/main/java/chat/rocket/android/directory/ui/DirectoryFragment.kt b/app/src/main/java/chat/rocket/android/directory/ui/DirectoryFragment.kt
index e7144808be..d163754b0e 100644
--- a/app/src/main/java/chat/rocket/android/directory/ui/DirectoryFragment.kt
+++ b/app/src/main/java/chat/rocket/android/directory/ui/DirectoryFragment.kt
@@ -23,6 +23,7 @@ import chat.rocket.android.directory.presentation.DirectoryPresenter
import chat.rocket.android.directory.presentation.DirectoryView
import chat.rocket.android.directory.uimodel.DirectoryUiModel
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extension.onQueryTextListener
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.isNotNullNorBlank
@@ -81,11 +82,25 @@ class DirectoryFragment : Fragment(), DirectoryView {
super.onViewCreated(view, savedInstanceState)
setupToolbar()
setupRecyclerView()
+ tintSortByDrawables()
setupListeners()
presenter.loadAllDirectoryChannels()
analyticsManager.logScreenView(ScreenViewEvent.Directory)
}
+ private fun tintSortByDrawables() {
+ ui{
+ val drawables = arrayOf(hashtagDrawable, userDrawable, arrowDownDrawable)
+ DrawableHelper.wrapDrawables(drawables)
+ DrawableHelper.tintDrawables(drawables, it, ThemeUtil.getThemeColorResource(R.attr.colorSubHeaderText))
+ DrawableHelper.compoundStartAndEndDrawable(
+ text_sort_by,
+ hashtagDrawable,
+ arrowDownDrawable
+ )
+ }
+ }
+
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.directory, menu)
diff --git a/app/src/main/java/chat/rocket/android/directory/ui/DirectorySortingBottomSheetFragment.kt b/app/src/main/java/chat/rocket/android/directory/ui/DirectorySortingBottomSheetFragment.kt
index 4290ac18c4..6aea0d0bd0 100644
--- a/app/src/main/java/chat/rocket/android/directory/ui/DirectorySortingBottomSheetFragment.kt
+++ b/app/src/main/java/chat/rocket/android/directory/ui/DirectorySortingBottomSheetFragment.kt
@@ -1,14 +1,19 @@
package chat.rocket.android.directory.ui
import DrawableHelper
+import android.content.res.ColorStateList
+import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
+import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import chat.rocket.android.R
+import chat.rocket.android.thememanager.util.ThemeUtil
+import chat.rocket.android.util.extensions.ui
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
@@ -64,6 +69,8 @@ class DirectorySortingBottomSheetFragment : BottomSheetDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
+ tintTextViewStartDrawables()
+ tintCheckDrawable()
setupView()
setupListeners()
}
@@ -126,4 +133,18 @@ class DirectorySortingBottomSheetFragment : BottomSheetDialogFragment() {
)
}
}
+
+ private fun tintTextViewStartDrawables(){
+ ui{
+ val drawables = arrayOf(hashtagDrawable, userDrawable)
+ DrawableHelper.wrapDrawables(drawables)
+ DrawableHelper.tintDrawables(drawables, it, ThemeUtil.getThemeColorResource(R.attr.colorBottomSheetFragmentText))
+ }
+ }
+
+ private fun tintCheckDrawable() {
+ context?.let {
+ DrawableHelper.tintDrawable(checkDrawable, it, ThemeUtil.getThemeColorResource(R.attr.colorAccent))
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/chat/rocket/android/helper/MessageParser.kt b/app/src/main/java/chat/rocket/android/helper/MessageParser.kt
index e91faac4f8..18b409e282 100644
--- a/app/src/main/java/chat/rocket/android/helper/MessageParser.kt
+++ b/app/src/main/java/chat/rocket/android/helper/MessageParser.kt
@@ -19,6 +19,7 @@ import chat.rocket.android.emoji.EmojiRepository
import chat.rocket.android.emoji.EmojiTypefaceSpan
import chat.rocket.android.server.domain.PublicSettings
import chat.rocket.android.server.domain.useRealName
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extensions.openTabbedUrl
import chat.rocket.common.model.SimpleUser
import chat.rocket.core.model.Message
@@ -142,10 +143,10 @@ class MessageParser @Inject constructor(
private val currentUser: String?
) : AbstractVisitor() {
- private val othersTextColor = ResourcesCompat.getColor(context.resources, R.color.colorAccent, context.theme)
+ private val othersTextColor = ThemeUtil.getThemeColor(R.attr.colorAccent)
private val othersBackgroundColor = ResourcesCompat.getColor(context.resources, android.R.color.transparent, context.theme)
- private val myselfTextColor = ResourcesCompat.getColor(context.resources, R.color.colorWhite, context.theme)
- private val myselfBackgroundColor = ResourcesCompat.getColor(context.resources, R.color.colorAccent, context.theme)
+ private val myselfTextColor = ThemeUtil.getThemeColor(android.R.attr.colorBackground)
+ private val myselfBackgroundColor = ThemeUtil.getThemeColor(R.attr.colorAccent)
private val padding = context.resources.getDimensionPixelSize(R.dimen.padding_mention).toFloat()
private val radius = context.resources.getDimensionPixelSize(R.dimen.radius_mention).toFloat()
diff --git a/app/src/main/java/chat/rocket/android/main/presentation/MainNavigator.kt b/app/src/main/java/chat/rocket/android/main/presentation/MainNavigator.kt
index 983f55bd28..e750022a3f 100644
--- a/app/src/main/java/chat/rocket/android/main/presentation/MainNavigator.kt
+++ b/app/src/main/java/chat/rocket/android/main/presentation/MainNavigator.kt
@@ -13,11 +13,13 @@ import chat.rocket.android.profile.ui.TAG_IMAGE_DIALOG_FRAGMENT
import chat.rocket.android.profile.ui.TAG_PROFILE_FRAGMENT
import chat.rocket.android.server.ui.changeServerIntent
import chat.rocket.android.settings.ui.TAG_SETTINGS_FRAGMENT
+import chat.rocket.android.thememanager.ui.ThemesActivity
import chat.rocket.android.util.extensions.addFragment
import chat.rocket.android.util.extensions.addFragmentBackStack
import chat.rocket.android.webview.adminpanel.ui.TAG_ADMIN_PANEL_WEB_VIEW_FRAGMENT
import chat.rocket.android.webview.ui.webViewIntent
+
class MainNavigator(internal val activity: MainActivity) {
fun toChatList(chatRoomId: String? = null, deepLinkInfo: DeepLinkInfo? = null) {
@@ -50,6 +52,10 @@ class MainNavigator(internal val activity: MainActivity) {
}
}
+ fun toChangeTheme() {
+ activity.startActivity(Intent(activity, ThemesActivity::class.java))
+ }
+
fun toProfileImage(avatarUrl: String) {
activity.addFragmentBackStack(TAG_IMAGE_DIALOG_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.profile.ui.newInstance(avatarUrl)
diff --git a/app/src/main/java/chat/rocket/android/main/ui/MainActivity.kt b/app/src/main/java/chat/rocket/android/main/ui/MainActivity.kt
index 66390b8ed0..62351aac43 100644
--- a/app/src/main/java/chat/rocket/android/main/ui/MainActivity.kt
+++ b/app/src/main/java/chat/rocket/android/main/ui/MainActivity.kt
@@ -18,6 +18,7 @@ import chat.rocket.android.core.behaviours.AppLanguageView
import chat.rocket.android.main.presentation.MainPresenter
import chat.rocket.android.push.refreshPushToken
import chat.rocket.android.server.ui.INTENT_CHAT_ROOM_ID
+import chat.rocket.android.thememanager.BaseActivity
import dagger.android.AndroidInjection
import dagger.android.AndroidInjector
import dagger.android.DispatchingAndroidInjector
@@ -26,7 +27,7 @@ import dagger.android.support.HasSupportFragmentInjector
import java.util.*
import javax.inject.Inject
-class MainActivity : AppCompatActivity(), HasActivityInjector,
+class MainActivity : BaseActivity(), HasActivityInjector,
HasSupportFragmentInjector, AppLanguageView {
@Inject
lateinit var activityDispatchingAndroidInjector: DispatchingAndroidInjector
diff --git a/app/src/main/java/chat/rocket/android/members/ui/MembersFragment.kt b/app/src/main/java/chat/rocket/android/members/ui/MembersFragment.kt
index 27a8e242d8..825226e0b6 100644
--- a/app/src/main/java/chat/rocket/android/members/ui/MembersFragment.kt
+++ b/app/src/main/java/chat/rocket/android/members/ui/MembersFragment.kt
@@ -18,10 +18,7 @@ import chat.rocket.android.members.adapter.MembersAdapter
import chat.rocket.android.members.presentation.MembersPresenter
import chat.rocket.android.members.presentation.MembersView
import chat.rocket.android.members.uimodel.MemberUiModel
-import chat.rocket.android.util.extensions.clearLightStatusBar
-import chat.rocket.android.util.extensions.inflate
-import chat.rocket.android.util.extensions.showToast
-import chat.rocket.android.util.extensions.ui
+import chat.rocket.android.util.extensions.*
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.app_bar_chat_room.*
import kotlinx.android.synthetic.main.fragment_members.*
@@ -136,7 +133,7 @@ class MembersFragment : Fragment(), MembersView {
} else {
setupToolbarTitle((getString(R.string.title_members)))
}
- this.clearLightStatusBar()
+ view?.let {this.clearInvisibleStatusBar(it)}
toolbar.isVisible = true
}
}
diff --git a/app/src/main/java/chat/rocket/android/profile/ui/ProfileFragment.kt b/app/src/main/java/chat/rocket/android/profile/ui/ProfileFragment.kt
index 86525d8277..30dbf4d656 100644
--- a/app/src/main/java/chat/rocket/android/profile/ui/ProfileFragment.kt
+++ b/app/src/main/java/chat/rocket/android/profile/ui/ProfileFragment.kt
@@ -5,7 +5,6 @@ import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
-import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
@@ -28,6 +27,7 @@ import chat.rocket.android.helper.AndroidPermissionsHelper.hasCameraPermission
import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.profile.presentation.ProfilePresenter
import chat.rocket.android.profile.presentation.ProfileView
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extension.dispatchImageSelection
import chat.rocket.android.util.extension.dispatchTakePicture
@@ -86,12 +86,11 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
super.onViewCreated(view, savedInstanceState)
setupToolbar()
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
- tintEditTextDrawableStart()
- }
+ tintEditTextDrawableStart()
presenter.loadUserProfile()
setupListeners()
+ tintAvatarOptionsDrawables()
subscribeEditTexts()
analyticsManager.logScreenView(ScreenViewEvent.Profile)
@@ -276,7 +275,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
val drawables = arrayOf(personDrawable, atDrawable, emailDrawable)
DrawableHelper.wrapDrawables(drawables)
- DrawableHelper.tintDrawables(drawables, this, R.color.colorDrawableTintGrey)
+ DrawableHelper.tintDrawables(drawables, this, ThemeUtil.getThemeColorResource(R.attr.colorDrawableStrongTint))
DrawableHelper.compoundDrawables(
arrayOf(text_name, text_username, text_email), drawables
)
@@ -344,14 +343,16 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
}
context?.let {
- AlertDialog.Builder(it)
+ val dialog = AlertDialog.Builder(it)
.setView(dialogLayout)
.setPositiveButton(R.string.msg_change_status) { dialog, _ ->
presenter.updateStatus(newStatus)
text_status.text = getString(R.string.status, newStatus.toString().capitalize())
this.currentStatus = newStatus.toString()
dialog.dismiss()
- }.show()
+ }.create()
+ dialog.show()
+ dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(ThemeUtil.getThemeColor(R.attr.colorAccent))
}
}
@@ -379,6 +380,21 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
}
}
+ private fun tintAvatarOptionsDrawables() {
+ (activity as MainActivity).apply {
+ val accountDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_account_circle_black_24dp, this)
+ val imageDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_image_black_24dp, this)
+ val cameraDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_photo_camera_black_24dp, this)
+ val closeDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_close_black_24dp, this)
+ val drawables = arrayOf(accountDrawable, imageDrawable, cameraDrawable, closeDrawable)
+ DrawableHelper.wrapDrawables(drawables)
+ DrawableHelper.tintDrawables(drawables, this, ThemeUtil.getThemeColorResource(R.attr.colorPrimaryText))
+ DrawableHelper.compoundDrawables(
+ arrayOf(button_view_profile_photo, button_open_gallery, button_take_a_photo, button_reset_avatar), drawables
+ )
+ }
+ }
+
private fun showChangesNotSavedDialog() {
context?.let {
val builder = AlertDialog.Builder(it)
@@ -394,7 +410,6 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
.create()
.show()
}
-
}
private fun updateProfile() {
diff --git a/app/src/main/java/chat/rocket/android/push/PushManager.kt b/app/src/main/java/chat/rocket/android/push/PushManager.kt
index efd3b84e6c..7027b3db37 100644
--- a/app/src/main/java/chat/rocket/android/push/PushManager.kt
+++ b/app/src/main/java/chat/rocket/android/push/PushManager.kt
@@ -26,6 +26,7 @@ import chat.rocket.android.server.domain.GetAccountInteractor
import chat.rocket.android.server.domain.GetSettingsInteractor
import chat.rocket.android.server.domain.siteName
import chat.rocket.android.server.ui.changeServerIntent
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.common.model.RoomType
import chat.rocket.common.model.roomTypeOf
import com.squareup.moshi.Json
@@ -367,7 +368,7 @@ class PushManager @Inject constructor(
with(this) {
setAutoCancel(true)
setShowWhen(true)
- color = ContextCompat.getColor(context, R.color.colorPrimary)
+ color = ThemeUtil.getThemeColor(R.attr.colorPrimary)
setDefaults(Notification.DEFAULT_ALL)
setSmallIcon(smallIcon)
setSound(alarmSound)
diff --git a/app/src/main/java/chat/rocket/android/server/ui/ChangeServerActivity.kt b/app/src/main/java/chat/rocket/android/server/ui/ChangeServerActivity.kt
index df6b72b5fd..eec927f5fc 100644
--- a/app/src/main/java/chat/rocket/android/server/ui/ChangeServerActivity.kt
+++ b/app/src/main/java/chat/rocket/android/server/ui/ChangeServerActivity.kt
@@ -7,6 +7,7 @@ import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import chat.rocket.android.server.presentation.ChangeServerPresenter
import chat.rocket.android.server.presentation.ChangeServerView
+import chat.rocket.android.thememanager.BaseActivity
import chat.rocket.android.util.extensions.showToast
import dagger.android.AndroidInjection
import javax.inject.Inject
@@ -24,7 +25,7 @@ fun Context.changeServerIntent(serverUrl: String? = null, chatRoomId: String? =
}
}
-class ChangeServerActivity : AppCompatActivity(), ChangeServerView {
+class ChangeServerActivity : BaseActivity(), ChangeServerView {
@Inject lateinit var presenter: ChangeServerPresenter
var progress: ProgressDialog? = null
diff --git a/app/src/main/java/chat/rocket/android/servers/adapter/ServerViewHolder.kt b/app/src/main/java/chat/rocket/android/servers/adapter/ServerViewHolder.kt
index c4f6c8a98c..067a49c0f5 100644
--- a/app/src/main/java/chat/rocket/android/servers/adapter/ServerViewHolder.kt
+++ b/app/src/main/java/chat/rocket/android/servers/adapter/ServerViewHolder.kt
@@ -3,7 +3,9 @@ package chat.rocket.android.servers.adapter
import android.view.View
import androidx.core.view.isInvisible
import androidx.recyclerview.widget.RecyclerView
+import chat.rocket.android.R
import chat.rocket.android.server.domain.model.Account
+import chat.rocket.android.thememanager.util.ThemeUtil
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.item_server.view.*
@@ -15,6 +17,9 @@ class ServerViewHolder(itemView: View, private val currentServerUrl: String) :
Glide.with(context).load(account.serverLogoUrl).into(image_server)
text_server_name.text = account.serverName ?: account.serverUrl
text_server_url.text = account.serverUrl
+ val checkDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_check, context)
+ DrawableHelper.tintDrawable(checkDrawable, context, ThemeUtil.getThemeColorResource(R.attr.colorAccent))
+ image_check.setImageDrawable(checkDrawable)
image_check.isInvisible = currentServerUrl != account.serverUrl
}
}
diff --git a/app/src/main/java/chat/rocket/android/settings/password/ui/PasswordActivity.kt b/app/src/main/java/chat/rocket/android/settings/password/ui/PasswordActivity.kt
index 169eba224a..d2d4f4313f 100644
--- a/app/src/main/java/chat/rocket/android/settings/password/ui/PasswordActivity.kt
+++ b/app/src/main/java/chat/rocket/android/settings/password/ui/PasswordActivity.kt
@@ -2,8 +2,8 @@ package chat.rocket.android.settings.password.ui
import android.os.Bundle
import androidx.fragment.app.Fragment
-import androidx.appcompat.app.AppCompatActivity
import chat.rocket.android.R
+import chat.rocket.android.thememanager.BaseActivity
import chat.rocket.android.util.extensions.addFragment
import chat.rocket.android.util.extensions.textContent
import dagger.android.AndroidInjection
@@ -13,7 +13,7 @@ import dagger.android.support.HasSupportFragmentInjector
import kotlinx.android.synthetic.main.app_bar_password.*
import javax.inject.Inject
-class PasswordActivity : AppCompatActivity(), HasSupportFragmentInjector {
+class PasswordActivity : BaseActivity(), HasSupportFragmentInjector {
@Inject lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector
override fun onCreate(savedInstanceState: Bundle?) {
diff --git a/app/src/main/java/chat/rocket/android/settings/presentation/SettingsPresenter.kt b/app/src/main/java/chat/rocket/android/settings/presentation/SettingsPresenter.kt
index fe1fa344ff..e367418167 100644
--- a/app/src/main/java/chat/rocket/android/settings/presentation/SettingsPresenter.kt
+++ b/app/src/main/java/chat/rocket/android/settings/presentation/SettingsPresenter.kt
@@ -144,6 +144,8 @@ class SettingsPresenter @Inject constructor(
fun toProfile() = navigator.toProfile()
+ fun toChangeTheme() = navigator.toChangeTheme()
+
fun toAdmin() = currentServer?.let { currentServer ->
tokenRepository.get(currentServer)?.let {
navigator.toAdminPanel(currentServer.adminPanelUrl(), it.authToken)
diff --git a/app/src/main/java/chat/rocket/android/settings/ui/SettingsFragment.kt b/app/src/main/java/chat/rocket/android/settings/ui/SettingsFragment.kt
index d3d3d20718..da6ff7466f 100644
--- a/app/src/main/java/chat/rocket/android/settings/ui/SettingsFragment.kt
+++ b/app/src/main/java/chat/rocket/android/settings/ui/SettingsFragment.kt
@@ -23,8 +23,10 @@ import chat.rocket.android.core.behaviours.AppLanguageView
import chat.rocket.android.helper.TextHelper.getDeviceAndAppInformation
import chat.rocket.android.settings.presentation.SettingsPresenter
import chat.rocket.android.settings.presentation.SettingsView
+import chat.rocket.android.thememanager.util.ThemeUtil
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast
+import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.invalidateFirebaseToken
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.app_bar.*
@@ -32,6 +34,10 @@ import kotlinx.android.synthetic.main.dialog_delete_account.*
import kotlinx.android.synthetic.main.fragment_settings.*
import timber.log.Timber
import javax.inject.Inject
+import android.widget.ArrayAdapter
+
+
+
internal const val TAG_SETTINGS_FRAGMENT = "SettingsFragment"
@@ -142,6 +148,8 @@ class SettingsFragment : Fragment(), SettingsView, AppLanguageView {
text_contact_us.setOnClickListener { contactSupport() }
+ text_change_theme.setOnClickListener { presenter.toChangeTheme() }
+
text_language.setOnClickListener { changeLanguage() }
text_review_this_app.setOnClickListener { showAppOnStore() }
@@ -208,10 +216,12 @@ class SettingsFragment : Fragment(), SettingsView, AppLanguageView {
}
}
}
+ val adapter = ArrayAdapter(
+ activity, R.layout.item_alert_dialog_single_choice, resources.getStringArray(R.array.languages))
AlertDialog.Builder(it)
.setTitle(R.string.title_choose_language)
.setSingleChoiceItems(
- resources.getStringArray(R.array.languages), localeIndex
+ adapter, localeIndex
) { dialog, option ->
val array = locales[option].split(",")
if (array.size > 1) {
@@ -242,12 +252,14 @@ class SettingsFragment : Fragment(), SettingsView, AppLanguageView {
private fun showLogoutDialog() {
context?.let {
- val builder = AlertDialog.Builder(it)
- builder.setTitle(R.string.title_are_you_sure)
+ val dialog = AlertDialog.Builder(it)
+ .setTitle(R.string.title_are_you_sure)
.setPositiveButton(R.string.action_logout) { _, _ -> presenter.logout() }
.setNegativeButton(android.R.string.no) { dialog, _ -> dialog.cancel() }
.create()
- .show()
+ dialog.show()
+ dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(ThemeUtil.getThemeColor(R.attr.colorAccent))
+ dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(ThemeUtil.getThemeColor(R.attr.colorAccent))
}
}
@@ -256,13 +268,19 @@ class SettingsFragment : Fragment(), SettingsView, AppLanguageView {
val dialogLayout = layoutInflater.inflate(R.layout.dialog_delete_account, null)
val editText = dialogLayout.findViewById(R.id.text_password)
- AlertDialog.Builder(it)
+ val dialog = AlertDialog.Builder(it)
.setView(dialogLayout)
.setPositiveButton(R.string.msg_delete_account) { _, _ ->
presenter.deleteAccount(editText.text.toString())
}.setNegativeButton(android.R.string.no) { dialog, _ -> dialog.cancel() }
.create()
- .show()
+ dialog.show()
+ dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(ThemeUtil.getThemeColor(R.attr.colorAccent))
+ dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(ThemeUtil.getThemeColor(R.attr.colorAccent))
+ val keyDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_key_black_20dp, it)
+ DrawableHelper.wrapDrawable(keyDrawable)
+ DrawableHelper.tintDrawable(keyDrawable, it, ThemeUtil.getThemeColorResource(R.attr.colorDrawableStrongTint))
+ DrawableHelper.compoundStartDrawable(dialog.text_password, keyDrawable)
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/chat/rocket/android/sortingandgrouping/ui/SortingAndGroupingBottomSheetFragment.kt b/app/src/main/java/chat/rocket/android/sortingandgrouping/ui/SortingAndGroupingBottomSheetFragment.kt
index ca62af7f67..bad2d64436 100644
--- a/app/src/main/java/chat/rocket/android/sortingandgrouping/ui/SortingAndGroupingBottomSheetFragment.kt
+++ b/app/src/main/java/chat/rocket/android/sortingandgrouping/ui/SortingAndGroupingBottomSheetFragment.kt
@@ -2,6 +2,7 @@ package chat.rocket.android.sortingandgrouping.ui
import DrawableHelper
import android.content.DialogInterface
+import android.graphics.drawable.Drawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -13,6 +14,8 @@ import chat.rocket.android.chatrooms.ui.ChatRoomsFragment
import chat.rocket.android.chatrooms.ui.TAG_CHAT_ROOMS_FRAGMENT
import chat.rocket.android.sortingandgrouping.presentation.SortingAndGroupingPresenter
import chat.rocket.android.sortingandgrouping.presentation.SortingAndGroupingView
+import chat.rocket.android.thememanager.util.ThemeUtil
+import chat.rocket.android.util.extensions.ui
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
@@ -32,11 +35,24 @@ class SortingAndGroupingBottomSheetFragment : BottomSheetDialogFragment(), Sorti
private val chatRoomFragment by lazy {
activity?.supportFragmentManager?.findFragmentByTag(TAG_CHAT_ROOMS_FRAGMENT) as ChatRoomsFragment
}
- private val filterDrawable by lazy { R.drawable.ic_filter_20dp }
- private val activityDrawable by lazy { R.drawable.ic_activity_20dp }
- private val unreadOnTopDrawable by lazy { R.drawable.ic_unread_20dp }
- private val groupByTypeDrawable by lazy { R.drawable.ic_group_by_type_20dp }
- private val groupByFavoritesDrawable by lazy { R.drawable.ic_favorites_20dp }
+ private val filterDrawable by lazy {
+ DrawableHelper.getDrawableFromId(R.drawable.ic_filter_20dp, requireContext())
+ }
+ private val activityDrawable by lazy {
+ DrawableHelper.getDrawableFromId(R.drawable.ic_activity_20dp, requireContext())
+ }
+ private val unreadOnTopDrawable by lazy {
+ DrawableHelper.getDrawableFromId(R.drawable.ic_unread_20dp, requireContext())
+ }
+ private val groupByTypeDrawable by lazy {
+ DrawableHelper.getDrawableFromId(R.drawable.ic_group_by_type_20dp, requireContext())
+ }
+ private val groupByFavoritesDrawable by lazy {
+ DrawableHelper.getDrawableFromId(R.drawable.ic_favorites_20dp, requireContext())
+ }
+ private val checkDrawable by lazy {
+ DrawableHelper.getDrawableFromId(R.drawable.ic_check, requireContext())
+ }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -53,6 +69,8 @@ class SortingAndGroupingBottomSheetFragment : BottomSheetDialogFragment(), Sorti
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
presenter.getSortingAndGroupingPreferences()
+ tintTextViewStartDrawables()
+ tintCheckDrawable()
setupListeners()
}
@@ -154,21 +172,21 @@ class SortingAndGroupingBottomSheetFragment : BottomSheetDialogFragment(), Sorti
text_sort_by.text = getString(R.string.msg_sort_by_placeholder, text.toLowerCase())
}
- private fun checkSelection(textView: TextView, @DrawableRes startDrawable: Int) {
+ private fun checkSelection(textView: TextView, startDrawable: Drawable) {
context?.let {
DrawableHelper.compoundStartAndEndDrawable(
textView,
- DrawableHelper.getDrawableFromId(startDrawable, it),
- DrawableHelper.getDrawableFromId(R.drawable.ic_check, it)
+ startDrawable,
+ checkDrawable
)
}
}
- private fun uncheckSelection(textView: TextView, @DrawableRes startDrawable: Int) {
+ private fun uncheckSelection(textView: TextView, startDrawable: Drawable) {
context?.let {
DrawableHelper.compoundStartDrawable(
textView,
- DrawableHelper.getDrawableFromId(startDrawable, it)
+ startDrawable
)
}
}
@@ -181,4 +199,18 @@ class SortingAndGroupingBottomSheetFragment : BottomSheetDialogFragment(), Sorti
isGroupByFavorites
)
}
+
+ private fun tintTextViewStartDrawables(){
+ ui{
+ val drawables = arrayOf(filterDrawable, activityDrawable, unreadOnTopDrawable, groupByTypeDrawable, groupByFavoritesDrawable)
+ DrawableHelper.wrapDrawables(drawables)
+ DrawableHelper.tintDrawables(drawables, it, ThemeUtil.getThemeColorResource(R.attr.colorBottomSheetFragmentText))
+ }
+ }
+
+ private fun tintCheckDrawable() {
+ context?.let {
+ DrawableHelper.tintDrawable(checkDrawable, it, ThemeUtil.getThemeColorResource(R.attr.colorAccent))
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/chat/rocket/android/thememanager/BaseActivity.kt b/app/src/main/java/chat/rocket/android/thememanager/BaseActivity.kt
new file mode 100644
index 0000000000..94adc67df4
--- /dev/null
+++ b/app/src/main/java/chat/rocket/android/thememanager/BaseActivity.kt
@@ -0,0 +1,59 @@
+package chat.rocket.android.thememanager
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.ViewModelProviders
+import chat.rocket.android.R
+import chat.rocket.android.thememanager.util.ThemeUtil
+import chat.rocket.android.thememanager.viewmodel.ThemesViewModel
+import chat.rocket.android.thememanager.viewmodel.ThemesViewModelFactory
+import dagger.android.AndroidInjection
+import javax.inject.Inject
+
+open class BaseActivity : AppCompatActivity() {
+ @Inject
+ lateinit var factory: ThemesViewModelFactory
+ lateinit var viewModel: ThemesViewModel
+ private var currentTheme: String = "AppTheme"
+ private var currentAccentStyle = 0
+ private var currentToolbarStyle = 0
+ private var currentBackgroundStyle = 0
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ AndroidInjection.inject(this)
+ viewModel = ViewModelProviders.of(this, factory).get(ThemesViewModel::class.java)
+ currentTheme = viewModel.getCurrentTheme().name
+ currentAccentStyle = viewModel.getCurrentTheme().getCustomAccentStyle(resources, this.packageName)
+ currentToolbarStyle = viewModel.getCurrentTheme().getCustomToolbarStyle(resources, this.packageName)
+ currentBackgroundStyle = viewModel.getCurrentTheme().getCustomBackgroundStyle(resources, this.packageName)
+ applyTheme(currentTheme, currentAccentStyle, currentToolbarStyle, currentBackgroundStyle)
+ super.onCreate(savedInstanceState)
+ }
+
+ override fun onResume() {
+ super.onResume()
+ val selectedTheme = viewModel.getCurrentTheme().name
+ val selectedAccentStyle = viewModel.getCurrentTheme().getCustomAccentStyle(resources, this.packageName)
+ val selectedToolbarStyle = viewModel.getCurrentTheme().getCustomToolbarStyle(resources, this.packageName)
+ val selectedBackgroundStyle = viewModel.getCurrentTheme().getCustomBackgroundStyle(resources, this.packageName)
+ if ((currentTheme != selectedTheme)
+ or (currentAccentStyle != selectedAccentStyle)
+ or (currentToolbarStyle != selectedToolbarStyle)
+ or (currentBackgroundStyle != selectedBackgroundStyle))
+ recreate()
+ }
+
+ private fun applyTheme(currentTheme: String, currentAccentStyle: Int, currentToolbarStyle: Int, currentBackgroundStyle: Int) {
+ setTheme(resources.getIdentifier(currentTheme, "style", this.packageName))
+ ThemeUtil.setTheme(theme, viewModel.getCurrentTheme())
+ if (currentBackgroundStyle != 0) {
+ setTheme(currentBackgroundStyle)
+ }
+ if (currentAccentStyle != 0) {
+ theme.applyStyle(currentAccentStyle, true)
+ }
+ if (currentToolbarStyle != 0) {
+ theme.applyStyle(currentToolbarStyle, true)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/chat/rocket/android/thememanager/adapter/CustomThemesAdapter.kt b/app/src/main/java/chat/rocket/android/thememanager/adapter/CustomThemesAdapter.kt
new file mode 100644
index 0000000000..8525de2a86
--- /dev/null
+++ b/app/src/main/java/chat/rocket/android/thememanager/adapter/CustomThemesAdapter.kt
@@ -0,0 +1,55 @@
+package chat.rocket.android.thememanager.adapter
+
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import chat.rocket.android.R
+import chat.rocket.android.thememanager.model.Theme
+import chat.rocket.android.util.extensions.inflate
+import kotlinx.android.synthetic.main.item_theme_row.view.*
+
+class CustomThemesAdapter(private val customThemes: List,
+ private val listener: (Int, String) -> Unit,
+ private val colorListener: (Int, String, Boolean) -> Unit) : RecyclerView.Adapter() {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
+ ViewHolder(parent.inflate(R.layout.item_custom_theme_row))
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val customTheme = customThemes[position]
+ holder.bind(customTheme)
+ holder.itemView.text_theme_name.setOnClickListener {
+ listener.invoke(position, customTheme.name)
+ }
+ holder.itemView.item_theme_preview_color_accent.setOnClickListener {
+ colorListener.invoke(position, "Custom Accent", customTheme.isDark)
+ }
+ holder.itemView.item_theme_preview_color_primary.setOnClickListener {
+ colorListener.invoke(position, "Custom Toolbar", customTheme.isDark)
+ }
+ holder.itemView.item_theme_preview_color_background.setOnClickListener {
+ colorListener.invoke(position, "Custom Background", customTheme.isDark)
+ }
+ }
+
+ override fun getItemCount(): Int = customThemes.size
+
+ class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ fun bind(theme: Theme) {
+ theme.setPreviewColors(itemView.context)
+ itemView.text_theme_name.text = theme.customName
+
+ val drawableBackground = DrawableHelper.getDrawableFromId(R.drawable.theme_preview, itemView.context).mutate()
+ val drawableAccent = DrawableHelper.getDrawableFromId(R.drawable.theme_preview, itemView.context).mutate()
+ val drawablePrimary = DrawableHelper.getDrawableFromId(R.drawable.theme_preview, itemView.context).mutate()
+
+ DrawableHelper.tintDrawable(drawableBackground, itemView.context, theme.colorPreviewBackground)
+ DrawableHelper.tintDrawable(drawableAccent, itemView.context, theme.colorPreviewAccent)
+ DrawableHelper.tintDrawable(drawablePrimary, itemView.context, theme.colorPreviewPrimary)
+
+ itemView.item_theme_preview_color_background.setImageDrawable(drawableBackground)
+ itemView.item_theme_preview_color_accent.setImageDrawable(drawableAccent)
+ itemView.item_theme_preview_color_primary.setImageDrawable(drawablePrimary)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/chat/rocket/android/thememanager/adapter/ThemesAdapter.kt b/app/src/main/java/chat/rocket/android/thememanager/adapter/ThemesAdapter.kt
new file mode 100644
index 0000000000..761150259b
--- /dev/null
+++ b/app/src/main/java/chat/rocket/android/thememanager/adapter/ThemesAdapter.kt
@@ -0,0 +1,50 @@
+package chat.rocket.android.thememanager.adapter
+
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import chat.rocket.android.R
+import chat.rocket.android.thememanager.model.Theme
+import chat.rocket.android.util.extensions.inflate
+import kotlinx.android.synthetic.main.item_theme_row.view.*
+
+class ThemesAdapter(private val themes: List, private val listener: (Theme) -> Unit) : RecyclerView.Adapter() {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
+ ViewHolder(parent.inflate(R.layout.item_theme_row))
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val theme = themes[position]
+ holder.bind(theme)
+ holder.itemView.setOnClickListener {
+ listener.invoke(theme)
+ }
+ }
+
+ override fun getItemCount(): Int = themes.size
+
+ class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ fun bind(theme: Theme) {
+ theme.setPreviewColors(itemView.context)
+ itemView.text_theme_name.text = theme.toString()
+
+ val drawablePrimaryText = DrawableHelper.getDrawableFromId(R.drawable.theme_preview, itemView.context).mutate()
+ val drawableBackground = DrawableHelper.getDrawableFromId(R.drawable.theme_preview, itemView.context).mutate()
+ val drawableAccent = DrawableHelper.getDrawableFromId(R.drawable.theme_preview, itemView.context).mutate()
+ val drawablePrimary = DrawableHelper.getDrawableFromId(R.drawable.theme_preview, itemView.context).mutate()
+ val drawableDescriptiveText = DrawableHelper.getDrawableFromId(R.drawable.theme_preview, itemView.context).mutate()
+
+ DrawableHelper.tintDrawable(drawableBackground, itemView.context, theme.colorPreviewBackground)
+ DrawableHelper.tintDrawable(drawablePrimaryText, itemView.context, theme.colorPreviewPrimaryText)
+ DrawableHelper.tintDrawable(drawableAccent, itemView.context, theme.colorPreviewAccent)
+ DrawableHelper.tintDrawable(drawablePrimary, itemView.context, theme.colorPreviewPrimary)
+ DrawableHelper.tintDrawable(drawableDescriptiveText, itemView.context, theme.colorPreviewDescriptiveText)
+
+ itemView.item_theme_preview_primary_text.setImageDrawable(drawablePrimaryText)
+ itemView.item_theme_preview_color_background.setImageDrawable(drawableBackground)
+ itemView.item_theme_preview_color_accent.setImageDrawable(drawableAccent)
+ itemView.item_theme_preview_color_primary.setImageDrawable(drawablePrimary)
+ itemView.item_theme_preview_color_descriptive_text.setImageDrawable(drawableDescriptiveText)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/chat/rocket/android/thememanager/di/BaseActivityModule.kt b/app/src/main/java/chat/rocket/android/thememanager/di/BaseActivityModule.kt
new file mode 100644
index 0000000000..46ad8198ea
--- /dev/null
+++ b/app/src/main/java/chat/rocket/android/thememanager/di/BaseActivityModule.kt
@@ -0,0 +1,12 @@
+package chat.rocket.android.thememanager.di
+
+import chat.rocket.android.thememanager.BaseActivity
+import dagger.Module
+import dagger.Provides
+
+@Module
+class BaseActivityModule {
+
+ @Provides
+ fun provideBaseActivity() = BaseActivity()
+}
\ No newline at end of file
diff --git a/app/src/main/java/chat/rocket/android/thememanager/infrastructure/ThemesRepository.kt b/app/src/main/java/chat/rocket/android/thememanager/infrastructure/ThemesRepository.kt
new file mode 100644
index 0000000000..4c74ca825c
--- /dev/null
+++ b/app/src/main/java/chat/rocket/android/thememanager/infrastructure/ThemesRepository.kt
@@ -0,0 +1,226 @@
+package chat.rocket.android.thememanager.infrastructure
+
+import android.content.SharedPreferences
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import chat.rocket.android.R
+import chat.rocket.android.thememanager.model.Theme
+import com.google.gson.Gson
+import javax.inject.Inject
+import java.text.SimpleDateFormat
+import java.util.*
+import kotlin.collections.ArrayList
+
+const val SELECTED_THEME = "selected_theme"
+const val LAST_CHANGED = "last_changed"
+const val IS_CUSTOM = "is_custom"
+const val CUSTOM_THEMES = "custom_themes"
+
+class ThemesRepository @Inject constructor(private val preferences: SharedPreferences) {
+
+ private val themeList = mutableListOf()
+ private val themes = MutableLiveData>()
+
+ private val customThemeList = mutableListOf()
+ private val customThemes = MutableLiveData>()
+ private val customThemeNamesArray = arrayListOf()
+
+ private var storedList = mutableListOf