Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Room Park Android
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vladislav Bogdashkin
Room Park Android
Commits
5d7e5a33
Commit
5d7e5a33
authored
Nov 18, 2019
by
Vladislav Bogdashkin
🎣
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feature/login' into develop
parents
9678c356
f5ee4da1
Changes
27
Show whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
271 additions
and
100 deletions
+271
-100
BigantoBaseController.kt
...iganto/visual/roompark/conductor/BigantoBaseController.kt
+8
-0
BigantoBasePresenter.kt
...biganto/visual/roompark/conductor/BigantoBasePresenter.kt
+18
-9
UserHolder.kt
...java/com/biganto/visual/roompark/data/local/UserHolder.kt
+9
-2
IRoomParkMobileApi.kt
...ompark/data/repository/api/retrofit/IRoomParkMobileApi.kt
+4
-5
CustomExceptionDeserializer.kt
...pository/api/retrofit/util/CustomExceptionDeserializer.kt
+5
-10
ContextModule.kt
...va/com/biganto/visual/roompark/di/dagger/ContextModule.kt
+3
-1
settings.kt
...com/biganto/visual/roompark/domain/interactor/settings.kt
+5
-0
authUseCase.kt
...om/biganto/visual/roompark/domain/use_case/authUseCase.kt
+1
-3
ScreenController.kt
...ual/roompark/presentation/screen/auth/ScreenController.kt
+69
-11
ScreenDI.kt
...anto/visual/roompark/presentation/screen/auth/ScreenDI.kt
+5
-0
ScreenPresenter.kt
...sual/roompark/presentation/screen/auth/ScreenPresenter.kt
+21
-5
ScreenViewState.kt
...sual/roompark/presentation/screen/auth/ScreenViewState.kt
+3
-0
HomeBottomNavigationController.kt
...creen/home/home_routing/HomeBottomNavigationController.kt
+17
-22
ScreenContract.kt
...l/roompark/presentation/screen/settings/ScreenContract.kt
+2
-0
ScreenController.kt
...roompark/presentation/screen/settings/ScreenController.kt
+22
-0
ScreenDI.kt
.../visual/roompark/presentation/screen/settings/ScreenDI.kt
+11
-4
ScreenPresenter.kt
.../roompark/presentation/screen/settings/ScreenPresenter.kt
+11
-0
ScreenViewState.kt
.../roompark/presentation/screen/settings/ScreenViewState.kt
+1
-0
ScreenController.kt
...l/roompark/presentation/screen/splash/ScreenController.kt
+7
-2
ScreenDI.kt
...to/visual/roompark/presentation/screen/splash/ScreenDI.kt
+5
-0
ScreenPresenter.kt
...al/roompark/presentation/screen/splash/ScreenPresenter.kt
+6
-0
either.kt
...n/java/com/biganto/visual/roompark/util/monades/either.kt
+10
-7
sign_in_button_selector.xml
app/src/main/res/color/sign_in_button_selector.xml
+3
-2
activity_main.xml
app/src/main/res/layout/activity_main.xml
+9
-10
authentication_screen.xml
app/src/main/res/layout/authentication_screen.xml
+9
-2
settings_screen.xml
app/src/main/res/layout/settings_screen.xml
+5
-5
styles.xml
app/src/main/res/values/styles.xml
+2
-0
No files found.
app/src/main/java/com/biganto/visual/roompark/conductor/BigantoBaseController.kt
View file @
5d7e5a33
...
...
@@ -19,6 +19,7 @@ import com.biganto.visual.roompark.util.monades.ExceptionString
import
com.biganto.visual.roompark.util.view_utils.snackbar.ISnackBarProvider
import
com.hannesdorfmann.mosby3.mvi.MviBasePresenter
import
io.reactivex.disposables.CompositeDisposable
import
timber.log.Timber
/**
* Created by Vladislav Bogdashkin on 28.05.2018.
...
...
@@ -47,7 +48,14 @@ abstract class BigantoBaseController<VS : BigantoBaseViewState,V: BigantoBaseCon
lateinit
var
toolBar
:
ICollapsingToolBar
lateinit
var
snackbar
:
ISnackBarProvider
override
fun
onAttach
(
view
:
View
)
{
Timber
.
d
(
"On Attach"
)
super
.
onAttach
(
view
)
}
override
fun
onDetach
(
view
:
View
)
{
Timber
.
d
(
"On Detach"
)
detachDisposable
.
clear
()
super
.
onDetach
(
view
)
}
...
...
app/src/main/java/com/biganto/visual/roompark/conductor/BigantoBasePresenter.kt
View file @
5d7e5a33
...
...
@@ -8,6 +8,7 @@ import com.hannesdorfmann.mosby3.mvi.MviBasePresenter
import
com.hannesdorfmann.mosby3.mvp.MvpView
import
com.jakewharton.rxrelay2.PublishRelay
import
io.reactivex.Observable
import
timber.log.Timber
/**
* Created by Vladislav Bogdashkin on 30.09.2019.
...
...
@@ -27,16 +28,20 @@ abstract class BigantoBasePresenter<V : MvpView, VS>
open
fun
vsByCode
(
code
:
Int
)
=
defaultErrorViewStateHandler
()
open
fun
vsByThrowable
(
t
:
Throwable
)
=
defaultErrorViewStateHandler
()
open
fun
parseError
(
t
:
Throwable
):
VS
=
open
fun
parseError
(
t
:
Throwable
)
:
VS
=
when
(
t
)
{
is
CustomApiException
->
parseError
(
t
)
is
NoNetworkException
->
parseError
(
t
)
else
->
parseError
(
t
)
is
CustomApiException
->
{
Timber
.
d
(
"CustomApiException ${t.messageStringId} / ${t.customMessage}"
)
parse
(
t
)
}
private
fun
parseError
(
e
:
CustomApiException
)
=
onCodeReturn
(
e
)
private
fun
parseError
(
e
:
NoNetworkException
)
=
onNoNetwork
(
e
)
private
fun
parseError
(
e
:
Exception
)
=
onRandomError
(
e
)
is
NoNetworkException
->
parse
(
t
)
else
->
parse
(
t
)
}
private
fun
parse
(
e
:
CustomApiException
)
=
onCodeReturn
(
e
)
private
fun
parse
(
e
:
NoNetworkException
)
=
onNoNetwork
(
e
)
private
fun
parse
(
e
:
Throwable
)
=
onRandomError
(
e
)
open
fun
onRandomError
(
t
:
Throwable
):
VS
=
vsByThrowable
(
t
).
invoke
(
...
...
@@ -48,7 +53,11 @@ abstract class BigantoBasePresenter<V : MvpView, VS>
ExceptionString
(
R
.
string
.
no_network_error
,
null
)
)
private
fun
onCodeReturn
(
e
:
CustomApiException
):
VS
=
vsByCode
(
e
.
code
).
invoke
(
ExceptionString
(
e
))
private
fun
onCodeReturn
(
e
:
CustomApiException
):
VS
{
Timber
.
d
(
"2 CustomApiException ${e.messageStringId} / ${e.customMessage}"
)
val
errst
=
ExceptionString
(
e
.
messageStringId
,
e
.
customMessage
)
Timber
.
d
(
"ExceptionString ${errst} / ${errst}"
)
return
vsByCode
(
e
.
code
).
invoke
(
errst
)
}
}
\ No newline at end of file
app/src/main/java/com/biganto/visual/roompark/data/local/UserHolder.kt
View file @
5d7e5a33
package
com.biganto.visual.roompark.data.local
import
android.content.Context
import
com.afollestad.rxkprefs.Pref
import
com.afollestad.rxkprefs.rxkPrefs
import
com.biganto.visual.androidplayer.data.repository.local.ILocalStore
import
dagger.Binds
...
...
@@ -28,6 +29,8 @@ class UserHolder @Inject constructor(val context : Context) : ILocalStore
}
private
val
prefs
=
rxkPrefs
(
context
)
private
val
userSession
:
Pref
<
String
>
=
prefs
.
string
(
RECENT_UUID_KEY
,
EMPTY_PREF_VALUE_KEY
)
companion
object
{
const
val
RECENT_UUID_KEY
=
"com.biganto.visual.androidplayer.LAST_USER_UUD"
const
val
EMPTY_PREF_VALUE_KEY
=
"NO_ACTIVE_SESSION"
...
...
@@ -46,15 +49,19 @@ class UserHolder @Inject constructor(val context : Context) : ILocalStore
.
observe
()
override
fun
recentUser
():
Observable
<
in
UserState
>
=
prefs
.
string
(
RECENT_UUID_KEY
,
EMPTY_PREF_VALUE_KEY
)
userSession
.
observe
()
.
map
{
Timber
.
d
(
" AUTH VALUE: $it"
)
if
(
it
==
EMPTY_PREF_VALUE_KEY
)
return
@map
UserState
.
NotAuthenticated
()
else
return
@map
UserState
.
Authenticated
(
it
)
}
override
fun
setRecentUser
(
uuid
:
String
?)
=
Completable
.
fromObservable
(
prefs
.
string
(
RECENT_UUID_KEY
,
uuid
?:
EMPTY_PREF_VALUE_KEY
).
observe
())
Completable
.
defer
{
Completable
.
fromCallable
{
userSession
.
set
(
uuid
?:
EMPTY_PREF_VALUE_KEY
)
}
.
doOnComplete
{
Timber
.
d
(
"complete save null value"
)
}
}
}
sealed
class
UserState
{
...
...
app/src/main/java/com/biganto/visual/roompark/data/repository/api/retrofit/IRoomParkMobileApi.kt
View file @
5d7e5a33
...
...
@@ -3,9 +3,7 @@ package com.biganto.visual.roompark.data.repository.api.retrofit
import
com.biganto.visual.roompark.data.repository.api.retrofit.raw.*
import
io.reactivex.Observable
import
retrofit2.Response
import
retrofit2.http.GET
import
retrofit2.http.POST
import
retrofit2.http.Query
import
retrofit2.http.*
/**
...
...
@@ -133,12 +131,13 @@ interface IRoomParkMobileApi{
@POST
(
"$API_URL$AUTH_METHOD$DELIMITER"
)
@FormUrlEncoded
fun
authoriz
(
@Query
(
CLIENT_TYPE_PARAM
)
clientType
:
String
=
DEFAULT_CLIENT_TYPE
,
@Query
(
CLIENT_VERSION_PARAM
)
clientVersion
:
String
=
DEFAULT_CLIENT_VERSION
,
@Query
(
API_VERSION_PARAM
)
apiVersion
:
String
=
DEFAULT_API_VERSION
,
@
Query
(
EMAIL_AUTH_PARAM
)
email
:
String
,
@
Query
(
PASSWORD_AUTH_PARAM
)
pwd
:
String
@
Field
(
EMAIL_AUTH_PARAM
)
email
:
String
,
@
Field
(
PASSWORD_AUTH_PARAM
)
pwd
:
String
):
Observable
<
Response
<
AuthRaw
>>
...
...
app/src/main/java/com/biganto/visual/roompark/data/repository/api/retrofit/util/CustomExceptionDeserializer.kt
View file @
5d7e5a33
...
...
@@ -2,12 +2,7 @@ package com.biganto.visual.roompark.data.repository.api.retrofit.util
import
com.biganto.visual.roompark.data.repository.api.retrofit.raw.ErrorRaw
import
com.biganto.visual.roompark.domain.custom_exception.parseException
import
com.google.gson.Gson
import
com.google.gson.JsonDeserializationContext
import
com.google.gson.JsonDeserializer
import
com.google.gson.JsonElement
import
org.json.JSONArray
import
org.json.JSONObject
import
com.google.gson.*
import
timber.log.Timber
import
java.lang.reflect.Type
...
...
@@ -23,9 +18,9 @@ class CustomExceptionDeserializer<T> : JsonDeserializer<T> {
//region valid case
when
(
json
){
is
J
SON
Object
->
if
(!
json
.
asJsonObject
.
keySet
().
contains
(
"errors"
))
is
J
son
Object
->
if
(!
json
.
asJsonObject
.
keySet
().
contains
(
"errors"
))
return
Gson
().
newBuilder
().
create
().
fromJson
(
json
,
typeOfT
)
is
J
SON
Array
->
return
Gson
().
newBuilder
().
create
().
fromJson
(
json
,
typeOfT
)
is
J
son
Array
->
return
Gson
().
newBuilder
().
create
().
fromJson
(
json
,
typeOfT
)
}
//endregion valid case
...
...
@@ -35,10 +30,10 @@ class CustomExceptionDeserializer<T> : JsonDeserializer<T> {
Timber
.
w
(
"api errorlist: $errorList"
)
when
(
json
)
{
is
JSON
Array
->
errorList
.
asJsonArray
.
forEach
{
is
Json
Array
->
errorList
.
asJsonArray
.
forEach
{
vals
.
add
(
ctx
.
deserialize
<
T
>(
it
,
ErrorRaw
::
class
.
java
)
as
ErrorRaw
)
}
is
J
SON
Object
->
json
.
asJsonObject
.
get
(
"errors"
).
asJsonArray
.
forEach
{
is
J
son
Object
->
json
.
asJsonObject
.
get
(
"errors"
).
asJsonArray
.
forEach
{
vals
.
add
(
ctx
.
deserialize
<
T
>(
it
,
ErrorRaw
::
class
.
java
)
as
ErrorRaw
)
}
else
->
throw
RuntimeException
(
"Unexpected JSON type: "
+
json
.
javaClass
)
...
...
app/src/main/java/com/biganto/visual/roompark/di/dagger/ContextModule.kt
View file @
5d7e5a33
...
...
@@ -59,7 +59,8 @@ class AuthContractModule @Inject constructor(
api
.
authenticate
(
email
,
password
)
.
map
(
::
fromRaw
)
.
flatMap
{
db
.
upsertUser
(
it
)
}
.
doOnNext
{
local
.
setRecentUser
(
it
.
uuid
.
toString
())
}
.
doOnNext
{
Timber
.
d
(
"user id: ${it.uuid}"
)}
.
doOnNext
{
local
.
setRecentUser
(
it
.
uuid
.
toString
()).
blockingAwait
()
}
.
map
(
::
fromEntity
)
override
fun
validateAuthState
():
Observable
<
Boolean
>
=
local
.
recentUser
()
...
...
@@ -68,5 +69,6 @@ class AuthContractModule @Inject constructor(
is
UserState
.
Authenticated
->
true
else
->
false
}
}
}
app/src/main/java/com/biganto/visual/roompark/domain/interactor/settings.kt
View file @
5d7e5a33
...
...
@@ -3,7 +3,9 @@ package com.biganto.visual.roompark.domain.interactor
import
com.biganto.visual.roompark.domain.model.CachedDataModel
import
com.biganto.visual.roompark.domain.model.PushSwitchModel
import
com.biganto.visual.roompark.domain.model.SettingsModel
import
com.biganto.visual.roompark.domain.use_case.AuthUseCase
import
io.reactivex.Observable
import
io.reactivex.schedulers.Schedulers
import
javax.inject.Inject
/**
...
...
@@ -11,10 +13,13 @@ import javax.inject.Inject
*/
class
SettingsInteractor
@Inject
constructor
(
private
val
auth
:
AuthUseCase
){
fun
fetchSettings
():
Observable
<
SettingsModel
>
=
Observable
.
just
(
sampleSettings
)
fun
signOut
()
=
auth
.
signOut
().
subscribeOn
(
Schedulers
.
io
())
companion
object
{
...
...
app/src/main/java/com/biganto/visual/roompark/domain/use_case/authUseCase.kt
View file @
5d7e5a33
...
...
@@ -10,11 +10,9 @@ import javax.inject.Inject
class
AuthUseCase
@Inject
constructor
(
private
val
authContract
:
AuthContract
){
fun
validateAuth
()
=
authContract
.
validateAuthState
()
fun
signIn
(
login
:
String
,
pwd
:
String
)
=
authContract
.
signIn
(
login
,
pwd
)
fun
signOut
()
=
authContract
.
signOut
()
}
\ No newline at end of file
app/src/main/java/com/biganto/visual/roompark/presentation/screen/auth/ScreenController.kt
View file @
5d7e5a33
...
...
@@ -3,6 +3,7 @@ package com.biganto.visual.roompark.presentation.screen.auth
import
android.view.View
import
butterknife.BindView
import
com.biganto.visual.roompark.R
import
com.biganto.visual.roompark.base.IBottomNavigation
import
com.biganto.visual.roompark.base.RoomParkApplication
import
com.biganto.visual.roompark.base.RoomParkMainActivity
import
com.biganto.visual.roompark.conductor.BigantoBaseController
...
...
@@ -11,8 +12,11 @@ import com.bluelinelabs.conductor.RouterTransaction
import
com.google.android.material.button.MaterialButton
import
com.google.android.material.textfield.TextInputLayout
import
com.jakewharton.rxbinding3.view.clicks
import
com.jakewharton.rxbinding3.widget.textChanges
import
io.reactivex.Observable
import
io.reactivex.android.schedulers.AndroidSchedulers
import
timber.log.Timber
import
java.util.concurrent.TimeUnit
import
javax.inject.Inject
/**
...
...
@@ -24,31 +28,64 @@ class AuthScreenController :
,
AuthScreen
,
AuthScreenPresenter
>()
,
AuthScreen
{
override
fun
onViewBound
(
v
:
View
)
{
}
toolBar
.
hideAll
()
bottomNavigation
.
hide
()
@BindView
(
R
.
id
.
login_text_input
)
lateinit
var
loginInput
:
TextInputLayout
@BindView
(
R
.
id
.
password_text_input
)
lateinit
var
pwdInput
:
TextInputLayout
@BindView
(
R
.
id
.
sign_in_button
)
lateinit
var
signInButton
:
MaterialButton
}
@BindView
(
R
.
id
.
login_text_input
)
lateinit
var
loginInput
:
TextInputLayout
@BindView
(
R
.
id
.
password_text_input
)
lateinit
var
pwdInput
:
TextInputLayout
@BindView
(
R
.
id
.
sign_in_button
)
lateinit
var
signInButton
:
MaterialButton
override
fun
tryAuth
():
Observable
<
AuthInputModel
>
=
signInButton
.
clicks
()
.
map
<
AuthInputModel
>{
AuthInputModel
(
loginInput
.
editText
?.
text
?.
toString
()
?:
""
,
pwdInput
.
editText
?.
text
?.
toString
()
?:
""
)
.
debounce
(
200L
,
TimeUnit
.
MILLISECONDS
)
.
doOnNext
{
signInButton
.
hideKeyboard
()
}
.
map
<
AuthInputModel
>
{
AuthInputModel
(
loginInput
.
editText
?.
text
?.
toString
()
?:
""
,
pwdInput
.
editText
?.
text
?.
toString
()
?:
""
)
}
.
observeOn
(
AndroidSchedulers
.
mainThread
())
override
fun
injectDependencies
()
{
getComponent
()
}
override
fun
onAttach
(
view
:
View
)
{
super
.
onAttach
(
view
)
detachDisposable
.
addAll
(
loginInput
.
editText
?.
textChanges
()
?.
doOnNext
{
Timber
.
d
(
"loginInput.isErrorEnabled ${loginInput.isErrorEnabled}"
)}
?.
filter
{
loginInput
.
isErrorEnabled
}
?.
subscribe
{
Timber
.
d
(
"got key $it"
)
loginInput
.
isErrorEnabled
=
false
loginInput
.
error
=
null
signInButton
.
isEnabled
=
true
},
pwdInput
.
editText
?.
textChanges
()
?.
filter
{
pwdInput
.
isErrorEnabled
}
?.
subscribe
{
pwdInput
.
isErrorEnabled
=
false
signInButton
.
isEnabled
=
true
}
)
}
@Inject
override
lateinit
var
injectedPresenter
:
AuthScreenPresenter
lateinit
var
bottomNavigation
:
IBottomNavigation
@Inject
override
lateinit
var
injectedPresenter
:
AuthScreenPresenter
// @Inject
// lateinit var snacky:ISnackBarProvider
...
...
@@ -63,8 +100,6 @@ class AuthScreenController :
// @Inject
// lateinit var ac: RoomParkMainActivity
override
fun
render
(
viewState
:
AuthScreenViewState
)
{
super
.
render
(
viewState
)
Timber
.
d
(
"Render state $viewState"
)
...
...
@@ -74,6 +109,8 @@ class AuthScreenController :
is
AuthScreenViewState
.
SignedIn
->
render
(
viewState
)
is
AuthScreenViewState
.
SignInError
->
render
(
viewState
)
is
AuthScreenViewState
.
SomeError
->
render
(
viewState
)
is
AuthScreenViewState
.
WrongLogin
->
render
(
viewState
)
is
AuthScreenViewState
.
WrongPassword
->
render
(
viewState
)
}
}
...
...
@@ -97,6 +134,27 @@ class AuthScreenController :
signInButton
.
isEnabled
=
true
}
private
fun
render
(
viewState
:
AuthScreenViewState
.
WrongLogin
){
// showError(viewState.exception)
loginInput
.
isErrorEnabled
=
true
loginInput
.
errorIconDrawable
=
null
viewState
.
exception
.
selectHandler
(
{
strId
->
loginInput
.
error
=
resources
?.
getString
(
strId
)},
{
message
->
loginInput
.
error
=
message
}
)
}
private
fun
render
(
viewState
:
AuthScreenViewState
.
WrongPassword
){
pwdInput
.
isErrorEnabled
=
true
pwdInput
.
errorIconDrawable
=
null
viewState
.
exception
.
selectHandler
(
{
strId
->
pwdInput
.
error
=
resources
?.
getString
(
strId
)},
{
message
->
pwdInput
.
error
=
message
}
)
}
private
fun
render
(
viewState
:
AuthScreenViewState
.
SomeError
)
=
showError
(
viewState
.
exception
)
...
...
app/src/main/java/com/biganto/visual/roompark/presentation/screen/auth/ScreenDI.kt
View file @
5d7e5a33
package
com.biganto.visual.roompark.presentation.screen.auth
import
android.content.Context
import
com.biganto.visual.roompark.base.IBottomNavigation
import
com.biganto.visual.roompark.base.RoomParkMainActivity
import
com.biganto.visual.roompark.data.repository.api.retrofit.di.RetrofitModule
import
com.biganto.visual.roompark.data.repository.db.requrey.DbModule
...
...
@@ -43,4 +44,8 @@ abstract class AuthScreenModule{
@Binds
abstract
fun
provideAuth
(
contract
:
AuthContractModule
):
AuthContract
@PerScreen
@Binds
abstract
fun
provideBottomNavigation
(
activitiy
:
RoomParkMainActivity
):
IBottomNavigation
}
app/src/main/java/com/biganto/visual/roompark/presentation/screen/auth/ScreenPresenter.kt
View file @
5d7e5a33
...
...
@@ -3,6 +3,7 @@ package com.biganto.visual.roompark.presentation.screen.auth
import
com.biganto.visual.roompark.conductor.BigantoBasePresenter
import
com.biganto.visual.roompark.domain.interactor.AuthInteractor
import
com.biganto.visual.roompark.util.monades.ExceptionString
import
io.reactivex.Observable
import
io.reactivex.android.schedulers.AndroidSchedulers
import
io.reactivex.schedulers.Schedulers
import
timber.log.Timber
...
...
@@ -18,26 +19,41 @@ class AuthScreenPresenter @Inject constructor(
)
:
BigantoBasePresenter
<
AuthScreen
,
AuthScreenViewState
>()
{
override
fun
attachView
(
view
:
AuthScreen
)
{
super
.
attachView
(
view
)
Timber
.
d
(
"on AttachView"
)
restoreStateObservable
.
accept
(
AuthScreenViewState
.
Idle
())
}
override
fun
detachView
()
{
super
.
detachView
()
Timber
.
d
(
"on DetachView"
)
restoreStateObservable
}
override
fun
defaultErrorViewStateHandler
()
=
{
e
:
ExceptionString
->
AuthScreenViewState
.
SomeError
(
e
)}
override
fun
vsByCode
(
code
:
Int
):
(
ExceptionString
)
->
AuthScreenViewState
=
when
(
code
)
{
101
->
{
e
:
ExceptionString
->
AuthScreenViewState
.
SignInError
(
e
)}
111
->
{
e
:
ExceptionString
->
AuthScreenViewState
.
WrongLogin
(
e
)}
112
->
{
e
:
ExceptionString
->
AuthScreenViewState
.
WrongPassword
(
e
)}
else
->
{
e
:
ExceptionString
->
AuthScreenViewState
.
SomeError
(
e
)}
}
override
fun
bindIntents
()
{
val
onAuth
=
intent
(
AuthScreen
::
tryAuth
)
.
flatMap
<
AuthScreenViewState
>
{
model
->
.
flatMap
<
AuthScreenViewState
>
{
model
->
interactor
.
signIn
(
model
.
login
,
model
.
pwd
)
.
doOnNext
{
Timber
.
d
(
"auth returned $it"
)
}
.
map
{
it
}
.
map
{
AuthScreenViewState
.
SignedIn
()
}
.
map
<
AuthScreenViewState
>
{
AuthScreenViewState
.
SignedIn
()
}
.
onErrorReturn
{
parseError
(
it
)}
.
startWith
(
Observable
.
just
(
AuthScreenViewState
.
Authorization
()))
}
// .startWith(Observable.just(AuthScreenViewState.Authorization()))
val
state
=
restoreStateObservable
...
...
app/src/main/java/com/biganto/visual/roompark/presentation/screen/auth/ScreenViewState.kt
View file @
5d7e5a33
...
...
@@ -13,4 +13,7 @@ sealed class AuthScreenViewState : BigantoBaseViewState() {
class
SignedIn
:
AuthScreenViewState
()
class
SignInError
(
val
exception
:
ExceptionString
)
:
AuthScreenViewState
()
class
SomeError
(
val
exception
:
ExceptionString
)
:
AuthScreenViewState
()
class
WrongLogin
(
val
exception
:
ExceptionString
)
:
AuthScreenViewState
()
class
WrongPassword
(
val
exception
:
ExceptionString
)
:
AuthScreenViewState
()
}
\ No newline at end of file
app/src/main/java/com/biganto/visual/roompark/presentation/screen/home/home_routing/HomeBottomNavigationController.kt
View file @
5d7e5a33
package
com.biganto.visual.roompark.presentation.screen.home.home_routing
import
android.os.Bundle
import
android.util.Log
import
android.view.View
import
androidx.annotation.IdRes
import
androidx.annotation.NonNull
...
...
@@ -56,40 +55,34 @@ class HomeBottomNavigationController(@IdRes toPage: Int = R.id.tab_feeds)
override
lateinit
var
injectedPresenter
:
HomeScreenPresenter
fun
getComponent
()
=
DaggerHomeScreenComponent
.
factory
()
.
create
(
RoomParkApplication
.
component
,
activity
as
RoomParkMainActivity
)
.
create
(
RoomParkApplication
.
component
,
activity
as
RoomParkMainActivity
)
.
inject
(
this
)
override
fun
render
(
viewState
:
HomeScreenViewState
)
{
when
(
viewState
)
{
when
(
viewState
)
{
is
HomeScreenViewState
.
Idle
->
render
(
viewState
)
is
HomeScreenViewState
.
ToScreen
->
render
(
viewState
)
is
HomeScreenViewState
.
SomeError
->
render
(
viewState
)
}
}
private
fun
render
(
viewState
:
HomeScreenViewState
.
Idle
){
private
fun
render
(
viewState
:
HomeScreenViewState
.
Idle
)
{
}
private
fun
render
(
viewState
:
HomeScreenViewState
.
SomeError
)
=
showError
(
viewState
.
exception
)
private
fun
render
(
viewState
:
HomeScreenViewState
.
ToScreen
){
private
fun
render
(
viewState
:
HomeScreenViewState
.
ToScreen
)
{
// snacky.showSnackBar("lul")
}
override
fun
getLayoutId
()
=
R
.
layout
.
tab_routing_screen_view
override
val
tag
:
String
...
...
@@ -100,7 +93,8 @@ class HomeBottomNavigationController(@IdRes toPage: Int = R.id.tab_feeds)
bottomNavigation
.
show
()
Timber
.
d
(
" onViewBound: ${this::class}"
)
bottomNavigationView
=
((
activity
as
RoomParkMainActivity
)
as
IBottomNavigation
).
bottomNavigation
bottomNavigationView
=
((
activity
as
RoomParkMainActivity
)
as
IBottomNavigation
).
bottomNavigation
bottomNavigationView
.
visibility
=
BottomNavigationView
.
VISIBLE
controllerContainer
=
view
.
findViewById
(
R
.
id
.
tabContainer
)
bottomNavigationView
.
setOnNavigationItemSelectedListener
{
item
->
...
...
@@ -146,19 +140,20 @@ class HomeBottomNavigationController(@IdRes toPage: Int = R.id.tab_feeds)
val
childRouter
=
getChildRouter
(
currentlySelectedItemId
)
Timber
.
d
(
"in back stack - ${childRouter?.backstackSize}"
)
if
(
childRouter
!=
null
)
{
val
backStackSizeCondition
=
childRouter
.
backstackSize
<
0
val
backStackResult
=
childRouter
.
handleBack
()
if
(
backStackResult
&&
backStackSizeCondition
)
if
(
childRouter
.
backstackSize
<
2
)
return
false
if
(
childRouter
.
handleBack
())
navigateTo
(
getControllerFor
(
R
.
id
.
tab_feeds
),
false
)
return
backStackResult
return
true
}
else
{
Log
.
e
(
TAG
,
"handleBack called with getChildRouter(currentlySelectedItemId) == null."
,
Timber
.
e
(
IllegalStateException
(
"handleBack called with getChildRouter(currentlySelectedItemId) == null."
))
"handleBack called with getChildRouter(currentlySelectedItemId) == null."
),
"handleBack called with getChildRouter(currentlySelectedItemId) == null."
)
}
return
false
}
...
...
app/src/main/java/com/biganto/visual/roompark/presentation/screen/settings/ScreenContract.kt
View file @
5d7e5a33
package
com.biganto.visual.roompark.presentation.screen.settings
import
com.biganto.visual.roompark.conductor.BigantoBaseContract
import
io.reactivex.Observable
/**
* Created by Vladislav Bogdashkin on 30.09.2019.
*/
interface
SettingsScreen
:
BigantoBaseContract
<
SettingsScreenViewState
>
{
fun
signOut
():
Observable
<
Int
>
}
app/src/main/java/com/biganto/visual/roompark/presentation/screen/settings/ScreenController.kt
View file @
5d7e5a33
...
...
@@ -13,8 +13,14 @@ import com.biganto.visual.roompark.base.RoomParkMainActivity
import
com.biganto.visual.roompark.conductor.BigantoBaseController
import
com.biganto.visual.roompark.presentation.screen.settings.util.CahcedListAdapter
import
com.biganto.visual.roompark.presentation.screen.settings.util.PushListAdapter
import
com.biganto.visual.roompark.presentation.screen.splash.SplashScreenController
import
com.biganto.visual.roompark.util.extensions.bytesToSize
import
com.bluelinelabs.conductor.RouterTransaction
import
com.bluelinelabs.conductor.changehandler.FadeChangeHandler
import
com.google.android.material.textview.MaterialTextView
import
com.jakewharton.rxbinding3.view.clicks
import
io.reactivex.Observable
import
io.reactivex.android.schedulers.AndroidSchedulers
import
timber.log.Timber
import
javax.inject.Inject
...
...
@@ -28,6 +34,11 @@ class SettingsScreenController :
,
SettingsScreenPresenter
>()
,
SettingsScreen
{
override
fun
signOut
():
Observable
<
Int
>
=
signOutButton
.
clicks
()
.
map
{
Timber
.
d
(
"Clicked sign out button"
);
1
}
.
observeOn
(
AndroidSchedulers
.
mainThread
())
override
fun
injectDependencies
()
{
getComponent
()
}
...
...
@@ -57,6 +68,9 @@ class SettingsScreenController :
@BindView
(
R
.
id
.
downloadFlatCardsIcon
)
lateinit
var
flatDownloaderButton
:
ImageView
@BindView
(
R
.
id
.
signOutButton
)
lateinit
var
signOutButton
:
MaterialTextView
private
fun
setToolbar
(){
toolBar
.
showAll
()
...
...
@@ -94,6 +108,7 @@ class SettingsScreenController :
is
SettingsScreenViewState
.
Idle
->
render
(
viewState
)
is
SettingsScreenViewState
.
LoadSettingsList
->
render
(
viewState
)
is
SettingsScreenViewState
.
SomeError
->
render
(
viewState
)
is
SettingsScreenViewState
.
SignOut
->
render
(
viewState
)
}
}
...
...
@@ -104,6 +119,13 @@ class SettingsScreenController :
}
private
fun
render
(
viewState
:
SettingsScreenViewState
.
SignOut
){
router
.
setRoot
(
RouterTransaction
.
with
(
SplashScreenController
())
.
pushChangeHandler
(
FadeChangeHandler
())
.
popChangeHandler
(
FadeChangeHandler
())
)
}
@SuppressLint
(
"SetTextI18n"
)
private
fun
render
(
viewState
:
SettingsScreenViewState
.
LoadSettingsList
){
...
...
app/src/main/java/com/biganto/visual/roompark/presentation/screen/settings/ScreenDI.kt
View file @
5d7e5a33
...
...
@@ -2,8 +2,10 @@ package com.biganto.visual.roompark.presentation.screen.settings
import
android.content.Context
import
com.biganto.visual.roompark.base.RoomParkMainActivity
import
com.biganto.visual.roompark.di.dagger.AppComponent
import
com.biganto.visual.roompark.di.dagger.PerScreen
import
com.biganto.visual.roompark.data.repository.api.retrofit.di.RetrofitModule
import
com.biganto.visual.roompark.data.repository.db.requrey.DbModule
import
com.biganto.visual.roompark.di.dagger.*
import
com.biganto.visual.roompark.domain.contract.AuthContract
import
dagger.Binds
import
dagger.BindsInstance
import
dagger.Component
...
...
@@ -12,7 +14,8 @@ import dagger.Module
@PerScreen
@Component
(
modules
=
[
SettingsScreenModule
::
class
],
modules
=
[
SettingsScreenModule
::
class
,
DataModule
::
class
,
RetrofitModule
::
class
,
AppModule
::
class
,
DbModule
::
class
],
dependencies
=
[
AppComponent
::
class
])
interface
SettingsScreenComponent
{
...
...
@@ -36,4 +39,8 @@ abstract class SettingsScreenModule{
@Binds
abstract
fun
provideContext
(
activity
:
RoomParkMainActivity
):
Context
@PerScreen
@Binds
abstract
fun
provideAuth
(
contract
:
AuthContractModule
):
AuthContract
}
app/src/main/java/com/biganto/visual/roompark/presentation/screen/settings/ScreenPresenter.kt
View file @
5d7e5a33
...
...
@@ -3,6 +3,7 @@ package com.biganto.visual.roompark.presentation.screen.settings
import
com.biganto.visual.roompark.conductor.BigantoBasePresenter
import
com.biganto.visual.roompark.domain.interactor.SettingsInteractor
import
com.biganto.visual.roompark.util.monades.ExceptionString
import
io.reactivex.Observable
import
io.reactivex.android.schedulers.AndroidSchedulers
import
io.reactivex.schedulers.Schedulers
import
timber.log.Timber
...
...
@@ -26,10 +27,20 @@ class SettingsScreenPresenter @Inject constructor(
val
fetchSettings
=
interactor
.
fetchSettings
()
.
map
{
SettingsScreenViewState
.
LoadSettingsList
(
it
)
}
val
onSignOut
=
intent
(
SettingsScreen
::
signOut
)
.
flatMap
{
interactor
.
signOut
()
.
andThen
(
Observable
.
just
<
SettingsScreenViewState
>(
SettingsScreenViewState
.
SignOut
()))
.
onErrorReturn
(
::
parseError
)
}
val
state
=
restoreStateObservable
.
mergeWith
(
fetchSettings
)
.
mergeWith
(
onSignOut
)
.
doOnError
{
Timber
.
e
(
it
)}
.
subscribeOn
(
Schedulers
.
io
())
.
onErrorReturn
(
::
parseError
)
.
observeOn
(
AndroidSchedulers
.
mainThread
())
subscribeViewState
(
state
.
cast
(
SettingsScreenViewState
::
class
.
java
),
SettingsScreen
::
render
)
...
...
app/src/main/java/com/biganto/visual/roompark/presentation/screen/settings/ScreenViewState.kt
View file @
5d7e5a33
...
...
@@ -13,4 +13,5 @@ sealed class SettingsScreenViewState : BigantoBaseViewState() {
class
Idle
:
SettingsScreenViewState
()
class
LoadSettingsList
(
val
settings
:
SettingsModel
)
:
SettingsScreenViewState
()
class
SomeError
(
val
exception
:
ExceptionString
)
:
SettingsScreenViewState
()
class
SignOut
()
:
SettingsScreenViewState
()
}
\ No newline at end of file
app/src/main/java/com/biganto/visual/roompark/presentation/screen/splash/ScreenController.kt
View file @
5d7e5a33
...
...
@@ -2,6 +2,7 @@ package com.biganto.visual.roompark.presentation.screen.splash
import
android.view.View
import
com.biganto.visual.roompark.R
import
com.biganto.visual.roompark.base.IBottomNavigation
import
com.biganto.visual.roompark.base.RoomParkApplication
import
com.biganto.visual.roompark.base.RoomParkMainActivity
import
com.biganto.visual.roompark.conductor.BigantoBaseController
...
...
@@ -23,6 +24,8 @@ class SplashScreenController :
override
fun
onViewBound
(
v
:
View
)
{
toolBar
.
hideAll
()
bottomNavigation
.
hide
()
}
override
fun
injectDependencies
()
{
...
...
@@ -46,6 +49,8 @@ class SplashScreenController :
// @Inject
// lateinit var ac: RoomParkMainActivity
@Inject
lateinit
var
bottomNavigation
:
IBottomNavigation
override
fun
render
(
viewState
:
SplashScreenViewState
)
{
when
(
viewState
){
...
...
@@ -72,8 +77,8 @@ class SplashScreenController :
private
fun
render
(
viewState
:
SplashScreenViewState
.
ToHomeScreen
){
router
.
setRoot
(
RouterTransaction
.
with
(
HomeBottomNavigationController
())
.
popChangeHandler
(
FadeChangeHandler
())
.
pushChangeHandler
(
FadeChangeHandler
())
.
popChangeHandler
(
FadeChangeHandler
(
200L
))
.
pushChangeHandler
(
FadeChangeHandler
(
300L
))
)
}
...
...
app/src/main/java/com/biganto/visual/roompark/presentation/screen/splash/ScreenDI.kt
View file @
5d7e5a33
package
com.biganto.visual.roompark.presentation.screen.splash
import
android.content.Context
import
com.biganto.visual.roompark.base.IBottomNavigation
import
com.biganto.visual.roompark.base.RoomParkMainActivity
import
com.biganto.visual.roompark.data.repository.api.retrofit.di.RetrofitModule
import
com.biganto.visual.roompark.data.repository.db.requrey.DbModule
...
...
@@ -50,4 +51,8 @@ abstract class SplashScreenModule{
// @Binds
// abstract fun provideToolbar(activitiy: RoomParkMainActivity): ICollapsingToolBar
@PerScreen
@Binds
abstract
fun
provideBottomNavigation
(
activitiy
:
RoomParkMainActivity
):
IBottomNavigation
}
app/src/main/java/com/biganto/visual/roompark/presentation/screen/splash/ScreenPresenter.kt
View file @
5d7e5a33
...
...
@@ -4,6 +4,9 @@ import com.biganto.visual.roompark.base.RoomParkMainActivity
import
com.biganto.visual.roompark.conductor.BigantoBasePresenter
import
com.biganto.visual.roompark.domain.interactor.SplashInteractor
import
com.biganto.visual.roompark.util.monades.ExceptionString
import
io.reactivex.android.schedulers.AndroidSchedulers
import
io.reactivex.schedulers.Schedulers
import
java.util.concurrent.TimeUnit
import
javax.inject.Inject
/**
...
...
@@ -29,7 +32,10 @@ class SplashScreenPresenter @Inject constructor(
if
(
it
)
SplashScreenViewState
.
ToHomeScreen
()
else
SplashScreenViewState
.
ToAuthScreen
()
}
.
delay
(
250
,
TimeUnit
.
MILLISECONDS
)
)
.
subscribeOn
(
Schedulers
.
io
())
.
observeOn
(
AndroidSchedulers
.
mainThread
())
subscribeViewState
(
state
.
cast
(
SplashScreenViewState
::
class
.
java
),
SplashScreen
::
render
)
}
...
...
app/src/main/java/com/biganto/visual/roompark/util/monades/either.kt
View file @
5d7e5a33
...
...
@@ -18,7 +18,7 @@ sealed class Either<out E, out V> {
data class
ExceptionString
(
@StringRes
private
val
stringId
:
Int
?,
private
val
message
:
String
?)
{
val
errorMessage
:
Either
<
Int
,
String
>
fun
selectHandler
(
a1
:(
Int
)->
Unit
,
a2
:(
String
)->
Unit
)
=
when
(
errorMessage
){
...
...
@@ -27,13 +27,16 @@ data class ExceptionString(@StringRes private val stringId: Int?, private val m
}
constructor
(
e
:
CustomApiException
)
:
this
(
if
(
e
.
m
essage
!=
null
)
null
else
e
.
messageStringId
,
if
(
e
.
messageStringId
!=
null
)
null
else
e
.
m
essage
if
(
e
.
customM
essage
!=
null
)
null
else
e
.
messageStringId
,
e
.
customM
essage
)
init
{
assert
(
stringId
==
null
&&
message
==
null
)
{
"both values cannot be null!"
}
errorMessage
=
if
(
stringId
!=
null
)
Either
.
Left
(
stringId
)
else
Either
.
Right
(
message
!!
)
}
val
errorMessage
:
Either
<
Int
,
String
>
=
if
(
stringId
!=
null
)
Either
.
Left
(
stringId
)
else
Either
.
Right
(
message
!!
)
// init {
// Timber.d(" messages: $stringId / $message")
// if (stringId==null && message==null) throw error{ "both values cannot be null!" }
// errorMessage = if (stringId!=null) Either.Left(stringId) else Either.Right(message!!)
// }
}
app/src/main/res/color/sign_in_button_selector.xml
View file @
5d7e5a33
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<item
android:state_enabled=
"false"
android:color=
"@color/colorAccent"
/>
<item
android:color=
"@color/colorGray"
/>
<item
android:state_enabled=
"false"
android:color=
"@color/colorGray"
/>
<item
android:color=
"@color/colorAccent"
/>
</selector>
\ No newline at end of file
app/src/main/res/layout/activity_main.xml
View file @
5d7e5a33
...
...
@@ -5,7 +5,6 @@
android:id=
"@+id/bottom_drawer_menu"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:fitsSystemWindows=
"true"
tools:context=
".base.RoomParkMainActivity"
>
...
...
@@ -24,11 +23,11 @@
android:clipToPadding=
"true"
android:theme=
"@style/ThemeOverlay.AppCompat.Light"
app:expanded=
"false"
app:liftOnScroll=
"true"
app:layout_behavior=
".util.view_utils.app_bar.DragControlAppBarLayoutBehaviour"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:liftOnScroll=
"true"
tools:visibility=
"visible"
>
<com.google.android.material.appbar.CollapsingToolbarLayout
...
...
@@ -47,9 +46,9 @@
android:layout_height=
"?android:attr/actionBarSize"
android:visibility=
"invisible"
app:layout_collapseMode=
"pin"
app:titleTextAppearance=
"@style/Header_TextView.Main_Header"
app:popupTheme=
"@style/ThemeOverlay.AppCompat.Light"
app:showAsAction=
"always"
app:titleTextAppearance=
"@style/Header_TextView.Main_Header"
tools:visibility=
"invisible"
>
</androidx.appcompat.widget.Toolbar>
...
...
@@ -62,7 +61,7 @@
android:id=
"@+id/conductor_container"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
app:layout_behavior=
"com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
>
app:layout_behavior=
"com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
>
<include
layout=
"@layout/test_progress_status"
...
...
@@ -71,12 +70,12 @@
</FrameLayout>
<!-- <com.bluelinelabs.conductor.ChangeHandlerFrameLayout-->
<!-- android:id="@+id/conductor_container"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- android:background="@color/colorBackground"-->
<!-- app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />-->
<!-- <com.bluelinelabs.conductor.ChangeHandlerFrameLayout-->
<!-- android:id="@+id/conductor_container"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- android:background="@color/colorBackground"-->
<!-- app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />-->
<!--</android.support.constraint.ConstraintLayout>-->
...
...
app/src/main/res/layout/authentication_screen.xml
View file @
5d7e5a33
...
...
@@ -52,13 +52,16 @@
android:layout_marginStart=
"16dp"
android:layout_marginTop=
"16dp"
android:layout_marginEnd=
"16dp"
android:nextFocusDown=
"@id/password_text_input"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/textView3"
>
<com.google.android.material.textfield.TextInputEditText
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
/>
android:layout_height=
"wrap_content"
android:inputType=
"textEmailAddress"
android:maxLines=
"1"
/>
</com.google.android.material.textfield.TextInputLayout>
<FrameLayout
...
...
@@ -76,12 +79,16 @@
<com.google.android.material.textfield.TextInputLayout
android:id=
"@+id/password_text_input"
style=
"@style/AuthTextInputLayout.Password"
android:nextFocusDown=
"@id/sign_in_button"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
<com.google.android.material.textfield.TextInputEditText
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
/>
android:layout_height=
"wrap_content"
android:inputType=
"textPassword"
android:maxLength=
"64"
android:maxLines=
"1"
/>
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout
...
...
app/src/main/res/layout/settings_screen.xml
View file @
5d7e5a33
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
<androidx.core.widget.NestedScrollView
xmlns:tools=
"http://schemas.android.com/tools"
android:id=
"@+id/nestedScrollContainer"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<LinearLayout
xmlns:tools=
"http://schemas.android.com/tools"
<LinearLayout
android:orientation=
"vertical"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
...
...
@@ -139,11 +139,11 @@
<com.google.android.material.textview.MaterialTextView
android:id=
"@+id/signOutButton"
style=
"@style/Default_TextView.Cancel_Text"
android:text=
"СМЕНИТЬ АККАУНТ"
android:layout_margin=
"32dp"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
/>
android:layout_margin=
"32dp"
android:text=
"СМЕНИТЬ АККАУНТ"
/>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
\ No newline at end of file
app/src/main/res/values/styles.xml
View file @
5d7e5a33
...
...
@@ -41,6 +41,7 @@
<style
name=
"Auth.ErrorText"
parent=
"TextAppearance.Design.Error"
>
<item
name=
"android:textColor"
>
@color/colorError
</item>
<item
name=
"android:textSize"
>
@dimen/lite_notice
</item>
</style>
<style
name=
"Auth.EditText"
parent=
"Widget.AppCompat.EditText"
>
...
...
@@ -151,6 +152,7 @@
<style
name=
"AuthButton.Enable"
>
<item
name=
"android:text"
>
"ВОЙТИ"
</item>
<item
name=
"android:textColor"
>
@color/sign_in_button_selector
</item>
<item
name=
"strokeColor"
>
@color/sign_in_button_selector
</item>
</style>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment