mirror of
https://github.com/smogon/pokemon-showdown-client.git
synced 2026-09-12 22:09:55 -05:00
Support PM windows
These are now called `mini-window`s by the client code, and they're now generic in the sense that any PS room can be a mini-window, not just PMs and News. This also adds BattleTextParser as a dependency of client-main, removing some duplicate code in exchange for a hopefully-negligible difference in load time.
This commit is contained in:
@@ -54,6 +54,7 @@
|
||||
<script defer src="/js/client-core.js?"></script>
|
||||
|
||||
<script defer src="/js/battle-dex.js?"></script>
|
||||
<script defer src="/js/battle-text-parser.js"></script>
|
||||
<script defer src="/js/client-main.js?"></script>
|
||||
<script defer src="/js/lib/sockjs-1.4.0-nwjsfix.min.js?"></script>
|
||||
<script defer src="/js/client-connection.js?"></script>
|
||||
@@ -68,14 +69,13 @@
|
||||
<script defer src="/js/battle-log.js?"></script>
|
||||
<script defer src="/js/panel-chat.js?"></script>
|
||||
|
||||
<script defer src="js/lib/soundmanager2-nodebug-jsmin.js"></script>
|
||||
<script defer src="js/lib/jquery-2.1.4.min.js"></script>
|
||||
<script defer src="data/graphics.js"></script>
|
||||
<script defer src="js/battle-text-parser.js"></script>
|
||||
<script defer src="data/text.js"></script>
|
||||
<script defer src="js/battle-tooltips.js"></script>
|
||||
<script defer src="js/battle.js"></script>
|
||||
<script defer src="js/panel-battle.js"></script>
|
||||
<script defer src="/js/lib/soundmanager2-nodebug-jsmin.js"></script>
|
||||
<script defer src="/js/lib/jquery-2.1.4.min.js"></script>
|
||||
<script defer src="/data/graphics.js"></script>
|
||||
<script defer src="/data/text.js"></script>
|
||||
<script defer src="/js/battle-tooltips.js"></script>
|
||||
<script defer src="/js/battle.js"></script>
|
||||
<script defer src="/js/panel-battle.js"></script>
|
||||
|
||||
<script defer src="/js/battle-dex-data.js?"></script>
|
||||
<script defer src="/data/pokedex.js?"></script>
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
/**
|
||||
* Text parser
|
||||
*
|
||||
* No dependencies
|
||||
* Optional dependency: BattleText
|
||||
*
|
||||
* @author Guangcong Luo <guangcongluo@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
declare const BattleText: {[id: string]: {[templateName: string]: string}};
|
||||
|
||||
type Args = [string, ...string[]];
|
||||
@@ -15,12 +25,14 @@ class BattleTextParser {
|
||||
this.perspective = perspective;
|
||||
}
|
||||
|
||||
static parseLine(line: string): {args: Args, kwArgs: KWArgs} {
|
||||
static parseLine(line: string, noDefault: true): Args | null;
|
||||
static parseLine(line: string): Args;
|
||||
static parseLine(line: string, noDefault?: boolean): Args | null {
|
||||
if (!line.startsWith('|')) {
|
||||
return {args: ['', line], kwArgs: {}};
|
||||
return ['', line];
|
||||
}
|
||||
if (line === '|') {
|
||||
return {args: ['done'], kwArgs: {}};
|
||||
return ['done'];
|
||||
}
|
||||
const index = line.indexOf('|', 1);
|
||||
const cmd = line.slice(1, index);
|
||||
@@ -28,23 +40,28 @@ class BattleTextParser {
|
||||
case 'chatmsg': case 'chatmsg-raw': case 'raw': case 'error': case 'html':
|
||||
case 'inactive': case 'inactiveoff': case 'warning':
|
||||
case 'fieldhtml': case 'controlshtml': case 'bigerror':
|
||||
case 'debug': case 'tier':
|
||||
return {args: [cmd, line.slice(index + 1)], kwArgs: {}};
|
||||
case 'debug': case 'tier': case 'challstr': case 'popup': case '':
|
||||
return [cmd, line.slice(index + 1)];
|
||||
case 'c': case 'chat': case 'uhtml': case 'uhtmlchange':
|
||||
// three parts
|
||||
const index2a = line.indexOf('|', index + 1);
|
||||
return {args: [cmd, line.slice(index + 1, index2a), line.slice(index2a + 1)], kwArgs: {}};
|
||||
case 'c:':
|
||||
return [cmd, line.slice(index + 1, index2a), line.slice(index2a + 1)];
|
||||
case 'c:': case 'pm':
|
||||
// four parts
|
||||
const index2b = line.indexOf('|', index + 1);
|
||||
const index3b = line.indexOf('|', index2b + 1);
|
||||
return {
|
||||
args: [cmd, line.slice(index + 1, index2b), line.slice(index2b + 1, index3b), line.slice(index3b + 1)],
|
||||
kwArgs: {},
|
||||
};
|
||||
return [cmd, line.slice(index + 1, index2b), line.slice(index2b + 1, index3b), line.slice(index3b + 1)];
|
||||
}
|
||||
let args: Args = line.slice(1).split('|') as any;
|
||||
let kwArgs: KWArgs = {};
|
||||
if (noDefault) return null;
|
||||
return line.slice(1).split('|') as [string, ...string[]];
|
||||
}
|
||||
|
||||
static parseBattleLine(line: string): {args: Args, kwArgs: KWArgs} {
|
||||
let args = this.parseLine(line, true);
|
||||
if (args) return {args, kwArgs: {}};
|
||||
|
||||
args = line.slice(1).split('|') as [string, ...string[]];
|
||||
const kwArgs: KWArgs = {};
|
||||
while (args.length > 1) {
|
||||
const lastArg = args[args.length - 1];
|
||||
if (lastArg.charAt(0) !== '[') break;
|
||||
@@ -159,7 +176,7 @@ class BattleTextParser {
|
||||
extractMessage(buf: string) {
|
||||
let out = '';
|
||||
for (const line of buf.split('\n')) {
|
||||
const {args, kwArgs} = BattleTextParser.parseLine(line);
|
||||
const {args, kwArgs} = BattleTextParser.parseBattleLine(line);
|
||||
out += this.parseArgs(args, kwArgs) || '';
|
||||
}
|
||||
return out;
|
||||
|
||||
@@ -3395,7 +3395,7 @@ class Battle {
|
||||
return;
|
||||
}
|
||||
if (!str) return;
|
||||
const {args, kwArgs} = BattleTextParser.parseLine(str);
|
||||
const {args, kwArgs} = BattleTextParser.parseBattleLine(str);
|
||||
|
||||
if (this.scene.maybeCloseMessagebar(args, kwArgs)) {
|
||||
this.activityStep--;
|
||||
@@ -3408,7 +3408,7 @@ class Battle {
|
||||
let nextKwargs: KWArgs = {};
|
||||
const nextLine = this.activityQueue[this.activityStep + 1] || '';
|
||||
if (nextLine.slice(0, 2) === '|-') {
|
||||
({args: nextArgs, kwArgs: nextKwargs} = BattleTextParser.parseLine(nextLine));
|
||||
({args: nextArgs, kwArgs: nextKwargs} = BattleTextParser.parseBattleLine(nextLine));
|
||||
}
|
||||
|
||||
if (this.debug) {
|
||||
|
||||
@@ -82,11 +82,10 @@ if (!window.console) {
|
||||
*********************************************************************/
|
||||
// PS's model classes are defined here
|
||||
|
||||
const PSURL = (() => {
|
||||
let prefix = '';
|
||||
if (document.location!.protocol !== 'http:') prefix = 'https:';
|
||||
return prefix + '//play.pokemonshowdown.com/';
|
||||
})();
|
||||
const PSURL = (
|
||||
(document.location!.protocol !== 'http:' ? 'https:' : '') +
|
||||
'//play.pokemonshowdown.com/'
|
||||
);
|
||||
|
||||
class PSSubscription {
|
||||
observable: PSModel | PSStreamModel<any>;
|
||||
|
||||
@@ -224,13 +224,16 @@ class PSTeams extends PSStreamModel<'team' | 'format'> {
|
||||
|
||||
class PSUser extends PSModel {
|
||||
name = "Guest";
|
||||
group = '';
|
||||
userid = "guest" as ID;
|
||||
named = false;
|
||||
registered = false;
|
||||
avatar = "1";
|
||||
setName(name: string, named: boolean, avatar: string) {
|
||||
setName(fullName: string, named: boolean, avatar: string) {
|
||||
const loggingIn = (!this.named && named);
|
||||
const {name, group} = BattleTextParser.parseNameParts(fullName);
|
||||
this.name = name;
|
||||
this.group = group;
|
||||
this.userid = toID(name);
|
||||
this.named = named;
|
||||
this.avatar = avatar;
|
||||
@@ -336,7 +339,7 @@ class PSServer {
|
||||
* Rooms
|
||||
*********************************************************************/
|
||||
|
||||
type PSRoomLocation = 'left' | 'right' | 'popup' | 'modal-popup' | 'semimodal-popup';
|
||||
type PSRoomLocation = 'left' | 'right' | 'popup' | 'mini-window' | 'modal-popup' | 'semimodal-popup';
|
||||
|
||||
interface RoomOptions {
|
||||
id: RoomID;
|
||||
@@ -427,7 +430,7 @@ class PlaceholderRoom extends PSRoom {
|
||||
* PS
|
||||
*********************************************************************/
|
||||
|
||||
type RoomType = {Model: typeof PSRoom, Component: any, title?: string};
|
||||
type RoomType = {Model?: typeof PSRoom, Component: any, title?: string};
|
||||
|
||||
/**
|
||||
* This model updates:
|
||||
@@ -464,6 +467,8 @@ const PS = new class extends PSModel {
|
||||
leftRoomList: RoomID[] = [];
|
||||
/** List of rooms on the right side of the top tabbar */
|
||||
rightRoomList: RoomID[] = [];
|
||||
/** List of mini-rooms in the Main Menu */
|
||||
miniRoomList: RoomID[] = [];
|
||||
/** Currently active popups, in stack order (bottom to top) */
|
||||
popups: RoomID[] = [];
|
||||
|
||||
@@ -527,54 +532,32 @@ const PS = new class extends PSModel {
|
||||
/** Tracks whether or not to display the "Use arrow keys" hint */
|
||||
arrowKeysUsed = false;
|
||||
|
||||
newsHTML = document.querySelector('.news-embed .pm-log')?.innerHTML || '';
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.addRoom({
|
||||
id: '' as RoomID,
|
||||
title: "Home",
|
||||
type: 'mainmenu',
|
||||
});
|
||||
|
||||
this.addRoom({
|
||||
id: 'rooms' as RoomID,
|
||||
title: "Rooms",
|
||||
type: 'rooms',
|
||||
});
|
||||
|
||||
if (this.newsHTML) {
|
||||
this.addRoom({
|
||||
id: 'news' as RoomID,
|
||||
title: "News",
|
||||
});
|
||||
}
|
||||
|
||||
this.updateLayout();
|
||||
window.addEventListener('resize', () => this.updateLayout());
|
||||
}
|
||||
|
||||
lineParse(str: string): [string, ...string[]] {
|
||||
if (!str.startsWith('|')) {
|
||||
return ['', str];
|
||||
}
|
||||
const index = str.indexOf('|', 1);
|
||||
const cmd = str.slice(1, index);
|
||||
switch (cmd) {
|
||||
case 'html':
|
||||
case 'raw':
|
||||
case 'challstr':
|
||||
case 'popup':
|
||||
case '':
|
||||
return [cmd, str.slice(index + 1)];
|
||||
case 'c':
|
||||
case 'uhtml':
|
||||
case 'uhtmlchange':
|
||||
// three parts
|
||||
const index2a = str.indexOf('|', index + 1);
|
||||
return [cmd, str.slice(index + 1, index2a), str.slice(index2a + 1)];
|
||||
case 'c:':
|
||||
case 'pm':
|
||||
// four parts
|
||||
const index2b = str.indexOf('|', index + 1);
|
||||
const index3b = str.indexOf('|', index2b + 1);
|
||||
return [cmd, str.slice(index + 1, index2b), str.slice(index2b + 1, index3b), str.slice(index3b + 1)];
|
||||
}
|
||||
return str.slice(1).split('|') as [string, ...string[]];
|
||||
}
|
||||
|
||||
// Panel layout
|
||||
///////////////
|
||||
/**
|
||||
@@ -750,6 +733,7 @@ const PS = new class extends PSModel {
|
||||
switch (hyphenIndex < 0 ? options.id : options.id.slice(0, hyphenIndex + 1)) {
|
||||
case 'teambuilder': case 'ladder': case 'battles': case 'rooms':
|
||||
case 'options': case 'volume': case 'teamdropdown': case 'formatdropdown':
|
||||
case 'news':
|
||||
options.type = options.id;
|
||||
break;
|
||||
case 'battle-': case 'user-': case 'team-':
|
||||
@@ -758,6 +742,9 @@ const PS = new class extends PSModel {
|
||||
case 'view-':
|
||||
options.type = 'html';
|
||||
break;
|
||||
case '':
|
||||
options.type = 'mainmenu';
|
||||
break;
|
||||
default:
|
||||
options.type = 'chat';
|
||||
break;
|
||||
@@ -779,12 +766,16 @@ const PS = new class extends PSModel {
|
||||
case 'formatdropdown':
|
||||
options.location = 'semimodal-popup';
|
||||
break;
|
||||
case 'news':
|
||||
options.location = 'mini-window';
|
||||
break;
|
||||
}
|
||||
if (options.id.startsWith('pm-')) options.location = 'mini-window';
|
||||
}
|
||||
|
||||
const roomType = this.roomTypes[options.type];
|
||||
if (roomType?.title) options.title = roomType.title;
|
||||
const Model = roomType ? roomType.Model : PlaceholderRoom;
|
||||
const Model = roomType ? (roomType.Model || PSRoom) : PlaceholderRoom;
|
||||
return new Model(options);
|
||||
}
|
||||
updateRoomTypes() {
|
||||
@@ -797,7 +788,8 @@ const PS = new class extends PSModel {
|
||||
|
||||
const options: RoomOptions = room;
|
||||
if (roomType.title) options.title = roomType.title;
|
||||
const newRoom = new roomType.Model(options);
|
||||
const Model = roomType.Model || PSRoom;
|
||||
const newRoom = new Model(options);
|
||||
this.rooms[roomid] = newRoom;
|
||||
if (this.leftRoom === room) this.leftRoom = newRoom;
|
||||
if (this.rightRoom === room) this.rightRoom = newRoom;
|
||||
@@ -937,6 +929,9 @@ const PS = new class extends PSModel {
|
||||
}
|
||||
if (!noFocus || !this.rightRoom) this.rightRoom = room;
|
||||
break;
|
||||
case 'mini-window':
|
||||
this.miniRoomList.push(room.id);
|
||||
break;
|
||||
case 'popup':
|
||||
case 'semimodal-popup':
|
||||
case 'modal-popup':
|
||||
@@ -979,6 +974,13 @@ const PS = new class extends PSModel {
|
||||
if (PS.room === room) PS.room = PS.activePanel;
|
||||
}
|
||||
|
||||
if (room.location === 'mini-window') {
|
||||
const miniRoomIndex = PS.miniRoomList.indexOf(room.id);
|
||||
if (miniRoomIndex >= 0) {
|
||||
PS.miniRoomList.splice(miniRoomIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.popups.length && room.id === this.popups[this.popups.length - 1]) {
|
||||
this.popups.pop();
|
||||
PS.room = this.popups.length ? PS.rooms[this.popups[this.popups.length - 1]]! : PS.activePanel;
|
||||
|
||||
@@ -360,6 +360,7 @@ class ChatPanel extends PSRoomPanel<ChatRoom> {
|
||||
};
|
||||
render() {
|
||||
const room = this.props.room;
|
||||
const isPM = !!room.pmTarget;
|
||||
|
||||
const challengeTo = room.challengingFormat ? <div class="challenge">
|
||||
<TeamForm format={room.challengingFormat} onSubmit={null}>
|
||||
@@ -381,11 +382,11 @@ class ChatPanel extends PSRoomPanel<ChatRoom> {
|
||||
|
||||
return <PSPanelWrapper room={room}>
|
||||
<div class="tournament-wrapper hasuserlist"></div>
|
||||
<ChatLog class="chat-log" room={this.props.room} onClick={this.focusIfNoSelection} left={146}>
|
||||
<ChatLog class="chat-log" room={this.props.room} onClick={this.focusIfNoSelection} left={isPM ? 0 : 146}>
|
||||
{challengeTo || challengeFrom && [challengeTo, challengeFrom]}
|
||||
</ChatLog>
|
||||
<ChatTextEntry room={this.props.room} onMessage={this.send} onKey={this.onKey} left={146} />
|
||||
<ChatUserList room={this.props.room} />
|
||||
<ChatTextEntry room={this.props.room} onMessage={this.send} onKey={this.onKey} left={isPM ? 0 : 146} />
|
||||
<ChatUserList room={this.props.room} minimized={isPM} />
|
||||
</PSPanelWrapper>;
|
||||
}
|
||||
}
|
||||
@@ -455,7 +456,7 @@ class ChatLog extends preact.Component<{
|
||||
}
|
||||
this.subscription = this.props.room.subscribe(msg => {
|
||||
if (!msg) return;
|
||||
const tokens = PS.lineParse(msg);
|
||||
const tokens = BattleTextParser.parseLine(msg);
|
||||
switch (tokens[0]) {
|
||||
case 'title':
|
||||
this.props.room.title = tokens[1];
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
* @license AGPLv3
|
||||
*/
|
||||
|
||||
// Example room with panel
|
||||
|
||||
class ExampleRoom extends PSRoom {
|
||||
readonly classType: string = 'example';
|
||||
constructor(options: RoomOptions) {
|
||||
@@ -27,3 +29,18 @@ PS.roomTypes['example'] = {
|
||||
Model: ExampleRoom,
|
||||
Component: ExamplePanel,
|
||||
};
|
||||
|
||||
// Example panel with no room
|
||||
|
||||
class ExampleViewPanel extends PSRoomPanel {
|
||||
render() {
|
||||
const room = this.props.room;
|
||||
return <PSPanelWrapper room={room}>
|
||||
<div class="mainmessage"><p>Loading...</p></div>
|
||||
</PSPanelWrapper>;
|
||||
}
|
||||
}
|
||||
|
||||
PS.roomTypes['exampleview'] = {
|
||||
Component: ExampleViewPanel,
|
||||
};
|
||||
|
||||
@@ -23,7 +23,7 @@ class MainMenuRoom extends PSRoom {
|
||||
pspl?: RoomInfo[],
|
||||
} = {};
|
||||
receive(line: string) {
|
||||
const tokens = PS.lineParse(line);
|
||||
const tokens = BattleTextParser.parseLine(line);
|
||||
switch (tokens[0]) {
|
||||
case 'challstr':
|
||||
PSLoginServer.query({
|
||||
@@ -242,13 +242,41 @@ class MainMenuRoom extends PSRoom {
|
||||
}
|
||||
}
|
||||
|
||||
class MainMenuPanel extends PSRoomPanel {
|
||||
class NewsPanel extends PSRoomPanel {
|
||||
render() {
|
||||
return <PSPanelWrapper room={this.props.room} scrollable>
|
||||
<div class="mini-window-body" dangerouslySetInnerHTML={{__html: PS.newsHTML}}></div>
|
||||
</PSPanelWrapper>;
|
||||
}
|
||||
}
|
||||
|
||||
class MainMenuPanel extends PSRoomPanel<MainMenuRoom> {
|
||||
focus() {
|
||||
(this.base!.querySelector('button.big') as HTMLButtonElement).focus();
|
||||
}
|
||||
submit = (e: Event) => {
|
||||
alert('todo: implement');
|
||||
};
|
||||
renderMiniRoom(room: PSRoom) {
|
||||
const roomType = PS.roomTypes[room.type];
|
||||
const Panel = roomType ? roomType.Component : PSRoomPanel;
|
||||
return <Panel key={room.id} room={room} />;
|
||||
}
|
||||
renderMiniRooms() {
|
||||
return PS.miniRoomList.map(roomid => {
|
||||
const room = PS.rooms[roomid]!;
|
||||
return <div class="pmbox">
|
||||
<div class="mini-window">
|
||||
<h3>
|
||||
<button class="closebutton" name="closeRoom" value={roomid} aria-label="Close" tabIndex={-1}><i class="fa fa-times-circle"></i></button>
|
||||
<button class="minimizebutton" tabIndex={-1}><i class="fa fa-minus-circle"></i></button>
|
||||
{room.title}
|
||||
</h3>
|
||||
{this.renderMiniRoom(room)}
|
||||
</div>
|
||||
</div>;
|
||||
});
|
||||
}
|
||||
render() {
|
||||
const onlineButton = ' button' + (PS.isOffline ? ' disabled' : '');
|
||||
const searchButton = (PS.down ? <div class="menugroup" style="background: rgba(10,10,10,.6)">
|
||||
@@ -274,22 +302,7 @@ class MainMenuPanel extends PSRoomPanel {
|
||||
<div class="mainmenuwrapper">
|
||||
<div class="leftmenu">
|
||||
<div class="activitymenu">
|
||||
<div class="pmbox">
|
||||
<div class="pm-window news-embed" data-newsid="<!-- newsid -->">
|
||||
<h3>
|
||||
<button class="closebutton" tabIndex={-1}><i class="fa fa-times-circle"></i></button>
|
||||
<button class="minimizebutton" tabIndex={-1}><i class="fa fa-minus-circle"></i></button>
|
||||
News
|
||||
</h3>
|
||||
<div class="pm-log" style="max-height:none">
|
||||
<div class="newsentry">
|
||||
<h4>Test client</h4>
|
||||
<p>Welcome to the test client! You can test client changes here!</p>
|
||||
<p>—<strong>Zarel</strong> <small class="date">on Sep 25, 2015</small></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{this.renderMiniRooms()}
|
||||
</div>
|
||||
<div class="mainmenu">
|
||||
{searchButton}
|
||||
@@ -437,6 +450,10 @@ class TeamForm extends preact.Component<{
|
||||
}
|
||||
}
|
||||
|
||||
PS.roomTypes['news'] = {
|
||||
Component: NewsPanel,
|
||||
};
|
||||
|
||||
PS.roomTypes['mainmenu'] = {
|
||||
Model: MainMenuRoom,
|
||||
Component: MainMenuPanel,
|
||||
|
||||
@@ -190,7 +190,6 @@ class TeamPanel extends PSRoomPanel {
|
||||
}
|
||||
|
||||
PS.roomTypes['team'] = {
|
||||
Model: PSRoom,
|
||||
Component: TeamPanel,
|
||||
title: "Team",
|
||||
};
|
||||
|
||||
@@ -221,7 +221,6 @@ class TeambuilderPanel extends PSRoomPanel {
|
||||
}
|
||||
|
||||
PS.roomTypes['teambuilder'] = {
|
||||
Model: PSRoom,
|
||||
Component: TeambuilderPanel,
|
||||
title: "Teambuilder",
|
||||
};
|
||||
|
||||
@@ -624,11 +624,9 @@ class FormatDropdownPanel extends PSRoomPanel {
|
||||
}
|
||||
|
||||
PS.roomTypes['teamdropdown'] = {
|
||||
Model: PSRoom,
|
||||
Component: TeamDropdownPanel,
|
||||
};
|
||||
|
||||
PS.roomTypes['formatdropdown'] = {
|
||||
Model: PSRoom,
|
||||
Component: FormatDropdownPanel,
|
||||
};
|
||||
|
||||
@@ -142,6 +142,12 @@ function PSPanelWrapper(props: {
|
||||
room: PSRoom, children: preact.ComponentChildren, scrollable?: boolean, width?: number,
|
||||
}) {
|
||||
const room = props.room;
|
||||
if (room.location === 'mini-window') {
|
||||
if (room.id === 'news') {
|
||||
return <div>{props.children}</div>;
|
||||
}
|
||||
return <div id={`room-${room.id}`} class="mini-window-contents ps-room-light">{props.children}</div>;
|
||||
}
|
||||
if (room.location !== 'left' && room.location !== 'right') {
|
||||
const style = PSMain.getPopupStyle(room, props.width);
|
||||
return <div class="ps-popup" id={`room-${room.id}`} style={style}>
|
||||
|
||||
@@ -531,10 +531,10 @@ select {
|
||||
color: #BB2222;
|
||||
}
|
||||
.minimizebutton:hover,
|
||||
.pm-window h3:hover .minimizebutton {
|
||||
.mini-window h3:hover .minimizebutton {
|
||||
color: #333333;
|
||||
}
|
||||
.pm-window h3 .closebutton:hover + .minimizebutton {
|
||||
.mini-window h3 .closebutton:hover + .minimizebutton {
|
||||
color: #999999 !important;
|
||||
}
|
||||
.closebutton:active,
|
||||
@@ -624,11 +624,11 @@ select {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow-scrolling: touch;
|
||||
}
|
||||
.ps-room.ps-room-light {
|
||||
.ps-room.ps-room-light, .ps-room-light {
|
||||
background: rgba(242,247,250,.85);
|
||||
color: black;
|
||||
}
|
||||
.ps-room.ps-room-opaque {
|
||||
.ps-room.ps-room-opaque, .ps-room-opaque {
|
||||
background: #EEF2F5;
|
||||
color: black;
|
||||
}
|
||||
@@ -824,13 +824,13 @@ p.or:after {
|
||||
margin: 0 auto;
|
||||
min-height: 2px;
|
||||
}
|
||||
.pm-window {
|
||||
.mini-window {
|
||||
margin: 0 -12px 12px -10px;
|
||||
}
|
||||
.tiny-layout .pm-window {
|
||||
.tiny-layout .mini-window {
|
||||
margin: 0 0 12px 0;
|
||||
}
|
||||
.pm-window h3 {
|
||||
.mini-window h3 {
|
||||
background: rgba(248,248,248,.8);
|
||||
color: #777777;
|
||||
margin: 0;
|
||||
@@ -841,33 +841,41 @@ p.or:after {
|
||||
border-top-right-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.pm-window h3:hover {
|
||||
.mini-window h3:hover {
|
||||
color: #333333;
|
||||
}
|
||||
.pm-window h3.pm-minimized {
|
||||
.mini-window h3.pm-minimized {
|
||||
border-radius: 5px;
|
||||
}
|
||||
.pm-window h3.pm-notifying {
|
||||
.mini-window h3.pm-notifying {
|
||||
border-color: #AA8866;
|
||||
background: #E3C3A3;
|
||||
}
|
||||
.pm-window h3.pm-notifying:hover {
|
||||
.mini-window h3.pm-notifying:hover {
|
||||
border-color: #604020;
|
||||
background: #CFAF8F;
|
||||
}
|
||||
.pm-window h3 .closebutton,
|
||||
.pm-window h3 .minimizebutton {
|
||||
.mini-window h3 .closebutton,
|
||||
.mini-window h3 .minimizebutton {
|
||||
float: right;
|
||||
margin: -3px -3px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
.pm-window h3 small {
|
||||
.mini-window h3 small {
|
||||
color: #888888;
|
||||
font-weight: normal;
|
||||
vertical-align: 1px;
|
||||
}
|
||||
.pm-log {
|
||||
.mini-window .mini-window-contents {
|
||||
position: relative;
|
||||
height: 300px;
|
||||
border: 1px solid #AAAAAA;
|
||||
border-top: 0;
|
||||
border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
.mini-window-body, .pm-log {
|
||||
min-height: 100px;
|
||||
max-height: 300px;
|
||||
background: rgba(242,247,250,.925);
|
||||
@@ -875,12 +883,18 @@ p.or:after {
|
||||
word-wrap: break-word;
|
||||
border: 1px solid #AAAAAA;
|
||||
border-top: 0;
|
||||
border-bottom: 0;
|
||||
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow-scrolling: touch;
|
||||
}
|
||||
.mini-window-body {
|
||||
border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
.pm-log {
|
||||
border-bottom: 0;
|
||||
}
|
||||
.pm-log-add {
|
||||
color: black;
|
||||
border: 1px solid #AAAAAA;
|
||||
@@ -888,17 +902,17 @@ p.or:after {
|
||||
border-bottom-right-radius: 5px;
|
||||
background: rgba(242,247,250,.85);
|
||||
}
|
||||
.pm-window.collapsed .pm-log,
|
||||
.pm-window.collapsed .pm-log-add {
|
||||
.mini-window.collapsed .pm-log,
|
||||
.mini-window.collapsed .pm-log-add {
|
||||
display: none;
|
||||
}
|
||||
.pm-window.focused h3,
|
||||
.pm-window.focused .pm-log,
|
||||
.pm-window.focused .pm-log-add {
|
||||
.mini-window.focused h3,
|
||||
.mini-window.focused .pm-log,
|
||||
.mini-window.focused .pm-log-add {
|
||||
border-color: #555555;
|
||||
}
|
||||
.pm-window.focused h3,
|
||||
.pm-window.focused h3:hover {
|
||||
.mini-window.focused h3,
|
||||
.mini-window.focused h3:hover {
|
||||
background: #f8f8f8;
|
||||
color: #222222;
|
||||
}
|
||||
@@ -916,6 +930,7 @@ p.or:after {
|
||||
font-size: 9pt;
|
||||
padding: 1px 10px;
|
||||
border-bottom: 1px solid #AAAAAA;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
.unread {
|
||||
background: rgba(255,240,130,0.33);
|
||||
@@ -1220,7 +1235,7 @@ p.or:after {
|
||||
}
|
||||
.chat-log .inner,
|
||||
.pm-log .inner {
|
||||
padding: 4px 8px 6px 8px;
|
||||
padding: 24px 8px 6px 8px;
|
||||
}
|
||||
a.ilink {
|
||||
text-decoration: none;
|
||||
@@ -3286,9 +3301,9 @@ a.ilink.yours {
|
||||
.dark .menugroup {
|
||||
background: rgba(0,0,0,.2);
|
||||
}
|
||||
.dark .pm-window.focused h3,
|
||||
.dark .pm-window.focused .pm-log,
|
||||
.dark .pm-window.focused .pm-log-add {
|
||||
.dark .mini-window.focused h3,
|
||||
.dark .mini-window.focused .pm-log,
|
||||
.dark .mini-window.focused .pm-log-add {
|
||||
border-color: #CCC;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
<script src="js/client-core.js"></script>
|
||||
|
||||
<script src="js/battle-dex.js"></script>
|
||||
<script src="js/battle-text-parser.js"></script>
|
||||
<script src="js/client-main.js"></script>
|
||||
<script src="js/lib/sockjs-1.4.0-nwjsfix.min.js"></script>
|
||||
<script src="js/client-connection.js"></script>
|
||||
@@ -72,7 +73,6 @@
|
||||
<script src="js/lib/soundmanager2-nodebug-jsmin.js"></script>
|
||||
<script src="js/lib/jquery-2.1.4.min.js"></script>
|
||||
<script src="data/graphics.js"></script>
|
||||
<script src="js/battle-text-parser.js"></script>
|
||||
<script src="data/text.js"></script>
|
||||
<script src="js/battle-tooltips.js"></script>
|
||||
<script src="js/battle.js"></script>
|
||||
|
||||
Reference in New Issue
Block a user