mirror of
https://github.com/smogon/pokemon-showdown-client.git
synced 2026-04-27 10:37:44 -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.
|
(on other OSes) to build.
|
||||||
|
|
||||||
You can make and test client changes simply by building after each change,
|
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
|
and opening `play.pokemonshowdown.com/testclient.html`. This will allow you
|
||||||
client without setting up your own login server.
|
to test changes to the client without setting up your own login server.
|
||||||
|
|
||||||
### Test keys
|
### Test keys
|
||||||
|
|
||||||
|
|
@ -78,7 +78,7 @@ grab it from:
|
||||||
|
|
||||||
Make sure to put it in `config/` and not `play.pokemonshowdown.com/config/`.
|
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
|
[5]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ if (!compileOpts.ignore) {
|
||||||
|
|
||||||
const diff = process.hrtime(compileStartTime);
|
const diff = process.hrtime(compileStartTime);
|
||||||
console.log(
|
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);
|
[divClass, divHTML, noNotify] = this.parseChatMessage(message, name, timestampHtml, isHighlighted);
|
||||||
if (!noNotify && isHighlighted) {
|
if (!noNotify && isHighlighted) {
|
||||||
const notifyTitle = "Mentioned by " + name + " in " + (battle?.roomid || '');
|
const notifyTitle = "Mentioned by " + name + " in " + (battle?.roomid || '');
|
||||||
if (window.PS) {
|
window.app?.rooms[battle?.roomid || '']?.notifyOnce(notifyTitle, "\"" + message + "\"", 'highlight');
|
||||||
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');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1238,9 +1229,9 @@ export class BattleLog {
|
||||||
}
|
}
|
||||||
const colorStyle = ` style="color:${BattleLog.usernameColor(toID(name))}"`;
|
const colorStyle = ` style="color:${BattleLog.usernameColor(toID(name))}"`;
|
||||||
const clickableName = `<small class="groupsymbol">${BattleLog.escapeHTML(group)}</small><span class="username">${BattleLog.escapeHTML(name)}</span>`;
|
const clickableName = `<small class="groupsymbol">${BattleLog.escapeHTML(group)}</small><span class="username">${BattleLog.escapeHTML(name)}</span>`;
|
||||||
let hlClass = isHighlighted ? ' highlighted' : '';
|
const isMine = (window.app?.user?.get('name') === name) || (window.PS?.user.name === name);
|
||||||
let isMine = (window.app?.user?.get('name') === name) || (window.PS?.user.name === name);
|
const hlClass = isHighlighted ? ' highlighted' : '';
|
||||||
let mineClass = isMine ? ' mine' : '';
|
const mineClass = isMine ? ' mine' : '';
|
||||||
|
|
||||||
let cmd = '';
|
let cmd = '';
|
||||||
let target = '';
|
let target = '';
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,12 @@ export class PSConnection {
|
||||||
|
|
||||||
tryConnectInWorker(): boolean {
|
tryConnectInWorker(): boolean {
|
||||||
if (this.socket) return false; // must be one or the other
|
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 {
|
try {
|
||||||
const worker = new Worker('/js/client-connection-worker.js');
|
const worker = new Worker('/js/client-connection-worker.js');
|
||||||
|
|
@ -63,7 +69,6 @@ export class PSConnection {
|
||||||
case 'connected':
|
case 'connected':
|
||||||
console.log('\u2705 (CONNECTED via worker)');
|
console.log('\u2705 (CONNECTED via worker)');
|
||||||
this.connected = true;
|
this.connected = true;
|
||||||
PS.connected = true;
|
|
||||||
this.queue.forEach(msg => worker.postMessage({ type: 'send', data: msg }));
|
this.queue.forEach(msg => worker.postMessage({ type: 'send', data: msg }));
|
||||||
this.queue = [];
|
this.queue = [];
|
||||||
PS.update();
|
PS.update();
|
||||||
|
|
@ -84,8 +89,8 @@ export class PSConnection {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
worker.onerror = (e: ErrorEvent) => {
|
worker.onerror = (ev: ErrorEvent) => {
|
||||||
console.warn('Worker connection error:', e);
|
console.warn('Worker connection error:', ev);
|
||||||
this.worker = null;
|
this.worker = null;
|
||||||
this.directConnect(); // fallback
|
this.directConnect(); // fallback
|
||||||
};
|
};
|
||||||
|
|
@ -116,7 +121,6 @@ export class PSConnection {
|
||||||
socket.onopen = () => {
|
socket.onopen = () => {
|
||||||
console.log('\u2705 (CONNECTED)');
|
console.log('\u2705 (CONNECTED)');
|
||||||
this.connected = true;
|
this.connected = true;
|
||||||
PS.connected = true;
|
|
||||||
this.reconnectDelay = 1000;
|
this.reconnectDelay = 1000;
|
||||||
this.queue.forEach(msg => socket.send(msg));
|
this.queue.forEach(msg => socket.send(msg));
|
||||||
this.queue = [];
|
this.queue = [];
|
||||||
|
|
@ -132,7 +136,6 @@ export class PSConnection {
|
||||||
this.handleDisconnect();
|
this.handleDisconnect();
|
||||||
console.log('\u2705 (DISCONNECTED)');
|
console.log('\u2705 (DISCONNECTED)');
|
||||||
this.connected = false;
|
this.connected = false;
|
||||||
PS.connected = false;
|
|
||||||
PS.isOffline = true;
|
PS.isOffline = true;
|
||||||
for (const roomid in PS.rooms) {
|
for (const roomid in PS.rooms) {
|
||||||
const room = PS.rooms[roomid]!;
|
const room = PS.rooms[roomid]!;
|
||||||
|
|
@ -143,10 +146,8 @@ export class PSConnection {
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.onerror = (ev: Event) => {
|
socket.onerror = (ev: Event) => {
|
||||||
PS.connected = false;
|
|
||||||
PS.isOffline = true;
|
PS.isOffline = true;
|
||||||
// no useful info to print from the event
|
// no useful info to print from the event
|
||||||
PS.alert(`Connection error`);
|
|
||||||
this.retryConnection();
|
this.retryConnection();
|
||||||
PS.update();
|
PS.update();
|
||||||
};
|
};
|
||||||
|
|
@ -154,7 +155,6 @@ export class PSConnection {
|
||||||
|
|
||||||
private handleDisconnect() {
|
private handleDisconnect() {
|
||||||
this.connected = false;
|
this.connected = false;
|
||||||
PS.connected = false;
|
|
||||||
PS.isOffline = true;
|
PS.isOffline = true;
|
||||||
this.socket = null;
|
this.socket = null;
|
||||||
for (const roomid in PS.rooms) {
|
for (const roomid in PS.rooms) {
|
||||||
|
|
@ -168,12 +168,14 @@ export class PSConnection {
|
||||||
private retryConnection() {
|
private retryConnection() {
|
||||||
if (!this.canReconnect()) return;
|
if (!this.canReconnect()) return;
|
||||||
if (this.reconnectTimer) return;
|
if (this.reconnectTimer) return;
|
||||||
|
|
||||||
this.reconnectTimer = setTimeout(() => {
|
this.reconnectTimer = setTimeout(() => {
|
||||||
this.reconnectTimer = null;
|
this.reconnectTimer = null;
|
||||||
if (!this.connected && this.canReconnect()) {
|
if (!this.connected && this.canReconnect()) {
|
||||||
PS.mainmenu.send('/reconnect');
|
PS.mainmenu.send('/reconnect');
|
||||||
this.reconnectDelay = Math.min(this.reconnectDelay * 2, this.reconnectCap);
|
this.reconnectDelay = Math.min(this.reconnectDelay * 2, this.reconnectCap);
|
||||||
}
|
}
|
||||||
|
PS.update();
|
||||||
}, this.reconnectDelay);
|
}, this.reconnectDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -182,17 +184,13 @@ export class PSConnection {
|
||||||
this.socket?.close();
|
this.socket?.close();
|
||||||
this.worker?.terminate();
|
this.worker?.terminate();
|
||||||
this.worker = null;
|
this.worker = null;
|
||||||
PS.connection = null;
|
this.handleDisconnect();
|
||||||
PS.connected = false;
|
PS.update();
|
||||||
PS.isOffline = true;
|
|
||||||
}
|
}
|
||||||
|
reconnect() {
|
||||||
reconnectTest() {
|
if (this.connected) return;
|
||||||
this.socket?.close();
|
if (this.worker && this.tryConnectInWorker()) return;
|
||||||
this.worker?.postMessage({ type: 'disconnect' });
|
this.directConnect();
|
||||||
this.worker = null;
|
|
||||||
PS.connected = false;
|
|
||||||
PS.isOffline = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
send(msg: string) {
|
send(msg: string) {
|
||||||
|
|
@ -213,7 +211,7 @@ export class PSConnection {
|
||||||
if (!PS.connection) {
|
if (!PS.connection) {
|
||||||
PS.connection = new PSConnection();
|
PS.connection = new PSConnection();
|
||||||
} else {
|
} else {
|
||||||
PS.connection.directConnect();
|
PS.connection.reconnect();
|
||||||
}
|
}
|
||||||
PS.prefs.doAutojoin();
|
PS.prefs.doAutojoin();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1042,13 +1042,16 @@ export class PSRoom extends PSStreamModel<Args | null> implements RoomOptions {
|
||||||
this.isSubtleNotifying = true;
|
this.isSubtleNotifying = true;
|
||||||
PS.update();
|
PS.update();
|
||||||
}
|
}
|
||||||
|
dismissNotificationAt(i: number) {
|
||||||
|
try {
|
||||||
|
this.notifications[i].notification?.close();
|
||||||
|
} catch {}
|
||||||
|
this.notifications.splice(i, 1);
|
||||||
|
}
|
||||||
dismissNotification(id: string) {
|
dismissNotification(id: string) {
|
||||||
const index = this.notifications.findIndex(n => n.id === id);
|
const index = this.notifications.findIndex(n => n.id === id);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
try {
|
this.dismissNotificationAt(index);
|
||||||
this.notifications[index].notification?.close();
|
|
||||||
} catch {}
|
|
||||||
this.notifications.splice(index, 1);
|
|
||||||
}
|
}
|
||||||
PS.update();
|
PS.update();
|
||||||
}
|
}
|
||||||
|
|
@ -1061,7 +1064,11 @@ export class PSRoom extends PSStreamModel<Args | null> implements RoomOptions {
|
||||||
lastMessageDates[PS.server.id][room.id] = room.lastMessageTime || 0;
|
lastMessageDates[PS.server.id][room.id] = room.lastMessageTime || 0;
|
||||||
PS.prefs.set('logtimes', lastMessageDates);
|
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;
|
this.isSubtleNotifying = false;
|
||||||
}
|
}
|
||||||
connect(): void {
|
connect(): void {
|
||||||
|
|
@ -1184,10 +1191,22 @@ export class PSRoom extends PSStreamModel<Args | null> implements RoomOptions {
|
||||||
'logout'() {
|
'logout'() {
|
||||||
PS.user.logOut();
|
PS.user.logOut();
|
||||||
},
|
},
|
||||||
'reconnect'() {
|
'reconnect,connect'() {
|
||||||
if (!PS.isOffline) {
|
if (this.connected && this.connected !== 'autoreconnect') {
|
||||||
return this.add(`|error|You are already connected.`);
|
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;
|
const uptime = Date.now() - PS.startTime;
|
||||||
if (uptime > 24 * 60 * 60 * 1000) {
|
if (uptime > 24 * 60 * 60 * 1000) {
|
||||||
PS.confirm(`It's been over a day since you first connected. Please refresh.`, {
|
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.`);
|
return this.add(`|error|You are already offline.`);
|
||||||
}
|
}
|
||||||
PS.connection?.disconnect();
|
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'() {
|
'cancelsearch'() {
|
||||||
if (PS.mainmenu.cancelSearch()) {
|
if (PS.mainmenu.cancelSearch()) {
|
||||||
|
|
@ -1730,7 +1738,6 @@ export const PS = new class extends PSModel {
|
||||||
user = new PSUser();
|
user = new PSUser();
|
||||||
server = new PSServer();
|
server = new PSServer();
|
||||||
connection: PSConnection | null = null;
|
connection: PSConnection | null = null;
|
||||||
connected = false;
|
|
||||||
/**
|
/**
|
||||||
* While PS is technically disconnected while it's trying to connect,
|
* While PS is technically disconnected while it's trying to connect,
|
||||||
* it still shows UI like it's connected, so you can click buttons
|
* 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) => {
|
handleHighlight = (args: Args) => {
|
||||||
let name;
|
let name;
|
||||||
let message;
|
let message;
|
||||||
let msgTime = 0;
|
let serverTime = 0;
|
||||||
if (args[0] === 'c:') {
|
if (args[0] === 'c:') {
|
||||||
msgTime = parseInt(args[1]);
|
serverTime = parseInt(args[1]);
|
||||||
name = args[2];
|
name = args[2];
|
||||||
message = args[3];
|
message = args[3];
|
||||||
} else {
|
} else {
|
||||||
name = args[1];
|
name = args[1];
|
||||||
message = args[2];
|
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] = {};
|
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
|
// 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);
|
const time = serverTime - (this.timeOffset || 0);
|
||||||
let mayNotify = serverMsgTime > lastMessageDate && name !== PS.user.userid;
|
|
||||||
if (PS.isVisible(this)) {
|
if (PS.isVisible(this)) {
|
||||||
this.lastMessageTime = null;
|
this.lastMessageTime = null;
|
||||||
lastMessageDates[PS.server.id][this.id] = serverMsgTime;
|
lastMessageDates[PS.server.id][this.id] = time;
|
||||||
PS.prefs.set('logtimes', lastMessageDates);
|
PS.prefs.set('logtimes', lastMessageDates);
|
||||||
} else {
|
} else {
|
||||||
// To be saved on focus
|
// To be saved on focus
|
||||||
let lastMessageTime = this.lastMessageTime || 0;
|
const lastMessageTime = this.lastMessageTime || 0;
|
||||||
if (lastMessageTime < serverMsgTime) this.lastMessageTime = serverMsgTime;
|
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({
|
override clientCommands = this.parseClientCommands({
|
||||||
'chall,challenge'(target) {
|
'chall,challenge'(target) {
|
||||||
|
|
|
||||||
|
|
@ -437,7 +437,7 @@ class NewsPanel extends PSRoomPanel {
|
||||||
change = (ev: Event) => {
|
change = (ev: Event) => {
|
||||||
const target = ev.currentTarget as HTMLInputElement;
|
const target = ev.currentTarget as HTMLInputElement;
|
||||||
if (target.value === '1') {
|
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 {
|
} else {
|
||||||
document.cookie = "preactalpha=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
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();
|
this.handleResize();
|
||||||
}
|
}
|
||||||
renderUser() {
|
renderUser() {
|
||||||
if (!PS.connected) {
|
if (!PS.connection?.connected) {
|
||||||
return <button class="button" disabled><em>Offline</em></button>;
|
return <button class="button" disabled><em>Offline</em></button>;
|
||||||
}
|
}
|
||||||
if (PS.user.initializing) {
|
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
|
* Everything else
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ License: GPLv2
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import url(./battle-log.css?v9.8);
|
@import url(./battle-log.css?v10);
|
||||||
|
|
||||||
.battle {
|
.battle {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
||||||
|
|
@ -566,6 +566,9 @@ summary:hover .expandbutton,
|
||||||
border-left: 1px solid #AAAAAA;
|
border-left: 1px solid #AAAAAA;
|
||||||
margin-left: -1px;
|
margin-left: -1px;
|
||||||
}
|
}
|
||||||
|
.dark .ps-room {
|
||||||
|
border-color: #34373b;
|
||||||
|
}
|
||||||
.scrollable {
|
.scrollable {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
-webkit-overflow-scrolling: touch;
|
-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: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%)); }
|
.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
|
* Room list
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user