추천 사이트 위치 조정
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
<script setup>
|
||||
import { getExternalFaviconUrl } from '~/lib/external-favicon-url.js'
|
||||
import { getVisibleSocialLinks } from '~/lib/social-links.js'
|
||||
|
||||
const route = useRoute()
|
||||
@@ -21,25 +20,6 @@ const { data: siteSettings } = await useFetch('/api/site-settings', {
|
||||
})
|
||||
})
|
||||
|
||||
const { data: navigation } = await useFetch('/api/navigation', {
|
||||
default: () => ({
|
||||
primary: [],
|
||||
footer: [],
|
||||
recommended: []
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* 공개 추천 사이트 목록(비가시 제외)
|
||||
* @returns {Array<{ id: string, label: string, url: string, descriptionText?: string, thumbnailUrl?: string }>}
|
||||
*/
|
||||
const recommendedSites = computed(() => {
|
||||
const list = navigation.value?.recommended
|
||||
if (!Array.isArray(list)) {
|
||||
return []
|
||||
}
|
||||
return list.filter((x) => x?.isVisible !== false)
|
||||
})
|
||||
const isPostDetailRoute = computed(() => route.path.startsWith('/post/'))
|
||||
const sidebarAdCode = computed(() => isPostDetailRoute.value ? siteSettings.value?.adPostSidebarCode : siteSettings.value?.adSidebarCode)
|
||||
const postTocItems = computed(() => Array.isArray(postToc.value) ? postToc.value : [])
|
||||
@@ -155,32 +135,6 @@ const updateActiveToc = () => {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 새 탭으로 열 외부 URL인지
|
||||
* @param {string} url - 링크
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isExternalNavUrl = (url) => /^https?:\/\//i.test(String(url || '').trim())
|
||||
|
||||
/**
|
||||
* 추천 사이트 보조 문구를 반환한다.
|
||||
* @param {Object} item - 추천 사이트 항목
|
||||
* @returns {string} 표시 문구
|
||||
*/
|
||||
const getRecommendedDisplayText = (item) => {
|
||||
return String(item?.descriptionText || '').trim() || String(item?.url || '').trim()
|
||||
}
|
||||
|
||||
/**
|
||||
* 추천 사이트 이미지 URL을 반환한다.
|
||||
* @param {Object} item - 추천 사이트 항목
|
||||
* @returns {string} 이미지 URL
|
||||
*/
|
||||
const getRecommendedImageUrl = (item) => {
|
||||
const thumbnailUrl = String(item?.thumbnailUrl || '').trim()
|
||||
return thumbnailUrl || getExternalFaviconUrl(item?.url, 64)
|
||||
}
|
||||
|
||||
/**
|
||||
* 게시글 목차 링크를 부드럽게 이동한다.
|
||||
* @param {MouseEvent} event - 클릭 이벤트
|
||||
@@ -449,46 +403,6 @@ watch([postTocItems, () => route.fullPath], async () => {
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-else-if="recommendedSites.length"
|
||||
class="right-sidebar__block site-sidebar-section py-5 sm:pl-5 pr-0"
|
||||
>
|
||||
<div class="right-sidebar__row flex items-center justify-between">
|
||||
<p class="right-sidebar__eyebrow text-xs font-semibold uppercase site-muted">
|
||||
Recommended
|
||||
</p>
|
||||
</div>
|
||||
<ul class="right-sidebar__recommended-list mt-4 list-none flex flex-col gap-2.5 p-0">
|
||||
<li v-for="item in recommendedSites" :key="item.id">
|
||||
<a
|
||||
class="right-sidebar__recommended-card site-interactive flex items-center gap-3 rounded-xl border border-[var(--site-line)] bg-[var(--site-panel)] px-3 py-2.5 transition-colors hover:border-[var(--site-accent)]"
|
||||
:href="item.url"
|
||||
:target="isExternalNavUrl(item.url) ? '_blank' : undefined"
|
||||
:rel="isExternalNavUrl(item.url) ? 'nofollow noopener noreferrer' : undefined"
|
||||
>
|
||||
<span class="right-sidebar__recommended-icon grid h-9 w-9 shrink-0 place-items-center overflow-hidden rounded-lg bg-[var(--site-paper)] text-xs font-bold text-[var(--site-text)] ring-1 ring-[var(--site-line)]">
|
||||
<img
|
||||
v-if="getRecommendedImageUrl(item)"
|
||||
class="h-full w-full object-cover"
|
||||
:src="getRecommendedImageUrl(item)"
|
||||
width="36"
|
||||
height="36"
|
||||
:alt="item.thumbnailUrl ? item.label : ''"
|
||||
loading="lazy"
|
||||
referrerpolicy="no-referrer"
|
||||
>
|
||||
<span v-else class="px-1 text-center leading-none">{{ (item.label || '?').slice(0, 1) }}</span>
|
||||
</span>
|
||||
<span class="min-w-0 flex-1">
|
||||
<span class="block truncate text-sm font-semibold text-[var(--site-text)]">{{ item.label }}</span>
|
||||
<span class="mt-0.5 block truncate text-[11px] site-muted" :class="item.descriptionText ? '' : 'font-mono'">{{ getRecommendedDisplayText(item) }}</span>
|
||||
</span>
|
||||
<span class="shrink-0 text-xs site-muted" aria-hidden="true">↗</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div v-if="showAboutSection" class="right-sidebar__block site-sidebar-section py-5 pl-5 pr-0">
|
||||
<p class="right-sidebar__about text-sm leading-6 site-muted">
|
||||
{{ siteSettings.description }}
|
||||
|
||||
Reference in New Issue
Block a user