Skip to content

Commit eca0a69

Browse files
committed
Remove new-tab-result & add silent option to sim
1 parent d70df8a commit eca0a69

13 files changed

Lines changed: 137 additions & 239 deletions

File tree

makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ PAGE_INDECES := ui/death_knight/blood/index.html \
4040
ui/warrior/arms/index.html \
4141
ui/warrior/fury/index.html \
4242
ui/warrior/protection/index.html \
43-
ui/raid/full/index.html \
44-
ui/results/detailed/index.html
43+
ui/raid/full/index.html
4544

4645
$(OUT_DIR)/.dirstamp: \
4746
$(OUT_DIR)/lib.wasm \

ui/core/components/detailed_results.tsx

Lines changed: 95 additions & 182 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
import { ref } from 'tsx-vanilla';
2-
import { REPO_NAME } from '../constants/other';
3-
import { IndividualSimUI } from '../individual_sim_ui';
4-
import { DetailedResultsUpdate, SimRun, SimRunData } from '../proto/ui';
1+
import { SimRun, SimRunData } from '../proto/ui';
52
import { SimResult } from '../proto_utils/sim_result';
63
import { SimUI } from '../sim_ui';
74
import { TypedEvent } from '../typed_event';
8-
import { isDevMode } from '../utils';
95
import { Component } from './component';
106
import { AuraMetricsTable } from './detailed_results/aura_metrics';
117
import { CastMetricsTable } from './detailed_results/cast_metrics';
@@ -24,6 +20,9 @@ import { ToplineResults } from './detailed_results/topline_results';
2420
import { RaidSimResultsManager } from './raid_sim_action';
2521
import { StickyToolbar } from './sticky_toolbar';
2622
import i18n from '../../i18n/config';
23+
import { ref } from 'tsx-vanilla';
24+
import { isDevMode } from '../utils';
25+
import { IndividualSimUI } from '../individual_sim_ui';
2726

2827
type Tab = {
2928
isActive?: boolean;
@@ -75,24 +74,27 @@ const tabs: Tab[] = [
7574
},
7675
];
7776

78-
export abstract class DetailedResults extends Component {
79-
protected readonly simUI: SimUI | null;
77+
export class DetailedResults extends Component {
78+
protected readonly simUI: SimUI;
8079
protected latestRun: SimRunData | null = null;
81-
protected latestDeathSeeds: BigInt[] = [];
80+
protected latestDeathSeeds: bigint[] = [];
8281
protected recentlyEditedSeed: boolean = false;
8382

8483
private currentSimResult: SimResult | null = null;
8584
private resultsEmitter: TypedEvent<SimResultData | null> = new TypedEvent<SimResultData | null>();
8685
private resultsFilter: ResultsFilter;
87-
private rootDiv: HTMLElement;
86+
private rootDiv: Element;
8887

89-
constructor(parent: HTMLElement, simUI: SimUI | null, cssScheme: string) {
88+
constructor(parent: HTMLElement, simUI: SimUI, simResultsManager: RaidSimResultsManager) {
9089
super(parent, 'detailed-results-manager-root');
9190

92-
this.rootElem.appendChild(
91+
this.simUI = simUI;
92+
93+
this.rootDiv = (
9394
<div className="dr-root dr-no-results">
94-
<div className="dr-toolbar sticky-toolbar">
95+
<div className="dr-toolbar">
9596
<div className="results-filter"></div>
97+
<div className="tabs-filler"></div>
9698
<ul className="nav nav-tabs" attributes={{ role: 'tablist' }}>
9799
{tabs.map(({ label, targetId, isActive, classes }) => (
98100
<li className={`nav-item dr-tab-tab ${classes?.join(' ') || ''}`} attributes={{ role: 'presentation' }}>
@@ -183,12 +185,27 @@ export abstract class DetailedResults extends Component {
183185
</div>
184186
</div>
185187
</div>
186-
</div>,
188+
</div>
189+
);
190+
191+
const simButtonRef = ref<HTMLButtonElement>();
192+
const deathButtonRef = ref<HTMLButtonElement>();
193+
194+
this.rootElem.appendChild(
195+
<>
196+
<div className="detailed-results-controls-div">
197+
<button className="detailed-results-1-iteration-button btn btn-primary" ref={simButtonRef} disabled={simUI.disabled}>
198+
{i18n.t('results_tab.details.sim_1_iteration')}
199+
</button>
200+
<button className="detailed-results-death-iteration-button btn btn-primary" ref={deathButtonRef} disabled={true}>
201+
{i18n.t('results_tab.details.sim_1_death')}
202+
</button>
203+
</div>
204+
{this.rootDiv}
205+
</>,
187206
);
188-
this.rootDiv = this.rootElem.querySelector('.dr-root')!;
189-
this.simUI = simUI;
190207

191-
this.simUI?.sim.settingsChangeEmitter.on(async () => await this.updateSettings());
208+
this.simUI.sim.settingsChangeEmitter.on(() => this.updateSettings());
192209

193210
// Allow styling the sticky toolbar
194211
const toolbar = document.querySelector<HTMLElement>('.dr-toolbar')!;
@@ -256,7 +273,6 @@ export abstract class DetailedResults extends Component {
256273

257274
const timeline = new Timeline({
258275
parent: this.rootElem.querySelector('.timeline')!,
259-
cssScheme: cssScheme,
260276
resultsEmitter: this.resultsEmitter,
261277
secondaryResource: (simUI as IndividualSimUI<any>)?.player?.secondaryResource,
262278
});
@@ -268,13 +284,12 @@ export abstract class DetailedResults extends Component {
268284

269285
new LogRunner({
270286
parent: this.rootElem.querySelector('.log')!,
271-
cssScheme: cssScheme,
272287
resultsEmitter: this.resultsEmitter,
273288
});
274289

275-
this.rootElem.classList.add('hide-threat-metrics', 'hide-threat-metrics');
290+
this.rootElem.classList.add('hide-threat-metrics');
276291

277-
this.resultsFilter.changeEmitter.on(() => this.updateResults());
292+
this.resultsFilter.changeEmitter.on(async () => await this.updateResults(this.latestRun));
278293

279294
this.resultsEmitter.on((_, resultData) => {
280295
if (resultData?.filter.player || resultData?.filter.player === 0) {
@@ -285,12 +300,68 @@ export abstract class DetailedResults extends Component {
285300
this.rootDiv.classList.remove('single-player');
286301
}
287302
});
303+
304+
const simButton = simButtonRef.value!;
305+
simButton?.addEventListener('click', () => {
306+
this.simUI?.runSimOnce();
307+
});
308+
309+
const deathButton = deathButtonRef.value!;
310+
deathButton?.addEventListener('click', () => {
311+
if (this.latestDeathSeeds.length > 1) {
312+
this.simUI?.sim.setFixedRngSeed(TypedEvent.nextEventID(), Number(this.latestDeathSeeds.pop()));
313+
this.recentlyEditedSeed = true;
314+
315+
if (isDevMode()) {
316+
console.log('Setting fixed seed:');
317+
console.log(this.simUI?.sim.getFixedRngSeed());
318+
}
319+
}
320+
321+
this.simUI?.runSimOnce();
322+
});
323+
324+
simResultsManager.currentChangeEmitter.on(async () => {
325+
const runData = simResultsManager.getRunData();
326+
if (runData) {
327+
this.updateSettings();
328+
await this.updateResults(runData);
329+
}
330+
331+
deathButton.disabled = this.latestDeathSeeds.length < 2;
332+
});
288333
}
289334

290-
abstract postMessage(update: DetailedResultsUpdate): Promise<void>;
335+
private updateSettings() {
336+
const settings = this.simUI?.sim.toProto();
337+
if (!settings) return;
338+
339+
if (settings.showDamageMetrics) {
340+
this.rootElem.classList.remove('hide-damage-metrics');
341+
} else {
342+
this.rootElem.classList.add('hide-damage-metrics');
343+
const damageTabEl = document.getElementById('damageTab')!;
344+
const healingTabEl = document.getElementById('healingTab')!;
345+
if (damageTabEl.classList.contains('active')) {
346+
damageTabEl.classList.remove('active', 'show');
347+
healingTabEl.classList.add('active', 'show');
348+
349+
const toolbar = document.getElementsByClassName('dr-toolbar')[0] as HTMLElement;
350+
toolbar.querySelector('.damage-metrics')?.children[0].classList.remove('active');
351+
toolbar.querySelector('.healing-metrics')?.children[0].classList.add('active');
352+
}
353+
}
354+
this.rootElem.classList[settings.showThreatMetrics ? 'remove' : 'add']('hide-threat-metrics');
355+
this.rootElem.classList[settings.showHealingMetrics ? 'remove' : 'add']('hide-healing-metrics');
356+
this.rootElem.classList[settings.showExperimental ? 'remove' : 'add']('hide-experimental');
357+
}
358+
359+
private async updateResults(simRunData: SimRunData | null) {
360+
if (simRunData?.run?.request?.requestId !== this.latestRun?.run?.request?.requestId) {
361+
this.latestRun = simRunData;
362+
this.currentSimResult = await SimResult.fromProto(simRunData?.run || SimRun.create());
363+
}
291364

292-
protected async setSimRunData(simRunData: SimRunData) {
293-
this.latestRun = simRunData;
294365
const latestSimResult = this.latestRun?.run?.result;
295366
const playerMetrics = latestSimResult?.raidMetrics?.parties.map(party => party.players).flat();
296367

@@ -302,7 +373,7 @@ export abstract class DetailedResults extends Component {
302373
if (playerMetrics?.length) {
303374
const deathSeeds = playerMetrics[0].deathSeeds;
304375

305-
if (isDevMode() && deathSeeds.length > 0) {
376+
if (isDevMode() && !!deathSeeds.length) {
306377
console.log('Found death seeds:');
307378
console.log(deathSeeds);
308379
}
@@ -312,35 +383,6 @@ export abstract class DetailedResults extends Component {
312383
}
313384
}
314385

315-
await this.postMessage(
316-
DetailedResultsUpdate.create({
317-
data: {
318-
oneofKind: 'runData',
319-
runData: simRunData,
320-
},
321-
}),
322-
);
323-
}
324-
325-
protected async updateSettings() {
326-
if (!this.simUI) return;
327-
328-
if (this.recentlyEditedSeed) {
329-
this.simUI.sim.setFixedRngSeed(TypedEvent.nextEventID(), 0);
330-
this.recentlyEditedSeed = false;
331-
}
332-
333-
await this.postMessage(
334-
DetailedResultsUpdate.create({
335-
data: {
336-
oneofKind: 'settings',
337-
settings: this.simUI.sim.toProto(),
338-
},
339-
}),
340-
);
341-
}
342-
343-
private updateResults() {
344386
const eventID = TypedEvent.nextEventID();
345387
if (this.currentSimResult == null) {
346388
this.rootDiv.classList.add('dr-no-results');
@@ -354,133 +396,4 @@ export abstract class DetailedResults extends Component {
354396
});
355397
}
356398
}
357-
358-
protected async handleMessage(data: DetailedResultsUpdate) {
359-
switch (data.data.oneofKind) {
360-
case 'runData':
361-
const runData = data.data.runData;
362-
this.currentSimResult = await SimResult.fromProto(runData.run || SimRun.create());
363-
this.updateResults();
364-
break;
365-
case 'settings':
366-
const settings = data.data.settings;
367-
if (settings.showDamageMetrics) {
368-
this.rootElem.classList.remove('hide-damage-metrics');
369-
} else {
370-
this.rootElem.classList.add('hide-damage-metrics');
371-
const damageTabEl = document.getElementById('damageTab')!;
372-
const healingTabEl = document.getElementById('healingTab')!;
373-
if (damageTabEl.classList.contains('active')) {
374-
damageTabEl.classList.remove('active', 'show');
375-
healingTabEl.classList.add('active', 'show');
376-
377-
const toolbar = document.getElementsByClassName('dr-toolbar')[0] as HTMLElement;
378-
toolbar.querySelector('.damage-metrics')?.children[0].classList.remove('active');
379-
toolbar.querySelector('.healing-metrics')?.children[0].classList.add('active');
380-
}
381-
}
382-
this.rootElem.classList[settings.showThreatMetrics ? 'remove' : 'add']('hide-threat-metrics');
383-
this.rootElem.classList[settings.showHealingMetrics ? 'remove' : 'add']('hide-healing-metrics');
384-
this.rootElem.classList[settings.showExperimental ? 'remove' : 'add']('hide-experimental');
385-
break;
386-
}
387-
}
388-
}
389-
390-
export class WindowedDetailedResults extends DetailedResults {
391-
constructor(parent: HTMLElement) {
392-
super(parent, null, new URLSearchParams(window.location.search).get('cssScheme') ?? '');
393-
394-
window.addEventListener('message', async event => await this.handleMessage(DetailedResultsUpdate.fromJson(event.data)));
395-
396-
this.rootElem.insertAdjacentHTML('beforeend', `<div class="sim-bg"></div>`);
397-
}
398-
399-
async postMessage(update: DetailedResultsUpdate): Promise<void> {
400-
await this.handleMessage(update);
401-
}
402-
}
403-
404-
export class EmbeddedDetailedResults extends DetailedResults {
405-
private tabWindow: Window | null = null;
406-
407-
constructor(parent: HTMLElement, simUI: SimUI, simResultsManager: RaidSimResultsManager) {
408-
super(parent, simUI, simUI.config.cssScheme);
409-
410-
const newTabButtonRef = ref<HTMLButtonElement>();
411-
const simButtonRef = ref<HTMLButtonElement>();
412-
const deathButtonRef = ref<HTMLButtonElement>();
413-
414-
this.rootElem.prepend(
415-
<div className="detailed-results-controls-div">
416-
<button className="detailed-results-new-tab-button btn btn-primary" ref={newTabButtonRef} disabled={simUI.disabled}>
417-
{i18n.t('results_tab.details.view_in_separate_tab')}
418-
</button>
419-
<button className="detailed-results-1-iteration-button btn btn-primary" ref={simButtonRef} disabled={simUI.disabled}>
420-
{i18n.t('results_tab.details.sim_1_iteration')}
421-
</button>
422-
<button className="detailed-results-death-iteration-button btn btn-primary" ref={deathButtonRef} disabled={true}>
423-
{i18n.t('results_tab.details.sim_1_death')}
424-
</button>
425-
</div>,
426-
);
427-
428-
const url = new URL(`${window.location.protocol}//${window.location.host}/${REPO_NAME}/results/detailed/index.html`);
429-
url.searchParams.append('cssClass', simUI.config.cssClass);
430-
431-
if (simUI.isIndividualSim()) {
432-
url.searchParams.append('isIndividualSim', '');
433-
this.rootElem.classList.add('individual-sim');
434-
}
435-
436-
const newTabButton = newTabButtonRef.value!;
437-
newTabButton?.addEventListener('click', () => {
438-
if (this.tabWindow == null || this.tabWindow.closed) {
439-
this.tabWindow = window.open(url.href, 'Detailed Results');
440-
this.tabWindow!.addEventListener('load', async () => {
441-
if (this.latestRun) {
442-
await Promise.all([this.updateSettings(), this.setSimRunData(this.latestRun)]);
443-
}
444-
});
445-
} else {
446-
this.tabWindow.focus();
447-
}
448-
});
449-
450-
const simButton = simButtonRef.value!;
451-
simButton?.addEventListener('click', () => {
452-
(window.opener || window.parent)!.postMessage('runOnce', '*');
453-
});
454-
455-
const deathButton = deathButtonRef.value!;
456-
deathButton?.addEventListener('click', () => {
457-
if (this.latestDeathSeeds.length > 1) {
458-
this.simUI?.sim.setFixedRngSeed(TypedEvent.nextEventID(), Number(this.latestDeathSeeds.pop()));
459-
this.recentlyEditedSeed = true;
460-
461-
if (isDevMode()) {
462-
console.log('Setting fixed seed:');
463-
console.log(this.simUI?.sim.getFixedRngSeed());
464-
}
465-
}
466-
467-
(window.opener || window.parent)!.postMessage('runOnce', '*');
468-
});
469-
470-
simResultsManager.currentChangeEmitter.on(async () => {
471-
const runData = simResultsManager.getRunData();
472-
if (runData) {
473-
await Promise.all([this.updateSettings(), this.setSimRunData(runData)]);
474-
}
475-
476-
deathButton.disabled = this.latestDeathSeeds.length < 2;
477-
});
478-
}
479-
480-
async postMessage(update: DetailedResultsUpdate) {
481-
if (this.tabWindow) {
482-
this.tabWindow.postMessage(DetailedResultsUpdate.toJson(update), '*');
483-
}
484-
await this.handleMessage(update);
485-
}
486399
}

ui/core/components/detailed_results/result_component.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ export interface SimResultData {
1111
export interface ResultComponentConfig {
1212
parent: HTMLElement;
1313
rootCssClass?: string;
14-
cssScheme?: string | null;
1514
resultsEmitter: TypedEvent<SimResultData | null>;
1615
}
1716

ui/core/components/detailed_results/topline_results.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export class ToplineResults extends ResultComponent {
1717
onSimResult(resultData: SimResultData) {
1818
const noManaClasses = [DeathKnight, Rogue, Warrior, Hunter];
1919
const players = resultData.result.getRaidIndexedPlayers(resultData.filter);
20+
2021
const content = RaidSimResultsManager.makeToplineResultsContent(resultData.result, resultData.filter, {
2122
showOutOfMana: players.length === 1 && !!players[0].spec && !noManaClasses.some(klass => PlayerSpecs.getPlayerClass(players[0].spec!) === klass),
2223
});

0 commit comments

Comments
 (0)