Skip to content

Commit

Permalink
✨ add screens for implementing sign up
Browse files Browse the repository at this point in the history
  • Loading branch information
kmkim2689 committed Jul 24, 2024
1 parent e12892a commit 15a10fe
Show file tree
Hide file tree
Showing 13 changed files with 408 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.pengcook.android.presentation

import android.net.Uri
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
Expand All @@ -25,6 +26,19 @@ fun loadImage(
}
}

@BindingAdapter("app:imageUri")
fun loadImage(
view: ImageView,
uri: Uri?,
) {
if (uri != null) {
Glide
.with(view.context)
.load(uri)
.into(view)
}
}

@BindingAdapter("app:favoriteCount")
fun favoriteCountText(
view: TextView,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package net.pengcook.android.presentation.core.util

open class Event<out T>(private val content: T) {
var hasBeenHandled = false
private set

fun getContentIfNotHandled(): T? {
return if (hasBeenHandled) {
null
} else {
hasBeenHandled = true
content
}
}

fun peekContent(): T = content
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package net.pengcook.android.presentation.signup

interface BottomButtonClickListener {
fun onConfirm()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package net.pengcook.android.presentation.signup

import java.io.File

sealed interface SignUpEvent {
class NavigateToMain(
val accessToken: String,
val refreshToken: String,
) : SignUpEvent

data object Error : SignUpEvent

data object NavigateBack : SignUpEvent
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package net.pengcook.android.presentation.signup

import java.io.File

data class SignUpForm(
val profileImage: File? = null,
val username: String = INITIAL_VALUE,
val nickname: String = INITIAL_VALUE,
val yearOfBirthday: Int = INITIAL_YEAR,
val monthOfBirthday: Int = INITIAL_MONTH,
val dayOfBirthday: Int = INITIAL_DAY,
val country: String = INITIAL_COUNTRY,
) {
companion object {
private const val INITIAL_VALUE = ""
private const val INITIAL_YEAR = 2024
private const val INITIAL_MONTH = 1
private const val INITIAL_DAY = 1
private const val INITIAL_COUNTRY = ""
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package net.pengcook.android.presentation.signup

import java.io.File

interface SignUpFormEventListener {
fun onProfileImageChange(image: File)

fun onUsernameChange(username: String)

fun onNicknameChange(nickname: String)

fun onYearOfBirthChange(year: Int)

fun onMonthOfBirthChange(month: Int)

fun onDayOfBirthChange(day: Int)

fun onCountryChange(country: String)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package net.pengcook.android.presentation.signup

import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import net.pengcook.android.R
import net.pengcook.android.databinding.FragmentSignUpBinding

class SignUpFragment : Fragment() {
private var _binding: FragmentSignUpBinding? = null
private val binding: FragmentSignUpBinding
get() = _binding!!
private val viewModel: SignUpViewModel by viewModels()
private val launcher =
registerForActivityResult<String, Uri>(ActivityResultContracts.GetContent()) { uri ->
try {
viewModel.changeProfileImage(uri)
} catch (e: RuntimeException) {

}
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
_binding = FragmentSignUpBinding.inflate(inflater)
binding.viewModel = viewModel
binding.lifecycleOwner = this
return binding.root
}

override fun onViewCreated(
view: View,
savedInstanceState: Bundle?,
) {
super.onViewCreated(view, savedInstanceState)
setUpBirthDateSpinner()
setUpCountrySpinner()
setUpClickListener()
observeViewModel()
}

private fun setUpClickListener() {
binding.ivProfileImage.setOnClickListener {
launcher.launch("image/*")
}
}

override fun onDestroy() {
super.onDestroy()
_binding = null
}

private fun setUpCountrySpinner() {
val countryAdapter =
ArrayAdapter(
requireContext(),
android.R.layout.simple_spinner_item,
List(100) { "country$it" },
)
countryAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
binding.formCountry.spFormContent.spDefault.adapter = countryAdapter
}

private fun setUpBirthDateSpinner() {
val yearAdapter =
ArrayAdapter(
requireContext(),
android.R.layout.simple_spinner_item,
List(100) { (it + 1820).toString() },
)
yearAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
binding.formBirthDate.spFormContent1.spDefault.adapter = yearAdapter

val monthAdapter =
ArrayAdapter(
requireContext(),
android.R.layout.simple_spinner_item,
List(12) { (it + 1).toString() },
)
monthAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
binding.formBirthDate.spFormContent2.spDefault.adapter = monthAdapter

val dayAdapter =
ArrayAdapter(
requireContext(),
android.R.layout.simple_spinner_item,
List(31) { (it + 1).toString() },
)
dayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
binding.formBirthDate.spFormContent3.spDefault.adapter = dayAdapter
}

private fun observeViewModel() {
viewModel.signUpEvent.observe(viewLifecycleOwner) { event ->
val signUpEvent = event.getContentIfNotHandled() ?: return@observe
when (signUpEvent) {
is SignUpEvent.NavigateToMain -> {
findNavController().navigate(R.id.action_signUpFragment_to_homeFragment)
}
is SignUpEvent.Error -> {

}
is SignUpEvent.NavigateBack -> {
findNavController().navigate(R.id.action_signUpFragment_to_onboardingFragment)
}
}
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package net.pengcook.android.presentation.signup

import android.net.Uri

data class SignUpUiState(
val isLoading: Boolean = false,
val profileImage: Uri? = null,
val fulfilled: Boolean = false,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package net.pengcook.android.presentation.signup

import android.net.Uri
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import net.pengcook.android.presentation.core.util.Event

class SignUpViewModel :
ViewModel(),
BottomButtonClickListener {
var usernameContent: MutableLiveData<String> = MutableLiveData("")
var nicknameContent: MutableLiveData<String> = MutableLiveData("")
var year: MutableLiveData<String> = MutableLiveData("")
var month: MutableLiveData<String> = MutableLiveData("")
var day: MutableLiveData<String> = MutableLiveData("")
var country: MutableLiveData<String> = MutableLiveData("")
private var _imageUri: MutableLiveData<Uri> = MutableLiveData()
val imageUri: LiveData<Uri>
get() = _imageUri

private var _signUpUiState: MutableLiveData<SignUpUiState> = MutableLiveData(SignUpUiState())
val signUpUiState: LiveData<SignUpUiState>
get() = _signUpUiState

private var _signUpEvent: MutableLiveData<Event<SignUpEvent>> = MutableLiveData()
val signUpEvent: LiveData<Event<SignUpEvent>>
get() = _signUpEvent

fun changeProfileImage(uri: Uri) {
_imageUri.value = uri
}

override fun onConfirm() {
_signUpUiState.value = signUpUiState.value?.copy(isLoading = true)
_signUpEvent.value = Event(SignUpEvent.NavigateToMain("", ""))
_signUpUiState.value = signUpUiState.value?.copy(isLoading = false)
}
}
Loading

0 comments on commit 15a10fe

Please sign in to comment.