Files
sori.studio/lib/analytics-display.js

67 lines
2.6 KiB
JavaScript

/**
* 통계 수치에 한국어 천 단위 구분을 적용한다.
* @param {unknown} value - 표시할 수치
* @returns {string} 구분 기호가 있는 숫자
*/
export const formatAnalyticsCount = (value) => {
const number = Number(value || 0)
return new Intl.NumberFormat('ko-KR').format(Number.isFinite(number) ? number : 0)
}
/**
* 현재 접속 시간을 최대 두 단위로 짧게 표시한다.
* @param {number} seconds - 접속 시간(초)
* @returns {string} 일·시간·분·초 표시
*/
export const formatRealtimeDuration = (seconds) => {
const input = Number(seconds)
const value = Number.isFinite(input) ? Math.max(0, Math.floor(input)) : 0
if (value >= 86400) {
const hours = Math.floor(value % 86400 / 3600)
return `${formatAnalyticsCount(Math.floor(value / 86400))}일${hours ? ` ${hours}시간` : ''}`
}
if (value >= 3600) {
const minutes = Math.floor(value % 3600 / 60)
return `${formatAnalyticsCount(Math.floor(value / 3600))}시간${minutes ? ` ${minutes}분` : ''}`
}
const minutes = Math.floor(value / 60)
const remainder = value % 60
return minutes ? `${minutes}분${remainder ? ` ${remainder}초` : ''}` : `${remainder}초`
}
/**
* 접속 페이지의 표시 제목을 반환한다.
* @param {Object} page - 활성 페이지
* @returns {string} 페이지 제목
*/
export const getActivePageTitle = (page) => page.postTitle || page.pageTitle || (page.path === '/' ? '홈' : page.path) || '알 수 없음'
/**
* 접속 페이지의 사이트 내부 공개 경로를 반환한다.
* @param {Object} page - 활성 페이지
* @returns {string} 바로가기 경로
*/
export const getActivePageHref = (page) => {
if (page.postSlug) return `/post/${encodeURIComponent(page.postSlug)}`
if (page.pageSlug) return `/pages/${encodeURIComponent(page.pageSlug)}`
const path = String(page.path || '').trim()
return path.startsWith('/') && !path.startsWith('//') && !path.includes('\\') && !/^\/admin(?:[/?#]|$)/.test(path) ? path : ''
}
/**
* 열린 페이지를 최근 확인 순으로 정렬하고 같은 경로를 중복 제거한다.
* @param {Object} session - 묶인 접속자
* @returns {Array<Object>} 최신 페이지부터의 고유 목록
*/
export const getRealtimePages = (session) => {
const pages = session.pages?.length ? session.pages : [session]
const ordered = [...pages].sort((left, right) => (Date.parse(right.lastSeenAt) || 0) - (Date.parse(left.lastSeenAt) || 0))
const seen = new Set()
return ordered.filter((page) => {
const key = getActivePageHref(page) || page.path || page.key || ''
if (seen.has(key)) return false
seen.add(key)
return true
})
}