Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ fun FeedCommentScreen(
isSaveVisible = true,
isSaved = feedDetail.isSaved,
isPinVisible = false,
isLockIcon = feedDetail.isPublic == false,
onLikeClick = { feedDetailViewModel.changeFeedLike() },
onCommentClick = { /* 스크롤 이동 or 포커스 처리 */ },
onBookmarkClick = { feedDetailViewModel.changeFeedSave() },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package com.texthip.thip.ui.feed.screen

import android.net.Uri
import android.os.Build
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.runtime.DisposableEffect
import androidx.compose.ui.platform.LocalContext
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
Expand Down Expand Up @@ -113,14 +117,27 @@ fun FeedWriteContent(
onSearchBooks: (String) -> Unit = {}
) {
val scrollState = rememberScrollState()
val imagePickerLauncher = rememberLauncherForActivityResult(
val focusManager = LocalFocusManager.current

val remainingSlots = 3 - uiState.currentImageCount

// Android 13+ Photo Picker (개수 제한 지원) - 최소 2로 설정하여 API 제약 회피
val photoPickerLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.PickMultipleVisualMedia(maxItems = maxOf(2, remainingSlots))
) { uris ->
if (uris.isNotEmpty() && remainingSlots > 0) {
onAddImages(uris.take(remainingSlots))
}
}

// Fallback for older Android versions
val legacyImagePickerLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.GetMultipleContents()
) { uris: List<Uri> ->
) { uris ->
if (uris.isNotEmpty()) {
onAddImages(uris)
}
}
Comment on lines +134 to 140

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

레거시 선택 경로에서 개수 제한 미적용

현재 GetMultipleContents 결과를 그대로 onAddImages(uris)로 넘겨 제한(최대 3장, 남은 슬롯 수)이 깨질 수 있습니다. ViewModel에서 방어 코드를 갖고 있더라도 UI 레이어에서 한 번 더 제한을 적용하는 것이 안전합니다.

-    ) { uris ->
-        if (uris.isNotEmpty()) {
-            onAddImages(uris)
-        }
-    }
+    ) { uris ->
+        if (uris.isNotEmpty() && remainingSlots > 0) {
+            onAddImages(uris.take(remainingSlots))
+        }
+    }
🤖 Prompt for AI Agents
In app/src/main/java/com/texthip/thip/ui/feed/screen/FeedWriteScreen.kt around
lines 134-140, the legacy GetMultipleContents launcher forwards all returned
URIs to onAddImages, bypassing the UI-level max-image and remaining-slot limits;
restrict the forwarded list by computing the allowed count (e.g., allowed =
min(uris.size, remainingSlotsOrMaxImages)) and call onAddImages with only
uris.take(allowed), optionally notify the user if some selections were dropped.

val focusManager = LocalFocusManager.current

Box {
Column(
Expand Down Expand Up @@ -197,7 +214,13 @@ fun FeedWriteContent(
)
.let {
if (uiState.canAddMoreImages) it.clickable {
imagePickerLauncher.launch("image/*")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && remainingSlots > 1) {
photoPickerLauncher.launch(
PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)
)
} else {
legacyImagePickerLauncher.launch("image/*")
}
} else it // 클릭 비활성화
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ data class FeedUiState(
val isLastPageMyFeeds: Boolean = false,
val error: String? = null
) {
val canLoadMoreAllFeeds: Boolean get() = !isLoading && !isLoadingMore && !isRefreshing && !isLastPageAllFeeds
val canLoadMoreMyFeeds: Boolean get() = !isLoading && !isLoadingMore && !isRefreshing && !isLastPageMyFeeds
val canLoadMoreAllFeeds: Boolean get() = !isLoading && !isLoadingMore && !isRefreshing && !isPullToRefreshing && !isLastPageAllFeeds
val canLoadMoreMyFeeds: Boolean get() = !isLoading && !isLoadingMore && !isRefreshing && !isPullToRefreshing && !isLastPageMyFeeds
val currentTabFeeds: List<Any>
get() = when (selectedTabIndex) {
0 -> allFeeds
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ import java.time.LocalDate

@Composable
fun GroupDatePicker(
modifier: Modifier = Modifier,
selectedDate: LocalDate,
minDate: LocalDate,
maxDate: LocalDate,
onDateSelected: (LocalDate) -> Unit,
modifier: Modifier = Modifier
onDateSelected: (LocalDate) -> Unit
) {
// 선택된 날짜에서 년/월/일 추출
val year = selectedDate.year
Expand All @@ -55,7 +55,7 @@ fun GroupDatePicker(
verticalAlignment = Alignment.CenterVertically
) {
GroupWheelPicker(
modifier = Modifier.width(48.dp),
modifier = modifier.width(48.dp),
items = years,
selectedItem = year,
onItemSelected = { newYear ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ fun GroupRoomDurationPicker(
startDate = newDate
},
modifier = Modifier
.weight(1f)
.pointerInput(Unit) {
detectTapGestures(
onPress = { isPickerTouched = true }
Expand All @@ -139,7 +138,6 @@ fun GroupRoomDurationPicker(
endDate = newDate
},
modifier = Modifier
.weight(1f)
.pointerInput(Unit) {
detectTapGestures(
onPress = { isPickerTouched = true }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import com.texthip.thip.ui.group.makeroom.viewmodel.GroupMakeRoomViewModel
import com.texthip.thip.ui.theme.ThipTheme
import com.texthip.thip.ui.theme.ThipTheme.colors
import com.texthip.thip.ui.theme.ThipTheme.typography
import com.texthip.thip.utils.rooms.advancedImePadding
import com.texthip.thip.utils.rooms.toDisplayStrings


Expand Down Expand Up @@ -106,7 +107,7 @@ fun GroupMakeRoomContent(
) {
val scrollState = rememberScrollState()

Box {
Box(modifier = Modifier.advancedImePadding()) {
Column(
modifier = modifier
.fillMaxSize()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ fun GroupRoomRecruitContent(
//참여 인원
Column(
verticalArrangement = Arrangement.Center,
modifier = Modifier.padding(start = 90.dp)
modifier = Modifier.padding(start = 50.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import com.texthip.thip.ui.group.room.viewmodel.GroupRoomUnlockViewModel
import com.texthip.thip.ui.theme.ThipTheme
import com.texthip.thip.ui.theme.ThipTheme.colors
import com.texthip.thip.ui.theme.ThipTheme.typography
import com.texthip.thip.utils.rooms.advancedImePadding
import kotlinx.coroutines.delay

@Composable
Expand Down Expand Up @@ -96,7 +97,7 @@ fun GroupRoomUnlockScreen(
}
}

Box(modifier = Modifier.fillMaxSize()) {
Box(modifier = Modifier.fillMaxSize().advancedImePadding()) {
Column(
modifier = Modifier.fillMaxSize()
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ fun SavedFeedCard(

Column(
modifier = Modifier
.padding(bottom = 16.dp)
.clickable { onContentClick() }, // 전체 영역 클릭 유지
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
Expand All @@ -89,8 +90,7 @@ fun SavedFeedCard(
style = typography.feedcopy_r400_s14_h20,
color = colors.White,
maxLines = maxLines,
modifier = Modifier
.fillMaxWidth(),
modifier = Modifier.fillMaxWidth(),
onTextLayout = { textLayoutResult ->
isTextTruncated = textLayoutResult.hasVisualOverflow
}
Expand Down