merge: 최신 main을 인게임 폰트 통일에 반영

This commit is contained in:
2026-08-17 10:53:27 +00:00
29 changed files with 1009 additions and 150 deletions
@@ -2,7 +2,7 @@
import { computed, onUnmounted, ref, watch } from 'vue';
import { addMinutes } from 'date-fns';
import ReservedCommandEditor from '../command/ReservedCommandEditor.vue';
import { formatLocalTimeSeconds } from '../../utils/legacyDateTime';
import { formatLocalDateTime, formatLocalTimeSeconds } from '../../utils/legacyDateTime';
import type {
CommandMapData,
CommandMapLayout,
@@ -65,6 +65,26 @@ const rows = computed<ReservedCommandRow[]>(() => {
});
});
const autonomousUntil = computed(() => {
if (props.autorunLimit == null) return null;
const baseYear = props.currentYear ?? 0;
const baseMonth = props.currentMonth ?? 1;
const currentAbsoluteMonth = baseYear * 12 + baseMonth - 1;
const lastAutonomousMonth = props.autorunLimit - 1;
if (lastAutonomousMonth < currentAbsoluteMonth) return null;
const untilYear = Math.floor(lastAutonomousMonth / 12);
const untilMonth = (lastAutonomousMonth % 12) + 1;
const base = props.general?.turnTime ? new Date(props.general.turnTime) : null;
const term = props.turnTermMinutes ?? 0;
const expiresAt =
base && Number.isFinite(base.getTime())
? addMinutes(base, (lastAutonomousMonth - currentAbsoluteMonth) * term)
: null;
const currentTimeLabel = expiresAt ? formatLocalDateTime(expiresAt) : '현재시각 확인 불가';
return `${untilYear}${untilMonth}月 · ${currentTimeLabel}까지`;
});
const currentServerTime = ref('--:--:--');
let sampledServerTimeMs: number | null = null;
let sampledClientTimeMs = 0;
@@ -112,6 +132,7 @@ onUnmounted(() => {
:current-time="currentServerTime"
:map-data="props.mapData"
:map-layout="props.mapLayout"
:autonomous-until="autonomousUntil"
@reserve-bulk="emit('set-general-turns', $event)"
@shift="emit('shift-general-turns', $event)"
@repeat="emit('repeat-general-turns', $event)"
@@ -26,10 +26,11 @@ const isActive = (link: MainNavigationLinkItem) => link.id === 'survey' && props
:link="entry"
:enabled="isNavigationConfigured(entry)"
:active="isActive(entry)"
lumen-variant="navigation"
/>
<div v-else-if="entry.kind === 'group'" class="main-menu-popup">
<button
class="main-menu-button"
class="main-menu-button legacy-button legacy-button--navigation"
type="button"
:data-menu-id="entry.id"
:aria-expanded="openId === entry.id"
@@ -63,9 +64,10 @@ const isActive = (link: MainNavigationLinkItem) => link.id === 'survey' && props
:link="entry.main"
:enabled="isNavigationConfigured(entry.main)"
:active="isActive(entry.main)"
lumen-variant="navigation"
/>
<button
class="main-menu-button main-menu-split__toggle"
class="main-menu-button main-menu-split__toggle legacy-button legacy-button--navigation"
type="button"
:data-menu-id="entry.id"
:aria-label="`${entry.main.label} 하위 메뉴`"
@@ -115,33 +117,6 @@ const isActive = (link: MainNavigationLinkItem) => link.id === 'survey' && props
min-width: 0;
}
.main-global-menu > :deep(.main-menu-link),
.main-menu-popup > .main-menu-button,
.main-menu-split > :deep(.main-menu-link),
.main-menu-split > .main-menu-split__toggle {
border-color: var(--sammo-button-navigation-border);
background-color: var(--sammo-button-navigation-bg);
background-image: none;
}
.main-global-menu > :deep(.main-menu-link:hover),
.main-global-menu > :deep(.main-menu-link:focus-visible),
.main-global-menu > :deep(.main-menu-link:active),
.main-menu-popup > .main-menu-button:hover,
.main-menu-popup > .main-menu-button:focus-visible,
.main-menu-popup > .main-menu-button:active,
.main-menu-popup > .main-menu-button[aria-expanded='true'],
.main-menu-split > :deep(.main-menu-link:hover),
.main-menu-split > :deep(.main-menu-link:focus-visible),
.main-menu-split > :deep(.main-menu-link:active),
.main-menu-split > .main-menu-split__toggle:hover,
.main-menu-split > .main-menu-split__toggle:focus-visible,
.main-menu-split > .main-menu-split__toggle:active,
.main-menu-split > .main-menu-split__toggle[aria-expanded='true'] {
border-color: var(--sammo-button-navigation-border);
background-color: var(--sammo-button-navigation-bg);
}
.main-menu-popup > .main-menu-button,
.main-menu-split > :deep(.main-menu-link) {
width: 100%;
@@ -157,7 +132,11 @@ const isActive = (link: MainNavigationLinkItem) => link.id === 'survey' && props
width: 28px;
padding: 0;
border-left-width: 0;
border-radius: 0 3px 3px 0;
border-radius: 0 5.25px 5.25px 0;
}
.main-menu-split > :deep(.main-menu-link) {
border-radius: 5.25px 0 0 5.25px;
}
.menu-caret {
@@ -33,15 +33,17 @@ const isActive = (link: MainNavigationLinkItem) => link.highlightStage === props
:link="entry"
:enabled="isNationNavigationEnabled(entry, access)"
:active="isActive(entry)"
lumen-variant="lumen"
/>
<div v-else-if="entry.kind === 'split'" class="nation-menu-split">
<MainNavigationLink
:link="entry.main"
:enabled="isNationNavigationEnabled(entry.main, access)"
:active="isActive(entry.main)"
lumen-variant="lumen"
/>
<button
class="main-menu-button nation-menu-split__toggle"
class="main-menu-button nation-menu-split__toggle legacy-button legacy-button--lumen"
type="button"
:data-menu-id="entry.id"
:aria-label="`${entry.main.label} 하위 메뉴`"
@@ -81,13 +83,14 @@ const isActive = (link: MainNavigationLinkItem) => link.highlightStage === props
.main-nation-menu :deep(.main-menu-link),
.main-nation-menu .main-menu-button {
border-color: color-mix(in srgb, var(--nation-menu-color) 85%, #000);
background-color: var(--nation-menu-color);
--legacy-button-bg: var(--nation-menu-color);
--legacy-button-border: color-mix(in srgb, var(--nation-menu-color) 90%, #000);
--legacy-button-color: #fff;
background-image: none;
}
.main-nation-menu.dark-label :deep(.main-menu-link),
.main-nation-menu.dark-label .main-menu-button {
color: #000;
--legacy-button-color: #000;
}
.nation-menu-split {
@@ -106,7 +109,11 @@ const isActive = (link: MainNavigationLinkItem) => link.highlightStage === props
width: 28px;
padding: 0;
border-left-width: 0;
border-radius: 0 3px 3px 0;
border-radius: 0 5.25px 5.25px 0;
}
.nation-menu-split > :deep(.main-menu-link) {
border-radius: 5.25px 0 0 5.25px;
}
.menu-caret {
@@ -8,11 +8,13 @@ const props = withDefaults(
enabled?: boolean;
compact?: boolean;
active?: boolean;
lumenVariant?: 'navigation' | 'lumen';
}>(),
{
enabled: true,
compact: false,
active: false,
lumenVariant: undefined,
}
);
@@ -22,13 +24,16 @@ const emit = defineEmits<{
const label = computed(() => (props.compact ? (props.link.compactLabel ?? props.link.label) : props.link.label));
const rel = computed(() => (props.link.newTab ? 'noopener noreferrer' : undefined));
const lumenClasses = computed(() =>
props.lumenVariant ? ['legacy-button', `legacy-button--${props.lumenVariant}`] : []
);
</script>
<template>
<RouterLink
v-if="enabled && link.to"
class="main-menu-link"
:class="{ highlight: active }"
:class="[lumenClasses, { highlight: active }]"
:to="link.to"
:target="link.newTab ? '_blank' : undefined"
:rel="rel"
@@ -40,7 +45,7 @@ const rel = computed(() => (props.link.newTab ? 'noopener noreferrer' : undefine
<a
v-else-if="enabled && link.href"
class="main-menu-link"
:class="{ highlight: active }"
:class="[lumenClasses, { highlight: active }]"
:href="link.href"
:target="link.newTab ? '_blank' : undefined"
:rel="rel"
@@ -52,6 +57,7 @@ const rel = computed(() => (props.link.newTab ? 'noopener noreferrer' : undefine
<span
v-else
class="main-menu-link disabled"
:class="lumenClasses"
role="link"
aria-disabled="true"
:title="link.unavailableReason"