mirror of
https://github.com/smogon/pokemon-showdown-client.git
synced 2026-03-21 09:35:44 -05:00
Preact: Support smogon sets in teambuilder (#2466)
--------- Co-authored-by: Guangcong Luo <guangcongluo@gmail.com>
This commit is contained in:
parent
fca55b15bc
commit
a3ecfed7e3
|
|
@ -332,7 +332,8 @@ export const defaultRulesES3 = {
|
|||
"no-invalid-this": "error",
|
||||
"no-new-wrappers": "error",
|
||||
// Map/Set can be polyfilled but it's nontrivial and it's easier just to use bare objects
|
||||
"no-restricted-globals": ["error", "Proxy", "Reflect", "Symbol", "WeakSet", "WeakMap", "Set", "Map"],
|
||||
// fetch can be polyfilled, but our standard is to use $.get or Net as appropriate.
|
||||
"no-restricted-globals": ["error", "Proxy", "Reflect", "Symbol", "WeakSet", "WeakMap", "Set", "Map", "fetch"],
|
||||
"unicode-bom": "error",
|
||||
};
|
||||
|
||||
|
|
@ -345,7 +346,9 @@ export const defaultRulesES3 = {
|
|||
export const defaultRulesES3TSChecked = {
|
||||
...defaultRulesTSChecked,
|
||||
"radix": "off",
|
||||
"no-restricted-globals": ["error", "Proxy", "Reflect", "Symbol", "WeakSet", "WeakMap", "Set", "Map"],
|
||||
// Map/Set can be polyfilled but it's nontrivial and it's easier just to use bare objects
|
||||
// fetch can be polyfilled, but our standard is to use $.get or Net as appropriate.
|
||||
"no-restricted-globals": ["error", "Proxy", "Reflect", "Symbol", "WeakSet", "WeakMap", "Set", "Map", "fetch"],
|
||||
"no-restricted-syntax": ["error", "YieldExpression", "AwaitExpression", "BigIntLiteral"],
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import preact from "../js/lib/preact";
|
||||
import { type Team } from "./client-main";
|
||||
import { type Team, Config } from "./client-main";
|
||||
import { PSTeambuilder } from "./panel-teamdropdown";
|
||||
import { Dex, type ModdedDex, toID, type ID, PSUtils } from "./battle-dex";
|
||||
import { Teams } from './battle-teams';
|
||||
|
|
@ -20,6 +20,13 @@ import { Net } from "./client-connection";
|
|||
|
||||
type SelectionType = 'pokemon' | 'ability' | 'item' | 'move' | 'stats' | 'details';
|
||||
|
||||
type SampleSets = {
|
||||
[speciesName: string]: {
|
||||
[setName: string]: Dex.PokemonSet,
|
||||
},
|
||||
};
|
||||
type SampleSetsTable = { dex?: SampleSets, stats?: SampleSets };
|
||||
|
||||
class TeamEditorState extends PSModel {
|
||||
team: Team;
|
||||
sets: Dex.PokemonSet[] = [];
|
||||
|
|
@ -135,6 +142,7 @@ class TeamEditorState extends PSModel {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (type === 'item') (this.search.prependResults ||= []).push(['item', '' as ID]);
|
||||
this.search.find(value || '');
|
||||
this.searchIndex = this.search.results?.[0]?.[0] === 'header' ? 1 : 0;
|
||||
|
|
@ -624,6 +632,49 @@ class TeamEditorState extends PSModel {
|
|||
this.team.packedTeam = Teams.pack(this.sets);
|
||||
this.team.iconCache = null;
|
||||
}
|
||||
|
||||
/** undefined: loading, null: unavailable */
|
||||
static sampleSets: { [formatid: string]: SampleSetsTable | null } = {};
|
||||
// not static for complicated reasons. either way leads to an obscure
|
||||
// race condition if fetchSampleSets is called simultaneously from
|
||||
// different TeamEditorState instances, but this way just means two
|
||||
// network requests rather than the UI getting out of sync.
|
||||
_sampleSetPromises: Record<string, Promise<void>> = {};
|
||||
fetchSampleSets(formatid: ID) {
|
||||
if (formatid in TeamEditorState.sampleSets) return;
|
||||
if (formatid.length <= 4) {
|
||||
TeamEditorState.sampleSets[formatid] = null;
|
||||
return;
|
||||
}
|
||||
if (!(formatid in this._sampleSetPromises)) {
|
||||
this._sampleSetPromises[formatid] = Net(
|
||||
`https://${Config.routes.client}/data/sets/${formatid}.json`
|
||||
).get().then(json => {
|
||||
const data = JSON.parse(json);
|
||||
TeamEditorState.sampleSets[formatid] = data;
|
||||
this.update();
|
||||
}).catch(() => {
|
||||
TeamEditorState.sampleSets[formatid] = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
/** returns null if sample sets aren't done loading */
|
||||
getSampleSets(set: Dex.PokemonSet): string[] | null {
|
||||
const d = TeamEditorState.sampleSets[this.format];
|
||||
if (d === undefined) {
|
||||
this.fetchSampleSets(this.format);
|
||||
return null;
|
||||
}
|
||||
if (!d?.dex) return [];
|
||||
const speciesid = toID(set.species);
|
||||
const all = {
|
||||
...d.dex[set.species],
|
||||
...d.dex[speciesid],
|
||||
...d.stats?.[set.species],
|
||||
...d.stats?.[speciesid],
|
||||
};
|
||||
return Object.keys(all);
|
||||
}
|
||||
}
|
||||
|
||||
export class TeamEditor extends preact.Component<{
|
||||
|
|
@ -691,7 +742,12 @@ export class TeamEditor extends preact.Component<{
|
|||
this.forceUpdate();
|
||||
};
|
||||
override render() {
|
||||
this.editor ||= new TeamEditorState(this.props.team);
|
||||
if (!this.editor) {
|
||||
this.editor = new TeamEditorState(this.props.team);
|
||||
this.editor.subscribe(() => {
|
||||
this.forceUpdate();
|
||||
});
|
||||
}
|
||||
const editor = this.editor;
|
||||
window.editor = editor; // debug
|
||||
editor.setReadonly(!!this.props.readOnly);
|
||||
|
|
@ -1833,6 +1889,25 @@ class TeamWizard extends preact.Component<{
|
|||
this.forceUpdate();
|
||||
}
|
||||
};
|
||||
loadSampleSet = (setName: string) => {
|
||||
const { editor } = this.props;
|
||||
const setIndex = editor.innerFocus!.setIndex;
|
||||
const set = editor.sets[setIndex];
|
||||
if (!set?.species) return;
|
||||
|
||||
const data = TeamEditorState.sampleSets?.[editor.format];
|
||||
const sid = toID(set.species);
|
||||
const setTemplate = data?.dex?.[set.species]?.[setName] ?? data?.dex?.[sid]?.[setName] ??
|
||||
data?.stats?.[set.species]?.[setName] ?? data?.stats?.[sid]?.[setName];
|
||||
if (!setTemplate) return;
|
||||
|
||||
const applied: Partial<Dex.PokemonSet> = JSON.parse(JSON.stringify(setTemplate));
|
||||
Object.assign(set, applied);
|
||||
|
||||
editor.save();
|
||||
this.props.onUpdate?.();
|
||||
this.forceUpdate();
|
||||
};
|
||||
updateSearch = (ev: Event) => {
|
||||
const searchBox = ev.currentTarget as HTMLInputElement;
|
||||
this.props.editor.setSearchValue(searchBox.value);
|
||||
|
|
@ -1967,6 +2042,7 @@ class TeamWizard extends preact.Component<{
|
|||
const { type, setIndex } = editor.innerFocus;
|
||||
const set = this.props.editor.sets[setIndex] as Dex.PokemonSet | undefined;
|
||||
const cur = (i: number) => setIndex === i ? ' cur' : '';
|
||||
const sampleSets = type === 'ability' ? editor.getSampleSets(set!) : [];
|
||||
return <div class="team-focus-editor">
|
||||
<ul class="tabbar">
|
||||
<li class="home-li"><button class="button" onClick={this.setFocus}>
|
||||
|
|
@ -1998,10 +2074,28 @@ class TeamWizard extends preact.Component<{
|
|||
/>
|
||||
{PSSearchResults.renderFilters(editor.search)}
|
||||
</div>
|
||||
<div class="wizardsearchresults" onScroll={this.scrollResults}><PSSearchResults
|
||||
search={editor.search} hideFilters resultIndex={editor.searchIndex}
|
||||
onSelect={this.selectResult} windowing={this.windowResults()}
|
||||
/></div>
|
||||
<div class="wizardsearchresults" onScroll={this.scrollResults}>
|
||||
<PSSearchResults
|
||||
search={editor.search} hideFilters resultIndex={editor.searchIndex}
|
||||
onSelect={this.selectResult} windowing={this.windowResults()}
|
||||
/>
|
||||
{sampleSets?.length !== 0 && (
|
||||
<div class="sample-sets">
|
||||
<h3>Sample sets</h3>
|
||||
{sampleSets ? (
|
||||
<div>
|
||||
{sampleSets.map(setName => <>
|
||||
<button class="button" onClick={() => this.loadSampleSet(setName)}>
|
||||
{setName}
|
||||
</button> {}
|
||||
</>)}
|
||||
</div>
|
||||
) : (
|
||||
<div>Loading...</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>;
|
||||
|
|
|
|||
|
|
@ -727,3 +727,13 @@ you can't delete it by pressing Backspace */
|
|||
.wizardsearchresults .dexlist, .searchresults .dexlist {
|
||||
min-width: 624px;
|
||||
}
|
||||
|
||||
.sample-sets {
|
||||
border: 1px solid #888;
|
||||
border-radius: 6px;
|
||||
margin: 5px 15px 12px 15px;
|
||||
padding: 12px;
|
||||
}
|
||||
.sample-sets h3 {
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user