mirror of
https://github.com/smogon/pokemon-showdown-client.git
synced 2026-05-09 04:23:01 -05:00
Merge af7339b031 into 10f8967023
This commit is contained in:
commit
5eb900c52c
|
|
@ -19,6 +19,7 @@ import { BattleTextParser, type Args } from './battle-text-parser';
|
|||
import type { BattleRoom } from './panel-battle';
|
||||
import { Teams } from './battle-teams';
|
||||
import type preact from '../js/lib/preact';
|
||||
import { PSHeader } from './panel-topbar';
|
||||
|
||||
declare const BattleTextAFD: any;
|
||||
declare const BattleTextNotAFD: any;
|
||||
|
|
@ -1044,6 +1045,11 @@ export class PSRoom extends PSStreamModel<Args | null> implements RoomOptions {
|
|||
}
|
||||
}
|
||||
} catch {}
|
||||
// extra check because the roomIsFocused is not accurate for some reason
|
||||
if (document.visibilityState !== 'visible') {
|
||||
PS.isNotifying = true;
|
||||
PSHeader.updateFavicon();
|
||||
}
|
||||
}
|
||||
if (options.noAutoDismiss && !options.id) {
|
||||
throw new Error(`Must specify id for manual dismissing`);
|
||||
|
|
@ -1073,6 +1079,7 @@ export class PSRoom extends PSStreamModel<Args | null> implements RoomOptions {
|
|||
this.notifications[i].notification?.close();
|
||||
} catch {}
|
||||
this.notifications.splice(i, 1);
|
||||
PSHeader.updateFavicon();
|
||||
}
|
||||
dismissNotification(id: string) {
|
||||
const index = this.notifications.findIndex(n => n.id === id);
|
||||
|
|
@ -1504,6 +1511,12 @@ export class PSRoom extends PSStreamModel<Args | null> implements RoomOptions {
|
|||
PS.prefs.set('nounlink', false);
|
||||
this.add('||Locked/banned users\' chat messages: HIDDEN');
|
||||
},
|
||||
'whatsnew'() {
|
||||
const success = PSHeader.clickCounter.click();
|
||||
if (success) {
|
||||
PS.join('patchnotes' as RoomID);
|
||||
}
|
||||
},
|
||||
'hl,highlight'(target) {
|
||||
let highlights = PS.prefs.highlights || {};
|
||||
if (target.includes(' ')) {
|
||||
|
|
@ -1930,6 +1943,8 @@ export const PS = new class extends PSModel {
|
|||
/** Tracks whether or not to display the "Use arrow keys" hint */
|
||||
arrowKeysUsed = false;
|
||||
|
||||
isNotifying = false;
|
||||
|
||||
newsHTML = document.querySelector('#room-news .readable-bg')?.innerHTML || '';
|
||||
newsId = document.getElementById('room-news')?.getAttribute('data-newsid') || null;
|
||||
|
||||
|
|
@ -2790,6 +2805,15 @@ export const PS = new class extends PSModel {
|
|||
this.prefs.set('autojoin', autojoin);
|
||||
}
|
||||
}
|
||||
getNotificationsCount() {
|
||||
let count = 0;
|
||||
const notificationRooms = [...PS.leftRoomList, ...PS.rightRoomList, ...PS.miniRoomList];
|
||||
for (const roomid of notificationRooms) {
|
||||
const miniNotifications = PS.rooms[roomid]?.notifications;
|
||||
if (miniNotifications?.length) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
requestNotifications() {
|
||||
try {
|
||||
if (window.webkitNotifications?.requestPermission) {
|
||||
|
|
|
|||
|
|
@ -1928,6 +1928,102 @@ class RulesPanel extends PSRoomPanel<PopupRoom> {
|
|||
}
|
||||
}
|
||||
|
||||
class PatchNotesPanel extends PSRoomPanel<PopupRoom> {
|
||||
static readonly id = 'patchnotes';
|
||||
static readonly routes = ['patchnotes'];
|
||||
static readonly location = 'semimodal-popup';
|
||||
static readonly noURL = true;
|
||||
static readonly Model = PopupRoom;
|
||||
|
||||
getRandomPatchNotes() {
|
||||
const allTitles = [
|
||||
"Patch Notes (because chaos needs documentation)",
|
||||
"Patch Notes: Now with 30% fewer bugs (No promises)",
|
||||
"Patch Notes — We Swear It’s Better This Time",
|
||||
"Patch Notes: Definitely Didn’t Break Anything Else",
|
||||
"Patch Notes: Technically “Improvements”",
|
||||
"Patch Notes — Version: “It Works on My Machine”",
|
||||
"Patch Notes (We Fixed Things You Didn’t Know Were Broken)",
|
||||
"Patch Notes: Stability? Never Heard of It.",
|
||||
"Patch Notes — Slightly More Functional Than Yesterday",
|
||||
"Patch Notes: The Bugs Strike Back",
|
||||
"Patch Notes (A Love Letter to Debugging)",
|
||||
"Patch Notes: Powered by Caffeine and Regret",
|
||||
"Patch Notes — “Trust Me Bro” Edition",
|
||||
];
|
||||
const allNotes = [
|
||||
"Fixed a bug where clicking really hard didn’t make things load faster.",
|
||||
"Improved stability by removing one line of code we didn’t understand.",
|
||||
"Added a 'quantum uncertainty' mode — the UI may or may not respond.",
|
||||
"Performance improved by at least 0.0001% (scientifically proven).",
|
||||
"Added new AI: 'Emotionally Unstable Bot' — it forfeits if you’re mean.",
|
||||
"Pokémon now occasionally question the meaning of their existence mid-battle.",
|
||||
"Critical hits are now determined by your karma.",
|
||||
"Fixed a bug where RNG was too fair.",
|
||||
"Improved matchmaking: you’ll now face someone just as tilted as you.",
|
||||
"Added experimental 'Therapist Mode': the game listens, you vent.",
|
||||
"The app now looks 30% faster, even if it isn’t.",
|
||||
"Chat filters now detect sarcasm with 4% accuracy.",
|
||||
"Fixed a bug where players were sometimes right on the internet.",
|
||||
"Improved mod tools: moderators can now sense chaos before it happens.",
|
||||
"Backend now powered by pure friendship and caffeine.",
|
||||
"Optimized the code to run slightly worse, but with more confidence.",
|
||||
"Fixed an issue where the bug fix introduced more bugs.",
|
||||
"Added 'Are you sure?' dialog. It doesn’t do anything, but feels safe.",
|
||||
"Reduced load times by moving progress bar faster.",
|
||||
"Replaced all semicolons with good vibes.",
|
||||
"New setting: 'Developer Tears Mode' — enhances realism.",
|
||||
"You can now press any key to feel like you’re helping.",
|
||||
"Made UI 15% shinier for improved morale.",
|
||||
"Bug reports are now automatically forwarded to the void.",
|
||||
"Buffed RNG. It’s now personal.",
|
||||
"Lucario’s aura now glows brighter when you lie.",
|
||||
"Fixed crash where Trainer couldn’t accept defeat gracefully.",
|
||||
"Buffed memes. Nerfed logic.",
|
||||
"New mechanic: 'Disconnect Immunity' — doesn’t exist, but sounds nice.",
|
||||
"Fixed an issue where players believed in fair matchups.",
|
||||
"Nerfed stall strategies. (You’re welcome.)",
|
||||
"Fixed an exploit where players had hope during battles.",
|
||||
"Blissey now charges for therapy sessions.",
|
||||
"Togekiss’s Air Slash now comes with a free rage quit.",
|
||||
"Increased Confusion duration — the devs thought it was funny.",
|
||||
"Garchomp’s Sand Veil now works indoors, somehow.",
|
||||
"Rebalanced RNG: it now hates everyone equally.",
|
||||
"Pikachu’s Thunderbolt now powered by real electricity bills.",
|
||||
"Machamp now flexes every 3 turns automatically.",
|
||||
"Buffed Magikarp’s Splash — it now causes mild emotional distress.",
|
||||
"Nerfed Toxic stall teams. We’re doing this for humanity.",
|
||||
"Alakazam now needs a PhD to understand its own Special Attack stat.",
|
||||
"Zoroark’s Illusion now also fools itself sometimes.",
|
||||
"Fixed a bug where Ditto copied your emotional damage too.",
|
||||
"Gengar now giggles 20% more menacingly.",
|
||||
"Nerfed RNG. It was getting too self-aware.",
|
||||
"Charizard finally acknowledged that it’s not a Dragon-type. Therapy helped.",
|
||||
];
|
||||
|
||||
const title = allTitles.sort(() => 0.5 - Math.random())[0];
|
||||
const notes = allNotes.sort(() => 0.5 - Math.random()).slice(0, 12);
|
||||
return { title, notes };
|
||||
}
|
||||
|
||||
override render() {
|
||||
const room = this.props.room;
|
||||
const patchNotesData = this.getRandomPatchNotes();
|
||||
return <PSPanelWrapper room={room} width={room.args?.width as number || 780}>
|
||||
<div class="pad">
|
||||
<h2>{patchNotesData.title}</h2>
|
||||
|
||||
{patchNotesData.notes
|
||||
.map((note, i) => <p><b>{i + 1}.</b> {note}</p>)}
|
||||
<p class="buttonbar"><button
|
||||
name="close"
|
||||
data-cmd="/close" class="button autofocus"
|
||||
> Close</button></p>
|
||||
</div>
|
||||
</PSPanelWrapper>;
|
||||
}
|
||||
}
|
||||
|
||||
PS.addRoomType(
|
||||
UserPanel,
|
||||
UserOptionsPanel,
|
||||
|
|
@ -1947,5 +2043,6 @@ PS.addRoomType(
|
|||
RoomTabListPanel,
|
||||
BattleOptionsPanel,
|
||||
BattleTimerPanel,
|
||||
RulesPanel
|
||||
RulesPanel,
|
||||
PatchNotesPanel
|
||||
);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,28 @@ window.addEventListener('dragover', e => {
|
|||
});
|
||||
|
||||
export class PSHeader extends preact.Component {
|
||||
static clickCounter = {
|
||||
count: 0,
|
||||
lastClick: 0,
|
||||
maxGap: 500,
|
||||
click() {
|
||||
const now = Date.now();
|
||||
|
||||
if (now - this.lastClick > this.maxGap) {
|
||||
this.count = 1;
|
||||
} else {
|
||||
this.count++;
|
||||
}
|
||||
|
||||
this.lastClick = now;
|
||||
|
||||
if (this.count === 10) {
|
||||
this.count = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
};
|
||||
static toggleMute = (e: Event) => {
|
||||
PS.prefs.set('mute', !PS.prefs.mute);
|
||||
PS.update();
|
||||
|
|
@ -152,6 +174,13 @@ export class PSHeader extends preact.Component {
|
|||
{closeButton}
|
||||
</li>;
|
||||
}
|
||||
static updateFavicon() {
|
||||
const favicon = document.querySelector('#dynamic-favicon');
|
||||
if (favicon instanceof HTMLLinkElement) {
|
||||
favicon.href = `${window.Dex.resourcePrefix}/${PS.isNotifying ? 'favicon-notify.ico' : 'favicon.ico'}`;
|
||||
favicon.dataset.on = PS.isNotifying ? '1' : '';
|
||||
}
|
||||
}
|
||||
handleResize = () => {
|
||||
if (!this.base) return;
|
||||
|
||||
|
|
@ -228,6 +257,7 @@ export class PSHeader extends preact.Component {
|
|||
src={`https://${Config.routes.client}/favicon-256.png`}
|
||||
alt="Pokémon Showdown! (beta)"
|
||||
width="50" height="50"
|
||||
data-cmd="/whatsnew"
|
||||
/>
|
||||
<div class="tablist" role="tablist">
|
||||
<ul>
|
||||
|
|
@ -269,6 +299,7 @@ export class PSHeader extends preact.Component {
|
|||
src={`https://${Config.routes.client}/favicon-256.png`}
|
||||
alt="Pokémon Showdown! (beta)"
|
||||
width="48" height="48"
|
||||
data-cmd="/whatsnew"
|
||||
/>
|
||||
</li>
|
||||
{PSHeader.renderRoomTab(PS.leftRoomList[0])}
|
||||
|
|
@ -308,13 +339,7 @@ export class PSMiniHeader extends preact.Component {
|
|||
};
|
||||
override render() {
|
||||
if (PS.leftPanelWidth !== null) return null;
|
||||
|
||||
let notificationsCount = 0;
|
||||
const notificationRooms = [...PS.leftRoomList, ...PS.rightRoomList];
|
||||
for (const roomid of notificationRooms) {
|
||||
const miniNotifications = PS.rooms[roomid]?.notifications;
|
||||
if (miniNotifications?.length) notificationsCount++;
|
||||
}
|
||||
const notificationsCount = PS.getNotificationsCount();
|
||||
const { icon, title } = PSHeader.roomInfo(PS.panel);
|
||||
const userColor = window.BattleLog && `color:${PS.user.away ? '#888' : BattleLog.usernameColor(PS.user.userid)}`;
|
||||
const showMenuButton = PSView.narrowMode;
|
||||
|
|
|
|||
|
|
@ -646,6 +646,11 @@ export class PSView extends preact.Component {
|
|||
PS.dragging = null;
|
||||
});
|
||||
|
||||
window.addEventListener('focus', () => {
|
||||
PS.isNotifying = false;
|
||||
PSHeader.updateFavicon();
|
||||
});
|
||||
|
||||
const colorSchemeQuery = window.matchMedia?.('(prefers-color-scheme: dark)');
|
||||
if (colorSchemeQuery?.media !== 'not all') {
|
||||
colorSchemeQuery.addEventListener('change', cs => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user