...
This commit is contained in:
parent
9fefdc22f2
commit
3c7f652f38
@ -197,7 +197,7 @@ class OverseasFinancialService(
|
||||
suspend fun fetchKeyMetrics(symbol: String): Result<KeyMetrics> {
|
||||
return try {
|
||||
val response: List<KeyMetrics> = client.get("$baseUrl/key-metrics-ttm/$symbol") {
|
||||
parameter("apikey", apiKey)
|
||||
parameter("apikey", "FzvO_2P679KGRDUVx3u7rkMvCvcqiynu")
|
||||
}.body()
|
||||
|
||||
if (response.isNotEmpty()) {
|
||||
|
||||
@ -3,12 +3,10 @@ package ui
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.gestures.awaitEachGesture
|
||||
import androidx.compose.foundation.gestures.awaitFirstDown
|
||||
import androidx.compose.foundation.gestures.detectTapGestures
|
||||
import androidx.compose.foundation.gestures.waitForUpOrCancellation
|
||||
import androidx.compose.foundation.horizontalScroll
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
@ -32,9 +30,12 @@ import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.pointer.PointerType
|
||||
import androidx.compose.ui.input.pointer.PointerEventType
|
||||
import androidx.compose.ui.input.pointer.isSecondaryPressed
|
||||
import androidx.compose.ui.input.pointer.onPointerEvent
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.layout.positionInParent
|
||||
import androidx.compose.ui.onExternalDrag
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
@ -79,6 +80,7 @@ fun TradingDecisionLog() {
|
||||
webSocketConnect = AutoTradingManager.webSocketConnect
|
||||
}
|
||||
val scrollState = rememberScrollState()
|
||||
val filterScrollState = rememberScrollState()
|
||||
|
||||
// [핵심] 원본 로그에서 필터 조건에 맞는 리스트만 산출
|
||||
val filteredLogs = TradingLogStore.decisionLogs.filter { log ->
|
||||
@ -131,6 +133,7 @@ fun TradingDecisionLog() {
|
||||
.fillMaxWidth()
|
||||
.horizontalScroll(scrollState),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
filterOptions.forEach { option ->
|
||||
val isSelected = selectedFilters.contains(option)
|
||||
@ -175,7 +178,8 @@ fun TradingDecisionLog() {
|
||||
if (newFilters.isEmpty()) newFilters.add("전체")
|
||||
selectedFilters = newFilters
|
||||
},
|
||||
label = option
|
||||
label = option,
|
||||
scrollState = scrollState
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -787,65 +791,74 @@ fun SettingSwitchField(
|
||||
}
|
||||
}
|
||||
}
|
||||
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class)
|
||||
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class, ExperimentalComposeUiApi::class)
|
||||
@Composable
|
||||
fun FilterChipWithRightClick(
|
||||
label: String,
|
||||
isSelected: Boolean,
|
||||
onClick: () -> Unit,
|
||||
onClear: () -> Unit
|
||||
onClear: () -> Unit,
|
||||
scrollState: ScrollState // 스크롤 제어를 위해 추가
|
||||
) {
|
||||
var showMenu by remember { mutableStateOf(false) }
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
Box {
|
||||
var componentOffset by remember { mutableStateOf(0f) }
|
||||
var componentWidth by remember { mutableStateOf(0) } // 칩 너비 추가
|
||||
|
||||
|
||||
Box(
|
||||
modifier = Modifier.onGloballyPositioned { coordinates ->
|
||||
componentOffset = coordinates.positionInParent().x
|
||||
componentWidth = coordinates.size.width // 칩의 실제 너비 저장
|
||||
}
|
||||
) {
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.padding(end = 6.dp)
|
||||
.pointerInput(label) {
|
||||
awaitEachGesture {
|
||||
val down = awaitFirstDown()
|
||||
// 💡 마우스 우클릭 검사
|
||||
if (down.type == PointerType.Mouse && currentEvent.buttons.isSecondaryPressed) {
|
||||
down.consume()
|
||||
showMenu = true
|
||||
} else {
|
||||
// 💡 터치/좌클릭 시 롱클릭 판별
|
||||
val up = withTimeoutOrNull(viewConfiguration.longPressTimeoutMillis) {
|
||||
waitForUpOrCancellation()
|
||||
}
|
||||
if (up == null) {
|
||||
showMenu = true // 롱클릭
|
||||
} else {
|
||||
up.consume()
|
||||
onClick() // 일반 클릭
|
||||
detectTapGestures(
|
||||
onTap = {
|
||||
onClick()
|
||||
coroutineScope.launch {
|
||||
// 부모(Row)의 전체 너비 가져오기
|
||||
val containerWidth = scrollState.maxValue + scrollState.viewportSize
|
||||
val viewportWidth = scrollState.viewportSize
|
||||
|
||||
// 🎯 중앙 정렬 공식:
|
||||
// (칩의 절대 위치) - (화면 절반) + (칩 너비의 절반)
|
||||
val targetScroll = (scrollState.value + componentOffset + (componentWidth / 2)) - (viewportWidth / 2)
|
||||
|
||||
// 0과 최대 스크롤 범위 사이로 제한하여 부드럽게 이동
|
||||
scrollState.animateScrollTo(
|
||||
targetScroll.toInt().coerceIn(0, scrollState.maxValue)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
// 마우스 우클릭 별도 감지
|
||||
.onPointerEvent(PointerEventType.Press) { event ->
|
||||
if (event.buttons.isSecondaryPressed) showMenu = true
|
||||
},
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
color = if (isSelected) Color(0xFF0E62CF) else Color(0xFFF0F2F5),
|
||||
border = BorderStroke(1.dp, if (isSelected) Color(0xFF0E62CF) else Color.LightGray)
|
||||
) {
|
||||
Text(
|
||||
text = label,
|
||||
modifier = Modifier.padding(horizontal = 12.dp, vertical = 6.dp),
|
||||
modifier = Modifier.padding(horizontal = 6.dp, vertical = 6.dp),
|
||||
fontSize = 11.sp,
|
||||
color = if (isSelected) Color.White else Color.Black,
|
||||
fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Normal
|
||||
color = if (isSelected) Color.White else Color.Black
|
||||
)
|
||||
}
|
||||
|
||||
// 💡 우클릭 시 나타나는 메뉴
|
||||
DropdownMenu(
|
||||
expanded = showMenu,
|
||||
onDismissRequest = { showMenu = false }
|
||||
) {
|
||||
DropdownMenu(expanded = showMenu, onDismissRequest = { showMenu = false }) {
|
||||
DropdownMenuItem(onClick = {
|
||||
onClear() // 실제 삭제 수행
|
||||
onClear()
|
||||
showMenu = false
|
||||
}) {
|
||||
val menuText = if (label == "전체") "전체 로그 초기화" else "'$label' 관련 로그 삭제"
|
||||
Text(menuText, color = Color.Red, fontSize = 12.sp)
|
||||
Text(if (label == "전체") "전체 로그 초기화" else "'$label' 삭제", color = Color.Red)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user