Skip to content

Commit

Permalink
Add Image Preview Screen.
Browse files Browse the repository at this point in the history
  • Loading branch information
bywindow committed Aug 20, 2024
1 parent 413e9bd commit 3bc31c5
Show file tree
Hide file tree
Showing 8 changed files with 484 additions and 81 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.goalpanzi.mission_mate.feature.board

import android.net.Uri
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavOptions
Expand All @@ -12,6 +13,7 @@ import com.goalpanzi.mission_mate.feature.board.screen.BoardFinishRoute
import com.goalpanzi.mission_mate.feature.board.screen.BoardMissionDetailRoute
import com.goalpanzi.mission_mate.feature.board.screen.BoardRoute
import com.goalpanzi.mission_mate.feature.board.screen.UserStoryScreen
import com.goalpanzi.mission_mate.feature.board.screen.VerificationPreviewRoute
import java.net.URLEncoder
import java.nio.charset.StandardCharsets

Expand All @@ -20,6 +22,7 @@ internal const val userCharacterTypeArg = "userCharacterType"
internal const val nicknameArg = "nickname"
internal const val dateArg = "date"
internal const val imageUrlArg = "imageUrl"
internal const val isUploadSuccessArg = "isUploadSuccess"

fun NavController.navigateToBoard(
missionId: Long,
Expand All @@ -37,13 +40,15 @@ fun NavGraphBuilder.boardNavGraph(
onNavigateDetail : (Long) -> Unit,
onNavigateFinish : (Long) -> Unit,
onNavigateStory: (UserStory) -> Unit,
onClickSetting: () -> Unit
onClickSetting: () -> Unit,
onNavigateToPreview: (Long, Uri) -> Unit
) {
composable(
"RouteModel.Board/{$missionIdArg}",
arguments = listOf(navArgument(missionIdArg) { type = NavType.LongType })
) { navBackStackEntry ->
val missionId = navBackStackEntry.arguments?.getLong(missionIdArg)
val isUploadSuccess = navBackStackEntry.savedStateHandle.get<Boolean>(isUploadSuccessArg)
BoardRoute(
onNavigateOnboarding = onNavigateOnboarding,
onNavigateDetail = {
Expand All @@ -53,7 +58,9 @@ fun NavGraphBuilder.boardNavGraph(
},
onNavigateFinish = onNavigateFinish,
onClickSetting = onClickSetting,
onClickStory = onNavigateStory
onClickStory = onNavigateStory,
onPreviewImage = onNavigateToPreview,
isUploadSuccess = isUploadSuccess ?: false
)
}
}
Expand Down Expand Up @@ -148,3 +155,33 @@ fun NavGraphBuilder.userStoryNavGraph(
}
}
}

fun NavController.navigateToVerificationPreview(
missionId: Long,
imageUrl: Uri
) {
val encodedUrl = URLEncoder.encode(imageUrl.toString(), StandardCharsets.UTF_8.toString())
this.navigate("RouteModel.VerificationPreview" + "/${missionId}" +"/${encodedUrl}")
}

fun NavGraphBuilder.verificationPreviewNavGraph(
onClickClose: () -> Unit,
onUploadSuccess: (key: String) -> Unit
) {
composable(
route = "RouteModel.VerificationPreview/{$missionIdArg}/{$imageUrlArg}",
arguments = listOf(
navArgument(missionIdArg) {
type = NavType.LongType
},
navArgument(imageUrlArg) {
type = NavType.StringType
}
)
) {
VerificationPreviewRoute(
onClickClose = onClickClose,
onUploadSuccess = { onUploadSuccess(isUploadSuccessArg) }
)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.goalpanzi.mission_mate.feature.board.screen

import android.content.Intent
import android.net.Uri
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
Expand Down Expand Up @@ -45,7 +47,6 @@ import com.goalpanzi.mission_mate.feature.board.model.toUserStory
import com.goalpanzi.mission_mate.feature.board.model.uimodel.MissionBoardUiModel
import com.goalpanzi.mission_mate.feature.board.model.uimodel.MissionUiModel
import com.goalpanzi.mission_mate.feature.board.model.uimodel.MissionVerificationUiModel
import com.goalpanzi.mission_mate.feature.board.util.ImageCompressor
import com.goalpanzi.mission_mate.feature.onboarding.component.StableImage
import com.luckyoct.core.model.response.BoardReward
import kotlinx.coroutines.delay
Expand All @@ -58,6 +59,8 @@ fun BoardRoute(
onNavigateFinish : (Long) -> Unit,
onClickSetting: () -> Unit,
onClickStory: (UserStory) -> Unit,
onPreviewImage: (Long, Uri) -> Unit,
isUploadSuccess: Boolean,
modifier: Modifier = Modifier,
viewModel: BoardViewModel = hiltViewModel()
) {
Expand All @@ -79,9 +82,11 @@ fun BoardRoute(
contract = ActivityResultContracts.PickVisualMedia(),
onResult = { imageUri ->
imageUri?.let { original ->
ImageCompressor.getCompressedImage(context, original).let { compressed ->
viewModel.verify(compressed)
}
context.contentResolver.takePersistableUriPermission(
original,
Intent.FLAG_GRANT_READ_URI_PERMISSION
)
onPreviewImage(viewModel.missionId, original)
}
}
)
Expand Down Expand Up @@ -116,6 +121,12 @@ fun BoardRoute(
}
}

LaunchedEffect(key1 = isUploadSuccess) {
if (isUploadSuccess) {
viewModel.onVerifySuccess()
}
}

if (isShownDeleteMissionDialog) {
DeleteMissionDialog(
onDismissRequest = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class BoardViewModel @Inject constructor(

val missionId: Long = savedStateHandle.get<Long>("missionId")!!

val viewedToolTip : StateFlow<Boolean> = getViewedTooltipUseCase().stateIn(
val viewedToolTip: StateFlow<Boolean> = getViewedTooltipUseCase().stateIn(
viewModelScope,
started = SharingStarted.WhileSubscribed(500),
initialValue = true
Expand All @@ -79,12 +79,12 @@ class BoardViewModel @Inject constructor(
val missionVerificationUiModel: StateFlow<MissionVerificationUiModel> =
_missionVerificationUiModel.asStateFlow()

val isHost : StateFlow<Boolean> =
val isHost: StateFlow<Boolean> =
combine(
getCachedMemberIdUseCase(),
missionUiModel.filter { it is MissionUiModel.Success }
){ memberId, mission ->
if(mission !is MissionUiModel.Success) return@combine false
) { memberId, mission ->
if (mission !is MissionUiModel.Success) return@combine false
memberId == mission.missionDetail.hostMemberId
}.stateIn(
viewModelScope,
Expand All @@ -108,7 +108,7 @@ class BoardViewModel @Inject constructor(
val boardRewardEvent: SharedFlow<BoardReward?> = _boardRewardEvent.asSharedFlow()

private val _boardPieces = MutableStateFlow<List<BoardPiece>>(emptyList())
val boardPieces : StateFlow<List<BoardPiece>> = _boardPieces.asStateFlow()
val boardPieces: StateFlow<List<BoardPiece>> = _boardPieces.asStateFlow()

fun getMissionBoards() {
viewModelScope.launch {
Expand Down Expand Up @@ -186,88 +186,78 @@ class BoardViewModel @Inject constructor(
}
}

fun setViewedTooltip(){
fun setViewedTooltip() {
viewModelScope.launch {
setViewedTooltipUseCase().collect()
}
}

fun verify(image: File) {
fun onVerifySuccess() {
viewModelScope.launch {
verifyMissionUseCase(missionId, image).collect {
when (it) {
is NetworkResult.Success -> {
// 내 캐릭터
val myBoardPiece = boardPieces.value.find { it.isMe }
val missionBoard = missionBoardUiModel.value
if(myBoardPiece != null && missionBoard is MissionBoardUiModel.Success){
val missionBoardList = missionBoard.missionBoards.missionBoardList
// 내 캐릭터보다 한칸 앞션 캐릭터
val nextBoardPiece = missionBoardList.filter { block ->
block.missionBoardMembers.isNotEmpty()
}.find {
it.number == myBoardPiece.index + 1
}
// 내 캐릭터
val myBoardPiece = boardPieces.value.find { it.isMe }
val missionBoard = missionBoardUiModel.value
if (myBoardPiece != null && missionBoard is MissionBoardUiModel.Success) {
val missionBoardList = missionBoard.missionBoards.missionBoardList
// 내 캐릭터보다 한칸 앞션 캐릭터
val nextBoardPiece = missionBoardList.filter { block ->
block.missionBoardMembers.isNotEmpty()
}.find {
it.number == myBoardPiece.index + 1
}

// 내 캐릭터와 같이 있던 캐릭터
val prevBoardPiece = missionBoardList.filter { block ->
block.missionBoardMembers.size >= 2
}.find {
it.number == myBoardPiece.index
// 내 캐릭터와 같이 있던 캐릭터
val prevBoardPiece = missionBoardList.filter { block ->
block.missionBoardMembers.size >= 2
}.find {
it.number == myBoardPiece.index
}
_boardPieces.emit(
buildList {
addAll(
boardPieces.value.map {
if (it.isMe) it.copy(
boardPieceType = BoardPieceType.MOVED,
count = if (nextBoardPiece != null) nextBoardPiece.missionBoardMembers.size + 1 else 1
) else if (nextBoardPiece != null && it.index == nextBoardPiece.number) {
it.copy(boardPieceType = BoardPieceType.HIDDEN)
} else it
}
_boardPieces.emit(
buildList {
addAll(
boardPieces.value.map {
if(it.isMe) it.copy(
boardPieceType = BoardPieceType.MOVED,
count = if(nextBoardPiece != null) nextBoardPiece.missionBoardMembers.size + 1 else 1
)else if(nextBoardPiece != null && it.index == nextBoardPiece.number){
it.copy(boardPieceType = BoardPieceType.HIDDEN)
} else it
}
)
if(prevBoardPiece != null){
val target = prevBoardPiece.missionBoardMembers.first {
it.nickname != myBoardPiece.nickname
}
add(
BoardPiece(
count = prevBoardPiece.missionBoardMembers.size - 1,
nickname = target.nickname,
drawableRes = target.character.imageId,
index = prevBoardPiece.number,
isMe = false
)
)
}
}
)

_missionBoardUiModel.emit(
missionBoard.copy(
missionBoards = missionBoard.missionBoards.copy(
passedCountByMe = missionBoard.missionBoards.passedCountByMe + 1
)
)
if (prevBoardPiece != null) {
val target = prevBoardPiece.missionBoardMembers.first {
it.nickname != myBoardPiece.nickname
}
add(
BoardPiece(
count = prevBoardPiece.missionBoardMembers.size - 1,
nickname = target.nickname,
drawableRes = target.character.imageId,
index = prevBoardPiece.number,
isMe = false
)
)
delay(400)
_boardRewardEvent.emit(
missionBoardList.find {
myBoardPiece.index + 1 == it.number
}?.boardReward
)
}
getMissionBoards()
getMission()
getMissionVerification()
}
else -> Unit
}
)

_missionBoardUiModel.emit(
missionBoard.copy(
missionBoards = missionBoard.missionBoards.copy(
passedCountByMe = missionBoard.missionBoards.passedCountByMe + 1
)
)
)
delay(400)
_boardRewardEvent.emit(
missionBoardList.find {
myBoardPiece.index + 1 == it.number
}?.boardReward
)
}
getMissionBoards()
getMission()
getMissionVerification()
}
}



}
Loading

0 comments on commit 3bc31c5

Please sign in to comment.