diff --git a/play.pokemonshowdown.com/src/battle-animations.ts b/play.pokemonshowdown.com/src/battle-animations.ts index c7c416e47..9ed8a19a2 100644 --- a/play.pokemonshowdown.com/src/battle-animations.ts +++ b/play.pokemonshowdown.com/src/battle-animations.ts @@ -740,9 +740,10 @@ export class BattleScene implements BattleSceneStub { } badgehtml += ''; } + const avatar = Dex.resolveAvatar(side.avatar); return ( `
?
+ .replace(/\n/g, '') // Firefox bug: just adds random newlines for fun apparently???
.replace(new RegExp(`?(?:${HTML_BLOCK_TAGS.join('|')})\\b[^>]*>`, 'gi'), '\n')
.replace(/\n{2,}/g, '\n')
.replace(/
]*>\n?/gi, '\n')
diff --git a/play.pokemonshowdown.com/src/panel-battle.tsx b/play.pokemonshowdown.com/src/panel-battle.tsx
index bcf3eac56..86aeb6cae 100644
--- a/play.pokemonshowdown.com/src/panel-battle.tsx
+++ b/play.pokemonshowdown.com/src/panel-battle.tsx
@@ -157,14 +157,15 @@ export class BattleRoom extends ChatRoom {
overlayActive: 'move' | 'switch' | null = null;
override interruptClose(explicit?: boolean, elem?: HTMLElement | null) {
- const battle = this.battle;
- const activeBattle = battle && !battle.ended && this.request && this.connectMode !== 'deleted';
- if (activeBattle || this.requireForfeit) {
+ if (this.isPlaying() || this.requireForfeit) {
PS.join('forfeitbattle' as RoomID, { parentElem: elem, parentRoomid: this.id });
return `You are still in ${this.title}`;
}
return super.interruptClose(explicit, elem);
}
+ isPlaying() {
+ return this.battle && !this.battle.ended && this.request && this.connectMode !== 'deleted';
+ }
override handleReconnect(): boolean | void {
if (this.battle) {
@@ -1172,9 +1173,7 @@ class BattlePanel extends PSRoomPanel {
return
{this.renderOldChoices(request, choices)}
-
-
- {choices.noCancel || room.battle.hardcoreMode ?
+ Waiting for opponent... {choices.noCancel || room.battle.hardcoreMode ?
null : }
{this.renderTeamList()}
diff --git a/play.pokemonshowdown.com/src/panel-chat.tsx b/play.pokemonshowdown.com/src/panel-chat.tsx
index 348257810..e9a736a14 100644
--- a/play.pokemonshowdown.com/src/panel-chat.tsx
+++ b/play.pokemonshowdown.com/src/panel-chat.tsx
@@ -281,12 +281,15 @@ export class ChatRoom extends PSRoom {
this.highlightRegExp[i] = new RegExp('(?:\\b|(?!\\w))(?:' + highlights[i].join('|') + ')(?:\\b|(?!\\w))', 'i');
}
}
- static isHighlightableChatMessage(message: string) {
+ static isHighlightableChatMessage(message: string, isDM = false) {
if (!message.startsWith('/')) return true;
const [cmd] = PSUtils.splitFirst(message.slice(1), ' ');
if (['raw', 'nonotify', 'text', 'error'].includes(cmd)) {
return false;
}
+ if (['uhtml', 'uhtmlchange'].includes(cmd)) {
+ return isDM;
+ }
if (cmd === 'subtlenotify') {
return 'subtle';
}
@@ -332,7 +335,8 @@ export class ChatRoom extends PSRoom {
if (!message) return false;
if (userid === PS.user.userid) return false;
- const highlightType = ChatRoom.isHighlightableChatMessage(message);
+ const isDM = this.id.startsWith("dm-");
+ const highlightType = ChatRoom.isHighlightableChatMessage(message, isDM);
const isIgnored = PS.prefs.ignore?.[userid];
if (isIgnored || !highlightType) return false;
if (highlightType === 'subtle') {
@@ -340,7 +344,7 @@ export class ChatRoom extends PSRoom {
return false;
}
- if (this.id.startsWith("dm-")) {
+ if (isDM) {
this.notify({
title: `${this.title}`,
body: this.getChatNotificationBody(message),
@@ -1630,8 +1634,8 @@ export class PSTextarea extends preact.Component<{
const textboxTest = this.base!.querySelector('textarea.heighttester')!;
textboxTest.style.width = `${textbox.offsetWidth}px`;
textboxTest.value = textbox.value;
- const newHeight = Math.max(textboxTest.scrollHeight + 40, 50);
- textbox.style.height = `${newHeight}px`;
+ // +2 for the borders
+ textbox.style.height = `${textboxTest.scrollHeight + 2}px`;
};
handleInput = (e: Event) => {
if (this.props.singleLine) {
@@ -1673,7 +1677,7 @@ export class PSTextarea extends preact.Component<{
/>
{!this.cssAutosize && }
;
}
diff --git a/play.pokemonshowdown.com/src/panel-mainmenu.tsx b/play.pokemonshowdown.com/src/panel-mainmenu.tsx
index a567f1ff0..f7ff7f5ae 100644
--- a/play.pokemonshowdown.com/src/panel-mainmenu.tsx
+++ b/play.pokemonshowdown.com/src/panel-mainmenu.tsx
@@ -414,10 +414,6 @@ export class MainMenuRoom extends PSRoom {
case 'userdetails':
let userid = response.userid;
fullid += ` ${userid}`;
- if (userid === PS.user.userid && response.avatar !== undefined) {
- PS.user.avatar = `${response.avatar}`;
- PS.user.update(null);
- }
let userdetails = this.userdetailsCache[userid];
if (!userdetails) {
this.userdetailsCache[userid] = response;
@@ -425,6 +421,12 @@ export class MainMenuRoom extends PSRoom {
response.status ||= '';
Object.assign(userdetails, response);
}
+ if (userid === PS.user.userid) {
+ if (response.avatar !== undefined && PS.user.avatar !== `${response.avatar}`) {
+ PS.user.avatar = `${response.avatar}`;
+ PS.user.update(null);
+ }
+ }
PS.rooms[`user-${userid}`]?.update(null);
PS.rooms[`viewuser-${userid}`]?.update(null);
PS.rooms[`users`]?.update(null);
diff --git a/play.pokemonshowdown.com/src/panel-popups.tsx b/play.pokemonshowdown.com/src/panel-popups.tsx
index eb0a582d4..94f292752 100644
--- a/play.pokemonshowdown.com/src/panel-popups.tsx
+++ b/play.pokemonshowdown.com/src/panel-popups.tsx
@@ -49,9 +49,6 @@ export class UserRoom extends PSRoom {
export class StatusEditor extends preact.Component {
declare state: { addingStatus?: boolean, statusChanged?: boolean };
- override componentDidMount() {
- this.fetchStatus();
- }
fetchStatus() {
if (!PS.user.userid) return;
PS.mainmenu.makeQuery('userdetails', PS.user.userid).then(() => this.forceUpdate());
@@ -680,6 +677,7 @@ class OptionsPanel extends PSRoomPanel {
override componentDidMount() {
super.componentDidMount();
this.subscribeTo(PS.user);
+ PS.mainmenu.makeQuery('userdetails', PS.user.userid).then(() => this.forceUpdate());
}
setTheme = (e: Event) => {
const theme = (e.currentTarget as HTMLSelectElement).value as 'light' | 'dark' | 'system';
@@ -1724,8 +1722,8 @@ class BattleOptionsPanel extends PSRoomPanel {
override render() {
const room = this.props.room;
const battleRoom = this.getBattleRoom();
- const isPlayer = !!battleRoom?.battle.myPokemon;
- const canOfferTie = battleRoom && ((battleRoom.battle.turn >= 100 && isPlayer) || PS.user.group === '~');
+ const isPlaying = !!battleRoom?.isPlaying();
+ const canOfferTie = battleRoom && ((battleRoom.battle.turn >= 100 && isPlaying) || PS.user.group === '~');
const sideBySideDisabled = !!battleRoom && battleRoom.width < 500;
let automaticLayout: BattleLayoutPreference | null = null;
if (battleRoom) {
@@ -1735,6 +1733,14 @@ class BattleOptionsPanel extends PSRoomPanel {
return
{battleRoom && <>
In this battle
+
@@ -1863,9 +1869,6 @@ class BattleOptionsPanel extends PSRoomPanel {
}
;
diff --git a/play.pokemonshowdown.com/src/panel-topbar.tsx b/play.pokemonshowdown.com/src/panel-topbar.tsx
index 1610ccef9..98732876c 100644
--- a/play.pokemonshowdown.com/src/panel-topbar.tsx
+++ b/play.pokemonshowdown.com/src/panel-topbar.tsx
@@ -15,6 +15,7 @@ import {
} from "./client-main";
import { PSView } from "./panels";
import type { Battle } from "./battle";
+import { Dex } from "./battle-dex";
import { BattleLog } from "./battle-log"; // optional
window.addEventListener('dragover', e => {
@@ -23,6 +24,16 @@ window.addEventListener('dragover', e => {
});
export class PSHeader extends preact.Component {
+ faviconNotifying = false;
+ updateFavicon = () => {
+ const notifying = Object.values(PS.rooms).some(room => room?.notifications.length);
+ if (notifying === this.faviconNotifying) return;
+
+ const favicon = document.querySelector('#dynamic-favicon');
+ if (!favicon) return;
+ favicon.href = `${Dex.resourcePrefix}${notifying ? 'favicon-notify.ico' : 'favicon.ico'}`;
+ this.faviconNotifying = notifying;
+ };
static toggleMute = (e: Event) => {
PS.prefs.set('mute', !PS.prefs.mute);
PS.update();
@@ -205,9 +216,11 @@ export class PSHeader extends preact.Component {
});
window.addEventListener('resize', this.handleResize);
this.handleResize();
+ this.updateFavicon();
}
override componentDidUpdate() {
this.handleResize();
+ this.updateFavicon();
}
renderUser() {
if (!PS.connection?.connected) {
diff --git a/play.pokemonshowdown.com/style/battle-log.css b/play.pokemonshowdown.com/style/battle-log.css
index 0c3cbb6ba..020807797 100644
--- a/play.pokemonshowdown.com/style/battle-log.css
+++ b/play.pokemonshowdown.com/style/battle-log.css
@@ -177,7 +177,9 @@ select.base-select::picker-icon {
}
.button option,
-.button optgroup {
+.button optgroup,
+.select option,
+.select optgroup {
background: #f6f6f6;
color: #222222;
}
@@ -283,7 +285,9 @@ select.base-select::picker-icon {
box-shadow: 0.5px 1px 2px rgba(255, 255, 255, 0.45);
}
.dark .button option,
-.dark .button optgroup {
+.dark .button optgroup,
+.dark .select option,
+.dark .select optgroup {
/* Chrome/Win does this thing where it takes