From a333ef9681753b73adea217624f91e79aaa7f13f Mon Sep 17 00:00:00 2001 From: hided62 Date: Tue, 4 Aug 2026 13:31:05 +0000 Subject: [PATCH] feat: complete legacy game screen parity --- .../src/components/main/CityBasicCard.vue | 51 +++++--- .../src/components/main/CommandListPanel.vue | 36 +++--- .../src/components/main/CommandSelectForm.vue | 69 +++++------ .../src/components/main/GeneralBasicCard.vue | 107 +++++++++------- .../src/components/main/MainFrontStatus.vue | 5 +- .../src/components/main/MainNationMenu.vue | 6 + .../src/components/main/MapViewer.vue | 35 +----- .../src/components/main/MessagePanel.vue | 5 +- .../src/components/main/NationBasicCard.vue | 57 +++++---- .../src/components/ui/LegacyHtmlEditor.vue | 117 ++++++++++++++++++ .../src/views/BattleCenterView.vue | 9 +- .../src/views/GlobalInfoView.vue | 17 +-- app/game-frontend/src/views/InheritView.vue | 9 +- app/game-frontend/src/views/MainView.vue | 34 +++-- app/game-frontend/src/views/MyPageView.vue | 37 +++++- .../src/views/NationCitiesView.vue | 10 +- .../src/views/NationInfoView.vue | 7 +- .../src/views/NationPersonnelView.vue | 22 +++- .../src/views/NationStratFinanView.vue | 10 +- 19 files changed, 436 insertions(+), 207 deletions(-) create mode 100644 app/game-frontend/src/components/ui/LegacyHtmlEditor.vue diff --git a/app/game-frontend/src/components/main/CityBasicCard.vue b/app/game-frontend/src/components/main/CityBasicCard.vue index e20a90c..92759f3 100644 --- a/app/game-frontend/src/components/main/CityBasicCard.vue +++ b/app/game-frontend/src/components/main/CityBasicCard.vue @@ -29,37 +29,52 @@ const props = defineProps<{
도시 정보를 불러오지 못했습니다.
-
{{ props.city.name }} (Lv {{ props.city.level }})
+
+ {{ props.city.name }} (Lv {{ props.city.level }}) · 국가 {{ props.city.nationId || '무주' }} +
-
인구 {{ props.city.population }}
-
농업 {{ props.city.agriculture }}
-
상업 {{ props.city.commerce }}
-
치안 {{ props.city.security }}
-
방어 {{ props.city.defence }}
-
성벽 {{ props.city.wall }}
-
보급 {{ props.city.supplyState }}
-
전방 {{ props.city.frontState }}
+ 인구{{ props.city.population.toLocaleString() }} 농업{{ props.city.agriculture.toLocaleString() }} 상업{{ props.city.commerce.toLocaleString() }} 치안{{ props.city.security.toLocaleString() }} 수비{{ props.city.defence.toLocaleString() }} 성벽{{ props.city.wall.toLocaleString() }} 보급{{ props.city.supplyState }} 전방{{ props.city.frontState }}
diff --git a/app/game-frontend/src/views/BattleCenterView.vue b/app/game-frontend/src/views/BattleCenterView.vue index c2d96c0..495a707 100644 --- a/app/game-frontend/src/views/BattleCenterView.vue +++ b/app/game-frontend/src/views/BattleCenterView.vue @@ -457,7 +457,7 @@ onMounted(() => { .log-block { border: 1px solid #666; padding: 0; - background: #111; + background: #000; min-height: 0; } @@ -469,7 +469,7 @@ onMounted(() => { justify-content: center; border-bottom: 1px solid #666; color: orange; - background: #252525; + background: #000; font-size: 1.3em; font-weight: 500; } @@ -479,6 +479,11 @@ onMounted(() => { border-bottom: 0; } +.log-line :deep(.hidden_but_copyable) { + color: transparent !important; + font-size: 0; +} + .empty { padding: 2px 8px; color: #999; diff --git a/app/game-frontend/src/views/GlobalInfoView.vue b/app/game-frontend/src/views/GlobalInfoView.vue index 5c03897..67dcbc9 100644 --- a/app/game-frontend/src/views/GlobalInfoView.vue +++ b/app/game-frontend/src/views/GlobalInfoView.vue @@ -3,6 +3,7 @@ import { computed, onMounted, ref } from 'vue'; import { useRouter } from 'vue-router'; import MapViewer from '../components/main/MapViewer.vue'; import { trpc } from '../utils/trpc'; +import { legacyNationTextColor } from '../utils/legacyNationColor'; type Result = Awaited>; type Layout = Awaited>; @@ -14,17 +15,9 @@ const goBack = () => router.push('/'); const state = (value: number) => ({ 0: '★', 1: '▲', 2: '', 7: '@' })[value] ?? 'ㆍ'; const stateClass = (value: number) => `state-${value}`; const nationMap = computed(() => new Map(data.value?.nations.map((nation) => [nation.id, nation]) ?? [])); -const isBrightColor = (color: string): boolean => { - const normalized = color.trim().replace(/^#/u, ''); - if (!/^[0-9a-f]{6}$/iu.test(normalized)) return false; - const red = Number.parseInt(normalized.slice(0, 2), 16); - const green = Number.parseInt(normalized.slice(2, 4), 16); - const blue = Number.parseInt(normalized.slice(4, 6), 16); - return red * 0.299 + green * 0.587 + blue * 0.114 > 170; -}; const nationNameStyle = (color: string) => ({ backgroundColor: color, - color: isBrightColor(color) ? '#000' : '#fff', + color: legacyNationTextColor(color), }); onMounted(async () => { try { @@ -55,7 +48,7 @@ onMounted(async () => { v-for="nation in data.nations" :key="nation.id" class="vertical" - :style="{ backgroundColor: nation.color }" + :style="nationNameStyle(nation.color)" > {{ nation.name }} @@ -63,7 +56,7 @@ onMounted(async () => { - {{ me.name }} + {{ me.name }} { {{ conflict.cityName }}
- {{ + {{ nationMap.get(Number(id))?.name }}{{ percent.toFixed(1) }}% { } return map; }); +const selectedSpecialWarInfo = computed( + () => status.value?.availableSpecialWar.find((entry) => entry.key === nextSpecialKey.value)?.info ?? '' +); const buffCost = (key: BuffKey, target: number): number => { const points = status.value?.inheritConst.inheritBuffPoints ?? [0, 0, 0, 0, 0, 0]; @@ -493,7 +496,11 @@ onMounted(() => {
{{ specialNameMap.get(nextSpecialKey) }} 특기를 다음에 얻도록 지정합니다.
{{ + selectedSpecialWarInfo + }}
{{ specialNameMap.get(nextSpecialKey) }} 특기를 다음에 + 얻도록 지정합니다.
필요 포인트: {{ status.inheritConst.inheritSpecificSpecialPoint }}
diff --git a/app/game-frontend/src/views/MainView.vue b/app/game-frontend/src/views/MainView.vue index 2106881..f9bb136 100644 --- a/app/game-frontend/src/views/MainView.vue +++ b/app/game-frontend/src/views/MainView.vue @@ -65,6 +65,18 @@ const nationAccess = computed(() => ({ })); const nationColor = computed(() => nation.value?.color ?? '#000000'); const voteActive = computed(() => Boolean(frontStatus.value?.latestVote)); +const formatRecord = (entry: { text: string; createdAt?: string | Date }, appendTime = false): string => { + if (!appendTime || /\d{2}:\d{2}\s*$/u.test(entry.text)) return formatLog(entry.text); + const parsed = entry.createdAt ? new Date(entry.createdAt) : null; + if (!parsed || Number.isNaN(parsed.getTime())) return formatLog(entry.text); + const time = new Intl.DateTimeFormat('ko-KR', { + timeZone: 'Asia/Seoul', + hour: '2-digit', + minute: '2-digit', + hour12: false, + }).format(parsed); + return formatLog(`${entry.text} ${time}`); +}; let surveyNoticeTimer: ReturnType | null = null; watch(surveyNotice, (notice) => { @@ -151,7 +163,9 @@ watch( > 실시간 동기화: {{ realtimeLabel }} - +
@@ -241,7 +255,7 @@ watch( v-for="entry in globalRecords" :key="entry.id" class="record-line" - v-html="formatLog(entry.text)" + v-html="formatRecord(entry)" />
기록이 없습니다.
@@ -255,7 +269,7 @@ watch( v-for="entry in generalRecords" :key="entry.id" class="record-line" - v-html="formatLog(entry.text)" + v-html="formatRecord(entry, true)" />
기록이 없습니다.
@@ -269,7 +283,7 @@ watch( v-for="entry in worldHistory" :key="entry.id" class="record-line" - v-html="formatLog(entry.text)" + v-html="formatRecord(entry)" />
기록이 없습니다.
@@ -350,7 +364,7 @@ watch( v-for="entry in globalRecords" :key="entry.id" class="record-line" - v-html="formatLog(entry.text)" + v-html="formatRecord(entry)" />
기록이 없습니다.
@@ -364,7 +378,7 @@ watch( v-for="entry in generalRecords" :key="entry.id" class="record-line" - v-html="formatLog(entry.text)" + v-html="formatRecord(entry, true)" />
기록이 없습니다.
@@ -378,7 +392,7 @@ watch( v-for="entry in worldHistory" :key="entry.id" class="record-line" - v-html="formatLog(entry.text)" + v-html="formatRecord(entry)" />
기록이 없습니다.
@@ -624,7 +638,6 @@ button { .desktop-message-panel { grid-column: 1 / -1; - height: 1377.5px; } .common-menu-middle { @@ -654,6 +667,11 @@ button { white-space: nowrap; } +.record-line :deep(.hidden_but_copyable) { + color: transparent !important; + font-size: 0; +} + .record-empty { color: #aaa; } diff --git a/app/game-frontend/src/views/MyPageView.vue b/app/game-frontend/src/views/MyPageView.vue index 7ff5f29..838adc0 100644 --- a/app/game-frontend/src/views/MyPageView.vue +++ b/app/game-frontend/src/views/MyPageView.vue @@ -386,20 +386,49 @@ onMounted(() => {
경험/공헌
{{ data.general.experience }} / {{ data.general.dedication }}
+
+
성격/특기
+
+ {{ data.general.traits?.personal ?? '-' }} / + {{ data.general.traits?.specialWar ?? '-' }} +
+
+
+
나이/다음턴
+
{{ data.general.age ?? '-' }}세 / {{ data.general.turnTime?.slice(11, 16) ?? '-' }}
+
- 명망 약간 ({{ data.general.experience }}) · 계급 - 약간 ({{ data.general.dedication }}) + 명망 + Lv {{ data.general.progression?.experienceLevel ?? 0 }} ({{ + data.general.experience + }}) + · 계급 + Lv {{ data.general.progression?.dedicationLevel ?? 0 }} ({{ + data.general.dedication + }})
전투 0 · 계략 0 · 사관 7년
승률 0% · 승리 0 · 패배 0
살상률 0% · 사살 0 · 피살 0
숙련도
-
보병 0.0K · 궁병 0.0K · 기병 0.0K · 귀병 0.0K · 차병 0.0K
- 병종 {{ data.general.crew ? '보병' : '-' }} · 부상 {{ data.general.injury }} · 부대 - · 벌점 - + 보병 {{ data.general.progression?.dex?.[0] ?? 0 }} · 궁병 + {{ data.general.progression?.dex?.[1] ?? 0 }} · 기병 + {{ data.general.progression?.dex?.[2] ?? 0 }} · 귀병 + {{ data.general.progression?.dex?.[3] ?? 0 }} · 차병 + {{ data.general.progression?.dex?.[4] ?? 0 }} +
+
+ 병종 {{ data.general.crewTypeId || '-' }} · 내정특기 + {{ data.general.traits?.specialDomestic ?? '-' }} · 부상 {{ data.general.injury }} · 부대 + {{ data.general.troopId || '-' }} · 벌점 {{ penalties.length || '-' }}
diff --git a/app/game-frontend/src/views/NationCitiesView.vue b/app/game-frontend/src/views/NationCitiesView.vue index f548695..f36e392 100644 --- a/app/game-frontend/src/views/NationCitiesView.vue +++ b/app/game-frontend/src/views/NationCitiesView.vue @@ -2,6 +2,7 @@ import { computed, onMounted, ref } from 'vue'; import { useRouter } from 'vue-router'; import { getNpcColor } from '../utils/npcColor'; +import { legacyNationTextColor } from '../utils/legacyNationColor'; import { cityLevelMap, regionMap } from '../utils/nationFormat'; import { trpc } from '../utils/trpc'; @@ -149,7 +150,14 @@ onMounted(async () => { > - + 【 {{ regionMap[city.region] }} | {{ cityLevelMap[city.level] }} 】 {{ city.id === data?.nation.capitalCityId ? `[${city.name}]` : city.name diff --git a/app/game-frontend/src/views/NationInfoView.vue b/app/game-frontend/src/views/NationInfoView.vue index dd303c2..e344999 100644 --- a/app/game-frontend/src/views/NationInfoView.vue +++ b/app/game-frontend/src/views/NationInfoView.vue @@ -2,6 +2,7 @@ import { computed, onMounted, ref } from 'vue'; import { useRouter } from 'vue-router'; import { formatLog } from '../utils/formatLog'; +import { legacyNationTextColor } from '../utils/legacyNationColor'; import { trpc } from '../utils/trpc'; type Result = Awaited>; @@ -35,7 +36,11 @@ onMounted(async () => { - diff --git a/app/game-frontend/src/views/NationPersonnelView.vue b/app/game-frontend/src/views/NationPersonnelView.vue index 7243853..47671ba 100644 --- a/app/game-frontend/src/views/NationPersonnelView.vue +++ b/app/game-frontend/src/views/NationPersonnelView.vue @@ -5,6 +5,7 @@ import { useRouter } from 'vue-router'; import { resolveGeneralIconBackgroundImage } from '../utils/generalIcon'; import { trpc } from '../utils/trpc'; import { cityLevelMap, formatOfficerLevelText, getNationChiefLevel, regionMap } from '../utils/nationFormat'; +import { legacyNationTextColor } from '../utils/legacyNationColor'; type PersonnelResponse = Awaited>; type GeneralEntry = PersonnelResponse['generals'][number]; @@ -213,7 +214,10 @@ onMounted(() => void loadPersonnel()); @@ -415,10 +419,22 @@ onMounted(() => void loadPersonnel()); - -
+ 【{{ data.nation.name }}】
【 {{ data.nation.name }} 】 【 {{ regionMap[city.region] ?? '-' }} 】
+ 【{{ cityLevelMap[city.level] ?? '-' }}】 + {{ city.name }} >; type NationEntry = StratFinanResponse['nationsList'][number]; @@ -194,7 +196,9 @@ onMounted(() => void loadStratFinan());
종료 시점
-
{{ nation.name }}
+
+ {{ nation.name }} +
{{ formatNumber(nation.power) }}
{{ formatNumber(nation.generalCount) }}
{{ formatNumber(nation.cityCount) }}
@@ -245,7 +249,7 @@ onMounted(() => void loadStratFinan());
-