기아자동차가 2018 SEMA에서 뛰어난 프레젠테이션을 선보였다. 새로운 독점 모델과 개조 차량들을 대거 공개한 것이다.
기아자동차 미국법인(Kia Motors America)은 신형 포르테 GT를 처음으로 공개해 모두를 놀라게 했다. 하지만 이게 전부가 아니었다. 초록색 람보르기니 스타일의 기아 포르테 페더레이션, 2020 기아 텔루라이드, 기아 포르테 드리프트 카, 퀸즐랜드 경찰 스팅어, K900 및 스팅어 DUB 에디션도 함께 선보였다.
기아는 또한 센트럴 홀과 사우스 홀 사이 공간을 활용해 스팅어와 2020년형 텔루라이드 시승 기회를 제공했다. 스팅어로는 소형 코스를 질주하며 드리프트 묘기를 선보였고, 제작한 4대의 텔루라이드 모델을 위한 오프로드 코스도 마련했다.
- {
const btn = w.querySelector(`[data-action="${action}"]`)
if (!btn) return
btn.dataset.state = on ? 'on' : 'off'
const label = btn.querySelector('.post-action-label')
if (label) label.textContent = on ? label.dataset.labelOn : label.dataset.labelOff
})
}
function setCountAll(n) {
wrappers.forEach((w) => {
const c = w.querySelector('[data-count]')
if (c) c.textContent = String(n)
})
}
function getCount() {
const c = wrappers[0]?.querySelector('[data-count]')
return Number(c?.textContent || 0)
}
function getState(action) {
const btn = wrappers[0]?.querySelector(`[data-action="${action}"]`)
return btn?.dataset.state === 'on'
}
async function loadInitial() {
try {
// Comprobar sesion PRIMERO. Sin esto, lanzabamos 3 fetches en
// paralelo y los anonimos (mayoria) generaban 2 invocations
// inutiles (vote + bookmark devolvian 401). Con miles de page
// renders/h post-cutover ese desperdicio se notaba en logs y
// function invocations facturadas.
//
// Reusa el helper kcbFetchSession (BaseLayout) que cachea el resultado
// en sessionStorage 10 min. Navbar/PostComments/PostActions todos
// usan el mismo helper → 1 fetch por sesion en lugar de 1 por page.
// Fallback in-place si el helper no esta cargado (orden inesperado).
if (typeof window.kcbFetchSession === 'function') {
window.__kcbSession = window.kcbFetchSession()
} else {
window.__kcbSession = window.__kcbSession || new Promise((resolve) => {
const start = () => {
fetch('/api/auth/session-check/', { credentials: 'same-origin' })
.then((r) => (r.ok ? r.json() : null))
.then(resolve)
.catch(() => resolve(null))
}
if ('requestIdleCallback' in window) {
requestIdleCallback(start, { timeout: 2000 })
} else {
setTimeout(start, 1000)
}
})
}
const s = await window.__kcbSession
if (s) {
userAuthenticated = Boolean(s.authenticated)
}
// Solo si el usuario esta autenticado pedimos su estado per-post.
// Para anonimos: vote_count se queda con el valor SSR inicial
// (data-count en el HTML); voted/bookmarked permanecen 'off'.
if (!userAuthenticated) return
const [voteRes, bmRes] = await Promise.all([
fetch(`/api/vote/${encodeURIComponent(slug)}`).catch(() => null),
fetch(`/api/bookmark/${encodeURIComponent(slug)}`).catch(() => null),
])
if (voteRes && voteRes.ok) {
const v = await voteRes.json()
setStateAll('like', Boolean(v.voted))
if (typeof v.vote_count === 'number') setCountAll(v.vote_count)
}
if (bmRes && bmRes.ok) {
const b = await bmRes.json()
setStateAll('bookmark', Boolean(b.bookmarked))
}
} catch {
/* silencioso — botones quedan en estado off */
}
}
function flashStatusAll(action, msg) {
wrappers.forEach((w) => {
const btn = w.querySelector(`[data-action="${action}"]`)
if (!btn) return
const prevTitle = btn.title
btn.title = msg
btn.classList.add('is-flash')
setTimeout(() => {
btn.title = prevTitle
btn.classList.remove('is-flash')
}, 1800)
})
}
async function handleVote() {
if (!userAuthenticated) {
flashStatusAll('like', signinHint)
const next = encodeURIComponent(location.pathname + location.search)
location.href = `/login/?next=${next}`
return
}
const prevState = getState('like')
// Optimistic UI (todas las instancias sincronizadas)
setStateAll('like', !prevState)
setCountAll(getCount() + (prevState ? -1 : 1))
try {
const res = await fetch(`/api/vote/${encodeURIComponent(slug)}`, { method: 'POST' })
if (!res.ok) throw new Error('vote failed')
const data = await res.json()
setStateAll('like', Boolean(data.voted))
if (typeof data.vote_count === 'number') setCountAll(data.vote_count)
// GA4: solo cuenta el voto positivo (toggle ON), no la retirada.
if (data.voted && window.kcbTrack) {
window.kcbTrack('post_vote', { slug })
}
} catch {
setStateAll('like', prevState)
setCountAll(getCount() + (prevState ? 1 : -1))
}
}
async function handleBookmark() {
if (!userAuthenticated) {
flashStatusAll('bookmark', signinHint)
const next = encodeURIComponent(location.pathname + location.search)
location.href = `/login/?next=${next}`
return
}
const prevState = getState('bookmark')
setStateAll('bookmark', !prevState)
try {
const res = await fetch(`/api/bookmark/${encodeURIComponent(slug)}`, { method: 'POST' })
if (!res.ok) throw new Error('bookmark failed')
const data = await res.json()
setStateAll('bookmark', Boolean(data.bookmarked))
// GA4: solo cuenta el bookmark positivo (toggle ON), no la retirada.
if (data.bookmarked && window.kcbTrack) {
window.kcbTrack('post_bookmark', { slug })
}
} catch {
setStateAll('bookmark', prevState)
}
}
// Bind click en TODOS los botones de TODAS las instancias
wrappers.forEach((w) => {
w.querySelector('[data-action="like"]')?.addEventListener('click', handleVote)
w.querySelector('[data-action="bookmark"]')?.addEventListener('click', handleBookmark)
})
loadInitial()
} // bindAll
})()
})(); Korean Car Blog 추가 → Korean Car Blog을 Google 선호 소스에 추가하세요
계속 읽기
이 주제에 관한 더 많은 글
Spy Shots2020년 9월 1일
기아 포르테 페이스리프트, 내외부 스파이샷 포착
Spy Shots2020년 8월 27일
기아 포르테 페이스리프트, 근접 스파이샷 포착
Spy Shots2020년 8월 18일
2021 소나타 N-Line: 전체 갤러리 확인
Spy Shots2020년 8월 17일

































댓글
아직 댓글이 없습니다. 가장 먼저 작성해 보세요.