Compare commits
No commits in common. "411e3d38e097f5d2e293a3ee4ec4bf01f21fb321" and "747107169b162898a244a10a1464c45716bca09c" have entirely different histories.
411e3d38e0
...
747107169b
@ -9,10 +9,9 @@
|
||||
<h2 class="help-version-title">
|
||||
<span>About Hard Lounge</span>
|
||||
<small>
|
||||
v{{
|
||||
store.state.serverConfiguration?.version
|
||||
}}
|
||||
(<router-link id="view-changelog" to="/changelog"
|
||||
v{{ store.state.serverConfiguration?.version }} (<router-link
|
||||
id="view-changelog"
|
||||
to="/changelog"
|
||||
>release notes</router-link
|
||||
>)
|
||||
</small>
|
||||
@ -54,8 +53,8 @@
|
||||
<div class="help-item">
|
||||
<div class="description">
|
||||
<p>
|
||||
IRC.SUPERNETS.ORG #SUPERBOWL FUCK YOUR NETWORK COLD HARD
|
||||
CHATS THIS IS NOT YOUR DADS FOOTBALL CHANNEL
|
||||
IRC.SUPERNETS.ORG #SUPERBOWL FUCK YOUR NETWORK COLD HARD CHATS THIS IS NOT
|
||||
YOUR DADS FOOTBALL CHANNEL
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -94,9 +93,7 @@
|
||||
|
||||
<div class="help-item">
|
||||
<div class="subject">
|
||||
<span v-if="!isApple"
|
||||
><kbd>Alt</kbd> <kbd>Shift</kbd> <kbd>↓</kbd></span
|
||||
>
|
||||
<span v-if="!isApple"><kbd>Alt</kbd> <kbd>Shift</kbd> <kbd>↓</kbd></span>
|
||||
<span v-else><kbd>⌥</kbd> <kbd>⇧</kbd> <kbd>↓</kbd></span>
|
||||
</div>
|
||||
<div class="description">
|
||||
@ -106,9 +103,7 @@
|
||||
|
||||
<div class="help-item">
|
||||
<div class="subject">
|
||||
<span v-if="!isApple"
|
||||
><kbd>Alt</kbd> <kbd>Shift</kbd> <kbd>↑</kbd></span
|
||||
>
|
||||
<span v-if="!isApple"><kbd>Alt</kbd> <kbd>Shift</kbd> <kbd>↑</kbd></span>
|
||||
<span v-else><kbd>⌥</kbd> <kbd>⇧</kbd> <kbd>↑</kbd></span>
|
||||
</div>
|
||||
<div class="description">
|
||||
@ -118,9 +113,7 @@
|
||||
|
||||
<div class="help-item">
|
||||
<div class="subject">
|
||||
<span v-if="!isApple"
|
||||
><kbd>Alt</kbd> <kbd>Shift</kbd> <kbd>←</kbd></span
|
||||
>
|
||||
<span v-if="!isApple"><kbd>Alt</kbd> <kbd>Shift</kbd> <kbd>←</kbd></span>
|
||||
<span v-else><kbd>⌥</kbd> <kbd>⇧</kbd> <kbd>←</kbd></span>
|
||||
</div>
|
||||
<div class="description">
|
||||
@ -130,9 +123,7 @@
|
||||
|
||||
<div class="help-item">
|
||||
<div class="subject">
|
||||
<span v-if="!isApple"
|
||||
><kbd>Alt</kbd> <kbd>Shift</kbd> <kbd>→</kbd></span
|
||||
>
|
||||
<span v-if="!isApple"><kbd>Alt</kbd> <kbd>Shift</kbd> <kbd>→</kbd></span>
|
||||
<span v-else><kbd>⌥</kbd> <kbd>⇧</kbd> <kbd>→</kbd></span>
|
||||
</div>
|
||||
<div class="description">
|
||||
@ -226,8 +217,8 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Close current contextual window (context menu, image
|
||||
viewer, topic edit, etc) and remove focus from input.
|
||||
Close current contextual window (context menu, image viewer, topic edit,
|
||||
etc) and remove focus from input.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -241,17 +232,15 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Mark any text typed after this shortcut to be colored.
|
||||
After hitting this shortcut, enter an integer in the
|
||||
range
|
||||
<code>0—15</code> to select the desired color, or use
|
||||
the autocompletion menu to choose a color name (see
|
||||
below).
|
||||
Mark any text typed after this shortcut to be colored. After hitting this
|
||||
shortcut, enter an integer in the range
|
||||
<code>0—15</code> to select the desired color, or use the autocompletion
|
||||
menu to choose a color name (see below).
|
||||
</p>
|
||||
<p>
|
||||
Background color can be specified by putting a comma and
|
||||
another integer in the range <code>0—15</code> after the
|
||||
foreground color number (autocompletion works too).
|
||||
Background color can be specified by putting a comma and another integer in
|
||||
the range <code>0—15</code> after the foreground color number
|
||||
(autocompletion works too).
|
||||
</p>
|
||||
<p>
|
||||
A color reference can be found
|
||||
@ -337,8 +326,8 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Mark all text typed after this shortcut to be reset to
|
||||
its original formatting.
|
||||
Mark all text typed after this shortcut to be reset to its original
|
||||
formatting.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -346,11 +335,10 @@
|
||||
<h2>Autocompletion</h2>
|
||||
|
||||
<p>
|
||||
To auto-complete nicknames, channels and commands, type one of
|
||||
the characters below to open a suggestion list. Use the
|
||||
<kbd>↑</kbd> and <kbd>↓</kbd> keys to highlight an item, and
|
||||
insert it by pressing <kbd>Tab</kbd> or <kbd>Enter</kbd> (or by
|
||||
clicking the desired item).
|
||||
To auto-complete nicknames, channels, commands, and emoji, type one of the
|
||||
characters below to open a suggestion list. Use the <kbd>↑</kbd> and
|
||||
<kbd>↓</kbd> keys to highlight an item, and insert it by pressing <kbd>Tab</kbd> or
|
||||
<kbd>Enter</kbd> (or by clicking the desired item).
|
||||
</p>
|
||||
<p>Autocompletion can be disabled in settings.</p>
|
||||
|
||||
@ -381,6 +369,18 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="help-item">
|
||||
<div class="subject">
|
||||
<code>:</code>
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Emoji (note: requires two search characters, to avoid conflicting with
|
||||
common emoticons like <code>:)</code>)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Commands</h2>
|
||||
|
||||
<div class="help-item">
|
||||
@ -397,9 +397,7 @@
|
||||
<code>/back</code>
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Remove your away status (set with <code>/away</code>).
|
||||
</p>
|
||||
<p>Remove your away status (set with <code>/away</code>).</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -409,8 +407,8 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Ban (<code>+b</code>) a user from the current channel.
|
||||
This can be a nickname or a hostmask.
|
||||
Ban (<code>+b</code>) a user from the current channel. This can be a
|
||||
nickname or a hostmask.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -430,8 +428,7 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Collapse all previews in the current channel (opposite
|
||||
of
|
||||
Collapse all previews in the current channel (opposite of
|
||||
<code>/expand</code>)
|
||||
</p>
|
||||
</div>
|
||||
@ -443,9 +440,8 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Connect to a new IRC network. If
|
||||
<code>port</code> starts with a <code>+</code> sign, the
|
||||
connection will be made secure using TLS.
|
||||
Connect to a new IRC network. If <code>port</code> starts with a
|
||||
<code>+</code> sign, the connection will be made secure using TLS.
|
||||
</p>
|
||||
<p>Alias: <code>/server</code></p>
|
||||
</div>
|
||||
@ -457,8 +453,7 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Send a
|
||||
<abbr title="Client-to-client protocol">CTCP</abbr>
|
||||
Send a <abbr title="Client-to-client protocol">CTCP</abbr>
|
||||
request. Read more about this on
|
||||
<a
|
||||
href="https://en.wikipedia.org/wiki/Client-to-client_protocol"
|
||||
@ -476,8 +471,8 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Remove op (<code>-o</code>) from one or several users in
|
||||
the current channel.
|
||||
Remove op (<code>-o</code>) from one or several users in the current
|
||||
channel.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -488,8 +483,8 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Remove voice (<code>-v</code>) from one or several users
|
||||
in the current channel.
|
||||
Remove voice (<code>-v</code>) from one or several users in the current
|
||||
channel.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -499,10 +494,7 @@
|
||||
<code>/disconnect [message]</code>
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Disconnect from the current network with an
|
||||
optionally-provided message.
|
||||
</p>
|
||||
<p>Disconnect from the current network with an optionally-provided message.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -525,8 +517,8 @@
|
||||
<div class="description">
|
||||
<p>
|
||||
Invite a user to the specified channel. If
|
||||
<code>channel</code> is omitted, user will be invited to
|
||||
the current channel.
|
||||
<code>channel</code> is omitted, user will be invited to the current
|
||||
channel.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -537,8 +529,8 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Block any messages from the specified user on the
|
||||
current network. This can be a nickname or a hostmask.
|
||||
Block any messages from the specified user on the current network. This can
|
||||
be a nickname or a hostmask.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -548,9 +540,7 @@
|
||||
<code>/ignorelist</code>
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Load the list of ignored users for the current network.
|
||||
</p>
|
||||
<p>Load the list of ignored users for the current network.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -560,8 +550,8 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Join a channel. Password is only needed in protected
|
||||
channels and can usually be omitted.
|
||||
Join a channel. Password is only needed in protected channels and can
|
||||
usually be omitted.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -581,10 +571,8 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Kick and ban (<code>+b</code>) a user from the current
|
||||
channel. Unlike
|
||||
<code>/ban</code>, only nicknames (and not host masks)
|
||||
can be used.
|
||||
Kick and ban (<code>+b</code>) a user from the current channel. Unlike
|
||||
<code>/ban</code>, only nicknames (and not host masks) can be used.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -594,9 +582,7 @@
|
||||
<code>/list</code>
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Retrieve a list of available channels on this network.
|
||||
</p>
|
||||
<p>Retrieve a list of available channels on this network.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -606,9 +592,8 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Send an action message to the current channel. Hard
|
||||
Lounge will display it inline, as if the message was
|
||||
posted in the third person.
|
||||
Send an action message to the current channel. Hard Lounge will display it
|
||||
inline, as if the message was posted in the third person.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -619,10 +604,9 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Set the given flags to the current channel if the active
|
||||
window is a channel, another user if the active window
|
||||
is a private message window, or yourself if the current
|
||||
window is a server window.
|
||||
Set the given flags to the current channel if the active window is a
|
||||
channel, another user if the active window is a private message window, or
|
||||
yourself if the current window is a server window.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -642,12 +626,10 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Prevent messages from generating any feedback for a
|
||||
channel. This turns off the highlight indicator, hides
|
||||
mentions and inhibits push notifications. Muting a
|
||||
network lobby mutes the entire network. Not specifying
|
||||
any channel target mutes the current channel. Revert
|
||||
with <code>/unmute</code>.
|
||||
Prevent messages from generating any feedback for a channel. This turns off
|
||||
the highlight indicator, hides mentions and inhibits push notifications.
|
||||
Muting a network lobby mutes the entire network. Not specifying any channel
|
||||
target mutes the current channel. Revert with <code>/unmute</code>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -675,10 +657,7 @@
|
||||
<code>/op nick [...nick]</code>
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Give op (<code>+o</code>) to one or several users in the
|
||||
current channel.
|
||||
</p>
|
||||
<p>Give op (<code>+o</code>) to one or several users in the current channel.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -688,9 +667,8 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Close the specified channel or private message window,
|
||||
or the current channel if <code>channel</code> is
|
||||
omitted.
|
||||
Close the specified channel or private message window, or the current
|
||||
channel if <code>channel</code> is omitted.
|
||||
</p>
|
||||
<p>Aliases: <code>/close</code>, <code>/leave</code></p>
|
||||
</div>
|
||||
@ -702,9 +680,8 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Leave and immediately rejoin the current channel. Useful
|
||||
to quickly get op from ChanServ in an empty channel, for
|
||||
example.
|
||||
Leave and immediately rejoin the current channel. Useful to quickly get op
|
||||
from ChanServ in an empty channel, for example.
|
||||
</p>
|
||||
<p>Alias: <code>/cycle</code></p>
|
||||
</div>
|
||||
@ -724,10 +701,7 @@
|
||||
<code>/quit [message]</code>
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Disconnect from the current network with an optional
|
||||
message.
|
||||
</p>
|
||||
<p>Disconnect from the current network with an optional message.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -765,9 +739,8 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Get the topic in the current channel. If
|
||||
<code>newtopic</code> is specified, sets the topic in
|
||||
the current channel.
|
||||
Get the topic in the current channel. If <code>newtopic</code> is specified,
|
||||
sets the topic in the current channel.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -778,8 +751,8 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Unban (<code>-b</code>) a user from the current channel.
|
||||
This can be a nickname or a hostmask.
|
||||
Unban (<code>-b</code>) a user from the current channel. This can be a
|
||||
nickname or a hostmask.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -790,8 +763,8 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Unblock messages from the specified user on the current
|
||||
network. This can be a nickname or a hostmask.
|
||||
Unblock messages from the specified user on the current network. This can be
|
||||
a nickname or a hostmask.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -802,9 +775,8 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Un-mutes the given channel(s) or the current channel if
|
||||
no channel is provided. See <code>/mute</code> for more
|
||||
information.
|
||||
Un-mutes the given channel(s) or the current channel if no channel is
|
||||
provided. See <code>/mute</code> for more information.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -815,8 +787,7 @@
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Give voice (<code>+v</code>) to one or several users in
|
||||
the current channel.
|
||||
Give voice (<code>+v</code>) to one or several users in the current channel.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -826,10 +797,7 @@
|
||||
<code>/whois nick</code>
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Retrieve information about the given user on the current
|
||||
network.
|
||||
</p>
|
||||
<p>Retrieve information about the given user on the current network.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1225,8 +1193,8 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from "vue";
|
||||
import { useStore } from "../../js/store";
|
||||
import {defineComponent, ref} from "vue";
|
||||
import {useStore} from "../../js/store";
|
||||
import SidebarToggle from "../SidebarToggle.vue";
|
||||
import VersionChecker from "../VersionChecker.vue";
|
||||
|
||||
@ -1238,8 +1206,7 @@ export default defineComponent({
|
||||
},
|
||||
setup() {
|
||||
const store = useStore();
|
||||
const isApple =
|
||||
navigator.platform.match(/(Mac|iPhone|iPod|iPad)/i) || false;
|
||||
const isApple = navigator.platform.match(/(Mac|iPhone|iPod|iPad)/i) || false;
|
||||
const isTouch = navigator.maxTouchPoints > 0;
|
||||
|
||||
return {
|
||||
|
@ -1,15 +1,35 @@
|
||||
import constants from "./constants";
|
||||
|
||||
import Mousetrap from "mousetrap";
|
||||
import { Strategy, Textcomplete, StrategyProps } from "@textcomplete/core";
|
||||
import { TextareaEditor } from "@textcomplete/textarea";
|
||||
import {Strategy, Textcomplete, StrategyProps} from "@textcomplete/core";
|
||||
import {TextareaEditor} from "@textcomplete/textarea";
|
||||
|
||||
import fuzzy from "fuzzy";
|
||||
|
||||
import { store } from "./store";
|
||||
import emojiMap from "./helpers/simplemap.json";
|
||||
import {store} from "./store";
|
||||
|
||||
export default enableAutocomplete;
|
||||
|
||||
const emojiSearchTerms = Object.keys(emojiMap);
|
||||
const emojiStrategy: StrategyProps = {
|
||||
id: "emoji",
|
||||
match: /(^|\s):([-+\w:?]{2,}):?$/,
|
||||
search(term: string, callback: (matches) => void) {
|
||||
// Trim colon from the matched term,
|
||||
// as we are unable to get a clean string from match regex
|
||||
term = term.replace(/:$/, "");
|
||||
callback(fuzzyGrep(term, emojiSearchTerms));
|
||||
},
|
||||
template([string, original]: [string, string]) {
|
||||
return `<span class="emoji">${String(emojiMap[original])}</span> ${string}`;
|
||||
},
|
||||
replace([, original]: [string, string]) {
|
||||
return "$1" + String(emojiMap[original]);
|
||||
},
|
||||
index: 2,
|
||||
};
|
||||
|
||||
const nicksStrategy: StrategyProps = {
|
||||
id: "nicks",
|
||||
match: /(^|\s)(@([a-zA-Z_[\]\\^{}|`@][a-zA-Z0-9_[\]\\^{}|`-]*)?)$/,
|
||||
@ -19,12 +39,7 @@ const nicksStrategy: StrategyProps = {
|
||||
if (term[0] === "@") {
|
||||
// TODO: type
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
|
||||
callback(
|
||||
completeNicks(term.slice(1), true).map((val) => [
|
||||
"@" + val[0],
|
||||
"@" + val[1],
|
||||
])
|
||||
);
|
||||
callback(completeNicks(term.slice(1), true).map((val) => ["@" + val[0], "@" + val[1]]));
|
||||
} else {
|
||||
callback(completeNicks(term, true));
|
||||
}
|
||||
@ -93,9 +108,7 @@ const foregroundColorStrategy: StrategyProps = {
|
||||
callback(matchingColorCodes);
|
||||
},
|
||||
template(value: string[]) {
|
||||
return `<span class="irc-fg${parseInt(value[0], 10)}">${
|
||||
value[1]
|
||||
}</span>`;
|
||||
return `<span class="irc-fg${parseInt(value[0], 10)}">${value[1]}</span>`;
|
||||
},
|
||||
replace(value: string) {
|
||||
return "\x03" + value[0];
|
||||
@ -106,11 +119,7 @@ const foregroundColorStrategy: StrategyProps = {
|
||||
const backgroundColorStrategy: StrategyProps = {
|
||||
id: "background-colors",
|
||||
match: /\x03(\d{2}),(\d{0,2}|[A-Za-z ]{0,10})$/,
|
||||
search(
|
||||
term: string,
|
||||
callback: (matchingColorCodes: string[][]) => void,
|
||||
match: string[]
|
||||
) {
|
||||
search(term: string, callback: (matchingColorCodes: string[][]) => void, match: string[]) {
|
||||
term = term.toLowerCase();
|
||||
const matchingColorCodes = constants.colorCodeMap
|
||||
.filter((i) => fuzzy.test(term, i[0]) || fuzzy.test(term, i[1]))
|
||||
@ -132,10 +141,10 @@ const backgroundColorStrategy: StrategyProps = {
|
||||
callback(matchingColorCodes);
|
||||
},
|
||||
template(value: string[]) {
|
||||
return `<span class="irc-fg${parseInt(
|
||||
value[2],
|
||||
return `<span class="irc-fg${parseInt(value[2], 10)} irc-bg irc-bg${parseInt(
|
||||
value[0],
|
||||
10
|
||||
)} irc-bg irc-bg${parseInt(value[0], 10)}">${value[1]}</span>`;
|
||||
)}">${value[1]}</span>`;
|
||||
},
|
||||
replace(value: string[]) {
|
||||
return "\x03$1," + value[0];
|
||||
@ -170,9 +179,7 @@ function enableAutocomplete(input: HTMLTextAreaElement) {
|
||||
const text = input.value;
|
||||
|
||||
if (tabCount === 0) {
|
||||
lastMatch =
|
||||
text.substring(0, input.selectionStart).split(/\s/).pop() ||
|
||||
"";
|
||||
lastMatch = text.substring(0, input.selectionStart).split(/\s/).pop() || "";
|
||||
|
||||
if (lastMatch.length === 0) {
|
||||
return;
|
||||
@ -212,6 +219,7 @@ function enableAutocomplete(input: HTMLTextAreaElement) {
|
||||
);
|
||||
|
||||
const strategies = [
|
||||
emojiStrategy,
|
||||
nicksStrategy,
|
||||
chanStrategy,
|
||||
commandStrategy,
|
||||
@ -253,10 +261,7 @@ function replaceNick(original: string, position = 1) {
|
||||
}
|
||||
|
||||
// If there is whitespace in the input already, append space to nick
|
||||
if (
|
||||
position > 0 &&
|
||||
/\s/.test(store.state.activeChannel?.channel.pendingMessage || "")
|
||||
) {
|
||||
if (position > 0 && /\s/.test(store.state.activeChannel?.channel.pendingMessage || "")) {
|
||||
return original + " ";
|
||||
}
|
||||
|
||||
@ -280,19 +285,14 @@ function rawNicks() {
|
||||
if (store.state.activeChannel.channel.users.length > 0) {
|
||||
const users = store.state.activeChannel.channel.users.slice();
|
||||
|
||||
return users
|
||||
.sort((a, b) => b.lastMessage - a.lastMessage)
|
||||
.map((u) => u.nick);
|
||||
return users.sort((a, b) => b.lastMessage - a.lastMessage).map((u) => u.nick);
|
||||
}
|
||||
|
||||
const me = store.state.activeChannel.network.nick;
|
||||
const otherUser = store.state.activeChannel.channel.name;
|
||||
|
||||
// If this is a query, add their name to autocomplete
|
||||
if (
|
||||
me !== otherUser &&
|
||||
store.state.activeChannel.channel.type === "query"
|
||||
) {
|
||||
if (me !== otherUser && store.state.activeChannel.channel.type === "query") {
|
||||
return [otherUser, me];
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
services:
|
||||
hardlounge:
|
||||
image: git.supernets.org/supernets/hardlounge:latest
|
||||
build: .
|
||||
#build: .
|
||||
ports:
|
||||
- "9000:9000"
|
||||
volumes:
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { expect } from "chai";
|
||||
import {expect} from "chai";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
@ -6,102 +6,68 @@ describe("public folder", function () {
|
||||
const publicFolder = path.join(__dirname, "..", "..", "public");
|
||||
|
||||
it("font awesome files are copied", function () {
|
||||
expect(
|
||||
fs.existsSync(path.join(publicFolder, "fonts", "fa-solid-900.woff"))
|
||||
).to.be.true;
|
||||
expect(
|
||||
fs.existsSync(
|
||||
path.join(publicFolder, "fonts", "fa-solid-900.woff2")
|
||||
)
|
||||
).to.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "fonts", "fa-solid-900.woff"))).to.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "fonts", "fa-solid-900.woff2"))).to.be.true;
|
||||
});
|
||||
|
||||
it("files in root folder are copied", function () {
|
||||
expect(fs.existsSync(path.join(publicFolder, "favicon.ico"))).to.be
|
||||
.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "favicon.ico"))).to.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "robots.txt"))).to.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "service-worker.js"))).to
|
||||
.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "thelounge.webmanifest")))
|
||||
.to.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "service-worker.js"))).to.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "thelounge.webmanifest"))).to.be.true;
|
||||
});
|
||||
|
||||
it("audio files are copied", function () {
|
||||
expect(fs.existsSync(path.join(publicFolder, "audio", "pop.wav"))).to.be
|
||||
.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "audio", "pop.wav"))).to.be.true;
|
||||
});
|
||||
|
||||
it("index HTML file is not copied", function () {
|
||||
expect(fs.existsSync(path.join(publicFolder, "index.html"))).to.be
|
||||
.false;
|
||||
expect(fs.existsSync(path.join(publicFolder, "index.html.tpl"))).to.be
|
||||
.false;
|
||||
expect(fs.existsSync(path.join(publicFolder, "index.html"))).to.be.false;
|
||||
expect(fs.existsSync(path.join(publicFolder, "index.html.tpl"))).to.be.false;
|
||||
});
|
||||
|
||||
it("javascript files are built", function () {
|
||||
expect(fs.existsSync(path.join(publicFolder, "js", "bundle.js"))).to.be
|
||||
.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "js", "bundle.vendor.js")))
|
||||
.to.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "js", "bundle.js"))).to.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "js", "bundle.vendor.js"))).to.be.true;
|
||||
});
|
||||
|
||||
it("style files are built", function () {
|
||||
expect(fs.existsSync(path.join(publicFolder, "css", "style.css"))).to.be
|
||||
.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "css", "style.css.map")))
|
||||
.to.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "themes", "default.css")))
|
||||
.to.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "themes", "morning.css")))
|
||||
.to.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "themes", "oled.css"))).to
|
||||
.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "css", "style.css"))).to.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "css", "style.css.map"))).to.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "themes", "default.css"))).to.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "themes", "morning.css"))).to.be.true;
|
||||
});
|
||||
|
||||
it("style files contain expected content", function (done) {
|
||||
fs.readFile(
|
||||
path.join(publicFolder, "css", "style.css"),
|
||||
"utf8",
|
||||
function (err, contents) {
|
||||
expect(err).to.be.null;
|
||||
fs.readFile(path.join(publicFolder, "css", "style.css"), "utf8", function (err, contents) {
|
||||
expect(err).to.be.null;
|
||||
|
||||
expect(contents.includes("var(--body-color)")).to.be.true;
|
||||
expect(contents.includes("url(../fonts/fa-solid-900.woff2)")).to
|
||||
.be.true;
|
||||
expect(contents.includes(".tooltipped{position:relative}")).to
|
||||
.be.true;
|
||||
expect(contents.includes("sourceMappingURL")).to.be.true;
|
||||
expect(contents.includes("var(--body-color)")).to.be.true;
|
||||
expect(contents.includes("url(../fonts/fa-solid-900.woff2)")).to.be.true;
|
||||
expect(contents.includes(".tooltipped{position:relative}")).to.be.true;
|
||||
expect(contents.includes("sourceMappingURL")).to.be.true;
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("javascript map is created", function () {
|
||||
expect(fs.existsSync(path.join(publicFolder, "js", "bundle.js.map"))).to
|
||||
.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "js", "bundle.js.map"))).to.be.true;
|
||||
});
|
||||
|
||||
it("loading-error-handlers.js is copied", function () {
|
||||
expect(
|
||||
fs.existsSync(
|
||||
path.join(publicFolder, "js", "loading-error-handlers.js")
|
||||
)
|
||||
).to.be.true;
|
||||
expect(fs.existsSync(path.join(publicFolder, "js", "loading-error-handlers.js"))).to.be
|
||||
.true;
|
||||
});
|
||||
|
||||
it("service worker has cacheName set", function (done) {
|
||||
fs.readFile(
|
||||
path.join(publicFolder, "service-worker.js"),
|
||||
"utf8",
|
||||
function (err, contents) {
|
||||
expect(err).to.be.null;
|
||||
fs.readFile(path.join(publicFolder, "service-worker.js"), "utf8", function (err, contents) {
|
||||
expect(err).to.be.null;
|
||||
|
||||
expect(contents.includes("const cacheName")).to.be.true;
|
||||
expect(contents.includes("__HASH__")).to.be.false;
|
||||
expect(contents.includes("const cacheName")).to.be.true;
|
||||
expect(contents.includes("__HASH__")).to.be.false;
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user