Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/week06-xml-advanced #32

Open
wants to merge 9 commits into
base: develop-xml
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -184,4 +184,10 @@ fabric.properties

!/gradle/wrapper/gradle-wrapper.jar

# End of https://www.toptal.com/developers/gitignore/api/android,androidstudio,kotlin
# End of https://www.toptal.com/developers/gitignore/api/android,androidstudio,kotlin

### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
16 changes: 8 additions & 8 deletions app/src/main/java/com/sopt/now/network/service/AuthService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,28 @@ import com.sopt.now.network.request.RequestLoginDto
import com.sopt.now.network.request.RequestSignUpDto
import com.sopt.now.network.response.ResponseDto
import com.sopt.now.network.response.ResponseInfoDto
import retrofit2.Call
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.PATCH
import retrofit2.http.POST

interface AuthService {
@POST("member/join")
fun signUp(
suspend fun signUp(
@Body request: RequestSignUpDto,
): Call<ResponseDto>
): Response<ResponseDto>

@POST("member/login")
fun login(
suspend fun login(
@Body request: RequestLoginDto,
): Call<ResponseDto>
): Response<ResponseDto>

@PATCH("member/password")
fun changePassword(
suspend fun changePassword(
@Body request: RequestChangePasswordDto,
): Call<ResponseDto>
): Response<ResponseDto>

@GET("member/info")
fun info(): Call<ResponseInfoDto>
suspend fun info(): Response<ResponseInfoDto>
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package com.sopt.now.network.service

import com.sopt.now.network.response.ResponseFollowerDto
import retrofit2.Call
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Query

interface FollowerService {
@GET("users")
fun getFollowers(
suspend fun getFollowers(
@Query("page") page: Int,
): Call<ResponseFollowerDto>
): Response<ResponseFollowerDto>
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,43 @@ package com.sopt.now.ui.change_password

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sopt.now.data.UserRepository
import com.sopt.now.network.request.RequestChangePasswordDto
import com.sopt.now.network.response.ResponseDto
import com.sopt.now.network.service.ServicePool
import com.sopt.now.ui.AuthState
import retrofit2.Call
import retrofit2.Callback
import kotlinx.coroutines.launch
import retrofit2.Response

class ChangePasswordViewModel(private val userRepository: UserRepository) : ViewModel() {
private val authService by lazy { ServicePool.authService }
val changePasswordStatus = MutableLiveData<AuthState>()

fun changePassword(request: RequestChangePasswordDto) {
authService.changePassword(request).enqueue(object : Callback<ResponseDto> {
override fun onResponse(
call: Call<ResponseDto>,
response: Response<ResponseDto>,
) {
if (response.isSuccessful) {
successResponse(response, request)
} else {
failResponse(response)
}
}

override fun onFailure(call: Call<ResponseDto>, t: Throwable) {
viewModelScope.launch {
runCatching {
authService.changePassword(request)
}.onSuccess { response ->
handleSuccess(response, request)
}.onFailure {
changePasswordStatus.value = AuthState(
isSuccess = false,
message = "서버 에러"
)
}
})
}
}

private fun handleSuccess(
response: Response<ResponseDto>,
request: RequestChangePasswordDto,
) {
if (response.isSuccessful) {
successResponse(response, request)
} else {
failResponse(response)
}
}

private fun successResponse(
Expand Down
12 changes: 5 additions & 7 deletions app/src/main/java/com/sopt/now/ui/follower/FollowerFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,13 @@ class FollowerFragment : Fragment() {
private lateinit var followerAdapter: FollowerAdapter

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

Comment on lines 23 to 26
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

왜 바꾸신 것일까여?


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

Expand All @@ -47,7 +45,7 @@ class FollowerFragment : Fragment() {

override fun onDestroyView() {
super.onDestroyView()
_binding?.rvFollower?.adapter = null
_binding = null
Comment on lines 47 to 49
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

followerAdapter 를 메모리 해제처리 해줘야합니다
즉 lateinit var로 선언하면 불가능해지겠죠?

binding.rvFollower.adapter = null
}
}
35 changes: 18 additions & 17 deletions app/src/main/java/com/sopt/now/ui/follower/FollowerViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,35 @@ import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sopt.now.network.response.ResponseFollowerDto
import com.sopt.now.network.service.ServicePool
import retrofit2.Call
import retrofit2.Callback
import kotlinx.coroutines.launch
import retrofit2.Response

class FollowerViewModel : ViewModel() {
private val _followers = MutableLiveData<List<ResponseFollowerDto.Data>>()
val followers: LiveData<List<ResponseFollowerDto.Data>> get() = _followers

fun loadFollowers() {
ServicePool.followerService.getFollowers(2).enqueue(object : Callback<ResponseFollowerDto> {
override fun onResponse(
call: Call<ResponseFollowerDto>,
response: Response<ResponseFollowerDto>,
) {
if (response.isSuccessful) {
response.body()?.data?.let { followers ->
_followers.value = followers
}
} else {
Log.e("FollowerViewModel", "Failed to fetch followers")
}
viewModelScope.launch {
runCatching {
ServicePool.followerService.getFollowers(2)
}.onSuccess { response ->
handleSuccess(response)
}.onFailure {t ->
Log.e("FollowerViewModel", "서버 에러", t)
}
}
}

override fun onFailure(call: Call<ResponseFollowerDto>, t: Throwable) {
Log.e("FollowerViewModel", "Error fetching followers", t)
private fun handleSuccess(response: Response<ResponseFollowerDto>) {
if (response.isSuccessful) {
response.body()?.data?.let { followers ->
_followers.value = followers
}
})
} else {
Log.e("FollowerViewModel", "Failed to fetch followers")
}
}
}
33 changes: 18 additions & 15 deletions app/src/main/java/com/sopt/now/ui/login/LoginViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,43 @@ package com.sopt.now.ui.login

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sopt.now.data.UserRepository
import com.sopt.now.network.request.RequestLoginDto
import com.sopt.now.network.response.ResponseDto
import com.sopt.now.network.service.ServicePool
import com.sopt.now.ui.AuthState
import kotlinx.coroutines.launch
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class LoginViewModel(private val userRepository: UserRepository) : ViewModel() {
private val authService by lazy { ServicePool.authService }
val loginStatus = MutableLiveData<AuthState>()
fun login(request: RequestLoginDto) {
authService.login(request).enqueue(object : Callback<ResponseDto> {
override fun onResponse(
call: Call<ResponseDto>,
response: Response<ResponseDto>,
) {
if (response.isSuccessful) {
successResponse(response)
} else {
failResponse(response)
}
}

override fun onFailure(call: Call<ResponseDto>, t: Throwable) {
loginStatus.value = AuthState(
fun login(request: RequestLoginDto) {
viewModelScope.launch {
runCatching {
authService.login(request)
}.onSuccess { response ->
handleSuccess(response)
}.onFailure {
loginStatus.value = AuthState (
isSuccess = false,
message = "서버 에러"
)
}
})
}
}

private fun handleSuccess(response: Response<ResponseDto>) {
if (response.isSuccessful) {
successResponse(response)
} else {
failResponse(response)
}
}
private fun successResponse(response: Response<ResponseDto>) {
val memberId = response.headers()["location"] ?: "unknown"
userRepository.setUserLoggedIn(true)
Expand Down
57 changes: 36 additions & 21 deletions app/src/main/java/com/sopt/now/ui/mypage/MypageViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,55 @@ package com.sopt.now.ui.mypage

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sopt.now.data.UserRepository
import com.sopt.now.network.response.ResponseInfoDto
import com.sopt.now.network.response.UserInfo
import com.sopt.now.network.service.ServicePool
import com.sopt.now.ui.AuthState
import retrofit2.Call
import retrofit2.Callback
import kotlinx.coroutines.launch
import retrofit2.Response

class MypageViewModel(private val userRepository: UserRepository): ViewModel() {
class MypageViewModel(private val userRepository: UserRepository) : ViewModel() {
private val authService by lazy { ServicePool.authService }
val userInfoStatus = MutableLiveData<AuthState>()
private val userInfoStatus = MutableLiveData<AuthState>()
val userLiveData = MutableLiveData<UserInfo?>()

fun info() {
authService.info().enqueue(object : Callback<ResponseInfoDto> {
override fun onResponse(call: Call<ResponseInfoDto>, response: Response<ResponseInfoDto>) {
if (response.isSuccessful) {
val userInfo = response.body()?.data
if (userInfo != null) {
userLiveData.postValue(userInfo)
userInfoStatus.value = AuthState(isSuccess = true, message = "회원 정보 조회 성공")
} else {
userInfoStatus.value = AuthState(isSuccess = false, message = "회원 정보 없음")
}
} else {
userInfoStatus.value = AuthState(isSuccess = false, message = "회원 정보 조회 실패")
}
viewModelScope.launch {
runCatching {
authService.info()
}.onSuccess { response ->
handleSuccess(response)
}.onFailure {
userInfoStatus.value = AuthState(
isSuccess = false,
message = "서버 에러"
)
}
}
}

override fun onFailure(call: Call<ResponseInfoDto>, t: Throwable) {
userInfoStatus.value = AuthState(isSuccess = false, message = "서버 에러")
}
})
private fun handleSuccess(response: Response<ResponseInfoDto>) {
if (response.isSuccessful) {
successResponse(response)
} else {
failResponse()
}
}

private fun successResponse(response: Response<ResponseInfoDto>) {
val userInfo = response.body()?.data
if (userInfo != null) {
userLiveData.postValue(userInfo)
userInfoStatus.value = AuthState(isSuccess = true, message = "회원 정보 조회 성공")
} else {
userInfoStatus.value = AuthState(isSuccess = false, message = "회원 정보 없음")
}
}

private fun failResponse() {
userInfoStatus.value = AuthState(isSuccess = false, message = "회원 정보 조회 실패")
}

fun logout() {
Expand Down
12 changes: 11 additions & 1 deletion app/src/main/java/com/sopt/now/ui/search/SearchFragment.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.sopt.now.ui.search

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import com.sopt.now.databinding.FragmentSearchBinding
Expand All @@ -14,6 +16,14 @@ class SearchFragment : Fragment() {
private val searchViewModel: SearchViewModel by viewModels()
private lateinit var repoAdapter: RepoAdapter

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentSearchBinding.inflate(inflater, container, false)
return _binding?.root
}
Comment on lines +24 to +25
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return _binding?.root
}
return binding.root
}


override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupAdapters()
Expand All @@ -34,7 +44,7 @@ class SearchFragment : Fragment() {

override fun onDestroyView() {
super.onDestroyView()
_binding?.rvRepo?.adapter = null
_binding = null
Comment on lines 46 to 48
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 _binding?.rvRepo?.adapter = null는 의미 없습니당

binding.rvRepo.adapter = null
}
}
Loading