From 2e50c0aad7b63a2adbba9ec82c4ab6fa9258df1d Mon Sep 17 00:00:00 2001 From: Aurastic <33085835+ISenseAura@users.noreply.github.com> Date: Tue, 15 Apr 2025 13:43:03 +0530 Subject: [PATCH] Preact: Add avatar and status options (#2360) --- play.pokemonshowdown.com/src/panel-popups.tsx | 99 ++++++++++++++++++- 1 file changed, 97 insertions(+), 2 deletions(-) diff --git a/play.pokemonshowdown.com/src/panel-popups.tsx b/play.pokemonshowdown.com/src/panel-popups.tsx index 8620bfa07..a21b48892 100644 --- a/play.pokemonshowdown.com/src/panel-popups.tsx +++ b/play.pokemonshowdown.com/src/panel-popups.tsx @@ -153,6 +153,7 @@ class UserPanel extends PSRoomPanel { return [
{user.avatar !== '[loading]' && } @@ -279,6 +280,7 @@ class OptionsPanel extends PSRoomPanel { static readonly id = 'options'; static readonly routes = ['options']; static readonly location = 'popup'; + declare state: { showStatusInput?: boolean, showStatusUpdated?: boolean }; setTheme = (e: Event) => { const theme = (e.currentTarget as HTMLSelectElement).value as 'light' | 'dark' | 'system'; @@ -300,6 +302,21 @@ class OptionsPanel extends PSRoomPanel { } PS.update(); }; + + handleShowStatusInput = (ev: Event) => { + ev.preventDefault(); + ev.stopImmediatePropagation(); + this.setState({ showStatusInput: !this.state.showStatusInput }); + }; + + editStatus = (ev: Event) => { + const statusInput = this.base!.querySelector('input[name=statustext]'); + PS.send(statusInput?.value?.length ? `|/status ${statusInput.value}` : `|/clearstatus`); + this.setState({ showStatusUpdated: true, showStatusInput: false }); + ev.preventDefault(); + ev.stopImmediatePropagation(); + }; + override render() { const room = this.props.room; return
@@ -308,8 +325,24 @@ class OptionsPanel extends PSRoomPanel { class="trainersprite yours" width="40" height="40" style={{ verticalAlign: 'middle' }} src={Dex.resolveAvatar(`${PS.user.avatar}`)} /> {} - {PS.user.name} + {PS.user.name}

+

+ +

+ + {this.state.showStatusInput ? ( +

+ + +

+ ) : ( +

+ +

+ )} +

Graphics

@@ -490,6 +523,68 @@ class LoginPanel extends PSRoomPanel { } } +class AvatarsPanel extends PSRoomPanel { + static readonly id = 'avatars'; + static readonly routes = ['avatars']; + static readonly location = 'semimodal-popup'; + + handleAvatar = (ev: Event) => { + let curtarget = ev.currentTarget as HTMLButtonElement; + let avatar = curtarget.value; + if (window.BattleAvatarNumbers) { + if (window.BattleAvatarNumbers[avatar]) avatar = window.BattleAvatarNumbers[avatar]; + } + PS.rooms['']?.send('/avatar ' + avatar); + PS.user.avatar = avatar; + ev.preventDefault(); + this.close(); + }; + + update = () => { + this.forceUpdate(); + }; + + override render() { + const room = this.props.room; + let avatars: number[] = []; + let cur = Number(PS.user.avatar); + + for (let i = 1; i <= 293; i++) { + if (i === 162 || i === 168) continue; + avatars.push(i); + } + + return

+ +
+ {avatars.map(i => { + const offset = `-${((i - 1) % 16) * 80 + 1}px -${Math.floor((i - 1) / 16) * 80 + 1}px`; + const style = { + backgroundPosition: offset, + }; + const className = `option pixelated${i === cur ? ' cur' : ''}`; + + return ( +
+
+

+
; + } +} + class PopupPanel extends PSRoomPanel { static readonly id = 'popup'; static readonly routes = ['popup-*']; @@ -511,4 +606,4 @@ class PopupPanel extends PSRoomPanel { } } -PS.addRoomType(UserPanel, VolumePanel, OptionsPanel, LoginPanel, PopupPanel); +PS.addRoomType(UserPanel, VolumePanel, OptionsPanel, LoginPanel, AvatarsPanel, PopupPanel);