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
@@ -0,0 +1,89 @@
package com.into.websoso.ui.createFeed.component

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.into.websoso.core.common.ui.component.AdaptationImage
import com.into.websoso.core.common.util.clickableWithoutRipple
import com.into.websoso.core.designsystem.component.NetworkImage
import com.into.websoso.core.designsystem.theme.WebsosoTheme
import com.into.websoso.core.resource.R.drawable.ic_feed_remove_image

@Composable
fun CreateFeedImageContainer(
imageUrls: List<String>,
onRemoveClick: (index: Int) -> Unit,
) {
LazyRow(
modifier = Modifier
.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(10.dp),
contentPadding = PaddingValues(horizontal = 20.dp),
) {
items(imageUrls.size) { index ->
CreateFeedImageBox(
imageUrl = imageUrls[index],
onRemoveClick = {
onRemoveClick(index)
},
)
}
}
}

@Composable
private fun CreateFeedImageBox(
imageUrl: String,
onRemoveClick: () -> Unit,
) {
Box(
modifier = Modifier
.size(100.dp)
.aspectRatio(1f)
.clip(RoundedCornerShape(8.dp)),
) {
Image(
painter = painterResource(ic_feed_remove_image),
contentDescription = null,
modifier = Modifier
.size(38.dp)
.padding(10.dp)
.align(Alignment.TopEnd)
.clickableWithoutRipple { onRemoveClick() },
)
Comment on lines +61 to +68
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

삭제 버튼의 접근성 개선 필요.

삭제 버튼의 contentDescription이 null로 설정되어 있어 접근성 도구(예: 화면 리더)를 사용하는 사용자가 이 버튼의 기능을 인식하기 어렵습니다. 삭제 버튼임을 나타내는 적절한 설명을 추가해야 합니다.

Image(
    painter = painterResource(ic_feed_remove_image),
-   contentDescription = null,
+   contentDescription = "이미지 삭제 버튼",
    modifier = Modifier
        .size(38.dp)
        .padding(10.dp)
        .align(Alignment.TopEnd)
        .clickableWithoutRipple { onRemoveClick() },
)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
painter = painterResource(ic_feed_remove_image),
contentDescription = null,
modifier = Modifier
.size(38.dp)
.padding(10.dp)
.align(Alignment.TopEnd)
.clickableWithoutRipple { onRemoveClick() },
)
Image(
painter = painterResource(ic_feed_remove_image),
contentDescription = "이미지 삭제 버튼",
modifier = Modifier
.size(38.dp)
.padding(10.dp)
.align(Alignment.TopEnd)
.clickableWithoutRipple { onRemoveClick() },
)
🤖 Prompt for AI Agents
In
app/src/main/java/com/into/websoso/ui/createFeed/component/CreateFeedImageContainer.kt
around lines 64 to 71, the delete button's contentDescription is set to null,
which hinders accessibility tools from conveying its purpose. Replace the null
contentDescription with a meaningful string that clearly describes the button's
function, such as "Delete image" or an equivalent localized description, to
improve accessibility for screen reader users.

NetworkImage(
imageUrl = imageUrl,
contentScale = ContentScale.Crop,
)
}
}

@Preview
@Composable
private fun CreateFeedImageContainerPreview() {
WebsosoTheme {
CreateFeedImageContainer(
imageUrls = listOf(
"https://github.com/user-attachments/assets/e89a02bb-549f-414d-809f-0ab1e8f72c5f",
"https://github.com/user-attachments/assets/e89a02bb-549f-414d-809f-0ab1e8f72c5f",
"https://github.com/user-attachments/assets/e89a02bb-549f-414d-809f-0ab1e8f72c5f",
),
onRemoveClick = {},
)
}
}
13 changes: 11 additions & 2 deletions app/src/main/res/layout/activity_create_feed.xml
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@
android:id="@+id/sc_create_feed_lock_toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={!viewModel.isPublic}"
android:background="@null"
android:checked="@={!viewModel.isPublic}"
android:thumb="@drawable/bg_create_feed_toggle_thumb"
Comment on lines +89 to 90
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

양방향 바인딩 표현식 오류
android:checked="@={!viewModel.isPublic}"은 DataBinding의 양방향 바인딩(@={})이 직접 변수 참조에만 지원됩니다. !viewModel.isPublic 같은 표현식에는 적용되지 않아 상태 변화가 뷰모델에 반영되지 않을 수 있습니다.
해결책:

- android:checked="@={!viewModel.isPublic}"
+ android:checked="@{!viewModel.isPublic}"

그리고 상태 변경 시 뷰모델 업데이트는 setOnCheckedChangeListener나 커스텀 BindingAdapter로 처리하세요.

🤖 Prompt for AI Agents
In app/src/main/res/layout/activity_create_feed.xml at lines 89-90, the two-way
data binding expression uses a negation operator inside the binding which is not
supported. To fix this, remove the negation from the binding expression and bind
directly to the variable without operators. Then handle the inversion logic and
update the ViewModel state by implementing a setOnCheckedChangeListener in the
code or create a custom BindingAdapter to manage the toggle state and
synchronize changes properly.

app:track="@drawable/bg_create_feed_toggle" />
</LinearLayout>
Expand Down Expand Up @@ -218,6 +218,15 @@
app:track="@drawable/bg_create_feed_toggle" />
</LinearLayout>

<androidx.compose.ui.platform.ComposeView
android:id="@+id/cv_create_feed_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll_create_feed_spoiler" />

<TextView
android:id="@+id/tv_create_feed_connect_novel"
android:layout_width="wrap_content"
Expand All @@ -228,7 +237,7 @@
android:textAppearance="@style/title2"
android:textColor="@color/black"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll_create_feed_spoiler" />
app:layout_constraintTop_toBottomOf="@id/cv_create_feed_image" />

<com.into.websoso.core.common.ui.custom.WebsosoSearchEditText
android:id="@+id/wset_create_feed_search_novel"
Expand Down
21 changes: 21 additions & 0 deletions core/resource/src/main/res/drawable/ic_feed_remove_image.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="19dp"
android:height="18dp"
android:viewportWidth="19"
android:viewportHeight="18">
<path
android:pathData="M9.469,9m-9,0a9,9 0,1 1,18 0a9,9 0,1 1,-18 0"
android:fillColor="#EEEEF2"/>
<path
android:strokeWidth="1"
android:pathData="M12.469,6L6.469,12"
android:fillColor="#00000000"
android:strokeColor="#949399"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M6.469,6L12.469,12"
android:fillColor="#00000000"
android:strokeColor="#949399"
android:strokeLineCap="round"/>
</vector>