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,103 @@
package com.metasearch.android.core.ui.component

import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import com.metasearch.android.core.designsystem.annotation.ComponentPreview
import com.metasearch.android.core.designsystem.theme.MetaSearchTheme
import com.metasearch.android.core.designsystem.theme.Neutral500
import com.metasearch.android.core.ui.R

@Composable
fun MetaSearchSearchBar(
modifier: Modifier = Modifier,
value: String,
onValueChange: (String) -> Unit,
onSearchClick: () -> Unit,
placeholder: String = "",
) {
Row(
modifier = modifier
.fillMaxWidth()
.padding(MetaSearchTheme.spacing.spacing4)
.border(
width = 1.dp,
color = Neutral500,
shape = RoundedCornerShape(
MetaSearchTheme.radius.full,
),
)
.padding(
horizontal = MetaSearchTheme.spacing.spacing4,
vertical = MetaSearchTheme.spacing.spacing3,
),
verticalAlignment = Alignment.CenterVertically,
) {
BasicTextField(
value = value,
onValueChange = onValueChange,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
keyboardActions = KeyboardActions(
onSearch = { onSearchClick() },
),
modifier = Modifier.weight(1f),
singleLine = true,
textStyle = MetaSearchTheme.typography.bodyLarge,
decorationBox = { innerTextField ->
if (value.isEmpty()) {
Text(
text = placeholder,
color = Neutral500,
style = MetaSearchTheme.typography.bodyLarge,
)
}
innerTextField()
},
)

Icon(
painter = painterResource(R.drawable.ic_search_line),
contentDescription = "Search Icon",
modifier = Modifier
.size(
MetaSearchTheme.spacing.spacing6,
)
.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() },
) {
onSearchClick()
},
tint = Neutral500,
)
Comment on lines +75 to +89
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Hardcoded content description should be a string resource.

The contentDescription = "Search Icon" on line 77 should be extracted to a string resource for proper internationalization support.

Suggested fix
         Icon(
             painter = painterResource(R.drawable.ic_search_line),
-            contentDescription = "Search Icon",
+            contentDescription = stringResource(R.string.search_icon_content_description),
             modifier = Modifier

Add the corresponding string resource in core/ui/src/main/res/values/strings.xml:

<string name="search_icon_content_description">Search</string>
🤖 Prompt for AI Agents
In
`@core/ui/src/main/java/com/metasearch/android/core/ui/component/MetaSearchSearchBar.kt`
around lines 75 - 89, The Icon in MetaSearchSearchBar.kt uses a hardcoded
contentDescription ("Search Icon"); extract this to a string resource and
reference it via stringResource in the composable. Add a string entry (e.g.
name="search_icon_content_description" value="Search") to your module's
strings.xml and replace the hardcoded contentDescription in the Icon call with
stringResource(R.string.search_icon_content_description) (keep the Icon,
onSearchClick, and Modifier usage unchanged).

}
}

@ComponentPreview
@Composable
private fun MetaSearchSearchBarPreview() {
MetaSearchTheme {
MetaSearchSearchBar(
value = "서울에서 밤에 찍은 고양이 사진",
onValueChange = {},
onSearchClick = {},
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class NLSearchPresenter @AssistedInject constructor(
is NLSearchUiEvent.OnInputChange -> inputString = event.inputString

is NLSearchUiEvent.OnNLSearchClick -> {
inputString = event.inputString

if (inputString.isBlank()) return
isLoading = true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,9 @@ private fun NLSearchUiContent(
NLSearchTextField(
modifier = modifier,
inputString = state.inputString,
onInputChange = {
state.eventSink(NLSearchUiEvent.OnInputChange(it))
},
onSearchClick = {
state.eventSink(NLSearchUiEvent.OnNLSearchClick(state.inputString))
onSearchClick = { lastInput ->
state.eventSink(NLSearchUiEvent.OnInputChange(lastInput))
state.eventSink(NLSearchUiEvent.OnNLSearchClick(lastInput))
},
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,86 +1,32 @@
package com.metasearch.android.feature.search.nls.component

import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.metasearch.android.core.designsystem.annotation.ComponentPreview
import com.metasearch.android.core.designsystem.theme.MetaSearchTheme
import com.metasearch.android.core.designsystem.theme.Neutral500
import com.metasearch.android.core.ui.component.MetaSearchSearchBar
import com.metasearch.android.feature.search.R

@Composable
fun NLSearchTextField(
modifier: Modifier = Modifier,
inputString: String,
onInputChange: (String) -> Unit,
onSearchClick: () -> Unit,
onSearchClick: (String) -> Unit,
) {
Row(
modifier = modifier
.fillMaxWidth()
.padding(MetaSearchTheme.spacing.spacing4)
.border(
width = 1.dp,
color = Neutral500,
shape = RoundedCornerShape(
MetaSearchTheme.radius.full,
),
)
.padding(
horizontal = MetaSearchTheme.spacing.spacing4,
vertical = MetaSearchTheme.spacing.spacing3,
),
verticalAlignment = Alignment.CenterVertically,
) {
BasicTextField(
value = inputString,
onValueChange = onInputChange,
modifier = Modifier.weight(1f),
singleLine = true,
textStyle = MetaSearchTheme.typography.bodyLarge,
decorationBox = { innerTextField ->
if (inputString.isEmpty()) {
Text(
text = stringResource(R.string.nl_search_text_field_placeholder),
color = Neutral500,
style = MetaSearchTheme.typography.bodyLarge,
)
}
innerTextField()
},
)
var localInput by remember(inputString) { mutableStateOf(inputString) }

Icon(
painter = painterResource(R.drawable.ic_search_line),
contentDescription = "NL Search Icon",
modifier = Modifier
.size(
MetaSearchTheme.spacing.spacing6,
)
.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() },
) {
onSearchClick()
},
tint = Neutral500,
)
}
MetaSearchSearchBar(
modifier = modifier,
value = localInput,
onValueChange = { localInput = it },
onSearchClick = { onSearchClick(localInput) },
placeholder = stringResource(R.string.nl_search_text_field_placeholder),
)
}

@ComponentPreview
Expand All @@ -90,7 +36,6 @@ private fun NLSearchTextFieldPreview() {
NLSearchTextField(
inputString = "서울에서 밤에 찍은 음식 사진",
onSearchClick = {},
onInputChange = {},
)
}
}