Commit 3414b6bb authored by Filipe de Lima Brito's avatar Filipe de Lima Brito

Merge branch 'develop-2.x' into improvement/svg-in-favor-of-text-drawable

parents fcc37452 d31b9ea1
......@@ -72,8 +72,8 @@ dependencies {
kapt libraries.roomProcessor
implementation libraries.roomRxjava
implementation libraries.rxjava
implementation libraries.rxandroid
implementation libraries.rxKotlin
implementation libraries.rxAndroid
implementation libraries.moshi
implementation libraries.okhttp
......@@ -81,6 +81,7 @@ dependencies {
implementation libraries.timber
implementation libraries.threeTenABP
implementation libraries.rxBinding
implementation libraries.fresco
api libraries.frescoOkHttp
......@@ -88,14 +89,12 @@ dependencies {
implementation libraries.frescoWebP
implementation libraries.frescoAnimatedWebP
implementation libraries.frescoImageViewer
kapt libraries.kotshiCompiler
implementation libraries.kotshiApi
implementation libraries.aVLoadingIndicatorView
implementation libraries.frescoImageViewer
implementation libraries.textDrawable
implementation libraries.aVLoadingIndicatorView
implementation('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') {
transitive = true
......
......@@ -19,14 +19,13 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
android:supportsRtl="true">
<activity
android:name=".authentication.ui.AuthenticationActivity"
android:configChanges="orientation"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.SplashScreen"
android:theme="@style/AuthenticationTheme"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
......@@ -41,8 +40,8 @@
android:theme="@style/AppTheme" />
<activity
android:name=".chatrooms.ui.ChatRoomsActivity"
android:theme="@style/ChatListTheme" />
android:name=".main.ui.MainActivity"
android:theme="@style/AppTheme" />
<activity
android:name=".chatroom.ui.ChatRoomActivity"
......
......@@ -25,8 +25,6 @@ import io.fabric.sdk.android.Fabric
import timber.log.Timber
import javax.inject.Inject
class RocketChatApplication : Application(), HasActivityInjector, HasServiceInjector {
@Inject
......
......@@ -3,6 +3,7 @@ package chat.rocket.android.authentication.infraestructure
import chat.rocket.android.authentication.domain.model.TokenModel
import chat.rocket.android.dagger.scope.PerActivity
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.infrastructure.LocalRepository.Companion.TOKEN_KEY
import chat.rocket.android.server.domain.MultiServerTokenRepository
import com.squareup.moshi.Moshi
......@@ -28,6 +29,7 @@ class SharedPreferencesMultiServerTokenRepository(private val repository: LocalR
repository.save("$TOKEN_KEY$server", adapter.toJson(token))
}
override fun clear(server: String) {
repository.clear("$TOKEN_KEY$server")
}
}
\ No newline at end of file
const val TOKEN_KEY = "token_"
\ No newline at end of file
......@@ -7,7 +7,7 @@ import chat.rocket.android.authentication.login.ui.LoginFragment
import chat.rocket.android.authentication.signup.ui.SignupFragment
import chat.rocket.android.authentication.twofactor.ui.TwoFAFragment
import chat.rocket.android.authentication.ui.AuthenticationActivity
import chat.rocket.android.chatrooms.ui.ChatRoomsActivity
import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.util.addFragmentBackStack
import chat.rocket.android.webview.webViewIntent
......@@ -36,7 +36,7 @@ class AuthenticationNavigator(internal val activity: AuthenticationActivity, int
}
fun toChatList() {
val chatList = Intent(activity, ChatRoomsActivity::class.java).apply {
val chatList = Intent(activity, MainActivity::class.java).apply {
//TODO any parameter to pass
}
activity.startActivity(chatList)
......
......@@ -55,7 +55,7 @@ class TwoFAFragment : Fragment(), TwoFAView {
activity?.apply {
text_two_factor_auth.requestFocus()
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(text_two_factor_auth, InputMethodManager.SHOW_IMPLICIT)
imm.showSoftInput(text_two_factor_auth, InputMethodManager.RESULT_UNCHANGED_SHOWN)
}
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
......
......@@ -2,7 +2,7 @@ package chat.rocket.android.chatrooms.di
import android.content.Context
import chat.rocket.android.chatrooms.presentation.ChatRoomsNavigator
import chat.rocket.android.chatrooms.ui.ChatRoomsActivity
import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.dagger.scope.PerActivity
import dagger.Module
import dagger.Provides
......@@ -12,5 +12,5 @@ class ChatRoomsModule {
@Provides
@PerActivity
fun provideAuthenticationNavigator(activity: ChatRoomsActivity, context: Context) = ChatRoomsNavigator(activity, context)
fun provideChatRoomsNavigator(activity: MainActivity, context: Context) = ChatRoomsNavigator(activity, context)
}
\ No newline at end of file
......@@ -3,9 +3,9 @@ package chat.rocket.android.chatrooms.presentation
import android.content.Context
import chat.rocket.android.R
import chat.rocket.android.chatroom.ui.chatRoomIntent
import chat.rocket.android.chatrooms.ui.ChatRoomsActivity
import chat.rocket.android.main.ui.MainActivity
class ChatRoomsNavigator(private val activity: ChatRoomsActivity, private val context: Context) {
class ChatRoomsNavigator(private val activity: MainActivity, private val context: Context) {
fun toChatRoom(chatRoomId: String, chatRoomName: String, chatRoomType: String, isChatRoomReadOnly: Boolean) {
activity.startActivity(context.chatRoomIntent(chatRoomId, chatRoomName, chatRoomType, isChatRoomReadOnly))
......
package chat.rocket.android.chatrooms.presentation
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.server.domain.GetChatRoomsInteractor
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.domain.SaveChatRoomsInteractor
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.launchUI
import chat.rocket.common.RocketChatException
import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.model.Subscription
import chat.rocket.core.internal.realtime.*
import chat.rocket.core.internal.rest.chatRooms
import chat.rocket.core.internal.rest.logout
import chat.rocket.core.internal.rest.unregisterPushToken
import chat.rocket.core.model.ChatRoom
import chat.rocket.core.model.Room
import kotlinx.coroutines.experimental.*
......@@ -23,6 +27,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
private val serverInteractor: GetCurrentServerInteractor,
private val getChatRoomsInteractor: GetChatRoomsInteractor,
private val saveChatRoomsInteractor: SaveChatRoomsInteractor,
private val localRepository: LocalRepository,
factory: RocketChatClientFactory) {
private val client: RocketChatClient = factory.create(serverInteractor.get()!!)
private val currentServer = serverInteractor.get()!!
......@@ -251,4 +256,32 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
client.removeStateChannel(stateChannel)
client.disconnect()
}
/**
* Logout from current server.
*/
fun logout() {
launchUI(strategy) {
try {
clearTokens()
client.logout()
//TODO: Add the code to unsubscribe to all subscriptions.
client.disconnect()
view.onLogout()
} catch (e: RocketChatException) {
Timber.e(e)
view.showMessage(e.message!!)
}
}
}
private suspend fun clearTokens() {
serverInteractor.clear()
val pushToken = localRepository.get(LocalRepository.KEY_PUSH_TOKEN)
if (pushToken != null) {
client.unregisterPushToken(pushToken)
localRepository.clear(LocalRepository.KEY_PUSH_TOKEN)
}
localRepository.clearAllFromServer(currentServer)
}
}
\ No newline at end of file
......@@ -12,4 +12,14 @@ interface ChatRoomsView : LoadingView, MessageView {
* @param dataSet The data set to show.
*/
suspend fun updateChatRooms(newDataSet: List<ChatRoom>)
/**
* Shows no chat rooms to display.
*/
fun showNoChatRoomsToDisplay()
/**
* User has successfully logged out from the current server.
**/
fun onLogout()
}
\ No newline at end of file
package chat.rocket.android.chatrooms.ui
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
import chat.rocket.android.R
import chat.rocket.android.util.addFragment
import dagger.android.AndroidInjection
import dagger.android.AndroidInjector
import dagger.android.DispatchingAndroidInjector
import dagger.android.support.HasSupportFragmentInjector
import javax.inject.Inject
class ChatRoomsActivity : AppCompatActivity(), HasSupportFragmentInjector {
@Inject lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat_rooms)
addFragment("ChatRoomsFragment", R.id.fragment_container) {
ChatRoomsFragment.newInstance()
}
}
override fun onDestroy() {
super.onDestroy()
}
override fun supportFragmentInjector(): AndroidInjector<Fragment> {
return fragmentDispatchingAndroidInjector
}
}
\ No newline at end of file
package chat.rocket.android.chatrooms.ui
import android.content.Intent
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
......@@ -10,23 +11,22 @@ import android.support.v7.widget.SearchView
import android.view.*
import android.widget.Toast
import chat.rocket.android.R
import chat.rocket.android.authentication.ui.AuthenticationActivity
import chat.rocket.android.chatrooms.presentation.ChatRoomsPresenter
import chat.rocket.android.chatrooms.presentation.ChatRoomsView
import chat.rocket.android.util.inflate
import chat.rocket.android.util.setVisible
import chat.rocket.android.widget.DividerItemDecoration
import chat.rocket.core.model.ChatRoom
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.app_bar.*
import kotlinx.android.synthetic.main.fragment_chat_rooms.*
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.async
import kotlinx.coroutines.experimental.launch
import timber.log.Timber
import javax.inject.Inject
class ChatRoomsFragment : Fragment(), ChatRoomsView {
@Inject lateinit var presenter: ChatRoomsPresenter
private var searchView: SearchView? = null
......@@ -41,45 +41,27 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
}
override fun onDestroy() {
Timber.d("Called on destroy...")
presenter.disconnect()
super.onDestroy()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = inflater.inflate(R.layout.fragment_chat_rooms, container, false)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = container?.inflate(R.layout.fragment_chat_rooms)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
(activity as AppCompatActivity).apply {
recycler_view.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
recycler_view.addItemDecoration(DividerItemDecoration(this, 144, 32))
recycler_view.itemAnimator = DefaultItemAnimator()
recycler_view.adapter = ChatRoomsAdapter(this) { chatRoom ->
presenter.loadChatRoom(chatRoom)
}
if (supportActionBar == null) {
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(false)
supportActionBar?.setDisplayShowHomeEnabled(true)
//TODO: should display the current server "SiteName" setting?
supportActionBar?.setDisplayShowTitleEnabled(true)
supportActionBar?.title = "Rocket.Chat"
}
}
setupToolbar()
setupRecyclerView()
presenter.loadChatRooms()
}
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
inflater?.inflate(R.menu.chatrooms_menu, menu)
val searchItem = menu?.findItem(R.id.action_search)
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.chatrooms, menu)
val searchItem = menu.findItem(R.id.action_search)
searchView = searchItem?.actionView as SearchView
val sv = searchView
sv?.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
searchView?.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
return queryChatRoomsByName(query)
}
......@@ -90,6 +72,13 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
})
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when (item?.itemId) {
R.id.action_logout -> presenter.logout()
}
return true
}
override suspend fun updateChatRooms(newDataSet: List<ChatRoom>) {
activity.apply {
launch(UI) {
......@@ -104,6 +93,8 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
}
}
override fun showNoChatRoomsToDisplay() = text_no_data_to_display.setVisible(true)
override fun showLoading() = view_loading.setVisible(true)
override fun hideLoading() = view_loading.setVisible(false)
......@@ -112,6 +103,30 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error))
override fun onLogout() {
activity?.apply {
finish()
val intent = Intent(this, AuthenticationActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
}
}
private fun setupToolbar() {
(activity as AppCompatActivity).supportActionBar?.title = getString(R.string.title_chats)
}
private fun setupRecyclerView() {
activity?.apply {
recycler_view.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
recycler_view.addItemDecoration(DividerItemDecoration(this, 144, 32))
recycler_view.itemAnimator = DefaultItemAnimator()
recycler_view.adapter = ChatRoomsAdapter(this) { chatRoom ->
presenter.loadChatRoom(chatRoom)
}
}
}
private fun queryChatRoomsByName(name: String?): Boolean {
presenter.chatRoomsByName(name ?: "")
return true
......
......@@ -10,8 +10,9 @@ import chat.rocket.android.chatroom.di.ChatRoomFragmentProvider
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatrooms.di.ChatRoomsFragmentProvider
import chat.rocket.android.chatrooms.di.ChatRoomsModule
import chat.rocket.android.chatrooms.ui.ChatRoomsActivity
import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.dagger.scope.PerActivity
import chat.rocket.android.profile.di.ProfileFragmentProvider
import dagger.Module
import dagger.android.ContributesAndroidInjector
......@@ -28,8 +29,8 @@ abstract class ActivityBuilder {
abstract fun bindAuthenticationActivity(): AuthenticationActivity
@PerActivity
@ContributesAndroidInjector(modules = [ChatRoomsModule::class, ChatRoomsFragmentProvider::class])
abstract fun bindMainActivity(): ChatRoomsActivity
@ContributesAndroidInjector(modules = [ChatRoomsModule::class, ChatRoomsFragmentProvider::class, ProfileFragmentProvider::class])
abstract fun bindMainActivity(): MainActivity
@PerActivity
@ContributesAndroidInjector(modules = [ChatRoomFragmentProvider::class])
......
......@@ -3,10 +3,16 @@ package chat.rocket.android.infrastructure
interface LocalRepository {
companion object {
val KEY_PUSH_TOKEN = "KEY_PUSH_TOKEN"
const val KEY_PUSH_TOKEN = "KEY_PUSH_TOKEN"
const val TOKEN_KEY = "token_"
const val SETTINGS_KEY = "settings_"
}
fun save(key: String, value: String?)
fun get(key: String): String?
fun clear(key: String)
fun clearAllFromServer(server: String)
}
\ No newline at end of file
......@@ -11,4 +11,14 @@ class SharedPrefsLocalRepository(private val preferences: SharedPreferences) : L
override fun get(key: String): String? {
return preferences.getString(key, null)
}
override fun clear(key: String) {
preferences.edit().remove(key).apply()
}
override fun clearAllFromServer(server: String) {
clear(LocalRepository.KEY_PUSH_TOKEN)
clear(LocalRepository.TOKEN_KEY + server)
clear(LocalRepository.SETTINGS_KEY + server)
}
}
\ No newline at end of file
package chat.rocket.android.main.ui
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
import android.view.Gravity
import android.view.MenuItem
import chat.rocket.android.R
import chat.rocket.android.chatrooms.ui.ChatRoomsFragment
import chat.rocket.android.profile.ui.ProfileFragment
import chat.rocket.android.util.addFragment
import dagger.android.AndroidInjection
import dagger.android.AndroidInjector
import dagger.android.DispatchingAndroidInjector
import dagger.android.support.HasSupportFragmentInjector
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.app_bar.*
import javax.inject.Inject
class MainActivity : AppCompatActivity(), HasSupportFragmentInjector {
@Inject lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
private var isFragmentAdded: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupToolbar()
setupNavigationView()
}
override fun onResume() {
super.onResume()
if (!isFragmentAdded) {
// Adding the first fragment.
addFragment("ChatRoomsFragment")
isFragmentAdded = true
}
}
override fun supportFragmentInjector(): AndroidInjector<Fragment> = fragmentDispatchingAndroidInjector
private fun setupToolbar() {
setSupportActionBar(toolbar)
toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp)
toolbar.setNavigationOnClickListener {
drawer_layout.openDrawer(Gravity.START)
}
}
private fun setupNavigationView() {
view_navigation.setNavigationItemSelectedListener { menuItem ->
menuItem.isChecked = true
drawer_layout.closeDrawer(Gravity.START)
onNavDrawerItemSelected(menuItem)
true
}
}
private fun onNavDrawerItemSelected(menuItem: MenuItem) {
when (menuItem.itemId) {
R.id.action_chat_rooms -> {
addFragment("ChatRoomsFragment", R.id.fragment_container) {
ChatRoomsFragment.newInstance()
}
}
R.id.action_profile -> {
addFragment("ProfileFragment", R.id.fragment_container) {
ProfileFragment.newInstance()
}
}
}
}
private fun addFragment(tag: String) {
addFragment(tag, R.id.fragment_container) {
ChatRoomsFragment.newInstance()
}
}
}
\ No newline at end of file
package chat.rocket.android.profile.di
import android.arch.lifecycle.LifecycleOwner
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.profile.presentation.ProfileView
import chat.rocket.android.profile.ui.ProfileFragment
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.experimental.Job
@Module
@PerFragment
class ProfileFragmentModule {
@Provides
fun profileView(frag: ProfileFragment): ProfileView {
return frag
}
@Provides
fun provideLifecycleOwner(frag: ProfileFragment): LifecycleOwner {
return frag
}
@Provides
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs)
}
}
\ No newline at end of file
package chat.rocket.android.profile.di
import chat.rocket.android.profile.ui.ProfileFragment
import dagger.Module
import dagger.android.ContributesAndroidInjector
@Module
abstract class ProfileFragmentProvider {
@ContributesAndroidInjector(modules = [ProfileFragmentModule::class])
abstract fun provideProfileFragment(): ProfileFragment
}
\ No newline at end of file
package chat.rocket.android.profile.presentation
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.helper.UrlHelper
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.launchUI
import chat.rocket.common.RocketChatException
import chat.rocket.common.util.ifNull
import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.me
import chat.rocket.core.internal.rest.updateProfile
import javax.inject.Inject
class ProfilePresenter @Inject constructor (private val view: ProfileView,
private val strategy: CancelStrategy,
serverInteractor: GetCurrentServerInteractor,
factory: RocketChatClientFactory) {
private val serverUrl = serverInteractor.get()!!
private val client: RocketChatClient = factory.create(serverUrl)
private lateinit var myselfId: String
fun loadUserProfile() {
launchUI(strategy) {
view.showLoading()
try {
val myself = client.me()
myselfId = myself.id
val avatarUrl = UrlHelper.getAvatarUrl(serverUrl, myself.username!!)
view.showProfile(avatarUrl, myself.name!!, myself.username!!, myself.emails?.get(0)?.address!!)
} catch (exception: RocketChatException) {
exception.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
} finally {
view.hideLoading()
}
}
}
fun updateUserProfile(email: String, name: String, username: String) {
launchUI(strategy) {
view.showLoading()
try {
val user = client.updateProfile(myselfId, email, name, username)
view.showProfileUpdateSuccessfullyMessage()
loadUserProfile()
} catch (exception: RocketChatException) {
exception.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
} finally {
view.hideLoading()
}
}
}
}
\ No newline at end of file
package chat.rocket.android.profile.presentation
import chat.rocket.android.core.behaviours.LoadingView
import chat.rocket.android.core.behaviours.MessageView
import chat.rocket.core.model.Myself
interface ProfileView : LoadingView, MessageView {
/**
* Shows the user profile.
*
* @param avatarUrl The user avatar URL.
* @param name The user display name.
* @param username The user username.
* @param email The user email.
*/
fun showProfile(avatarUrl: String, name: String, username: String, email: String)
/**
* Shows a profile update successfully message
*/
fun showProfileUpdateSuccessfullyMessage()
}
\ No newline at end of file
package chat.rocket.android.profile.ui
import DrawableHelper
import android.os.Build
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.view.ActionMode
import android.view.*
import android.widget.Toast
import chat.rocket.android.R
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.util.getObservable
import chat.rocket.android.util.inflate
import chat.rocket.android.util.setVisible
import chat.rocket.android.util.textContent
import dagger.android.support.AndroidSupportInjection
import io.reactivex.rxkotlin.Observables
import kotlinx.android.synthetic.main.app_bar.*
import kotlinx.android.synthetic.main.avatar_profile.*
import kotlinx.android.synthetic.main.fragment_profile.*
import javax.inject.Inject
class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
@Inject lateinit var presenter: ProfilePresenter
private lateinit var currentName: String
private lateinit var currentUsername: String
private lateinit var currentEmail: String
private var actionMode: ActionMode? = null
companion object {
fun newInstance() = ProfileFragment()
}
override fun onCreate(savedInstanceState: Bundle?) {
AndroidSupportInjection.inject(this)
super.onCreate(savedInstanceState)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = container?.inflate(R.layout.fragment_profile)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupToolbar()
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
tintEditTextDrawableStart()
}
presenter.loadUserProfile()
}
override fun showProfile(avatarUrl: String, name: String, username: String, email: String) {
image_avatar.setImageURI(avatarUrl)
text_name.textContent = name
text_username.textContent = username
text_email.textContent = email
currentName = name
currentUsername = username
currentEmail = email
profile_container.setVisible(true)
listenToChanges()
}
override fun showProfileUpdateSuccessfullyMessage() = showMessage(getString(R.string.msg_profile_update_successfully))
override fun showLoading() {
enableUserInput(false)
view_loading.setVisible(true)
}
override fun hideLoading() {
view_loading.setVisible(false)
enableUserInput(true)
}
override fun showMessage(message: String) = Toast.makeText(activity, message, Toast.LENGTH_SHORT).show()
override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error))
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
mode.menuInflater.inflate(R.menu.profile, menu)
mode.title = getString(R.string.title_update_profile)
return true
}
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean = false
override fun onActionItemClicked(mode: ActionMode, menuItem: MenuItem): Boolean {
return when (menuItem.itemId) {
R.id.action_profile -> {
presenter.updateUserProfile(text_email.textContent, text_name.textContent, text_username.textContent)
mode.finish()
true
}
else -> {
false
}
}
}
override fun onDestroyActionMode(mode: ActionMode) {
actionMode = null
}
private fun setupToolbar() {
(activity as MainActivity).toolbar.title = getString(R.string.title_profile)
}
private fun tintEditTextDrawableStart() {
(activity as MainActivity).apply {
val personDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_person_black_24dp, this)
val atDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_at_black_24dp, this)
val emailDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_email_black_24dp, this)
val drawables = arrayOf(personDrawable, atDrawable, emailDrawable)
DrawableHelper.wrapDrawables(drawables)
DrawableHelper.tintDrawables(drawables, this, R.color.colorDrawableTintGrey)
DrawableHelper.compoundDrawables(arrayOf(text_name, text_username, text_email), drawables)
}
}
private fun listenToChanges() {
Observables.combineLatest(text_name.getObservable(), text_username.getObservable(), text_email.getObservable()).subscribe({ t ->
if (t.first.toString() != currentName || t.second.toString() != currentUsername || t.third.toString() != currentEmail) {
startActionMode()
} else {
finishActionMode()
}
})
}
private fun startActionMode() {
if (actionMode == null) {
actionMode = (activity as MainActivity).startSupportActionMode(this)
}
}
private fun finishActionMode() = actionMode?.finish()
private fun enableUserInput(value: Boolean) {
text_name.isEnabled = value
text_username.isEnabled = value
text_email.isEnabled = value
}
}
\ No newline at end of file
......@@ -20,7 +20,7 @@ import android.text.Spanned
import android.util.Log
import chat.rocket.android.BuildConfig
import chat.rocket.android.R
import chat.rocket.android.chatrooms.ui.ChatRoomsActivity
import chat.rocket.android.main.ui.MainActivity
import org.json.JSONObject
import java.io.Serializable
import java.util.*
......@@ -455,7 +455,7 @@ object PushManager {
}
private fun getContentIntent(context: Context, notificationId: Int, pushMessage: PushMessage, grouped: Boolean = false): PendingIntent {
val notificationIntent = Intent(context, ChatRoomsActivity::class.java)
val notificationIntent = Intent(context, MainActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP)
.putExtra(EXTRA_NOT_ID, notificationId)
.putExtra(EXTRA_HOSTNAME, pushMessage.host)
......
......@@ -3,4 +3,5 @@ package chat.rocket.android.server.domain
interface CurrentServerRepository {
fun save(url: String)
fun get(): String?
fun clear()
}
\ No newline at end of file
......@@ -4,4 +4,8 @@ import javax.inject.Inject
class GetCurrentServerInteractor @Inject constructor(private val repository: CurrentServerRepository) {
fun get(): String? = repository.get()
fun clear() {
repository.clear()
}
}
\ No newline at end of file
......@@ -6,4 +6,6 @@ interface MultiServerTokenRepository {
fun get(server: String): TokenModel?
fun save(server: String, token: TokenModel)
fun clear(server: String)
}
\ No newline at end of file
package chat.rocket.android.server.infraestructure
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.infrastructure.LocalRepository.Companion.SETTINGS_KEY
import chat.rocket.android.server.domain.SettingsRepository
import chat.rocket.core.internal.SettingsAdapter
import chat.rocket.core.model.Value
......@@ -21,8 +22,4 @@ class SharedPreferencesSettingsRepository(private val localRespository: LocalRep
return null
}
companion object {
private const val SETTINGS_KEY = "settings_"
}
}
\ No newline at end of file
......@@ -16,4 +16,8 @@ class SharedPrefsCurrentServerRepository(private val preferences: SharedPreferen
companion object {
private const val CURRENT_SERVER_KEY = "current_server"
}
override fun clear() {
preferences.edit().remove(CURRENT_SERVER_KEY).apply()
}
}
\ No newline at end of file
package chat.rocket.android.util
import android.app.Activity
import android.content.Context
import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
import android.view.inputmethod.InputMethodManager
import chat.rocket.android.R
fun AppCompatActivity.addFragment(tag: String, layoutId: Int, newInstance: () -> Fragment) {
......@@ -19,3 +22,8 @@ fun AppCompatActivity.addFragmentBackStack(tag: String, layoutId: Int, newInstan
.addToBackStack(tag)
.commit()
}
fun Activity.hideKeyboard() {
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(currentFocus.windowToken, InputMethodManager.RESULT_UNCHANGED_SHOWN)
}
\ No newline at end of file
......@@ -4,7 +4,12 @@ import android.support.annotation.LayoutRes
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.TextView
import com.jakewharton.rxbinding2.widget.RxTextView
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import java.util.concurrent.TimeUnit
fun String.ifEmpty(value: String): String {
if (isEmpty()) {
......@@ -36,3 +41,10 @@ var TextView.hintContent: String
set(value) {
hint = value
}
fun EditText.getObservable(): Observable<CharSequence> {
return RxTextView.textChanges(this)
.debounce(100, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(AndroidSchedulers.mainThread())
}
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M20,2H4c-1.1,0 -2,0.9 -2,2v18l4,-4h14c1.1,0 2,-0.9 2,-2V4c0,-1.1 -0.9,-2 -2,-2z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M3,18h18v-2L3,16v2zM3,13h18v-2L3,11v2zM3,6v2h18L21,6L3,6z"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<color android:color="@color/colorPrimary"/>
</item>
<!--<item>
<bitmap
android:gravity="center"
android:src="@mipmap/ic_launcher"/>
</item>-->
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="@color/colorPrimary" />
<solid
android:color="@android:color/transparent" />
<corners
android:radius="2dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@style/ChatListTheme"
tools:context=".chatrooms.ui.ChatRoomsActivity">
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@style/AppTheme"
tools:context=".main.ui.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="@+id/layout_app_bar"
layout="@layout/app_bar" />
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="@+id/view_navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/navigation" />
</android.support.v4.widget.DrawerLayout>
\ No newline at end of file
......@@ -10,7 +10,7 @@
android:id="@+id/image_avatar"
android:layout_width="40dp"
android:layout_height="40dp"
app:roundedCornerRadius="2dp" />
app:roundedCornerRadius="3dp" />
<!-- TODO define the correct bg color for this-->
<ImageView
......
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="6dp">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/image_avatar"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_centerHorizontal="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:roundedCornerRadius="2dp" />
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
......@@ -23,7 +23,7 @@
<EditText
android:id="@+id/text_username_or_email"
style="@style/AuthenticationEditText"
style="@style/EditText.Authentication"
android:layout_marginTop="32dp"
android:drawableStart="@drawable/ic_assignment_ind_black_24dp"
android:hint="@string/msg_username_or_email"
......@@ -35,7 +35,7 @@
<EditText
android:id="@+id/text_password"
style="@style/AuthenticationEditText"
style="@style/EditText.Authentication"
android:layout_marginTop="16dp"
android:drawableStart="@drawable/ic_lock_black_24dp"
android:hint="@string/msg_password"
......
......@@ -24,7 +24,7 @@
<EditText
android:id="@+id/text_server_url"
style="@style/AuthenticationEditText"
style="@style/EditText.Authentication"
android:layout_below="@id/text_headline"
android:layout_marginStart="0dp"
android:layout_marginTop="32dp"
......
......@@ -17,10 +17,10 @@
<EditText
android:id="@+id/text_name"
style="@style/AuthenticationEditText"
style="@style/EditText.Authentication"
android:layout_marginTop="32dp"
android:drawableStart="@drawable/ic_person_black_24dp"
android:hint="@string/msg_name_and_surname"
android:hint="@string/msg_name"
android:imeOptions="actionNext"
android:inputType="textCapWords"
app:layout_constraintLeft_toLeftOf="parent"
......@@ -29,7 +29,7 @@
<EditText
android:id="@+id/text_username"
style="@style/AuthenticationEditText"
style="@style/EditText.Authentication"
android:layout_marginTop="16dp"
android:drawableStart="@drawable/ic_at_black_24dp"
android:hint="@string/msg_username"
......@@ -41,7 +41,7 @@
<EditText
android:id="@+id/text_password"
style="@style/AuthenticationEditText"
style="@style/EditText.Authentication"
android:layout_marginTop="16dp"
android:drawableStart="@drawable/ic_lock_black_24dp"
android:hint="@string/msg_password"
......@@ -53,7 +53,7 @@
<EditText
android:id="@+id/text_email"
style="@style/AuthenticationEditText"
style="@style/EditText.Authentication"
android:layout_marginTop="16dp"
android:drawableStart="@drawable/ic_email_black_24dp"
android:hint="@string/msg_email"
......
......@@ -14,7 +14,7 @@
<EditText
android:id="@+id/text_two_factor_auth"
style="@style/AuthenticationEditText"
style="@style/EditText.Authentication"
android:layout_below="@id/text_headline"
android:layout_marginTop="32dp"
android:drawableStart="@drawable/ic_vpn_key_black_24dp"
......
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".chatrooms.ui.ChatRoomsFragment">
<include
android:id="@+id/layout_app_bar"
layout="@layout/app_bar"
android:background="@color/black" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:gravity="center_horizontal"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
android:layout_height="match_parent" />
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"
app:indicatorColor="@color/black"
app:indicatorName="BallPulseIndicator"
app:indicatorName="BallPulseIndicator" />
<TextView
android:id="@+id/text_no_data_to_display"
style="@style/TextAppearance.AppCompat.Subhead"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/msg_no_data_to_display"
android:visibility="gone"
tools:visibility="visible" />
</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relative_layout"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
tools:context=".profile.ui.ProfileFragment">
<LinearLayout
android:id="@+id/profile_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
<include
android:id="@+id/layout_avatar_profile"
layout="@layout/avatar_profile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp" />
<EditText
android:id="@+id/text_name"
style="@style/EditText.Profile"
android:layout_marginTop="32dp"
android:drawableStart="@drawable/ic_person_black_24dp"
android:hint="@string/msg_name"
android:inputType="textCapWords" />
<EditText
android:id="@+id/text_username"
style="@style/EditText.Profile"
android:layout_marginTop="16dp"
android:drawableStart="@drawable/ic_at_black_24dp"
android:hint="@string/msg_username"
android:inputType="text" />
<EditText
android:id="@+id/text_email"
style="@style/EditText.Profile"
android:layout_marginTop="16dp"
android:drawableStart="@drawable/ic_email_black_24dp"
android:hint="@string/msg_email"
android:inputType="textEmailAddress" />
</LinearLayout>
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
app:indicatorColor="@color/black"
app:indicatorName="BallPulseIndicator" />
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search_white_24px"
android:title="@string/search"
android:title="@string/action_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always|collapseActionView" />
app:showAsAction="ifRoom|collapseActionView" />
<item android:id="@+id/action_logout"
android:title="@string/action_logout"
app:showAsAction="never" />
</menu>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/action_chat_rooms"
android:checked="true"
android:icon="@drawable/ic_chat_bubble_black_24dp"
android:title="@string/title_chats" />
<item
android:id="@+id/action_profile"
android:icon="@drawable/ic_person_black_24dp"
android:title="@string/title_profile" />
</group>
</menu>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_profile"
android:icon="@drawable/ic_check_white_24dp"
android:title="@string/action_update" />
</menu>
\ No newline at end of file
......@@ -5,22 +5,29 @@
<string name="title_log_in">Entrar</string>
<string name="title_sign_up">Inscreva-se</string>
<string name="title_legal_terms">Termos Legais</string>
<string name="title_chats">Chats</string>
<string name="title_profile">Perfil</string>
<string name="title_update_profile">Editar perfil</string>
<!-- Actions -->
<string name="action_connect">Conectar</string>
<string name="action_send">Enviar</string>
<string name="action_terms_of_service">Termos de Serviço</string>
<string name="action_privacy_policy">Política de Privacidade</string>
<string name="search">Pesquisar</string>
<string name="action_search">Pesquisar</string>
<string name="action_update">Atualizar</string>
<string name="action_logout">Sair</string>
<!-- Regular information messages -->
<string name="msg_no_internet_connection">Sem conexão à internet</string>
<string name="msg_invalid_server_url">URL de servidor inválida</string>
<string name="msg_generic_error">Desculpe, ocorreu um erro, tente novamente</string>
<string name="msg_no_data_to_display">Nenhum dado para exibir</string>
<string name="msg_profile_update_successfully">Perfil atualizado com sucesso</string>
<string name="msg_username">nome de usuário</string>
<string name="msg_username_or_email">nome de usuário ou email</string>
<string name="msg_password">senha</string>
<string name="msg_name_and_surname">nome e sobrenome</string>
<string name="msg_name">nome</string>
<string name="msg_email">email</string>
<string name="msg_or_continue_using_social_accounts">Ou continue através de contas sociais</string>
<string name="msg_new_user">Novo usuário? %1$s</string>
......
<resources>
<string name="app_name" translatable="false">Rocket Chat</string>
<string name="app_name" translatable="false">Rocket.Chat</string>
<!-- Titles -->
<string name="title_sign_in_your_server">Sign in your server</string>
<string name="title_log_in">Log in</string>
<string name="title_sign_up">Sign up</string>
<string name="title_legal_terms">Legal Terms</string>
<string name="title_chats">Chats</string>
<string name="title_profile">Profile</string>
<string name="title_update_profile">Update profile</string>
<!-- Actions -->
<string name="action_connect">Connect</string>
<string name="action_send">Send</string>
<string name="action_terms_of_service">Terms of Service</string>
<string name="action_privacy_policy">Privacy Policy</string>
<string name="search">Search</string>
<string name="action_search">Search</string>
<string name="action_update">Update</string>
<string name="action_logout">Log Out</string>
<!-- Regular information messages -->
<string name="msg_no_internet_connection">No internet connection</string>
<string name="msg_invalid_server_url">Invalid server URL</string>
<string name="msg_generic_error">Sorry, an error has occurred, please try again</string>
<string name="msg_no_data_to_display">No data to display</string>
<string name="msg_profile_update_successfully">Profile update successfully</string>
<string name="msg_username">username</string>
<string name="msg_username_or_email">username or email</string>
<string name="msg_password">password</string>
<string name="msg_name_and_surname">name and surname</string>
<string name="msg_name">name</string>
<string name="msg_email">email</string>
<string name="msg_or_continue_using_social_accounts">Or continue using social accounts</string>
<string name="msg_new_user">New user? %1$s</string>
......
......@@ -6,11 +6,9 @@
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:statusBarColor">@color/colorPrimaryDark</item>
</style>
<style name="AppTheme.SplashScreen" parent="AppTheme" >
<item name="android:windowBackground">@drawable/splash_screen</item>
<item name="android:statusBarColor">@color/colorPrimaryDark</item>
<item name="windowActionModeOverlay">true</item>
</style>
<style name="AuthenticationTheme" parent="Theme.AppCompat.NoActionBar">
......@@ -18,11 +16,6 @@
<item name="android:windowBackground">@color/colorPrimary</item>
</style>
<style name="ChatListTheme" parent="AppTheme">
<item name="android:windowTranslucentStatus">true</item>
<item name="colorControlHighlight">@color/colorPrimary</item> <!-- We need this item because of this FloatingSearchView's issue: https://github.com/arimorty/floatingsearchview/issues/222 -->
</style>
<!-- Widget styles. -->
<style name="HeadlineTextView" parent="TextAppearance.AppCompat.Headline">
<item name="android:layout_width">wrap_content</item>
......@@ -32,7 +25,7 @@
<item name="android:layout_marginEnd">@dimen/screen_edge_left_and_right_margins</item>
</style>
<style name="AuthenticationEditText" parent="Widget.AppCompat.EditText">
<style name="EditText.Authentication" parent="Widget.AppCompat.EditText">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">50dp</item>
<item name="android:layout_marginStart">@dimen/screen_edge_left_and_right_margins</item>
......@@ -43,7 +36,11 @@
<item name="android:drawablePadding">@dimen/edit_text_drawable_padding</item>
<item name="android:drawableTint" tools:ignore="NewApi">@color/colorDrawableTintGrey</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:background">@drawable/style_edit_text</item>
<item name="android:background">@drawable/style_edit_text_authentication</item>
</style>
<style name="EditText.Profile" parent="EditText.Authentication">
<item name="android:background">@drawable/style_edit_text_profile</item>
</style>
<style name="AuthenticationLabel" parent="TextAppearance.AppCompat.Medium">
......@@ -54,7 +51,7 @@
<item name="android:maxLines">1</item>
<item name="android:drawablePadding">@dimen/edit_text_drawable_padding</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:background">@drawable/style_edit_text</item>
<item name="android:background">@drawable/style_edit_text_authentication</item>
</style>
<style name="AuthenticationButton" parent="Widget.AppCompat.Button">
......
......@@ -15,17 +15,17 @@ ext {
exoPlayer : '2.6.0',
playServices : '11.8.0',
room : '1.0.0',
rxjava : '2.1.4',
rxandroid : '2.0.1',
rxKotlin : '2.2.0',
rxAndroid : '2.0.1',
moshi : '1.6.0-SNAPSHOT',
okhttp : '3.9.0',
timber : '4.5.1',
threeTenABP : '1.0.5',
rxBinding : '2.0.0',
fresco : '1.7.1',
frescoImageViewer : '0.5.0',
kotshi : '0.3.0',
frescoImageViewer : '0.5.0',
aVLoadingIndicatorView : '2.1.3',
textDrawable : '1.0.2',
// For testing
junit : '4.12',
......@@ -57,8 +57,8 @@ ext {
roomProcessor : "android.arch.persistence.room:compiler:${versions.room}",
roomRxjava : "android.arch.persistence.room:rxjava2:${versions.room}",
rxjava : "io.reactivex.rxjava2:rxjava:${versions.rxjava}",
rxandroid : "io.reactivex.rxjava2:rxandroid:${versions.rxandroid}",
rxKotlin : "io.reactivex.rxjava2:rxkotlin:${versions.rxKotlin}",
rxAndroid : "io.reactivex.rxjava2:rxandroid:${versions.rxAndroid}",
moshi : "com.squareup.moshi:moshi:${versions.moshi}",
moshiKotlin : "com.squareup.moshi:moshi-kotlin:${versions.moshi}",
......@@ -67,6 +67,7 @@ ext {
timber : "com.jakewharton.timber:timber:${versions.timber}",
threeTenABP : "com.jakewharton.threetenabp:threetenabp:${versions.threeTenABP}",
rxBinding : "com.jakewharton.rxbinding2:rxbinding-kotlin:${versions.rxBinding}",
fresco : "com.facebook.fresco:fresco:${versions.fresco}",
frescoOkHttp : "com.facebook.fresco:imagepipeline-okhttp3:${versions.fresco}",
......@@ -74,14 +75,12 @@ ext {
frescoWebP : "com.facebook.fresco:webpsupport:${versions.fresco}",
frescoAnimatedWebP : "com.facebook.fresco:animated-webp:${versions.fresco}",
frescoImageViewer : "com.github.stfalcon:frescoimageviewer:${versions.frescoImageViewer}",
kotshiApi : "se.ansman.kotshi:api:${versions.kotshi}",
kotshiCompiler : "se.ansman.kotshi:compiler:${versions.kotshi}",
aVLoadingIndicatorView : "com.wang.avi:library:${versions.aVLoadingIndicatorView}",
frescoImageViewer : "com.github.stfalcon:frescoimageviewer:${versions.frescoImageViewer}",
textDrawable : "com.github.rocketchat:textdrawable:${versions.textDrawable}",
aVLoadingIndicatorView : "com.wang.avi:library:${versions.aVLoadingIndicatorView}",
// For testing
junit : "junit:junit:$versions.junit",
......
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