Improved code

This commit is contained in:
2019-09-08 18:57:30 +02:00
parent df3f1f409d
commit 3c801987bb
10 changed files with 452 additions and 270 deletions
@@ -13,6 +13,7 @@
| Party
a.link-plain.chat-log-tab(#whisperTab tabindex (click)="switchTab('whisper')")
| Whisper
input.link-plain.chat-log-tab.chat-log-filter(#filterTab type="text" [style.background-color]="filterColor" (keyup.enter)="(unFocus())" (keyup.esc)="(unFocus())" [placeholder]="'Filter'" (keyup)="filterChat()")
.chat-log-scroll-outer()
.chat-log-scroll-inner(#scroll)
.chat-log-scroll-inner-inner(#lines)
@@ -25,3 +26,4 @@ button.game-button.chat-log-toggle(#toggleButton (click)="toggle()" title="Toggl
path.main-bubble(fill="currentColor" d="M416 192c0-88.4-93.1-160-208-160S0 103.6 0 192c0 34.3 14.1 65.9 38 92-13.4 30.2-35.5 54.2-35.8 54.5-2.2 2.3-2.8 5.7-1.5 8.7S4.8 352 8 352c36.6 0 66.9-12.3 88.7-25 32.2 15.7 70.3 25 111.3 25 114.9 0 208-71.6 208-160z")
path(fill="currentColor" d="M538 412c23.9-26 38-57.7 38-92 0-66.9-53.5-124.2-129.3-148.1.9 6.6 1.3 13.3 1.3 20.1 0 105.9-107.7 192-240 192-10.8 0-21.3-.8-31.7-1.9C207.8 439.6 281.8 480 368 480c41 0 79.1-9.2 111.3-25 21.8 12.7 52.1 25 88.7 25 3.2 0 6.1-1.9 7.3-4.8 1.3-2.9.7-6.3-1.5-8.7-.3-.3-22.4-24.2-35.8-54.5z")
.whispers-count(#count)
+143 -104
View File
@@ -1,159 +1,198 @@
@import '../../../../styles/partials/variables';
$chat-log-bg: rgba(0, 0, 0, 0.2);
$chat-log-bg-faded: rgba(0, 0, 0, 0.1);
$chat-log-bg-hover: rgba(0, 0, 0, 0.5);
$chat-log-tabs-height: 30px;
$chat-log-buttons-width: 40px;
$resizer-size: 12px;
$resizer-offset: $resizer-size / 2;
.chat-log {
display: flex;
position: absolute;
bottom: 0;
left: 0;
right: 0;
min-width: 200px;
max-width: 100%;
max-height: calc(100vh - 220px);
min-height: 120px;
display: flex;
position: absolute;
bottom: 0;
left: 0;
right: 0;
min-width: 200px;
max-width: 100%;
max-height: calc(100vh - 220px);
min-height: 120px;
}
.chat-log-buttons {
flex-direction: column-reverse;
width: $chat-log-buttons-width;
padding: 5px 3px;
padding-bottom: 30px;
z-index: 2;
flex-direction: column-reverse;
width: $chat-log-buttons-width;
padding: 5px 3px;
padding-bottom: 30px;
z-index: 2;
}
.chat-log-toggle {
position: absolute;
bottom: 5px;
left: 4px;
z-index: 3;
position: absolute;
bottom: 5px;
left: 4px;
z-index: 3;
}
.has-unread .main-bubble {
color: $chat-whisper;
color: $chat-whisper;
}
.whispers-count {
color: white;
font-weight: bold;
text-align: center;
position: absolute;
left: 6px;
top: 9px;
width: 16px;
font-size: 10px;
display: flex;
justify-content: center;
align-items: center;
line-height: 1rem;
color: white;
font-weight: bold;
text-align: center;
position: absolute;
left: 6px;
top: 9px;
width: 16px;
font-size: 10px;
display: flex;
justify-content: center;
align-items: center;
line-height: 1rem;
}
.whisper-icon {
position: absolute;
top: 0;
left: 0;
font-size: 14px;
color: $chat-whisper !important;
position: absolute;
top: 0;
left: 0;
font-size: 14px;
color: $chat-whisper !important;
}
.chat-log-content {
position: relative;
display: flex;
background: $chat-log-bg;
padding: 5px 0;
padding-left: 40px;
margin-left: -$chat-log-buttons-width;
border-radius: $border-radius-base;
word-break: break-word;
white-space: pre-line;
line-height: 20px;
height: 100%;
width: 100%;
position: relative;
display: flex;
background: $chat-log-bg;
padding: 5px 0;
padding-left: 40px;
margin-left: -$chat-log-buttons-width;
border-radius: $border-radius-base;
word-break: break-word;
white-space: pre-line;
line-height: 20px;
height: 100%;
width: 100%;
}
.chat-log-tabs {
position: absolute;
top: -$chat-log-tabs-height;
left: 30px;
display: flex;
user-select: none;
position: absolute;
top: -$chat-log-tabs-height;
left: 30px;
display: flex;
user-select: none;
text-shadow: 0px 0px 4px #000000;
}
.chat-log-tab {
background: $chat-log-bg-faded;
padding: 5px 10px 0;
margin-left: 10px;
height: $chat-log-tabs-height;
border-top-left-radius: $border-radius-base;
border-top-right-radius: $border-radius-base;
color: white;
overflow: hidden;
&.active {
background: $chat-log-bg;
}
background: $chat-log-bg-faded;
padding: 5px 10px 0;
margin-left: 10px;
height: $chat-log-tabs-height;
border-top-left-radius: $border-radius-base;
border-top-right-radius: $border-radius-base;
color: white;
overflow: hidden;
&.active {
background: $chat-log-bg;
}
}
.chat-log-scroll-outer {
overflow: hidden;
width: 100%;
overflow: hidden;
width: 100%;
}
.chat-log-scroll-inner {
width: calc(100% + 50px);
height: 100%;
overflow-x: hidden;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
width: calc(100% + 50px);
height: 100%;
overflow-x: hidden;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
.chat-log-scroll-inner-inner {
display: flex;
flex-direction: column;
justify-content: flex-end;
min-height: 100%;
padding: 0 5px;
display: flex;
flex-direction: column;
justify-content: flex-end;
min-height: 100%;
padding: 0 5px;
}
.chat-log-resize-top {
position: absolute;
top: -$resizer-offset;
right: $resizer-offset;
height: $resizer-size;
left: 250px;
cursor: ns-resize;
position: absolute;
top: -$resizer-offset;
right: $resizer-offset;
height: $resizer-size;
left: 250px;
cursor: ns-resize;
}
.chat-log-resize-top-right {
position: absolute;
top: -($resizer-offset + 1);
right: -($resizer-offset + 1);
width: $resizer-size + 4;
height: $resizer-size + 4;
cursor: nesw-resize;
position: absolute;
top: -($resizer-offset + 1);
right: -($resizer-offset + 1);
width: $resizer-size + 4;
height: $resizer-size + 4;
cursor: nesw-resize;
}
.chat-log-resize-right {
position: absolute;
top: $resizer-offset;
right: -$resizer-offset;
width: $resizer-size;
bottom: $resizer-offset;
cursor: ew-resize;
position: absolute;
top: $resizer-offset;
right: -$resizer-offset;
width: $resizer-size;
bottom: $resizer-offset;
cursor: ew-resize;
}
.resize-icon {
font-size: 18px;
position: absolute;
top: -3px;
right: 1px;
transform: rotate(45deg);
color: rgba(255, 255, 255, 0.2);
font-size: 18px;
position: absolute;
top: -3px;
right: 1px;
transform: rotate(45deg);
color: rgba(255, 255, 255, 0.2);
}
.chat-log-filter {
padding-bottom: 5px;
border: none;
width: 100px;
}
.chat-log-filter::-webkit-input-placeholder {
opacity: 1;
color: white;
text-shadow: 0px 0px 4px #000000;
}
.chat-log-filter:-moz-placeholder {
/* Firefox 18- */
opacity: 1;
color: white;
text-shadow: 0px 0px 4px #000000;
}
.chat-log-filter::-moz-placeholder {
/* Firefox 19+ */
opacity: 1;
color: white;
text-shadow: 0px 0px 4px #000000;
}
.chat-log-filter:-ms-input-placeholder {
opacity: 1;
color: white;
text-shadow: 0px 0px 4px #000000;
}
@media only screen and (max-width: 360px) {
.chat-log-filter {
position: absolute;
left: 0;
bottom: 35px;
width: 100%;
border-radius: 2px;
}
}
+55 -91
View File
@@ -12,6 +12,8 @@ import { DEFAULT_CHATLOG_OPACITY, PONY_TYPE, SECOND } from '../../../common/cons
import { faCaretUp, faArrowDown } from '../../../client/icons';
import { sampleMessages } from '../../../common/debugData';
import { findEntityById } from '../../../common/worldMap';
import { colorToRGBA, rgb2hsl, HSL, hsl2CSS } from '../../../common/color';
import * as moment from 'moment';
interface IndexEntryUser {
id: number;
@@ -103,11 +105,9 @@ export function createChatLogLineDOM(clickLabel: ClickHandler, clickName: ClickH
line.root = element('div', 'chat-line', [
element('span', 'chat-line-lead'),
line.time = element('span', 'chat-line-name', [
textNode(`[`),
line.timeContent = element(
'span', 'chat-line-time-content', [textNode('')], undefined),
line.index = element('span', 'chat-line-time-index', [line.indexText = textNode('')]),
textNode('] '),
]),
line.label = element(
'span', 'chat-line-label mr-1', [line.labelText = textNode('')], undefined, { click: () => clickLabel(line.entry) }),
@@ -127,7 +127,7 @@ export function createChatLogLineDOM(clickLabel: ClickHandler, clickName: ClickH
return line;
}
export function updateChatLogLine(line: ChatLogLineDOM, entry: ChatLogMessage) {
export function updateChatLogLine(line: ChatLogLineDOM, entry: ChatLogMessage, hourMode?: '12' | '24') {
const { classes, label, message, prefix, suffix } = entry;
const hasSpace = message.indexOf(' ') !== -1;
@@ -137,27 +137,23 @@ export function updateChatLogLine(line: ChatLogLineDOM, entry: ChatLogMessage) {
line.labelText.nodeValue = label ? `[${label}]` : '';
updateChatLogName(line, entry);
updateTime(line);
updateTime(line, hourMode);
line.prefixText.nodeValue = prefix || '';
line.suffixText.nodeValue = suffix ? ` ${suffix}: ` : ': ';
replaceNodes(line.message, message);
}
function updateTime(line: ChatLogLineDOM) {
function updateTime(line: ChatLogLineDOM, hourMode?: '12' | '24') {
line.time.style.display = 'inline';
replaceNodes(line.timeContent, getCurrentTime());
if (!hourMode) return;
if (hourMode === '24')
replaceNodes(line.timeContent, `[${moment().format('HH:mm:ss')}] `);
if (hourMode === '12')
replaceNodes(line.timeContent, `[${moment().format('LTS')}] `);
}
function getCurrentTime() {
const date = new Date();
const hours = date.getHours().toString();
const minutes = date.getMinutes().toString();
const seconds = date.getSeconds().toString();
return `${hours.length === 1 ? `0${hours}` : hours}:${minutes.length === 1 ? `0${minutes}` : minutes}:${seconds.length === 1 ? `0${seconds}` : seconds}`;
}
function setNameColors(line: ChatLogLineDOM | undefined, colors?: string[] | null) {
function setNameColors(line: ChatLogLineDOM | undefined, colors?: string[]) {
if (!colors || !line) return;
if (colors[1]) line.name.style.color = colors[1];
if (colors[0]) line.nameContent.style.color = colors[0];
@@ -232,6 +228,7 @@ export class ChatLog implements AfterViewInit, OnDestroy, DoCheck {
local: ChatLogMessage[] = [];
party: ChatLogMessage[] = [];
whisper: ChatLogMessage[] = [];
filterColor = this.inactiveBg;
unread = 0;
private subscriptions: Subscription[] = [];
private startX = 0;
@@ -243,9 +240,8 @@ export class ChatLog implements AfterViewInit, OnDestroy, DoCheck {
private indexes = new Map<string, IndexEntry>();
private messageCounter = 0;
private lastOpacity = 0;
private autoClear: null | NodeJS.Timeout = null;
private autoUnfocus: null | NodeJS.Timeout = null;
filterColor = this.inactiveBg;
private autoClear?: NodeJS.Timeout;
private autoUnfocus?: NodeJS.Timeout;
constructor(
private game: PonyTownGame,
private settingsService: SettingsService,
@@ -460,7 +456,7 @@ export class ChatLog implements AfterViewInit, OnDestroy, DoCheck {
if (!value) {
this.clearTimeOutAutoClear();
this.unFocus();
this.showHideChatLogLines('', false);
this.filterChatLogLines('', false);
return;
}
else this.filterColor = this.bg;
@@ -482,9 +478,10 @@ export class ChatLog implements AfterViewInit, OnDestroy, DoCheck {
value = value.slice(1);
try {
const regExp = new RegExp(value);
this.showHideChatLogLines(regExp, toLowerCase);
this.filterChatLogLines(regExp, toLowerCase);
this.filterTab.nativeElement.style.color = '';
} catch (err) {
} catch (err) {// If the user inputs invalid regExp we just notify him by changing text color to red
if (DEVELOPMENT) console.error(err);
this.filterTab.nativeElement.style.color = '#ff6666';
}
return;
@@ -493,10 +490,10 @@ export class ChatLog implements AfterViewInit, OnDestroy, DoCheck {
value = value.toLowerCase();
toLowerCase = true;
}
this.showHideChatLogLines(value, toLowerCase);
this.filterChatLogLines(value, toLowerCase);
}
showHideChatLogLines(content: string | RegExp, caseSensitive: boolean) {
filterChatLogLines(content: string | RegExp, caseSensitive: boolean) {
const lines = this.linesElement.getElementsByTagName('div');
for (let i = 0; i < lines.length; i++) {
@@ -507,11 +504,12 @@ export class ChatLog implements AfterViewInit, OnDestroy, DoCheck {
if (typeof content === 'string') {
if (caseSensitive)
textContent.toLowerCase().includes(content) ? lines[i].hidden = false : lines[i].hidden = true;
lines[i].hidden = !textContent.toLowerCase().includes(content);
else
textContent.includes(content) ? lines[i].hidden = false : lines[i].hidden = true;
lines[i].hidden = !textContent.includes(content);
} else {
textContent.match(content) ? lines[i].hidden = false : lines[i].hidden = true;
lines[i].hidden = !textContent.match(content);
}
}
}
@@ -523,79 +521,45 @@ export class ChatLog implements AfterViewInit, OnDestroy, DoCheck {
lines[i].hidden = false;
}
}
private getRGB(hex: string) {
const bigint = parseInt(hex, 16);
const r = (bigint >> 16) & 255;
const g = (bigint >> 8) & 255;
const b = bigint & 255;
return [r, g, b];
}
private RGBToHSL(rgb: number[]) {
let r = rgb[0] / 255;
let g = rgb[1] / 255;
let b = rgb[2] / 255;
let max = Math.max(r, g, b);
let min = Math.min(r, g, b);
let delta = max - min;
let h = 0;
let s;
let l;
if (max === min) h = 0;
else if (r === max) h = (g - b) / delta;
else if (g === max) h = 2 + (b - r) / delta;
else if (b === max) h = 4 + (r - g) / delta;
h = Math.min(h * 60, 360);
if (h < 0) h += 360;
l = (min + max) / 2;
if (max === min) s = 0;
else if (l <= 0.5) s = delta / (max + min);
else s = delta / (2 - max - min);
h = Math.floor(h);
s = Math.floor(s * 100);
l = Math.floor(l * 100);
if (l < 40) {
if (l > 20 && l < 40) {
l += 20;
if (s > 11) s -= 11;
brightenDarkColors(hsl: HSL) {
if (hsl.l < 40) {
if (hsl.l > 20 && hsl.l < 40) {
hsl.l += 20;
if (hsl.s > 11) hsl.s -= 11;
} else {
l = 40;
if (s > 11) s = 0;
hsl.l = 40;
if (hsl.s > 11) hsl.s = 0;
}
}
return `hsl(${h}, ${s}%, ${l}%)`;
return hsl;
}
fixColor(color: string) {
while (color.length <= 7) {
color = `0${color}`;
}
color = color.replace(/0/g, '1');
return color.substr(0, 6);
}
private getCharaterColors(id: number | undefined) {
if (!id) return null;
private getCharacterColors(id: number | undefined) {
if (!id) return;
const entity = findEntityById(this.game.map, id) as Pony;
if (!entity || !entity.palettePonyInfo) return null;
if (!entity || !entity.palettePonyInfo) return;
let colors = [];
let body = entity.palettePonyInfo.body;
let mane = entity.palettePonyInfo.mane;
let { body, mane } = entity.palettePonyInfo;
if (body && body.palette && body.palette.colors[1]) {
let bodyColor = this.fixColor(body.palette.colors[1].toString(16));
const RGB = this.getRGB(bodyColor);
colors.push(this.RGBToHSL(RGB));
const rgb = colorToRGBA(body.palette.colors[1]);
const hsl = rgb2hsl(rgb);
this.brightenDarkColors(hsl);
colors.push(hsl2CSS(hsl));
}
if (mane && mane.palette && mane.palette.colors[1]) {
let maneColor = this.fixColor(mane.palette.colors[1].toString(16));
const RGB = this.getRGB(maneColor);
colors.push(this.RGBToHSL(RGB));
const rgb = colorToRGBA(mane.palette.colors[1]);
const hsl = rgb2hsl(rgb);
this.brightenDarkColors(hsl);
colors.push(hsl2CSS(hsl));
} else if (colors && colors[0]) {
colors.push((colors[0]));
}
@@ -604,12 +568,12 @@ export class ChatLog implements AfterViewInit, OnDestroy, DoCheck {
}
clearTimeOutAutoClear() {
if (this.autoClear) clearTimeout(this.autoClear);
this.autoClear = null;
this.autoClear = undefined;
this.filterColor = this.inactiveBg;
}
clearTimeOutAutoUnfocus() {
if (this.autoUnfocus) clearTimeout(this.autoUnfocus);
this.autoUnfocus = null;
this.autoUnfocus = undefined;
}
unFocus() {
this.clearTimeOutAutoUnfocus();
@@ -624,9 +588,7 @@ export class ChatLog implements AfterViewInit, OnDestroy, DoCheck {
const open = this.open;
const scrolledToEnd = open ? this.scrolledToEnd : false;
const tab = this.activeTab;
let colors: string[] | null = null;
colors = this.getCharaterColors(message.id);
const colors = this.getCharacterColors(message.id);
this.addEntryToList(this.local, GENERAL_CHAT_LIMIT, open && tab === 'local', entry);
setNameColors(entry.dom, colors);
@@ -686,7 +648,7 @@ export class ChatLog implements AfterViewInit, OnDestroy, DoCheck {
if (isOpen) {
entry.dom = removedDom || createChatLogLineDOM(this.clickLabel, this.clickNameHandler);
updateChatLogLine(entry.dom, entry);
updateChatLogLine(entry.dom, entry, this.settings.timestamp);
this.linesElement.appendChild(entry.dom.root);
}
}
@@ -702,6 +664,7 @@ export class ChatLog implements AfterViewInit, OnDestroy, DoCheck {
this.regenerateList();
this.scrollToEnd();
this.updateTabs();
this.filterChat();
}
}
private updateTabs() {
@@ -749,8 +712,8 @@ export class ChatLog implements AfterViewInit, OnDestroy, DoCheck {
this.messages.forEach(entry => {
if (!entry.dom) {
entry.dom = createChatLogLineDOM(this.clickLabel, this.clickNameHandler);
setNameColors(entry.dom, this.getCharaterColors(entry.entityId));
updateChatLogLine(entry.dom, entry);
setNameColors(entry.dom, this.getCharacterColors(entry.entityId));
updateChatLogLine(entry.dom, entry, this.settings.timestamp);
}
lines.appendChild(entry.dom.root);
@@ -767,7 +730,8 @@ export class ChatLog implements AfterViewInit, OnDestroy, DoCheck {
}
if (resizeX) {
this.settings.chatlogWidth = clamp(x - this.startX, 200 + 74.7, 2000);
const filterBoxWidth = 80;
this.settings.chatlogWidth = clamp(x - this.startX, 200 + filterBoxWidth, 2000);
}
if (resizeY) {