Skip to content

Instantly share code, notes, and snippets.

@kyodgorbek
Last active December 21, 2018 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kyodgorbek/72d1d3997e13ea4cf7d17890f5a960d3 to your computer and use it in GitHub Desktop.
Save kyodgorbek/72d1d3997e13ea4cf7d17890f5a960d3 to your computer and use it in GitHub Desktop.
class CustomAlertDialog(context: Context) : AlertDialog(context, R.style.AppTheme_FullScreenDialogStyle), CustomAlertDialogBuilder.CustomDialogInterface {
var dismissListener: CustomAlertDialogBuilder.OnDismissListener? = null
private var cancelableDialog = true
var alertDialogInfo = CustomAlertDialogBuilder.AlertDialogInfo()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.custom_dialog)
if (cancelableDialog) {
rootDialogLayout.setOnClickListener { dismiss() }
}
btnPositive.visibility = if (alertDialogInfo.positiveText != null) View.VISIBLE else View.GONE
btnPositive.text = alertDialogInfo.positiveText
btnNegative.visibility = if (alertDialogInfo.negativeText != null) View.VISIBLE else View.GONE
btnNegative.text = alertDialogInfo.negativeText
btnNeutral.visibility = if (alertDialogInfo.neutralText != null) View.VISIBLE else View.GONE
btnNeutral.text = alertDialogInfo.neutralText
dialogTitle.visibility = if (alertDialogInfo.titleText != null) View.VISIBLE else View.GONE
dialogTitle.text = alertDialogInfo.titleText
alertDialogInfo.textColor?.let {
btnPositive.setTextColor(it)
btnNegative.setTextColor(it)
btnNeutral.setTextColor(it)
message?.setTextColor(it)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
buttonsControl?.dividerDrawable?.colorFilter = PorterDuffColorFilter(it, PorterDuff.Mode.MULTIPLY)
}
}
message?.text = this.alertDialogInfo.message
alertDialogInfo.background?.let {
backgroundImage.setImageResource(it)
}
btnPositive.setOnClickListener { alertDialogInfo.onPositiveClickListener?.onClick(this) }
btnNeutral.setOnClickListener { alertDialogInfo.onNeutralClickListener?.onClick(this) }
btnNegative.setOnClickListener { alertDialogInfo.onNegativeClickListener?.onClick(this) }
}
override fun setCancelable(flag: Boolean) {
super.setCancelable(flag)
cancelableDialog = flag
}
override fun onStart() {
super.onStart()
val animationSet = AnimatorSet()
val decorView = this
.window
.decorView
decorView.setBackgroundColor(Color.TRANSPARENT)
backgroundImage?.let {
val titleAnimation = ObjectAnimator.ofFloat(dialogTitle, View.TRANSLATION_Y, -50.dp.toFloat(), 0f)
val imageAnimation = ObjectAnimator.ofFloat(it, View.SCALE_X, 0f, 1f)
val startAnimation = ObjectAnimator.ofFloat(decorView, View.ALPHA, 0f, 1f)
animationSet.playTogether(titleAnimation, imageAnimation, startAnimation)
}
animationSet.duration = 350
animationSet.interpolator = LinearInterpolator()
animationSet.start()
}
override fun dismiss() {
val animationSet = AnimatorSet()
val decorView = this
.window
.decorView
backgroundImage?.let {
val imageAnimation = ObjectAnimator.ofFloat(it, View.SCALE_X, 1f, 0f)
val titleAnimation = ObjectAnimator.ofFloat(dialogTitle, View.TRANSLATION_Y, 0f, -50.dp.toFloat())
val endAnimation = ObjectAnimator.ofFloat(decorView, View.ALPHA, 1.0f, 0.0f)
val listeners = object : AnimationListener() {
override fun onAnimationEnd(animation: Animator?) {
super@CustomAlertDialog.dismiss()
dismissListener?.onDismiss()
}
}
imageAnimation.addListener(listeners)
animationSet.playTogether(titleAnimation, endAnimation, imageAnimation)
}
animationSet.duration = 350
animationSet.interpolator = LinearInterpolator()
animationSet.start()
}
override fun dismiss(callDismissListener: Boolean) {
if (!callDismissListener)
setOnDismissListener { }
dismiss()
}
override fun dismiss(onDismissListener: CustomAlertDialogBuilder.OnDismissListener) {
dismissListener = onDismissListener
dismiss()
}
}
class LogInPresenter(val view: BaseMvpView) : BaseMvpPresenter(view), LogInPresenterInterface {
val network = UsersNetwork()
override fun logIn(email: String, password: String) {
if (validateField(email, password)) {
view.showLoading()
network.logIn(email, password)
.observeOn(AndroidSchedulers.mainThread())
.doOnNext({ saveUserToken(it) })
.flatMap { network.getMyProfile() }
.flatMap { network.updateDeviceToken(it) }
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ loginSucceed(it, email) }, this::showError)
}
}
override fun showError(throwable: Throwable) {
//mView.hideLoading();
//mView.showError(throwable.getMessage());
}
private fun saveUserToken(logInResponse: LogInResponse) {
UsersDatabase().saveToken(logInResponse.token)
UsersDatabase().saveRefreshToken(logInResponse.refreshToken)
}
override fun logInWithFacebook(token: String) {
view.showLoading()
network.loginWithFacebookToken(token)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ facebookLoginSuccess(it) }, this::showError)
}
private fun facebookLoginSuccess(user: Pair<Pair<String, String>, User>) {
view.hideLoading()
UsersDatabase().saveToken(user.first.first)
UsersDatabase().saveRefreshToken(user.first.second)
UsersDatabase().saveUser(user.second)
view.context?.startActivity(Intent(view.context, MainActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK))
}
private fun loginSucceed(user: User, email: String) {
view.hideLoading()
user.email = email
UsersDatabase().saveUser(user)
view.context?.startActivity(Intent(view.context, MainActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK))
}
override fun checkIsUserJustSignedUp() {
// with(UsersDatabase.getCurrentUser()) {
// if (!this?.email.isNullOrEmpty() && !this?.password.isNullOrEmpty()) {
// this!!
// logIn(email, password)
// }
// }
}
private fun validateField(email: String, password: String): Boolean {
if (email.isEmpty() || !email.matches(android.util.Patterns.EMAIL_ADDRESS.toRegex())) {
view.showError(R.string.error_email_input)
return false
}
if (password.isEmpty()) {
view.showError(R.string.error_password_input)
return false
}
return true
}
}
class MainActivity : BaseMvpActivity(), MainView {
companion object {
const val ACTION_FRAGMENT = "FRAGMENT_CHANGE"
const val DELETE_THERAPY = "DELETE_THERAPY"
const val CHANGE_PROFILE = "CHANGE_PROFILE"
const val UPDATE_DATA = "UPDATE_DATA"
}
private var presenter = MainPresenter(this)
private var navigator: Navigator? = null
private var needUpdateData: Boolean = false
private var pushData: Bundle = Bundle()
private var needRedirect: Boolean = false
private var fragmentReceiver: BroadcastReceiver? = null
private var actionDrawerClose: (() -> Unit)? = null
private var firstScreen: String = Screen.HOME
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
handleInComeIntent()
initNavigation()
initData()
initUI()
}
private fun initData() {
presenter.subscribeToNotification()
if (needUpdateData)
presenter.getSession(firstScreen)
else moveToScreen(firstScreen, null)
presenter.getHelpTexts()
}
private fun initNavigation() {
navigator = getNavigator()
(application as HealApplication).setNavigator(navigator)
}
private fun initUI() {
Glide.with(this)
.load(R.drawable.splash)
.into(backgroundImage)
initNavDrawer()
val keyboardUtil = KeyboardUtil(this, drawerLayout.getChildAt(1))
keyboardUtil.enable()
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
this.intent = intent
handleInComeIntent()
if (needRedirect) {
needRedirect = false
(application as HealApplication).router.navigateTo(firstScreen, pushData)
}
}
override fun onStart() {
super.onStart()
fragmentReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
when (intent?.action) {
ACTION_FRAGMENT -> {
changeBackground()
}
DELETE_THERAPY -> {
checkMenuState()
}
CHANGE_PROFILE -> {
updateIcons()
navList.updateMenuItems()
}
}
}
}
val intentFilter = IntentFilter(ACTION_FRAGMENT)
intentFilter.addAction(DELETE_THERAPY)
intentFilter.addAction(CHANGE_PROFILE)
fragmentReceiver?.let { LocalBroadcastManager.getInstance(this).registerReceiver(it, intentFilter) }
}
fun changeBackground() {
val fragment = supportFragmentManager.findFragmentById(R.id.fragmentContainer)
if (fragment != null && fragment is BaseMvpFragment) {
fragment.rootView.isDrawingCacheEnabled = true
(fragment as? HomeFragment)?.take()
fragment.rootView.buildDrawingCache(true)
val cache = fragment.rootView.getDrawingCache(true)
cache?.let {
if (backgroundImage.scaleType == ImageView.ScaleType.FIT_XY) {
backgroundImage.scaleType = ImageView.ScaleType.FIT_CENTER
}
backgroundImage.setImageDrawable(null)
val bitmap = Bitmap.createBitmap(cache)
backgroundImage.setImageBitmap(bitmap)
}
fragment.rootView.isDrawingCacheEnabled = false
}
}
private fun updateIcons() {
presenter.getGender()?.let {
when (it) {
User.Gender.MALE -> navList.updateIconForMenuItem(R.string.item_menu_pain_profile, R.drawable.ic_icon_menu_pain_profile_man)
User.Gender.FEMALE -> navList.updateIconForMenuItem(R.string.item_menu_pain_profile, R.drawable.ic_menu_pain_profile_woman)
}
}
}
private fun checkMenuState() {
navList.updateState(if (presenter.isFullMenu()) MenuView.MenuState.FULL else MenuView.MenuState.SHORT)
}
override fun onStop() {
super.onStop()
fragmentReceiver?.let { LocalBroadcastManager.getInstance(this).unregisterReceiver(it) }
}
private fun handleInComeIntent() {
needRedirect = false
intent?.let { intent ->
needUpdateData = intent.getBooleanExtra(UPDATE_DATA, true)
//Local reminder
when (intent.getStringExtra(Notifications.PushData.ACTION)) {
Notifications.PushData.Reminder.OPEN_SESSION -> {
pushData.putAll(intent.extras)
firstScreen = Screen.START_SESSION
needRedirect = true
}
}
//From server push notification
when (intent.getStringExtra(Notifications.PushData.HEAL_EVENT)?.substringAfterLast("\\")) {
Notifications.PushData.Message.MESSAGE_EVENT -> {
firstScreen = Screen.CHAT
needRedirect = true
}
Notifications.PushData.Evaluation.EVALUATION_EVENT -> {
pushData.putInt(Notifications.PushData.Evaluation.EVALUATION_ID, intent.getStringExtra(Notifications.PushData.Evaluation.EVALUATION_ID).toInt())
pushData.putString(Notifications.PushData.ACTION, Notifications.PushData.Evaluation.EVALUATION)
firstScreen = Screen.START_SESSION
needRedirect = true
}
}
intent?.extras?.clear()
val closeIntent = Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
sendBroadcast(closeIntent)
toggleDrawerScreen(false)
}
}
override fun handleNewDialogMessage() {
val currentFragment = supportFragmentManager.findFragmentById(R.id.fragmentContainer)
if (currentFragment !is ChatFragment) {
val badgeCount = navList.updateBadgeForMenuItem(R.string.support_feedback, 1)
Notifications.sendNotification(this,
Notifications.MessageNotification(this, Notifications.PushData.Message.LOCAL_PUSH_ID, badgeCount).createNotification(),
Notifications.PushData.Message.LOCAL_PUSH_ID)
}
}
override fun setChatBadgeCount(count: Int) {
navList.clearBadgeForMenuItem(R.string.support_feedback)
navList.updateBadgeForMenuItem(R.string.support_feedback, count)
}
override fun startEvaluation(evaluationId: Int) {
EvaluationDialog(evaluationId, activity = this).build()?.show()
}
private fun initNavDrawer() {
closeDrawer.setOnClickListener { toggleDrawerScreen(false) }
drawerLayout?.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.END)
drawerLayout?.addDrawerListener(object : DrawerLayout.DrawerListener {
override fun onDrawerStateChanged(newState: Int) {
}
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
}
override fun onDrawerClosed(drawerView: View) {
actionDrawerClose?.invoke()
}
override fun onDrawerOpened(drawerView: View) {
actionDrawerClose = null
}
})
navList.setOnItemClickListener(object : ItemClickListener<MenuView.MenuItem> {
override fun onItemClicked(t: MenuView.MenuItem, position: Int) {
val fragment = supportFragmentManager.findFragmentById(R.id.fragmentContainer)
var screen = ""
@Suppress("Annotator", "Annotator", "Annotator", "Annotator", "Annotator", "Annotator", "Annotator", "Annotator", "Annotator") val currentScreen = fragment!!.arguments?.getString(ScreenNavigator.SCREEN_NAME)
val data = Bundle()
when (t.title) {
R.string.item_menu_home -> {
screen = Screen.HOME
}
R.string.item_menu_session -> {
screen = Screen.START_SESSION
}
R.string.item_menu_pain_profile -> {
screen = Screen.SELF_DIAGNOSIS
}
R.string.item_menu_favourite -> {
screen = Screen.FAVOURITE_EXERCISES
}
R.string.item_menu_progress_prognosis -> {
screen = Screen.PROGRESS
}
R.string.item_menu_schedule_reminders -> {
screen = Screen.SCHEDULE
}
R.string.item_menu_therapy_settings -> {
screen = Screen.THERAPY_SETTINGS
}
R.string.sign_out -> {
toggleDrawerScreen(false)
presenter.logOut()
return
}
R.string.support_feedback -> {
navList.clearBadgeForMenuItem(R.string.support_feedback)
Notifications.cancelNotification(this@MainActivity, Notifications.PushData.Message.LOCAL_PUSH_ID)
screen = Screen.CHAT
}
R.string.item_menu_account -> {
data.putBoolean("profile", true)
screen = Screen.PROFILE
}
R.string.therapy_information -> {
screen = Screen.THERAPY_INFO
}
R.string.about_healo -> {
data.putBoolean(AboutFragment.BACKGROUND_VIDEO, true)
screen = Screen.ABOUT
}
R.string.activity_journal -> {
screen = Screen.ACTIVITY_JOURNAL
}
R.string.privacy_policy_title -> {
screen = Screen.WEB_PAGE
data.putBoolean(WebPageFragment.DIALOG, false)
data.putString(WebPageFragment.TOOLBAR_TITLE, getString(t.title))
data.putString(WebPageFragment.URL, BuildConfig.PRIVACY_POLICY)
}
R.string.payment_settings ->
screen = Screen.PAYMENT_SETTINGS
R.string.subscriptions -> screen = Screen.SUBSCRIPTIONS
else -> toggleDrawerScreen(false)
}
toggleDrawerScreen(false)
if (screen != currentScreen) {
actionDrawerClose = if ((fragment is OnBackPressed) && (fragment.onBackPressed(screen, data))) {
null
} else {
{ HealApplication.INSTANCE.router.navigateTo(screen, data) }
}
} else {
actionDrawerClose = null
}
}
})
navList.addItemDecoration(object : RecyclerView.ItemDecoration() {
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
super.getItemOffsets(outRect, view, parent, state)
val position = parent.getChildAdapterPosition(view)
if (position == 0) {
outRect.top = 9.5f.dp
}
}
})
updateIcons()
navList.layoutParams.width = getScreenWidth() / 2
drawerListContainer.layoutParams.width = getScreenWidth() / 2
drawerListContainer.invalidate()
navList.requestLayout()
}
fun toggleDrawerScreen(open: Boolean) {
if (open) {
hideKeyboard()
setDrawerAnimation()
drawerLayout?.openDrawer(Gravity.END)
} else {
drawerLayout?.closeDrawer(Gravity.END, true)
}
}
private fun setDrawerAnimation() {
val animatorRecycler = ObjectAnimator.ofFloat(navList, View.TRANSLATION_X, 250f, 0f)
animatorRecycler.duration = 500
animatorRecycler.interpolator = LinearInterpolator()
animatorRecycler.start()
}
private fun getScreenWidth(): Int {
val display = windowManager.defaultDisplay
val size = Point()
display.getSize(size)
return Math.max(size.x, size.y)
}
override fun onBackPressed() {
val fragment = supportFragmentManager.findFragmentById(R.id.fragmentContainer)
if (fragment is OnBackPressed) {
if (fragment.onBackPressed(null, null))
super.onBackPressed()
} else {
if (drawerLayout.isDrawerOpen(Gravity.END)) {
drawerLayout.closeDrawer(Gravity.END, true)
} else {
super.onBackPressed()
}
}
}
override fun moveToScreen(screen: String, data: Bundle?) {
val bundle = Bundle()
if (data != null)
bundle.putAll(data)
bundle.putAll(pushData)
checkMenuState()
if (needRedirect) {
(application as HealApplication).router.newRootScreen(Screen.HOME, null)
(application as HealApplication).router.navigateTo(screen, bundle)
} else {
(application as HealApplication).router.newRootScreen(screen, bundle)
}
}
override fun onDestroy() {
super.onDestroy()
presenter.disconnectFromNotification()
}
private fun hideKeyboard() {
KeyboardUtil.hideKeyboard(this)
}
override fun startGuide() {
startActivityForResult(Intent(this, GuidanceActivity::class.java), GuidanceActivity.REQUEST_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
DiagnosticActivity.handleResult(data, requestCode, resultCode, (application as HealApplication).router)
if (requestCode == GuidanceActivity.REQUEST_CODE) {
moveToScreen(Screen.PROFILE, null)
}
}
override fun onLogout() {
finish()
HealApplication.logout()
}
private fun getNavigator(): Navigator {
return ScreenNavigator(this, R.id.fragmentContainer, Screen::class.java).navigator
}
override fun networkAvailable(isNetworkAvailable: Boolean) {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment