mirror of
https://github.com/smogon/pokemon-showdown-client.git
synced 2026-03-21 17:50:29 -05:00
Preact minor updates batch 25
- Fix various reconnect bugs - Move table styling to battle-log - Fix highlighting bugs - Bump cookie expiration another month Trivial - Fix rounding in build time - Fix left border in vertical tabs dark mode - Improve README wording
This commit is contained in:
parent
c20898479f
commit
ae69319e63
|
|
@ -56,8 +56,8 @@ require v20 or later) and Git, and run `node build` (on Windows) or `./build`
|
|||
(on other OSes) to build.
|
||||
|
||||
You can make and test client changes simply by building after each change,
|
||||
and opening `testclient.html`. This will allow you to test changes to the
|
||||
client without setting up your own login server.
|
||||
and opening `play.pokemonshowdown.com/testclient.html`. This will allow you
|
||||
to test changes to the client without setting up your own login server.
|
||||
|
||||
### Test keys
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ grab it from:
|
|||
|
||||
Make sure to put it in `config/` and not `play.pokemonshowdown.com/config/`.
|
||||
|
||||
(This is the only supported method of logging in on the beta Preact testclient.)
|
||||
(This is the only supported method of logging in on the beta testclient.)
|
||||
|
||||
[5]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
||||
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ if (!compileOpts.ignore) {
|
|||
|
||||
const diff = process.hrtime(compileStartTime);
|
||||
console.log(
|
||||
`(${compiledFiles} ${compiledFiles !== 1 ? "files" : "file"} in ${diff[0] + Math.round(diff[1] / 1e6) / 1e3}s) DONE`
|
||||
`(${compiledFiles} ${compiledFiles !== 1 ? "files" : "file"} in ${(diff[0] + diff[1] / 1e9).toFixed(3)}s) DONE`
|
||||
);
|
||||
|
||||
/*********************************************************
|
||||
|
|
|
|||
|
|
@ -183,16 +183,7 @@ export class BattleLog {
|
|||
[divClass, divHTML, noNotify] = this.parseChatMessage(message, name, timestampHtml, isHighlighted);
|
||||
if (!noNotify && isHighlighted) {
|
||||
const notifyTitle = "Mentioned by " + name + " in " + (battle?.roomid || '');
|
||||
if (window.PS) {
|
||||
const room = window.PS.rooms[battle?.roomid || ''];
|
||||
room.notify({
|
||||
title: notifyTitle,
|
||||
body: `"${message}"`,
|
||||
id: 'highlight',
|
||||
});
|
||||
} else {
|
||||
window.app?.rooms[battle?.roomid || '']?.notifyOnce(notifyTitle, "\"" + message + "\"", 'highlight');
|
||||
}
|
||||
window.app?.rooms[battle?.roomid || '']?.notifyOnce(notifyTitle, "\"" + message + "\"", 'highlight');
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -1238,9 +1229,9 @@ export class BattleLog {
|
|||
}
|
||||
const colorStyle = ` style="color:${BattleLog.usernameColor(toID(name))}"`;
|
||||
const clickableName = `<small class="groupsymbol">${BattleLog.escapeHTML(group)}</small><span class="username">${BattleLog.escapeHTML(name)}</span>`;
|
||||
let hlClass = isHighlighted ? ' highlighted' : '';
|
||||
let isMine = (window.app?.user?.get('name') === name) || (window.PS?.user.name === name);
|
||||
let mineClass = isMine ? ' mine' : '';
|
||||
const isMine = (window.app?.user?.get('name') === name) || (window.PS?.user.name === name);
|
||||
const hlClass = isHighlighted ? ' highlighted' : '';
|
||||
const mineClass = isMine ? ' mine' : '';
|
||||
|
||||
let cmd = '';
|
||||
let target = '';
|
||||
|
|
|
|||
|
|
@ -50,6 +50,12 @@ export class PSConnection {
|
|||
|
||||
tryConnectInWorker(): boolean {
|
||||
if (this.socket) return false; // must be one or the other
|
||||
if (this.connected) return true;
|
||||
|
||||
if (this.worker) {
|
||||
this.worker.postMessage({ type: 'connect', server: PS.server });
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
const worker = new Worker('/js/client-connection-worker.js');
|
||||
|
|
@ -63,7 +69,6 @@ export class PSConnection {
|
|||
case 'connected':
|
||||
console.log('\u2705 (CONNECTED via worker)');
|
||||
this.connected = true;
|
||||
PS.connected = true;
|
||||
this.queue.forEach(msg => worker.postMessage({ type: 'send', data: msg }));
|
||||
this.queue = [];
|
||||
PS.update();
|
||||
|
|
@ -84,8 +89,8 @@ export class PSConnection {
|
|||
}
|
||||
};
|
||||
|
||||
worker.onerror = (e: ErrorEvent) => {
|
||||
console.warn('Worker connection error:', e);
|
||||
worker.onerror = (ev: ErrorEvent) => {
|
||||
console.warn('Worker connection error:', ev);
|
||||
this.worker = null;
|
||||
this.directConnect(); // fallback
|
||||
};
|
||||
|
|
@ -116,7 +121,6 @@ export class PSConnection {
|
|||
socket.onopen = () => {
|
||||
console.log('\u2705 (CONNECTED)');
|
||||
this.connected = true;
|
||||
PS.connected = true;
|
||||
this.reconnectDelay = 1000;
|
||||
this.queue.forEach(msg => socket.send(msg));
|
||||
this.queue = [];
|
||||
|
|
@ -132,7 +136,6 @@ export class PSConnection {
|
|||
this.handleDisconnect();
|
||||
console.log('\u2705 (DISCONNECTED)');
|
||||
this.connected = false;
|
||||
PS.connected = false;
|
||||
PS.isOffline = true;
|
||||
for (const roomid in PS.rooms) {
|
||||
const room = PS.rooms[roomid]!;
|
||||
|
|
@ -143,10 +146,8 @@ export class PSConnection {
|
|||
};
|
||||
|
||||
socket.onerror = (ev: Event) => {
|
||||
PS.connected = false;
|
||||
PS.isOffline = true;
|
||||
// no useful info to print from the event
|
||||
PS.alert(`Connection error`);
|
||||
this.retryConnection();
|
||||
PS.update();
|
||||
};
|
||||
|
|
@ -154,7 +155,6 @@ export class PSConnection {
|
|||
|
||||
private handleDisconnect() {
|
||||
this.connected = false;
|
||||
PS.connected = false;
|
||||
PS.isOffline = true;
|
||||
this.socket = null;
|
||||
for (const roomid in PS.rooms) {
|
||||
|
|
@ -168,12 +168,14 @@ export class PSConnection {
|
|||
private retryConnection() {
|
||||
if (!this.canReconnect()) return;
|
||||
if (this.reconnectTimer) return;
|
||||
|
||||
this.reconnectTimer = setTimeout(() => {
|
||||
this.reconnectTimer = null;
|
||||
if (!this.connected && this.canReconnect()) {
|
||||
PS.mainmenu.send('/reconnect');
|
||||
this.reconnectDelay = Math.min(this.reconnectDelay * 2, this.reconnectCap);
|
||||
}
|
||||
PS.update();
|
||||
}, this.reconnectDelay);
|
||||
}
|
||||
|
||||
|
|
@ -182,17 +184,13 @@ export class PSConnection {
|
|||
this.socket?.close();
|
||||
this.worker?.terminate();
|
||||
this.worker = null;
|
||||
PS.connection = null;
|
||||
PS.connected = false;
|
||||
PS.isOffline = true;
|
||||
this.handleDisconnect();
|
||||
PS.update();
|
||||
}
|
||||
|
||||
reconnectTest() {
|
||||
this.socket?.close();
|
||||
this.worker?.postMessage({ type: 'disconnect' });
|
||||
this.worker = null;
|
||||
PS.connected = false;
|
||||
PS.isOffline = true;
|
||||
reconnect() {
|
||||
if (this.connected) return;
|
||||
if (this.worker && this.tryConnectInWorker()) return;
|
||||
this.directConnect();
|
||||
}
|
||||
|
||||
send(msg: string) {
|
||||
|
|
@ -213,7 +211,7 @@ export class PSConnection {
|
|||
if (!PS.connection) {
|
||||
PS.connection = new PSConnection();
|
||||
} else {
|
||||
PS.connection.directConnect();
|
||||
PS.connection.reconnect();
|
||||
}
|
||||
PS.prefs.doAutojoin();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1042,13 +1042,16 @@ export class PSRoom extends PSStreamModel<Args | null> implements RoomOptions {
|
|||
this.isSubtleNotifying = true;
|
||||
PS.update();
|
||||
}
|
||||
dismissNotificationAt(i: number) {
|
||||
try {
|
||||
this.notifications[i].notification?.close();
|
||||
} catch {}
|
||||
this.notifications.splice(i, 1);
|
||||
}
|
||||
dismissNotification(id: string) {
|
||||
const index = this.notifications.findIndex(n => n.id === id);
|
||||
if (index !== -1) {
|
||||
try {
|
||||
this.notifications[index].notification?.close();
|
||||
} catch {}
|
||||
this.notifications.splice(index, 1);
|
||||
this.dismissNotificationAt(index);
|
||||
}
|
||||
PS.update();
|
||||
}
|
||||
|
|
@ -1061,7 +1064,11 @@ export class PSRoom extends PSStreamModel<Args | null> implements RoomOptions {
|
|||
lastMessageDates[PS.server.id][room.id] = room.lastMessageTime || 0;
|
||||
PS.prefs.set('logtimes', lastMessageDates);
|
||||
}
|
||||
this.notifications = this.notifications.filter(notification => notification.noAutoDismiss);
|
||||
for (let i = this.notifications.length - 1; i >= 0; i--) {
|
||||
if (!this.notifications[i].noAutoDismiss) {
|
||||
this.dismissNotificationAt(i);
|
||||
}
|
||||
}
|
||||
this.isSubtleNotifying = false;
|
||||
}
|
||||
connect(): void {
|
||||
|
|
@ -1184,10 +1191,22 @@ export class PSRoom extends PSStreamModel<Args | null> implements RoomOptions {
|
|||
'logout'() {
|
||||
PS.user.logOut();
|
||||
},
|
||||
'reconnect'() {
|
||||
if (!PS.isOffline) {
|
||||
return this.add(`|error|You are already connected.`);
|
||||
'reconnect,connect'() {
|
||||
if (this.connected && this.connected !== 'autoreconnect') {
|
||||
return this.errorReply(`You are already connected.`);
|
||||
}
|
||||
|
||||
if (!PS.isOffline) {
|
||||
// connect to room
|
||||
try {
|
||||
this.connect();
|
||||
} catch (err: any) {
|
||||
this.errorReply(err.message);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// connect to server
|
||||
const uptime = Date.now() - PS.startTime;
|
||||
if (uptime > 24 * 60 * 60 * 1000) {
|
||||
PS.confirm(`It's been over a day since you first connected. Please refresh.`, {
|
||||
|
|
@ -1207,17 +1226,6 @@ export class PSRoom extends PSStreamModel<Args | null> implements RoomOptions {
|
|||
return this.add(`|error|You are already offline.`);
|
||||
}
|
||||
PS.connection?.disconnect();
|
||||
this.add(`||You are now offline.`);
|
||||
},
|
||||
'connect'() {
|
||||
if (this.connected && this.connected !== 'autoreconnect') {
|
||||
return this.errorReply(`You are already connected.`);
|
||||
}
|
||||
try {
|
||||
this.connect();
|
||||
} catch (err: any) {
|
||||
this.errorReply(err.message);
|
||||
}
|
||||
},
|
||||
'cancelsearch'() {
|
||||
if (PS.mainmenu.cancelSearch()) {
|
||||
|
|
@ -1730,7 +1738,6 @@ export const PS = new class extends PSModel {
|
|||
user = new PSUser();
|
||||
server = new PSServer();
|
||||
connection: PSConnection | null = null;
|
||||
connected = false;
|
||||
/**
|
||||
* While PS is technically disconnected while it's trying to connect,
|
||||
* it still shows UI like it's connected, so you can click buttons
|
||||
|
|
|
|||
|
|
@ -250,31 +250,42 @@ export class ChatRoom extends PSRoom {
|
|||
handleHighlight = (args: Args) => {
|
||||
let name;
|
||||
let message;
|
||||
let msgTime = 0;
|
||||
let serverTime = 0;
|
||||
if (args[0] === 'c:') {
|
||||
msgTime = parseInt(args[1]);
|
||||
serverTime = parseInt(args[1]);
|
||||
name = args[2];
|
||||
message = args[3];
|
||||
} else {
|
||||
name = args[1];
|
||||
message = args[2];
|
||||
}
|
||||
let lastMessageDates = Dex.prefs('logtimes') || (PS.prefs.set('logtimes', {}), Dex.prefs('logtimes'));
|
||||
if (toID(name) === PS.user.userid) return false;
|
||||
if (message.startsWith(`/raw `)) return false;
|
||||
|
||||
const lastMessageDates = Dex.prefs('logtimes') || (PS.prefs.set('logtimes', {}), Dex.prefs('logtimes'));
|
||||
if (!lastMessageDates[PS.server.id]) lastMessageDates[PS.server.id] = {};
|
||||
let lastMessageDate = lastMessageDates[PS.server.id][this.id] || 0;
|
||||
const lastMessageDate = lastMessageDates[PS.server.id][this.id] || 0;
|
||||
// because the time offset to the server can vary slightly, subtract it to not have it affect comparisons between dates
|
||||
let serverMsgTime = msgTime - (this.timeOffset || 0);
|
||||
let mayNotify = serverMsgTime > lastMessageDate && name !== PS.user.userid;
|
||||
const time = serverTime - (this.timeOffset || 0);
|
||||
if (PS.isVisible(this)) {
|
||||
this.lastMessageTime = null;
|
||||
lastMessageDates[PS.server.id][this.id] = serverMsgTime;
|
||||
lastMessageDates[PS.server.id][this.id] = time;
|
||||
PS.prefs.set('logtimes', lastMessageDates);
|
||||
} else {
|
||||
// To be saved on focus
|
||||
let lastMessageTime = this.lastMessageTime || 0;
|
||||
if (lastMessageTime < serverMsgTime) this.lastMessageTime = serverMsgTime;
|
||||
const lastMessageTime = this.lastMessageTime || 0;
|
||||
if (lastMessageTime < time) this.lastMessageTime = time;
|
||||
}
|
||||
return !!(ChatRoom.getHighlight(message, this.id) && mayNotify);
|
||||
if (ChatRoom.getHighlight(message, this.id)) {
|
||||
const mayNotify = time > lastMessageDate;
|
||||
if (mayNotify) this.notify({
|
||||
title: `Mentioned by ${name} in ${this.id}`,
|
||||
body: `"${message}"`,
|
||||
id: 'highlight',
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
override clientCommands = this.parseClientCommands({
|
||||
'chall,challenge'(target) {
|
||||
|
|
|
|||
|
|
@ -437,7 +437,7 @@ class NewsPanel extends PSRoomPanel {
|
|||
change = (ev: Event) => {
|
||||
const target = ev.currentTarget as HTMLInputElement;
|
||||
if (target.value === '1') {
|
||||
document.cookie = "preactalpha=1; expires=Thu, 1 Jun 2025 12:00:00 UTC; path=/";
|
||||
document.cookie = "preactalpha=1; expires=Thu, 1 Jul 2025 12:00:00 UTC; path=/";
|
||||
} else {
|
||||
document.cookie = "preactalpha=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ export class PSHeader extends preact.Component {
|
|||
this.handleResize();
|
||||
}
|
||||
renderUser() {
|
||||
if (!PS.connected) {
|
||||
if (!PS.connection?.connected) {
|
||||
return <button class="button" disabled><em>Offline</em></button>;
|
||||
}
|
||||
if (PS.user.initializing) {
|
||||
|
|
|
|||
|
|
@ -622,6 +622,35 @@ input[type=range]:active::-webkit-slider-thumb {
|
|||
}
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
* Table
|
||||
*********************************************************/
|
||||
|
||||
.table-header {
|
||||
position: relative;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
.ladder table, .ladder td, .ladder th,
|
||||
.table, .table td, .table th {
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #BBBBBB;
|
||||
}
|
||||
.ladder td, .ladder th,
|
||||
.table td, .table th {
|
||||
padding: 3px 5px;
|
||||
}
|
||||
.ladder th, .table th {
|
||||
text-align: left;
|
||||
font-size: 9pt;
|
||||
background: #EEEEEE;
|
||||
color: #111111;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
* Everything else
|
||||
*********************************************************/
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ License: GPLv2
|
|||
|
||||
*/
|
||||
|
||||
@import url(./battle-log.css?v9.8);
|
||||
@import url(./battle-log.css?v10);
|
||||
|
||||
.battle {
|
||||
position: absolute;
|
||||
|
|
|
|||
|
|
@ -566,6 +566,9 @@ summary:hover .expandbutton,
|
|||
border-left: 1px solid #AAAAAA;
|
||||
margin-left: -1px;
|
||||
}
|
||||
.dark .ps-room {
|
||||
border-color: #34373b;
|
||||
}
|
||||
.scrollable {
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
|
@ -1029,35 +1032,6 @@ form.menugroup {
|
|||
.button.mainmenu6:hover { background: linear-gradient(to bottom, hsl(270,40%,62%), hsl(270,40%,42%)); }
|
||||
.button.mainmenu6:active { background: linear-gradient(to bottom, hsl(270,40%,42%), hsl(300,40%,58%)); }
|
||||
|
||||
/*********************************************************
|
||||
* Ladder
|
||||
*********************************************************/
|
||||
|
||||
.table-header {
|
||||
position: relative;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
.ladder table, .ladder td, .ladder th,
|
||||
.table, .table td, .table th {
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #BBBBBB;
|
||||
}
|
||||
.ladder td, .ladder th,
|
||||
.table td, .table th {
|
||||
padding: 3px 5px;
|
||||
}
|
||||
.ladder th, .table th {
|
||||
text-align: left;
|
||||
font-size: 9pt;
|
||||
background: #EEEEEE;
|
||||
color: #111111;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
* Room list
|
||||
*********************************************************/
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user