mirror of
https://github.com/smogon/pokemon-showdown-client.git
synced 2026-09-12 22:09:55 -05:00
Preact: Add avatar and status options (#2360)
This commit is contained in:
@@ -153,6 +153,7 @@ class UserPanel extends PSRoomPanel<UserRoom> {
|
||||
return [<div class="userdetails">
|
||||
{user.avatar !== '[loading]' &&
|
||||
<img
|
||||
{...(room.isSelf ? { 'data-href': 'avatars' } : {})}
|
||||
class={'trainersprite' + (room.isSelf ? ' yours' : '')}
|
||||
src={Dex.resolveAvatar(`${user.avatar || 'unknown'}`)}
|
||||
/>}
|
||||
@@ -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<HTMLInputElement>('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 <PSPanelWrapper room={room}><div class="pad">
|
||||
@@ -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}
|
||||
<strong>{PS.user.name}</strong>
|
||||
</p>
|
||||
<p>
|
||||
<button class="button" data-href="avatars"> Avatar..</button>
|
||||
</p>
|
||||
|
||||
{this.state.showStatusInput ? (
|
||||
<p>
|
||||
<input name="statustext"></input>
|
||||
<button class="button" onClick={this.editStatus}><i class="fa fa-pencil"></i></button>
|
||||
</p>
|
||||
) : (
|
||||
<p>
|
||||
<button class="button" onClick={this.handleShowStatusInput} disabled={this.state.showStatusUpdated}>
|
||||
{this.state.showStatusUpdated ? 'Status Updated' : 'Status..'}</button>
|
||||
</p>
|
||||
)}
|
||||
|
||||
<hr />
|
||||
<h3>Graphics</h3>
|
||||
<p>
|
||||
@@ -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 <PSPanelWrapper room={room} width={480}><div class="pad">
|
||||
<label class="optlabel"><strong>Choose an avatar or </strong>
|
||||
<button class="button" onClick={() => this.close()}> Cancel</button>
|
||||
</label>
|
||||
<div class="avatarlist">
|
||||
{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 (
|
||||
<button
|
||||
key={i}
|
||||
value={i}
|
||||
style={style}
|
||||
className={className}
|
||||
title={`/avatar ${i}`}
|
||||
onClick={this.handleAvatar}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
</div>
|
||||
<div style="clear:left"></div>
|
||||
<p><button class="button" data-cmd="/close">Cancel</button></p>
|
||||
</div></PSPanelWrapper>;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user