Skip to content

Commit

Permalink
feat: Improve UI in some fragments (#1935)
Browse files Browse the repository at this point in the history
Detail:
- Improve TicketsFragment, EventsFragment, ProfileFragment
- Add margin to align title in Action bar

Fixes: #1934
  • Loading branch information
anhanh11001 authored and iamareebjamal committed Jun 9, 2019
1 parent 79345b0 commit 31f7427
Show file tree
Hide file tree
Showing 18 changed files with 429 additions and 307 deletions.
184 changes: 142 additions & 42 deletions app/src/main/java/org/fossasia/openevent/general/auth/ProfileFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import android.content.ActivityNotFoundException
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
Expand All @@ -13,21 +15,28 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.navigation.Navigation.findNavController
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.fragment_profile.view.profileCoordinatorLayout
import kotlinx.android.synthetic.main.fragment_profile.view.avatar
import kotlinx.android.synthetic.main.fragment_profile.view.email
import kotlinx.android.synthetic.main.fragment_profile.view.name
import kotlinx.android.synthetic.main.fragment_profile.view.editProfileRL
import kotlinx.android.synthetic.main.fragment_profile.view.logoutLL
import kotlinx.android.synthetic.main.fragment_profile.view.manageEventsLL
import kotlinx.android.synthetic.main.fragment_profile.view.settingsLL
import kotlinx.android.synthetic.main.fragment_profile.view.ticketIssuesLL
import kotlinx.android.synthetic.main.fragment_profile.view.loginButton
import kotlinx.android.synthetic.main.fragment_profile.view.verificationLayout
import kotlinx.android.synthetic.main.fragment_profile.view.verifiedTextView
import kotlinx.android.synthetic.main.fragment_profile.view.verifiedTick
import kotlinx.android.synthetic.main.fragment_profile.view.resendEmailTextView
import kotlinx.android.synthetic.main.dialog_change_password.view.oldPassword
import kotlinx.android.synthetic.main.dialog_change_password.view.newPassword
import kotlinx.android.synthetic.main.dialog_change_password.view.confirmNewPassword
import kotlinx.android.synthetic.main.dialog_change_password.view.textInputLayoutConfirmNewPassword
import kotlinx.android.synthetic.main.dialog_change_password.view.textInputLayoutNewPassword
import kotlinx.android.synthetic.main.fragment_profile.view.login
import kotlinx.android.synthetic.main.fragment_profile.view.logout
import kotlinx.android.synthetic.main.fragment_profile.view.accountInfoContainer
import kotlinx.android.synthetic.main.fragment_profile.view.accountAvatar
import kotlinx.android.synthetic.main.fragment_profile.view.accountEmail
import kotlinx.android.synthetic.main.fragment_profile.view.accountName
import kotlinx.android.synthetic.main.fragment_profile.view.accountNotVerified
import kotlinx.android.synthetic.main.fragment_profile.view.accountVerified
import kotlinx.android.synthetic.main.fragment_profile.view.profileSettingContainer
import kotlinx.android.synthetic.main.fragment_profile.view.editProfile
import kotlinx.android.synthetic.main.fragment_profile.view.manageEvents
import kotlinx.android.synthetic.main.fragment_profile.view.settings
import kotlinx.android.synthetic.main.fragment_profile.view.ticketIssues
import kotlinx.android.synthetic.main.fragment_profile.view.changePassword
import org.fossasia.openevent.general.BuildConfig
import org.fossasia.openevent.general.CircleTransform
import org.fossasia.openevent.general.PLAY_STORE_BUILD_FLAVOR
import org.fossasia.openevent.general.R
import org.fossasia.openevent.general.utils.Utils
import org.fossasia.openevent.general.utils.Utils.requireDrawable
Expand All @@ -43,9 +52,10 @@ const val PROFILE_FRAGMENT = "profileFragment"

class ProfileFragment : Fragment() {
private val profileViewModel by viewModel<ProfileViewModel>()
private val smartAuthViewModel by viewModel<SmartAuthViewModel>()

private lateinit var rootView: View
private var emailSettings: String? = null
private var emailSettings: String = ""
private var user: User? = null

private fun redirectToLogin() {
Expand All @@ -62,11 +72,10 @@ class ProfileFragment : Fragment() {
}

private fun handleLayoutVisibility(isLoggedIn: Boolean) {
rootView.editProfileRL.isVisible = isLoggedIn
rootView.logoutLL.isVisible = isLoggedIn
rootView.loginButton.isVisible = !isLoggedIn
rootView.verificationLayout.isVisible = isLoggedIn
rootView.resendEmailTextView.isVisible = isLoggedIn
rootView.login.isVisible = !isLoggedIn
rootView.logout.isVisible = isLoggedIn
rootView.profileSettingContainer.isVisible = isLoggedIn
rootView.accountInfoContainer.isVisible = isLoggedIn
}

override fun onCreateView(
Expand All @@ -90,7 +99,7 @@ class ProfileFragment : Fragment() {
profileViewModel.message
.nonNull()
.observe(viewLifecycleOwner, Observer {
rootView.profileCoordinatorLayout.snackbar(it)
rootView.snackbar(it)
})

profileViewModel.user
Expand All @@ -100,63 +109,154 @@ class ProfileFragment : Fragment() {
updateProfile(it)
})

profileViewModel.updatedPassword
.nonNull()
.observe(viewLifecycleOwner, Observer {
if (BuildConfig.FLAVOR == PLAY_STORE_BUILD_FLAVOR) {
smartAuthViewModel.saveCredential(emailSettings, it,
SmartAuthUtil.getCredentialsClient(requireActivity()))
}
})

profileViewModel.updatedUser
.nonNull()
.observe(viewLifecycleOwner, Observer {
user = it
updateProfile(it)
})

rootView.editProfileRL.setOnClickListener {
rootView.editProfile.setOnClickListener {
findNavController(rootView).navigate(ProfileFragmentDirections.actionProfileToEditProfile())
}
return rootView
}

private fun updateProfile(it: User) {
rootView.name.text = "${it.firstName.nullToEmpty()} ${it.lastName.nullToEmpty()}"
rootView.email.text = it.email
emailSettings = it.email
rootView.verifiedTick.isVisible = it.isVerified
rootView.resendEmailTextView.isVisible = !it.isVerified
rootView.verifiedTextView.text =
if (it.isVerified) getString(R.string.verified) else getString(R.string.not_verified)
if (it.isVerified)
rootView.verifiedTextView.setTextColor(
resources.getColorStateList(android.R.color.holo_green_light)
)

rootView.accountName.text = "${it.firstName.nullToEmpty()} ${it.lastName.nullToEmpty()}"
rootView.accountEmail.text = it.email
emailSettings = it.email.nullToEmpty()
rootView.accountNotVerified.isVisible = !it.isVerified
rootView.accountVerified.isVisible = it.isVerified
Picasso.get()
.load(it.avatarUrl)
.placeholder(requireDrawable(requireContext(), R.drawable.ic_account_circle_grey))
.transform(CircleTransform())
.into(rootView.avatar)
.into(rootView.accountAvatar)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

rootView.manageEventsLL.setOnClickListener { startOrgaApp("com.eventyay.organizer") }
rootView.manageEvents.setOnClickListener { startOrgaApp("com.eventyay.organizer") }

rootView.settingsLL.setOnClickListener {
rootView.settings.setOnClickListener {
findNavController(rootView).navigate(ProfileFragmentDirections.actionProfileToSettings(emailSettings))
}

rootView.ticketIssuesLL.setOnClickListener {
rootView.ticketIssues.setOnClickListener {
Utils.openUrl(requireContext(), resources.getString(R.string.ticket_issues_url))
}

rootView.logoutLL.setOnClickListener { showLogoutDialog() }
rootView.loginButton.setOnClickListener { redirectToLogin() }
rootView.logout.setOnClickListener { showLogoutDialog() }
rootView.login.setOnClickListener { redirectToLogin() }

rootView.resendEmailTextView.setOnClickListener {
rootView.accountNotVerified.setOnClickListener {
val userEmail = user?.email
if (userEmail != null) {
profileViewModel.resendVerificationEmail(userEmail)
} else {
rootView.profileCoordinatorLayout.snackbar(getString(R.string.error))
rootView.snackbar(getString(R.string.error))
}
}
rootView.changePassword.setOnClickListener {
handleChangePassword()
}
}

private fun handleChangePassword() {
val layout = layoutInflater.inflate(R.layout.dialog_change_password, null)

val alertDialog = AlertDialog.Builder(requireContext())
.setTitle(getString(R.string.title_change_password))
.setView(layout)
.setPositiveButton(getString(R.string.change)) { _, _ ->
profileViewModel.changePassword(layout.oldPassword.text.toString(), layout.newPassword.text.toString())
}
.setNegativeButton(getString(R.string.cancel)) { dialog, _ ->
dialog.cancel()
}
.show()
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = false

layout.newPassword.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
if (!layout.textInputLayoutNewPassword.isEndIconVisible) {
layout.textInputLayoutNewPassword.isEndIconVisible = true
}

if (layout.newPassword.text.toString().length >= 6) {
layout.textInputLayoutNewPassword.error = null
layout.textInputLayoutNewPassword.isErrorEnabled = false
} else {
layout.textInputLayoutNewPassword.error = getString(R.string.invalid_password_message)
}
if (layout.confirmNewPassword.text.toString() == layout.newPassword.text.toString()) {
layout.textInputLayoutConfirmNewPassword.error = null
layout.textInputLayoutConfirmNewPassword.isErrorEnabled = false
} else {
layout.textInputLayoutConfirmNewPassword.error =
getString(R.string.invalid_confirm_password_message)
}
when (layout.textInputLayoutConfirmNewPassword.isErrorEnabled ||
layout.textInputLayoutNewPassword.isErrorEnabled ||
layout.oldPassword.text.toString().length < 6) {
true -> alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = false
false -> alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = true
}
}

override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { /*Do Nothing*/ }
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { /*Do Nothing*/ }
})

layout.confirmNewPassword.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
if (!layout.textInputLayoutConfirmNewPassword.isEndIconVisible) {
layout.textInputLayoutConfirmNewPassword.isEndIconVisible = true
}

if (layout.confirmNewPassword.text.toString() == layout.newPassword.text.toString()) {
layout.textInputLayoutConfirmNewPassword.error = null
layout.textInputLayoutConfirmNewPassword.isErrorEnabled = false
} else {
layout.textInputLayoutConfirmNewPassword.error =
getString(R.string.invalid_confirm_password_message)
}
when (layout.textInputLayoutConfirmNewPassword.isErrorEnabled ||
layout.textInputLayoutNewPassword.isErrorEnabled ||
layout.oldPassword.text.toString().length < 6) {
true -> alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = false
false -> alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = true
}
}

override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { /*Do Nothing*/ }
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { /*Do Nothiing*/ }
})

layout.oldPassword.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
when (layout.textInputLayoutConfirmNewPassword.isErrorEnabled ||
layout.textInputLayoutNewPassword.isErrorEnabled ||
layout.oldPassword.text.toString().length < 6) {
true -> alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = false
false -> alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = true
}
}

override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { /*Do Nothing*/ }
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { /*Do Nothing*/ }
})
}

private fun startOrgaApp(packageName: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class ProfileViewModel(private val authService: AuthService, private val resourc
val message: LiveData<String> = mutableMessage
private val mutableUpdatedUser = MutableLiveData<User>()
val updatedUser: LiveData<User> = mutableUpdatedUser
private val mutableUpdatedPassword = MutableLiveData<String>()
val updatedPassword: LiveData<String> = mutableUpdatedPassword

fun isLoggedIn() = authService.isLoggedIn()

Expand All @@ -36,6 +38,21 @@ class ProfileViewModel(private val authService: AuthService, private val resourc
}
}

fun changePassword(oldPassword: String, newPassword: String) {
compositeDisposable += authService.changePassword(oldPassword, newPassword)
.withDefaultSchedulers()
.subscribe({
if (it.passwordChanged) {
mutableMessage.value = "Password changed successfully!"
mutableUpdatedPassword.value = newPassword
}
}, {
if (it.message.toString() == "HTTP 400 BAD REQUEST")
mutableMessage.value = "Incorrect Old Password provided!"
else mutableMessage.value = "Unable to change password!"
})
}

fun getProfile() {
compositeDisposable += authService.getProfile()
.withDefaultSchedulers()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ import androidx.navigation.Navigation.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearSnapHelper
import androidx.recyclerview.widget.RecyclerView
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.fragment_order_details.view.orderDetailCoordinatorLayout
import kotlinx.android.synthetic.main.fragment_order_details.view.orderDetailsRecycler
import kotlinx.android.synthetic.main.fragment_order_details.view.backgroundImage
import kotlinx.android.synthetic.main.item_card_order_details.view.orderDetailCardView
import kotlinx.android.synthetic.main.item_enlarged_qr.view.enlargedQrImage
import org.fossasia.openevent.general.BuildConfig
Expand Down Expand Up @@ -53,6 +55,11 @@ class OrderDetailsFragment : Fragment() {
.nonNull()
.observe(this, Observer {
ordersRecyclerAdapter.setEvent(it)
Picasso.get()
.load(it.originalImageUrl)
.error(R.drawable.header)
.placeholder(R.drawable.header)
.into(rootView.backgroundImage)
})

orderDetailsViewModel.attendees
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import android.content.Intent
import android.net.Uri
import android.provider.CalendarContract
import android.view.View
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.widget.FrameLayout
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.item_card_order_details.view.calendar
Expand All @@ -15,6 +17,7 @@ import kotlinx.android.synthetic.main.item_card_order_details.view.eventSummary
import kotlinx.android.synthetic.main.item_card_order_details.view.location
import kotlinx.android.synthetic.main.item_card_order_details.view.map
import kotlinx.android.synthetic.main.item_card_order_details.view.name
import kotlinx.android.synthetic.main.item_card_order_details.view.mainLayout
import kotlinx.android.synthetic.main.item_card_order_details.view.orderIdentifier
import kotlinx.android.synthetic.main.item_card_order_details.view.organizer
import kotlinx.android.synthetic.main.item_card_order_details.view.qrCodeView
Expand Down Expand Up @@ -57,6 +60,17 @@ class OrderDetailsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
itemView.date.text = "$formattedDate\n$formattedTime $timezone"
itemView.eventSummary.text = event.description?.stripHtml()
itemView.ticketCountTextView.text = "Ticket ${position + 1} of $count"
if (position == 0) {
val params: FrameLayout.LayoutParams =
FrameLayout.LayoutParams(resources.getDimension(R.dimen.ticket_width).toInt(), MATCH_PARENT)
params.leftMargin = resources.getDimension(R.dimen.layout_margin_large).toInt()
itemView.mainLayout.layoutParams = params
} else if (position + 1 == count) {
val params: FrameLayout.LayoutParams =
FrameLayout.LayoutParams(resources.getDimension(R.dimen.ticket_width).toInt(), MATCH_PARENT)
params.rightMargin = resources.getDimension(R.dimen.layout_margin_large).toInt()
itemView.mainLayout.layoutParams = params
}

if (event.organizerName.isNullOrEmpty()) {
itemView.organizerLabel.visibility = View.GONE
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/drawable/border.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
<stroke
android:width="0.5dp"
android:color="@color/grey" />
</shape>
</shape>
7 changes: 7 additions & 0 deletions app/src/main/res/drawable/border_curved.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="@color/greyMore" />
<corners android:radius="10dp"/>
</shape>
9 changes: 0 additions & 9 deletions app/src/main/res/drawable/ic_baseline_event_black.xml

This file was deleted.

9 changes: 0 additions & 9 deletions app/src/main/res/drawable/ic_settings_black.xml

This file was deleted.

Loading

0 comments on commit 31f7427

Please sign in to comment.