fix(toolbar): enforce single-row flex layout and remove server host control
This commit is contained in:
parent
3c1ed16bf9
commit
c6bf2464e8
137
play.html
137
play.html
|
|
@ -46,9 +46,146 @@
|
||||||
|
|
||||||
#d2-toolbar-container {
|
#d2-toolbar-container {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
width: 100%;
|
||||||
z-index: 50;
|
z-index: 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#d2-toolbar,
|
||||||
|
.d2-toolbar {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1000;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
width: 100%;
|
||||||
|
height: 32px;
|
||||||
|
min-height: 32px;
|
||||||
|
max-height: 32px;
|
||||||
|
padding: 0 12px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: linear-gradient(180deg, #1b1712 0%, #0d0b08 100%);
|
||||||
|
border-bottom: 1px solid #4a3c24;
|
||||||
|
color: #d6c496;
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d2-toolbar__group {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
gap: 6px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d2-toolbar__status {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 3px 8px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background: #14110d;
|
||||||
|
border: 1px solid #352b1b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d2-toolbar__status-dot {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
background: #6b6b6b;
|
||||||
|
box-shadow: 0 0 4px rgba(0, 0, 0, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.d2-toolbar__status-dot--disconnected { background: #767676; }
|
||||||
|
.d2-toolbar__status-dot--connecting { background: #e6a822; box-shadow: 0 0 6px #e6a822; }
|
||||||
|
.d2-toolbar__status-dot--bncs { background: #4495e8; box-shadow: 0 0 6px #4495e8; }
|
||||||
|
.d2-toolbar__status-dot--mcp { background: #36c5d6; box-shadow: 0 0 6px #36c5d6; }
|
||||||
|
.d2-toolbar__status-dot--d2gs { background: #2ecc71; box-shadow: 0 0 6px #2ecc71; }
|
||||||
|
.d2-toolbar__status-dot--error { background: #e74c3c; box-shadow: 0 0 6px #e74c3c; }
|
||||||
|
|
||||||
|
.d2-toolbar__rtt {
|
||||||
|
font-family: "JetBrains Mono", "Consolas", monospace;
|
||||||
|
font-size: 11px;
|
||||||
|
color: #a89974;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d2-toolbar__label {
|
||||||
|
color: #b59e68;
|
||||||
|
font-size: 11px;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d2-toolbar__select {
|
||||||
|
height: 22px;
|
||||||
|
padding: 0 6px;
|
||||||
|
background: #120f0b;
|
||||||
|
border: 1px solid #4a3c24;
|
||||||
|
border-radius: 2px;
|
||||||
|
color: #e2d1a0;
|
||||||
|
font-size: 11px;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d2-toolbar__select:hover,
|
||||||
|
.d2-toolbar__btn:hover {
|
||||||
|
border-color: #c7b377;
|
||||||
|
color: #fff2c6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d2-toolbar__btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 22px;
|
||||||
|
padding: 0 8px;
|
||||||
|
background: linear-gradient(180deg, #2b2316 0%, #17120b 100%);
|
||||||
|
border: 1px solid #574629;
|
||||||
|
border-radius: 2px;
|
||||||
|
color: #dfc991;
|
||||||
|
font-size: 11px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d2-toolbar__btn--active {
|
||||||
|
background: linear-gradient(180deg, #524020 0%, #2e2310 100%);
|
||||||
|
border-color: #d4b46a;
|
||||||
|
color: #fff5d6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d2-toolbar__diag {
|
||||||
|
position: absolute;
|
||||||
|
top: 32px;
|
||||||
|
left: 12px;
|
||||||
|
right: 12px;
|
||||||
|
z-index: 1001;
|
||||||
|
display: none;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 6px 10px;
|
||||||
|
background: rgba(38, 12, 10, 0.96);
|
||||||
|
border: 1px solid #a93226;
|
||||||
|
border-top: none;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
color: #ffd6d1;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d2-toolbar__diag--visible {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
#play-workspace {
|
#play-workspace {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,39 @@ async function bootPlayApp(): Promise<PlayAppController> {
|
||||||
const initialSettings = settingsStore.get()
|
const initialSettings = settingsStore.get()
|
||||||
setLang(initialSettings.lang)
|
setLang(initialSettings.lang)
|
||||||
|
|
||||||
|
let sessionRef: OnlineSession | null = null
|
||||||
|
|
||||||
|
const toolbar = new Toolbar({
|
||||||
|
store: settingsStore,
|
||||||
|
container: toolbarContainer,
|
||||||
|
callbacks: {
|
||||||
|
onLangChange: (lang: GameLang) => {
|
||||||
|
setLang(lang)
|
||||||
|
sessionRef?.hudManager.setLang(lang)
|
||||||
|
},
|
||||||
|
onViewportChange: (profile: ViewportProfile) => {
|
||||||
|
applyViewportProfileToDom(profile, {
|
||||||
|
stageEl,
|
||||||
|
glCanvas: viewCanvas,
|
||||||
|
hudCanvas,
|
||||||
|
})
|
||||||
|
sessionRef?.hudManager.resize(profile.width, profile.height)
|
||||||
|
sessionRef?.camera.resize(profile)
|
||||||
|
},
|
||||||
|
onAutomapRevealChange: (mode) => {
|
||||||
|
sessionRef?.automapView.setMode(mode)
|
||||||
|
},
|
||||||
|
onInspectorToggle: (open) => {
|
||||||
|
sessionRef?.packetInspector.setOpen(open)
|
||||||
|
},
|
||||||
|
onServerHostReconnect: (newHost) => {
|
||||||
|
void sessionRef?.disconnect(`Reconnecting to ${newHost}`)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
const initialCacheStatus = await registerAssetCache()
|
const initialCacheStatus = await registerAssetCache()
|
||||||
|
toolbar.setAssetCacheUsageBytes(initialCacheStatus.usageBytes)
|
||||||
|
|
||||||
const minimap = new Minimap()
|
const minimap = new Minimap()
|
||||||
const renderer = new SpriteRenderer(viewCanvas)
|
const renderer = new SpriteRenderer(viewCanvas)
|
||||||
|
|
@ -183,8 +215,6 @@ async function bootPlayApp(): Promise<PlayAppController> {
|
||||||
let itemsAtlasHandle: AtlasHandle | undefined
|
let itemsAtlasHandle: AtlasHandle | undefined
|
||||||
let lastRenderSnapshot: SceneFrameSnapshot | null = null
|
let lastRenderSnapshot: SceneFrameSnapshot | null = null
|
||||||
|
|
||||||
let sessionRef: OnlineSession | null = null
|
|
||||||
|
|
||||||
const hudManager = new HudManager(hudCanvas, {
|
const hudManager = new HudManager(hudCanvas, {
|
||||||
onRenderAutomapOverlay: (ctx, font, logicalWidth, logicalHeight) => {
|
onRenderAutomapOverlay: (ctx, font, logicalWidth, logicalHeight) => {
|
||||||
minimap.drawHudOverlay(ctx, font, logicalWidth, logicalHeight)
|
minimap.drawHudOverlay(ctx, font, logicalWidth, logicalHeight)
|
||||||
|
|
@ -339,35 +369,6 @@ async function bootPlayApp(): Promise<PlayAppController> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const toolbar = new Toolbar({
|
|
||||||
store: settingsStore,
|
|
||||||
container: toolbarContainer,
|
|
||||||
callbacks: {
|
|
||||||
onLangChange: (lang: GameLang) => {
|
|
||||||
setLang(lang)
|
|
||||||
session.hudManager.setLang(lang)
|
|
||||||
},
|
|
||||||
onViewportChange: (profile: ViewportProfile) => {
|
|
||||||
applyViewportProfileToDom(profile, {
|
|
||||||
stageEl,
|
|
||||||
glCanvas: viewCanvas,
|
|
||||||
hudCanvas,
|
|
||||||
})
|
|
||||||
session.hudManager.resize(profile.width, profile.height)
|
|
||||||
session.camera.resize(profile)
|
|
||||||
},
|
|
||||||
onAutomapRevealChange: (mode) => {
|
|
||||||
session.automapView.setMode(mode)
|
|
||||||
},
|
|
||||||
onInspectorToggle: (open) => {
|
|
||||||
inspector.setOpen(open)
|
|
||||||
},
|
|
||||||
onServerHostReconnect: (newHost) => {
|
|
||||||
void session.disconnect(`Reconnecting to ${newHost}`)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
toolbar.setAssetCacheUsageBytes(initialCacheStatus.usageBytes)
|
|
||||||
void assetsReadyPromise.then(async () => {
|
void assetsReadyPromise.then(async () => {
|
||||||
const updatedStatus = await getAssetCacheStatus()
|
const updatedStatus = await getAssetCacheStatus()
|
||||||
toolbar.setAssetCacheUsageBytes(updatedStatus.usageBytes)
|
toolbar.setAssetCacheUsageBytes(updatedStatus.usageBytes)
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,11 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 10px;
|
gap: 12px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
min-height: 32px;
|
min-height: 32px;
|
||||||
|
|
@ -17,15 +19,21 @@
|
||||||
background: linear-gradient(180deg, #1b1712 0%, #0d0b08 100%);
|
background: linear-gradient(180deg, #1b1712 0%, #0d0b08 100%);
|
||||||
border-bottom: 1px solid #4a3c24;
|
border-bottom: 1px solid #4a3c24;
|
||||||
color: #d6c496;
|
color: #d6c496;
|
||||||
font-family: "Exocet", "Cinzel", "Noto Serif SC", "PingFang SC", Georgia, serif;
|
font-family: var(--font-display, "D2Exocet", "Cinzel", "Noto Serif SC", "PingFang SC", Georgia, serif);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.d2-toolbar__group {
|
.d2-toolbar__group {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
flex-shrink: 0;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,13 +82,12 @@ export interface ToolbarSnapshot {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persistent 32px Top DOM Toolbar (`#d2-toolbar`) with 6 primary controls:
|
* Persistent 32px Top DOM Toolbar (`#d2-toolbar`) with 5 primary controls:
|
||||||
* 1. Connection Status + RTT (`ms`) + Diagnostics (5-per-IP quota / WSS TLS error) + Inspector toggle
|
* 1. Connection Status + RTT (`ms`) + Diagnostics (5-per-IP quota / WSS TLS error) + Inspector toggle
|
||||||
* 2. Server Host Input (`www.laiseek.xyz` default, bare-IP over HTTPS guard, mid-game reconnect prompt)
|
* 2. Live Language Toggle (`中` / `EN`)
|
||||||
* 3. Live Language Toggle (`中` / `EN`)
|
* 3. Lighting Preset Selector (`auto | noon | dusk | night | torch | cold | fullbright`)
|
||||||
* 4. Lighting Preset Selector (`auto | noon | dusk | night | torch | cold | fullbright`)
|
* 4. Automap Reveal Selector (`off | level | act`)
|
||||||
* 5. Automap Reveal Selector (`off | level | act`)
|
* 5. Viewport Size Toggle (`800x600 | 1024x768`) + Asset Cache Clear button
|
||||||
* 6. Viewport Size Toggle (`800x600 | 1024x768`) + Asset Cache Clear button
|
|
||||||
*/
|
*/
|
||||||
export class Toolbar {
|
export class Toolbar {
|
||||||
private readonly store: SettingsStore
|
private readonly store: SettingsStore
|
||||||
|
|
@ -112,9 +111,6 @@ export class Toolbar {
|
||||||
private statusDotEl: HTMLElement | null = null
|
private statusDotEl: HTMLElement | null = null
|
||||||
private statusTextEl: HTMLElement | null = null
|
private statusTextEl: HTMLElement | null = null
|
||||||
private rttTextEl: HTMLElement | null = null
|
private rttTextEl: HTMLElement | null = null
|
||||||
private serverLabelEl: HTMLElement | null = null
|
|
||||||
private serverInputEl: HTMLInputElement | null = null
|
|
||||||
private serverApplyBtnEl: HTMLButtonElement | null = null
|
|
||||||
private langBtnZhEl: HTMLButtonElement | null = null
|
private langBtnZhEl: HTMLButtonElement | null = null
|
||||||
private langBtnEnEl: HTMLButtonElement | null = null
|
private langBtnEnEl: HTMLButtonElement | null = null
|
||||||
private lightingLabelEl: HTMLElement | null = null
|
private lightingLabelEl: HTMLElement | null = null
|
||||||
|
|
@ -395,8 +391,146 @@ export class Toolbar {
|
||||||
this.rootEl = null
|
this.rootEl = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ensureStyles(doc: Document): void {
|
||||||
|
if (!doc.head || doc.getElementById('d2-toolbar-styles')) return
|
||||||
|
const styleEl = doc.createElement('style')
|
||||||
|
styleEl.id = 'd2-toolbar-styles'
|
||||||
|
styleEl.textContent = `
|
||||||
|
#d2-toolbar,
|
||||||
|
.d2-toolbar {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1000;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
width: 100%;
|
||||||
|
height: 32px;
|
||||||
|
min-height: 32px;
|
||||||
|
max-height: 32px;
|
||||||
|
padding: 0 12px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: linear-gradient(180deg, #1b1712 0%, #0d0b08 100%);
|
||||||
|
border-bottom: 1px solid #4a3c24;
|
||||||
|
color: #d6c496;
|
||||||
|
font-family: var(--font-display, "D2Exocet", "Cinzel", "Noto Serif SC", "PingFang SC", Georgia, serif);
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.d2-toolbar__group {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
gap: 6px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.d2-toolbar__divider {
|
||||||
|
width: 1px;
|
||||||
|
height: 18px;
|
||||||
|
background: #3a2f1d;
|
||||||
|
}
|
||||||
|
.d2-toolbar__status {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 3px 8px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background: #14110d;
|
||||||
|
border: 1px solid #352b1b;
|
||||||
|
}
|
||||||
|
.d2-toolbar__status-dot {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
background: #6b6b6b;
|
||||||
|
box-shadow: 0 0 4px rgba(0, 0, 0, 0.8);
|
||||||
|
}
|
||||||
|
.d2-toolbar__status-dot--disconnected { background: #767676; }
|
||||||
|
.d2-toolbar__status-dot--connecting { background: #e6a822; box-shadow: 0 0 6px #e6a822; }
|
||||||
|
.d2-toolbar__status-dot--bncs { background: #4495e8; box-shadow: 0 0 6px #4495e8; }
|
||||||
|
.d2-toolbar__status-dot--mcp { background: #36c5d6; box-shadow: 0 0 6px #36c5d6; }
|
||||||
|
.d2-toolbar__status-dot--d2gs { background: #2ecc71; box-shadow: 0 0 6px #2ecc71; }
|
||||||
|
.d2-toolbar__status-dot--error { background: #e74c3c; box-shadow: 0 0 6px #e74c3c; }
|
||||||
|
.d2-toolbar__rtt {
|
||||||
|
font-family: "JetBrains Mono", "Consolas", monospace;
|
||||||
|
font-size: 11px;
|
||||||
|
color: #a89974;
|
||||||
|
}
|
||||||
|
.d2-toolbar__label {
|
||||||
|
color: #b59e68;
|
||||||
|
font-size: 11px;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
}
|
||||||
|
.d2-toolbar__select {
|
||||||
|
height: 22px;
|
||||||
|
padding: 0 6px;
|
||||||
|
background: #120f0b;
|
||||||
|
border: 1px solid #4a3c24;
|
||||||
|
border-radius: 2px;
|
||||||
|
color: #e2d1a0;
|
||||||
|
font-size: 11px;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.d2-toolbar__select:hover,
|
||||||
|
.d2-toolbar__btn:hover {
|
||||||
|
border-color: #c7b377;
|
||||||
|
color: #fff2c6;
|
||||||
|
}
|
||||||
|
.d2-toolbar__btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 22px;
|
||||||
|
padding: 0 8px;
|
||||||
|
background: linear-gradient(180deg, #2b2316 0%, #17120b 100%);
|
||||||
|
border: 1px solid #574629;
|
||||||
|
border-radius: 2px;
|
||||||
|
color: #dfc991;
|
||||||
|
font-size: 11px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.d2-toolbar__btn--active {
|
||||||
|
background: linear-gradient(180deg, #524020 0%, #2e2310 100%);
|
||||||
|
border-color: #d4b46a;
|
||||||
|
color: #fff5d6;
|
||||||
|
}
|
||||||
|
.d2-toolbar__diag {
|
||||||
|
position: absolute;
|
||||||
|
top: 32px;
|
||||||
|
left: 12px;
|
||||||
|
right: 12px;
|
||||||
|
z-index: 1001;
|
||||||
|
display: none;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 6px 10px;
|
||||||
|
background: rgba(38, 12, 10, 0.96);
|
||||||
|
border: 1px solid #a93226;
|
||||||
|
border-top: none;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
color: #ffd6d1;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.d2-toolbar__diag--visible {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
doc.head.appendChild(styleEl)
|
||||||
|
}
|
||||||
|
|
||||||
private mountDom(container: HTMLElement | null): void {
|
private mountDom(container: HTMLElement | null): void {
|
||||||
const doc = document
|
const doc = document
|
||||||
|
this.ensureStyles(doc)
|
||||||
const root = doc.createElement('header')
|
const root = doc.createElement('header')
|
||||||
root.id = 'd2-toolbar'
|
root.id = 'd2-toolbar'
|
||||||
root.className = 'd2-toolbar'
|
root.className = 'd2-toolbar'
|
||||||
|
|
@ -430,35 +564,7 @@ export class Toolbar {
|
||||||
statusGroup.appendChild(statusBadge)
|
statusGroup.appendChild(statusBadge)
|
||||||
statusGroup.appendChild(inspectorBtn)
|
statusGroup.appendChild(inspectorBtn)
|
||||||
|
|
||||||
// Group 2: Server Host Input
|
// Group 2: Language Toggle (中 / EN)
|
||||||
const serverGroup = doc.createElement('div')
|
|
||||||
serverGroup.className = 'd2-toolbar__group'
|
|
||||||
const serverLabel = doc.createElement('label')
|
|
||||||
serverLabel.className = 'd2-toolbar__label'
|
|
||||||
serverLabel.htmlFor = 'd2-toolbar-server-host'
|
|
||||||
const serverInput = doc.createElement('input')
|
|
||||||
serverInput.type = 'text'
|
|
||||||
serverInput.id = 'd2-toolbar-server-host'
|
|
||||||
serverInput.className = 'd2-toolbar__input'
|
|
||||||
serverInput.value = this.serverInputValue
|
|
||||||
serverInput.addEventListener('keydown', (ev) => {
|
|
||||||
if (ev.key === 'Enter') {
|
|
||||||
ev.preventDefault()
|
|
||||||
this.submitServerHost(serverInput.value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const serverApplyBtn = doc.createElement('button')
|
|
||||||
serverApplyBtn.type = 'button'
|
|
||||||
serverApplyBtn.id = 'd2-toolbar-server-apply'
|
|
||||||
serverApplyBtn.className = 'd2-toolbar__btn'
|
|
||||||
serverApplyBtn.addEventListener('click', () => {
|
|
||||||
this.submitServerHost(serverInput.value)
|
|
||||||
})
|
|
||||||
serverGroup.appendChild(serverLabel)
|
|
||||||
serverGroup.appendChild(serverInput)
|
|
||||||
serverGroup.appendChild(serverApplyBtn)
|
|
||||||
|
|
||||||
// Group 3: Language Toggle (中 / EN)
|
|
||||||
const langGroup = doc.createElement('div')
|
const langGroup = doc.createElement('div')
|
||||||
langGroup.className = 'd2-toolbar__group'
|
langGroup.className = 'd2-toolbar__group'
|
||||||
const langBtnZh = doc.createElement('button')
|
const langBtnZh = doc.createElement('button')
|
||||||
|
|
@ -478,7 +584,7 @@ export class Toolbar {
|
||||||
langGroup.appendChild(langBtnZh)
|
langGroup.appendChild(langBtnZh)
|
||||||
langGroup.appendChild(langBtnEn)
|
langGroup.appendChild(langBtnEn)
|
||||||
|
|
||||||
// Group 4: Lighting Selector
|
// Group 3: Lighting Selector
|
||||||
const lightingGroup = doc.createElement('div')
|
const lightingGroup = doc.createElement('div')
|
||||||
lightingGroup.className = 'd2-toolbar__group'
|
lightingGroup.className = 'd2-toolbar__group'
|
||||||
const lightingLabel = doc.createElement('label')
|
const lightingLabel = doc.createElement('label')
|
||||||
|
|
@ -493,7 +599,7 @@ export class Toolbar {
|
||||||
lightingGroup.appendChild(lightingLabel)
|
lightingGroup.appendChild(lightingLabel)
|
||||||
lightingGroup.appendChild(lightingSelect)
|
lightingGroup.appendChild(lightingSelect)
|
||||||
|
|
||||||
// Group 5: Automap Reveal Selector (Off / Level / Act)
|
// Group 4: Automap Reveal Selector (Off / Level / Act)
|
||||||
const automapGroup = doc.createElement('div')
|
const automapGroup = doc.createElement('div')
|
||||||
automapGroup.className = 'd2-toolbar__group'
|
automapGroup.className = 'd2-toolbar__group'
|
||||||
const automapLabel = doc.createElement('label')
|
const automapLabel = doc.createElement('label')
|
||||||
|
|
@ -508,7 +614,7 @@ export class Toolbar {
|
||||||
automapGroup.appendChild(automapLabel)
|
automapGroup.appendChild(automapLabel)
|
||||||
automapGroup.appendChild(automapSelect)
|
automapGroup.appendChild(automapSelect)
|
||||||
|
|
||||||
// Group 6: Viewport Size Selector (800x600 / 1024x768) + Asset Cache Clear button
|
// Group 5: Viewport Size Selector (800x600 / 1024x768) + Asset Cache Clear button
|
||||||
const viewportGroup = doc.createElement('div')
|
const viewportGroup = doc.createElement('div')
|
||||||
viewportGroup.className = 'd2-toolbar__group'
|
viewportGroup.className = 'd2-toolbar__group'
|
||||||
const viewportLabel = doc.createElement('label')
|
const viewportLabel = doc.createElement('label')
|
||||||
|
|
@ -545,7 +651,6 @@ export class Toolbar {
|
||||||
diagBanner.className = 'd2-toolbar__diag'
|
diagBanner.className = 'd2-toolbar__diag'
|
||||||
|
|
||||||
root.appendChild(statusGroup)
|
root.appendChild(statusGroup)
|
||||||
root.appendChild(serverGroup)
|
|
||||||
root.appendChild(langGroup)
|
root.appendChild(langGroup)
|
||||||
root.appendChild(lightingGroup)
|
root.appendChild(lightingGroup)
|
||||||
root.appendChild(automapGroup)
|
root.appendChild(automapGroup)
|
||||||
|
|
@ -560,9 +665,6 @@ export class Toolbar {
|
||||||
this.statusDotEl = dot
|
this.statusDotEl = dot
|
||||||
this.statusTextEl = statusText
|
this.statusTextEl = statusText
|
||||||
this.rttTextEl = rttText
|
this.rttTextEl = rttText
|
||||||
this.serverLabelEl = serverLabel
|
|
||||||
this.serverInputEl = serverInput
|
|
||||||
this.serverApplyBtnEl = serverApplyBtn
|
|
||||||
this.langBtnZhEl = langBtnZh
|
this.langBtnZhEl = langBtnZh
|
||||||
this.langBtnEnEl = langBtnEn
|
this.langBtnEnEl = langBtnEn
|
||||||
this.lightingLabelEl = lightingLabel
|
this.lightingLabelEl = lightingLabel
|
||||||
|
|
@ -598,21 +700,6 @@ export class Toolbar {
|
||||||
? 'd2-toolbar__btn d2-toolbar__btn--active'
|
? 'd2-toolbar__btn d2-toolbar__btn--active'
|
||||||
: 'd2-toolbar__btn'
|
: 'd2-toolbar__btn'
|
||||||
}
|
}
|
||||||
if (this.serverLabelEl) {
|
|
||||||
this.serverLabelEl.textContent = tToolbar('toolbar.server.label', lang)
|
|
||||||
}
|
|
||||||
if (this.serverInputEl) {
|
|
||||||
this.serverInputEl.placeholder = tToolbar('toolbar.server.placeholder', lang)
|
|
||||||
if (this.serverInputEl.value !== snap.serverInputValue) {
|
|
||||||
this.serverInputEl.value = snap.serverInputValue
|
|
||||||
}
|
|
||||||
this.serverInputEl.className = snap.serverInputValid
|
|
||||||
? 'd2-toolbar__input'
|
|
||||||
: 'd2-toolbar__input d2-toolbar__input--invalid'
|
|
||||||
}
|
|
||||||
if (this.serverApplyBtnEl) {
|
|
||||||
this.serverApplyBtnEl.textContent = tToolbar('toolbar.server.apply', lang)
|
|
||||||
}
|
|
||||||
if (this.langBtnZhEl) {
|
if (this.langBtnZhEl) {
|
||||||
this.langBtnZhEl.className =
|
this.langBtnZhEl.className =
|
||||||
lang === 'zh' ? 'd2-toolbar__btn d2-toolbar__btn--active' : 'd2-toolbar__btn'
|
lang === 'zh' ? 'd2-toolbar__btn d2-toolbar__btn--active' : 'd2-toolbar__btn'
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue