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

[스레드뷰] 서버 연결 및 부가 기능 추가 #515

Merged
merged 32 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
bcddada
refactor: StudyId Long으로 타입 수정
s9hn Sep 21, 2023
dcda56c
feat: 스레드뷰 스토리완성, 플로우적용
s9hn Sep 21, 2023
f095e27
refactor: 홈뷰 서버통신에러 핫픽스
s9hn Sep 21, 2023
44beda0
feat: 스토리구현~
s9hn Sep 21, 2023
850eeb2
feat: 피드구현
s9hn Sep 23, 2023
c698862
refactor: StudyId Long으로 타입 수정
s9hn Sep 21, 2023
265c5d8
feat: 스레드뷰 스토리완성, 플로우적용
s9hn Sep 21, 2023
1547666
refactor: 홈뷰 서버통신에러 핫픽스
s9hn Sep 21, 2023
7c11d54
feat: 스토리구현~
s9hn Sep 21, 2023
16c184e
feat: 피드구현
s9hn Sep 23, 2023
cec1264
feat: 관련 서버통신 함수 추가
s9hn Oct 6, 2023
6dce285
refactor: 코드수정
s9hn Oct 7, 2023
c9a6e25
refactor: 코드수정
s9hn Oct 10, 2023
811e43f
feat: 갤러리 권한 추가
s9hn Oct 12, 2023
e413fcc
refactor: 데이터레이어 수정
s9hn Oct 15, 2023
de0d0c3
refactor: uiState 적용
s9hn Oct 15, 2023
a478a7f
refactor: dataBinding 제거
s9hn Oct 15, 2023
b403185
feat: spinner 대충구현
s9hn Oct 16, 2023
71a73d6
chore: merge
s9hn Oct 16, 2023
f123d47
refactor: 스레드뷰 통신 리팩터링
s9hn Oct 16, 2023
6ce5160
feat: 스터디 정보 다이얼로그 생성 및 서버 연결
RightHennessy Oct 17, 2023
5295358
chore: merge commit
RightHennessy Oct 17, 2023
d43f170
feat: 드롭다운 요소 클릭 시 드롭다운 닫히게
RightHennessy Oct 17, 2023
8c2b777
feat: 채팅 및 커서 스타일 추가, 전송 시 focus 뺏음
RightHennessy Oct 17, 2023
9111ebf
fix: studyId 초기화 이후 정보 불러오도록 변경 / uistate update 로직 변경
RightHennessy Oct 17, 2023
e4e28fb
feat: 채팅 입력 시 아래로 스크롤 기능 추가
RightHennessy Oct 17, 2023
633d5ed
refactor: 스레드 아이템의 프로필 부분 레이아웃 수정
RightHennessy Oct 17, 2023
aaab9ab
feat: 본인 클릭여부 판단하여 프로필 액티비티로 전환하는 기능 추가
RightHennessy Sep 23, 2023
10eb173
feat: 프로필 이미지 클릭시 ProfileActivity로 이동
RightHennessy Oct 17, 2023
052f906
chore: merge commit
RightHennessy Oct 17, 2023
bcb4b19
feat: 채팅의 내용이 비어있는 경우 toast
RightHennessy Oct 17, 2023
b6c2da1
Merge branch 'develop' of https://github.com/woowacourse-teams/2023-y…
RightHennessy Oct 17, 2023
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
4 changes: 3 additions & 1 deletion android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />

<application
android:name=".application.Team201App"
Expand All @@ -23,7 +24,8 @@
android:windowSoftInputMode="adjustPan" />
<activity
android:name=".presentation.studyThread.ThreadActivity"
android:exported="false" />
android:exported="true"
android:screenOrientation="portrait" />
<activity
android:name=".presentation.report.ReportActivity"
android:exported="false"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.created.domain.repository.SettingRepository
import com.created.domain.repository.SplashRepository
import com.created.domain.repository.StudyDetailRepository
import com.created.domain.repository.StudyListRepository
import com.created.domain.repository.ThreadRepository
import com.created.domain.repository.UpdateStudyRepository
import com.created.team201.data.repository.DefaultAuthRepository
import com.created.team201.data.repository.DefaultCreateStudyRepository
Expand All @@ -25,6 +26,7 @@ import com.created.team201.data.repository.DefaultSettingRepository
import com.created.team201.data.repository.DefaultSplashRepository
import com.created.team201.data.repository.DefaultStudyDetailRepository
import com.created.team201.data.repository.DefaultStudyListRepository
import com.created.team201.data.repository.DefaultThreadRepository
import com.created.team201.data.repository.DefaultUpdateStudyRepository
import dagger.Binds
import dagger.Module
Expand Down Expand Up @@ -87,4 +89,8 @@ interface RepositoryModule {
@Binds
@Singleton
fun bindDefaultUpdateStudyRepository(defaultUpdateStudyRepository: DefaultUpdateStudyRepository): UpdateStudyRepository

@Binds
@Singleton
fun bindDefaultThreadRepository(defaultThreadRepository: DefaultThreadRepository): ThreadRepository
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.created.team201.data.remote.api.ProfileService
import com.created.team201.data.remote.api.ReportService
import com.created.team201.data.remote.api.SettingService
import com.created.team201.data.remote.api.StudyDetailService
import com.created.team201.data.remote.api.ThreadService
import com.created.team201.data.remote.api.UpdateStudyService
import dagger.Module
import dagger.Provides
Expand Down Expand Up @@ -84,4 +85,9 @@ object ServiceModule {
@Provides
fun provideSettingService(@AuthRetrofit retrofit: Retrofit): SettingService =
retrofit.create(SettingService::class.java)

@Singleton
@Provides
fun provideThreadService(@AuthRetrofit retrofit: Retrofit): ThreadService =
retrofit.create(ThreadService::class.java)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ fun HomeStudyResponseDto.toUserStudy(): UserStudy =
isMaster = isMaster,
studyId = studyId,
studyName = studyName,
mustDo = mustDo,
mustDo = mustDo ?: "",
leftDays = leftDays,
grassSeedsCount = grassSeedsCount,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.created.team201.data.mapper

import com.created.domain.model.Feeds
import com.created.domain.model.MustDo
import com.created.domain.model.MustDoCertification
import com.created.team201.data.remote.response.FeedsResponseDto
import com.created.team201.data.remote.response.MustDoCertificationResponseDto

fun MustDoCertificationResponseDto.toDomain(): MustDoCertification = MustDoCertification(
studyName = studyName,
upcomingRound = upcomingRound.toUpcomingRound(),
me = me.toMustDo(),
others = others.map { it.toMustDo() }

)

fun MustDoCertificationResponseDto.UpcomingRound.toUpcomingRound(): MustDoCertification.UpcomingRound =
MustDoCertification.UpcomingRound(
id = id, weekNumber = weekNumber

)

fun MustDoCertificationResponseDto.User.toMustDo(): MustDo = MustDo(
id = id,
isCertified = isCertified,
nickname = nickname,
profileImageUrl = profileImageUrl
)

fun FeedsResponseDto.toFeeds(): Feeds = Feeds(
author = this.author.toAuthor(),
content = content,
createdAt = createdAt,
id = id.toLong(),
imageUrl = imageUrl ?: ""
// 서버 널 확인
)

fun FeedsResponseDto.Author.toAuthor(): Feeds.Author = Feeds.Author(
id = id.toLong(), nickname = nickname, profileImageUrl = profileImageUrl
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.created.team201.data.remote.api

import com.created.team201.data.remote.request.FeedRequestDto
import com.created.team201.data.remote.response.FeedsResponseDto
import com.created.team201.data.remote.response.MustDoCertificationResponseDto
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path

interface ThreadService {

@GET("v1/studies/{id}/certifications")
suspend fun getMustDoCertification(
@Path("id") studyId: Long,
): MustDoCertificationResponseDto

@POST("v1/studies/{id}/feeds")
suspend fun postFeeds(
@Path("id") studyId: Long,
@Body content: FeedRequestDto
): Response<Unit>

@GET("v1/studies/{id}/feeds")
suspend fun getFeeds(
@Path("id") studyId: Long,
): List<FeedsResponseDto>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.created.team201.data.remote.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class FeedRequestDto(
@SerialName("content")
val content: String,
@SerialName("imageUrl")
val imageUrl: String?
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.created.team201.data.remote.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class FeedsResponseDto(
@SerialName("id")
val id: Int,
@SerialName("author")
val author: Author,
@SerialName("imageUrl")
val imageUrl: String?,
@SerialName("content")
val content: String,
@SerialName("createdAt")
val createdAt: String
) {
@Serializable
data class Author(
@SerialName("id")
val id: Int,
@SerialName("nickname")
val nickname: String,
@SerialName("profileImageUrl")
val profileImageUrl: String
)
}

Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import kotlinx.serialization.Serializable
@Serializable
data class HomeStudyResponseDto(
@SerialName("id")
val studyId: Int,
val studyId: Long,
@SerialName("name")
val studyName: String,
@SerialName("todoContent")
val mustDo: String,
val mustDo: String?,
@SerialName("leftDays")
val leftDays: Int,
@SerialName("grassCount")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.created.team201.data.remote.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class MustDoCertificationResponseDto(
@SerialName("studyName")
val studyName: String,
@SerialName("upcomingRound")
val upcomingRound: UpcomingRound,
@SerialName("me")
val me: User,
@SerialName("others")
val others: List<User>
) {
@Serializable
data class User(
@SerialName("id")
val id: Int,
@SerialName("nickname")
val nickname: String,
@SerialName("profileImageUrl")
val profileImageUrl: String,
@SerialName("isCertified")
val isCertified: Boolean
)

@Serializable
data class UpcomingRound(
@SerialName("id")
val id: Int,
@SerialName("weekNumber")
val weekNumber: Int,
)
}

Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ class DefaultSplashRepository @Inject constructor() : SplashRepository {
.get()
documentTask.addOnSuccessListener { documentSnapshot ->
CoroutineScope(Dispatchers.IO).launch {
onSuccess.invoke(documentSnapshot.toObject<AppUpdateInformation>()?.run {
copy(message = message.replace("\\n", "\n"))
} ?: DEFAULT_APP_INFORMATION)
onSuccess.invoke(
documentSnapshot.toObject<AppUpdateInformation>()?.run {
copy(message = message.replace("\\n", "\n"))
} ?: DEFAULT_APP_INFORMATION,
)
}
}
documentTask.addOnFailureListener { exception ->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.created.team201.data.repository

import com.created.domain.model.Feeds
import com.created.domain.model.MustDoCertification
import com.created.domain.repository.ThreadRepository
import com.created.team201.data.mapper.toDomain
import com.created.team201.data.mapper.toFeeds
import com.created.team201.data.remote.api.ThreadService
import com.created.team201.data.remote.request.FeedRequestDto
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import javax.inject.Inject

class DefaultThreadRepository @Inject constructor(
private val threadService: ThreadService
) : ThreadRepository {

override suspend fun getMustDoCertification(studyId: Long): MustDoCertification {
val mustDoCertification = threadService.getMustDoCertification(studyId = studyId)

return mustDoCertification.toDomain()
}

override fun getFeeds(studyId: Long): Flow<List<Feeds>> = flow {
while (true) {
val feeds = threadService.getFeeds(studyId).map { it.toFeeds() }

emit(feeds)
delay(1000)
}
}.flowOn(Dispatchers.IO)

override suspend fun updateFeeds(studyId: Long, content: String, image: String?) {
threadService.postFeeds(
studyId,
FeedRequestDto(
content = content, imageUrl = image
)
)
}

override fun postMustDoCertification(studyId: Long) {
TODO("Not yet implemented")
}

override fun getStudyInfo(studyId: Long) {
TODO("Not yet implemented")
}

override fun getMustDo(studyId: Long) {
TODO("Not yet implemented")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import com.created.team201.databinding.FragmentHomeBinding
import com.created.team201.presentation.common.BindingFragment
import com.created.team201.presentation.home.HomeViewModel.UserStudyState.Joined
import com.created.team201.presentation.home.adapter.HomeAdapter
import kotlinx.coroutines.flow.Flow
import com.created.team201.presentation.studyThread.ThreadActivity
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
Expand All @@ -30,12 +29,17 @@ class HomeFragment : BindingFragment<FragmentHomeBinding>(R.layout.fragment_home
collectUiState()
}

override fun onResume() {
super.onResume()
homeViewModel.updateUserStudy()
}

private fun setupViewModel() {
binding.lifecycleOwner = viewLifecycleOwner
binding.vm = homeViewModel
}

private fun navigateToThreadActivity(studyId: Int) {
private fun navigateToThreadActivity(studyId: Long) {
startActivity(ThreadActivity.getIntent(requireContext(), studyId))
}

Expand All @@ -51,5 +55,6 @@ class HomeFragment : BindingFragment<FragmentHomeBinding>(R.layout.fragment_home

private fun setupAdapter() {
binding.rvHome.adapter = homeAdapter
binding.rvHome.setHasFixedSize(true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,7 @@ class HomeViewModel @Inject constructor(
private val _userStudyUiState: MutableStateFlow<UserStudyState> = MutableStateFlow(Idle)
val userStudyUiState: StateFlow<UserStudyState> get() = _userStudyUiState

init {
updateUserStudy()
}

private fun updateUserStudy() {
fun updateUserStudy() {
viewModelScope.launch {
runCatching {
homeRepository.getUserStudies()
Expand All @@ -40,10 +36,7 @@ class HomeViewModel @Inject constructor(
}

sealed interface UserStudyState {
data class Joined(
val userStudies: List<UserStudy>
) : UserStudyState

data class Joined(val userStudies: List<UserStudy>) : UserStudyState
object Nothing : UserStudyState
object Idle : UserStudyState
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.created.domain.model.UserStudy


class HomeAdapter(
private val onClick: (studyId: Int) -> Unit
private val onClick: (studyId: Long) -> Unit
) : ListAdapter<UserStudy, HomeViewHolder>(diffCallBack) {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeViewHolder {
Expand Down
Loading