2017-09-02 01:50:31 +00:00
|
|
|
|
<template>
|
2018-04-08 00:22:32 +00:00
|
|
|
|
<div style="height:100%;display:flex;flex-direction:column;flex:1;margin:0 5px;position:relative" id="conversation">
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<div style="display:flex" v-if="isPrivate(conversation)" class="header">
|
2018-03-28 13:51:05 +00:00
|
|
|
|
<img :src="characterImage" style="height:60px;width:60px;margin-right:10px" v-if="settings.showAvatars"/>
|
2019-09-17 17:14:14 +00:00
|
|
|
|
<div style="flex:1;position:relative;display:flex;flex-direction:column;user-select:text">
|
2017-09-02 01:50:31 +00:00
|
|
|
|
<div>
|
2019-07-15 16:59:16 +00:00
|
|
|
|
<user :character="conversation.character" :match="true"></user>
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<a href="#" @click.prevent="showLogs()" class="btn">
|
2018-03-28 13:51:05 +00:00
|
|
|
|
<span class="fa fa-file-alt"></span> <span class="btn-text">{{l('logs.title')}}</span>
|
|
|
|
|
</a>
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<a href="#" @click.prevent="showSettings()" class="btn">
|
2018-01-06 16:14:21 +00:00
|
|
|
|
<span class="fa fa-cog"></span> <span class="btn-text">{{l('conversationSettings.title')}}</span>
|
2017-09-02 01:50:31 +00:00
|
|
|
|
</a>
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<a href="#" @click.prevent="reportDialog.report()" class="btn">
|
2018-03-28 13:51:05 +00:00
|
|
|
|
<span class="fa fa-exclamation-triangle"></span><span class="btn-text">{{l('chat.report')}}</span></a>
|
2019-07-08 23:27:14 +00:00
|
|
|
|
|
|
|
|
|
<a href="#" @click.prevent="showAds()" class="btn">
|
|
|
|
|
<span class="fa fa-ad"></span><span class="btn-text">Ads</span>
|
|
|
|
|
</a>
|
2019-07-15 16:59:16 +00:00
|
|
|
|
|
|
|
|
|
<a href="#" @click.prevent="showChannels()" class="btn">
|
|
|
|
|
<span class="fa fa-tv"></span><span class="btn-text">Channels</span>
|
|
|
|
|
</a>
|
2023-03-12 05:43:58 +00:00
|
|
|
|
|
|
|
|
|
<a href="#" @click.prevent="showMemo()" class="btn">
|
|
|
|
|
<span class="fas fa-edit"></span><span class="btn-text">Memo</span>
|
|
|
|
|
</a>
|
2017-09-02 01:50:31 +00:00
|
|
|
|
</div>
|
2019-09-17 17:14:14 +00:00
|
|
|
|
<div style="overflow:auto;overflow-x:hidden;max-height:50px;user-select:text">
|
2017-09-02 01:50:31 +00:00
|
|
|
|
{{l('status.' + conversation.character.status)}}
|
|
|
|
|
<span v-show="conversation.character.statusText"> – <bbcode :text="conversation.character.statusText"></bbcode></span>
|
2023-03-12 05:43:58 +00:00
|
|
|
|
<div v-show="userMemo"><b>Memo:</b> {{ userMemo }}</div>
|
2017-09-02 01:50:31 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<div v-else-if="isChannel(conversation)" class="header">
|
2017-09-02 01:50:31 +00:00
|
|
|
|
<div style="display: flex; align-items: center;">
|
|
|
|
|
<div style="flex: 1;">
|
|
|
|
|
<span v-show="conversation.channel.id.substr(0, 4) !== 'adh-'" class="fa fa-star" :title="l('channel.official')"
|
2018-03-04 02:32:26 +00:00
|
|
|
|
style="margin-right:5px;vertical-align:sub"></span>
|
|
|
|
|
<h5 style="margin:0;display:inline;vertical-align:middle">{{conversation.name}}</h5>
|
2018-08-10 16:59:37 +00:00
|
|
|
|
<a href="#" @click.prevent="descriptionExpanded = !descriptionExpanded" class="btn">
|
2017-09-02 01:50:31 +00:00
|
|
|
|
<span class="fa" :class="{'fa-chevron-down': !descriptionExpanded, 'fa-chevron-up': descriptionExpanded}"></span>
|
2018-01-06 16:14:21 +00:00
|
|
|
|
<span class="btn-text">{{l('channel.description')}}</span>
|
2017-09-02 01:50:31 +00:00
|
|
|
|
</a>
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<a href="#" @click.prevent="showManage()" v-show="isChannelMod" class="btn">
|
2018-07-20 01:12:26 +00:00
|
|
|
|
<span class="fa fa-edit"></span> <span class="btn-text">{{l('manageChannel.open')}}</span>
|
|
|
|
|
</a>
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<a href="#" @click.prevent="showLogs()" class="btn">
|
2018-03-28 13:51:05 +00:00
|
|
|
|
<span class="fa fa-file-alt"></span> <span class="btn-text">{{l('logs.title')}}</span>
|
|
|
|
|
</a>
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<a href="#" @click.prevent="showSettings()" class="btn">
|
2018-01-06 16:14:21 +00:00
|
|
|
|
<span class="fa fa-cog"></span> <span class="btn-text">{{l('conversationSettings.title')}}</span>
|
2017-09-02 01:50:31 +00:00
|
|
|
|
</a>
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<a href="#" @click.prevent="reportDialog.report()" class="btn">
|
2018-03-28 13:51:05 +00:00
|
|
|
|
<span class="fa fa-exclamation-triangle"></span><span class="btn-text">{{l('chat.report')}}</span></a>
|
2017-09-02 01:50:31 +00:00
|
|
|
|
</div>
|
2020-03-22 18:39:45 +00:00
|
|
|
|
|
|
|
|
|
<!-- <ul class="nav nav-pills mode-switcher">-->
|
|
|
|
|
<!-- <li v-for="mode in modes" class="nav-item">-->
|
|
|
|
|
<!-- <a :class="isChannel(conversation) ? {active: conversation.mode == mode, disabled: conversation.channel.mode != 'both'} : undefined"-->
|
|
|
|
|
<!-- class="nav-link" href="#" @click.prevent="setMode(mode)">{{l('channel.mode.' + mode)}}</a>-->
|
|
|
|
|
<!-- </li>-->
|
|
|
|
|
<!-- <li>-->
|
|
|
|
|
<!-- <a @click.prevent="toggleNonMatchingAds()" :class="{active: showNonMatchingAds}" v-show="(conversation.mode == 'both' || conversation.mode == 'ads')"-->
|
|
|
|
|
<!-- class="nav-link" href="#">Non-Matching</a>-->
|
|
|
|
|
<!-- </li>-->
|
|
|
|
|
<!-- </ul>-->
|
|
|
|
|
|
|
|
|
|
<div class="btn-toolbar">
|
|
|
|
|
<dropdown :keep-open="false" title="View" :icon-class="{fas: true, 'fa-comments': conversation.mode === 'chat', 'fa-ad': conversation.mode === 'ads', 'fa-asterisk': conversation.mode === 'both'}" wrap-class="btn-group views" link-class="btn btn-secondary dropdown-toggle" v-show="(conversation.channel.mode == 'both')">
|
|
|
|
|
<button v-for="mode in modes" class="dropdown-item" :class="{ selected: conversation.mode == mode }" type="button" @click="setMode(mode)">{{l('channel.mode.' + mode)}}</button>
|
|
|
|
|
</dropdown>
|
|
|
|
|
|
2020-03-30 15:40:25 +00:00
|
|
|
|
<dropdown :keep-open="false" wrap-class="btn-group ads" link-style="" link-class="btn btn-secondary dropdown-toggle dropdown-toggle-split" v-show="(conversation.channel.mode == 'both' || conversation.channel.mode == 'ads')">
|
|
|
|
|
<button class="dropdown-item" type="button" @click="toggleAutoPostAds()">{{conversation.adManager.isActive() ? 'Pause' : 'Start'}} Posting Ads</button>
|
2020-11-25 05:44:22 +00:00
|
|
|
|
<button class="dropdown-item" type="button" @click="showAdSettings()">Edit Channel Ads...</button>
|
2020-03-22 18:39:45 +00:00
|
|
|
|
<div class="dropdown-divider"></div>
|
|
|
|
|
<button class="dropdown-item" :class="{ selected: showNonMatchingAds }" type="button" @click="toggleNonMatchingAds()">Show Incompatible Ads</button>
|
2020-03-30 15:40:25 +00:00
|
|
|
|
|
|
|
|
|
<template v-slot:split>
|
|
|
|
|
<a class="btn btn-secondary" @click="toggleAutoPostAds()">
|
|
|
|
|
<i :class="{fas: true, 'fa-pause': conversation.adManager.isActive(), 'fa-play': !conversation.adManager.isActive()}"></i>
|
|
|
|
|
{{conversation.adManager.isActive() ? 'Pause' : 'Start'}} Ads
|
|
|
|
|
</a>
|
|
|
|
|
</template>
|
2020-03-22 18:39:45 +00:00
|
|
|
|
</dropdown>
|
|
|
|
|
</div>
|
|
|
|
|
|
2017-09-02 01:50:31 +00:00
|
|
|
|
</div>
|
2017-10-16 23:58:57 +00:00
|
|
|
|
<div style="z-index:5;position:absolute;left:0;right:0;max-height:60%;overflow:auto"
|
2019-01-03 17:38:17 +00:00
|
|
|
|
:style="{display: descriptionExpanded ? 'block' : 'none'}" class="bg-solid-text border-bottom">
|
2017-09-02 01:50:31 +00:00
|
|
|
|
<bbcode :text="conversation.channel.description"></bbcode>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div v-else class="header" style="display:flex;align-items:center">
|
|
|
|
|
<h4>{{l('chat.consoleTab')}}</h4>
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<a href="#" @click.prevent="showLogs()" class="btn">
|
2018-03-28 13:51:05 +00:00
|
|
|
|
<span class="fa fa-file-alt"></span> <span class="btn-text">{{l('logs.title')}}</span>
|
|
|
|
|
</a>
|
2017-09-02 01:50:31 +00:00
|
|
|
|
</div>
|
2018-04-08 00:22:32 +00:00
|
|
|
|
<div class="search input-group" v-show="showSearch">
|
|
|
|
|
<div class="input-group-prepend">
|
|
|
|
|
<div class="input-group-text"><span class="fas fa-search"></span></div>
|
|
|
|
|
</div>
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<input v-model="searchInput" @keydown.esc="hideSearch()" @keypress="lastSearchInput = Date.now()"
|
2018-03-04 02:32:26 +00:00
|
|
|
|
:placeholder="l('chat.search')" ref="searchField" class="form-control"/>
|
2018-04-11 19:17:58 +00:00
|
|
|
|
<a class="btn btn-sm btn-light" style="position:absolute;right:5px;top:50%;transform:translateY(-50%);line-height:0;z-index:10"
|
2018-04-16 23:14:13 +00:00
|
|
|
|
@click="hideSearch"><i class="fas fa-times"></i></a>
|
2018-03-04 02:32:26 +00:00
|
|
|
|
</div>
|
2019-06-02 23:57:32 +00:00
|
|
|
|
<div class="auto-ads" v-show="isAutopostingAds()">
|
2019-06-07 19:31:42 +00:00
|
|
|
|
<h4>{{l('admgr.activeHeader')}}</h4>
|
2019-06-02 23:57:32 +00:00
|
|
|
|
<div class="update">{{adAutoPostUpdate}}</div>
|
|
|
|
|
|
|
|
|
|
<div v-show="adAutoPostNextAd" class="next">
|
2020-12-31 01:59:56 +00:00
|
|
|
|
<h5>{{l('admgr.comingNext')}} <a @click="skipAd()"><i class='adAction fas fa-arrow-right' /></a></h5>
|
|
|
|
|
<div>{{(adAutoPostNextAd ? adAutoPostNextAd.substr(0, 100) : '')}}...</div>
|
|
|
|
|
|
2019-06-02 23:57:32 +00:00
|
|
|
|
</div>
|
2019-06-07 19:31:42 +00:00
|
|
|
|
|
2019-12-07 15:23:58 +00:00
|
|
|
|
<a class="btn btn-sm btn-outline-primary renew-autoposts" @click="renewAutoPosting()" v-if="!adsRequireSetup">{{l('admgr.renew')}}</a>
|
2020-03-22 18:39:45 +00:00
|
|
|
|
<a class="btn btn-sm btn-outline-primary renew-autoposts" @click="showAdSettings()" v-if="adsRequireSetup">{{l('admgr.setup')}}</a>
|
2019-06-02 23:57:32 +00:00
|
|
|
|
</div>
|
2019-10-21 22:55:05 +00:00
|
|
|
|
<div class="border-top messages" :class="getMessageWrapperClasses()" ref="messages"
|
|
|
|
|
@scroll="onMessagesScroll" style="flex:1;overflow:auto;margin-top:2px">
|
2018-03-04 02:32:26 +00:00
|
|
|
|
<template v-for="message in messages">
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<message-view :message="message" :channel="isChannel(conversation) ? conversation.channel : undefined" :key="message.id"
|
2017-10-16 23:58:57 +00:00
|
|
|
|
:classes="message == conversation.lastRead ? 'last-read' : ''">
|
2017-09-02 01:50:31 +00:00
|
|
|
|
</message-view>
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<span v-if="hasSFC(message) && message.sfc.action === 'report'" :key="'r' + message.id">
|
2017-10-16 23:58:57 +00:00
|
|
|
|
<a :href="'https://www.f-list.net/fchat/getLog.php?log=' + message.sfc.logid"
|
2018-04-08 00:22:32 +00:00
|
|
|
|
v-if="message.sfc.logid" target="_blank">{{l('events.report.viewLog')}}</a>
|
2017-10-16 23:58:57 +00:00
|
|
|
|
<span v-else>{{l('events.report.noLog')}}</span>
|
|
|
|
|
<span v-show="!message.sfc.confirmed">
|
2019-01-03 17:38:17 +00:00
|
|
|
|
| <a href="#" @click.prevent="message.sfc.action === 'report' && acceptReport(message.sfc)">{{l('events.report.confirm')}}</a>
|
2017-09-02 01:50:31 +00:00
|
|
|
|
</span>
|
2017-10-16 23:58:57 +00:00
|
|
|
|
</span>
|
2017-09-02 01:50:31 +00:00
|
|
|
|
</template>
|
|
|
|
|
</div>
|
2018-07-20 01:12:26 +00:00
|
|
|
|
<bbcode-editor v-model="conversation.enteredText" @keydown="onKeyDown" :extras="extraButtons" @input="keepScroll"
|
2019-01-03 17:38:17 +00:00
|
|
|
|
:classes="'form-control chat-text-box' + (isChannel(conversation) && conversation.isSendingAds ? ' ads-text-box' : '')"
|
|
|
|
|
:hasToolbar="settings.bbCodeBar" ref="textBox" style="position:relative;margin-top:5px"
|
2022-12-10 22:42:15 +00:00
|
|
|
|
:maxlength="isChannel(conversation) || isPrivate(conversation) ? conversation.maxMessageLength : undefined"
|
|
|
|
|
:characterName="ownName"
|
|
|
|
|
>
|
|
|
|
|
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<span v-if="isPrivate(conversation) && conversation.typingStatus !== 'clear'" class="chat-info-text">
|
2022-12-10 22:42:15 +00:00
|
|
|
|
<user :character="conversation.character" :match="false" :bookmark="false"></user> {{l('chat.typing.' + conversation.typingStatus, '').trim()}}
|
2017-09-02 01:50:31 +00:00
|
|
|
|
</span>
|
2018-07-20 01:12:26 +00:00
|
|
|
|
<div v-show="conversation.infoText" class="chat-info-text">
|
2018-01-06 16:14:21 +00:00
|
|
|
|
<span class="fa fa-times" style="cursor:pointer" @click.stop="conversation.infoText = ''"></span>
|
2017-09-02 01:50:31 +00:00
|
|
|
|
<span style="flex:1;margin-left:5px">{{conversation.infoText}}</span>
|
|
|
|
|
</div>
|
2018-07-20 01:12:26 +00:00
|
|
|
|
<div v-show="conversation.errorText" class="chat-info-text">
|
2018-01-06 16:14:21 +00:00
|
|
|
|
<span class="fa fa-times" style="cursor:pointer" @click.stop="conversation.errorText = ''"></span>
|
2017-09-02 01:50:31 +00:00
|
|
|
|
<span class="redText" style="flex:1;margin-left:5px">{{conversation.errorText}}</span>
|
|
|
|
|
</div>
|
2018-07-20 01:12:26 +00:00
|
|
|
|
<div class="bbcode-editor-controls">
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<div v-if="isChannel(conversation) || isPrivate(conversation)" style="margin-right:5px">
|
2018-07-20 01:12:26 +00:00
|
|
|
|
{{getByteLength(conversation.enteredText)}} / {{conversation.maxMessageLength}}
|
|
|
|
|
</div>
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<ul class="nav nav-pills send-ads-switcher" v-if="isChannel(conversation)"
|
2018-07-20 01:12:26 +00:00
|
|
|
|
style="position:relative;z-index:10;margin-right:5px">
|
2020-03-22 18:39:45 +00:00
|
|
|
|
<li class="nav-item" v-show="((conversation.channel.mode === 'both') || (conversation.channel.mode === 'chat'))">
|
2019-06-07 19:31:42 +00:00
|
|
|
|
<a href="#" :class="{active: !conversation.isSendingAds, disabled: (conversation.channel.mode != 'both') || (conversation.adManager.isActive())}"
|
2018-07-20 01:12:26 +00:00
|
|
|
|
class="nav-link" @click.prevent="setSendingAds(false)">{{l('channel.mode.chat')}}</a>
|
|
|
|
|
</li>
|
2020-03-22 18:39:45 +00:00
|
|
|
|
<li class="nav-item" v-show="((conversation.channel.mode === 'both') || (conversation.channel.mode === 'ads'))">
|
2019-06-07 19:31:42 +00:00
|
|
|
|
<a href="#" :class="{active: conversation.isSendingAds, disabled: (conversation.channel.mode != 'both') || (conversation.adManager.isActive())}"
|
2018-07-20 01:12:26 +00:00
|
|
|
|
class="nav-link" @click.prevent="setSendingAds(true)">{{adsMode}}</a>
|
|
|
|
|
</li>
|
2020-03-22 18:39:45 +00:00
|
|
|
|
<!-- <li class="nav-item">-->
|
|
|
|
|
<!-- <a href="#" :class="{active: conversation.adManager.isActive()}" class="nav-link toggle-autopost" @click="toggleAutoPostAds()">{{l('admgr.toggleAutoPost')}}</a>-->
|
|
|
|
|
<!-- </li>-->
|
2018-07-20 01:12:26 +00:00
|
|
|
|
</ul>
|
|
|
|
|
<div class="btn btn-sm btn-primary" v-show="!settings.enterSend" @click="sendButton">{{l('chat.send')}}</div>
|
2017-09-02 01:50:31 +00:00
|
|
|
|
</div>
|
2018-07-20 01:12:26 +00:00
|
|
|
|
</bbcode-editor>
|
2018-03-28 13:51:05 +00:00
|
|
|
|
<command-help ref="helpDialog"></command-help>
|
2017-09-02 01:50:31 +00:00
|
|
|
|
<settings ref="settingsDialog" :conversation="conversation"></settings>
|
2020-03-22 18:39:45 +00:00
|
|
|
|
<adSettings ref="adSettingsDialog" :conversation="conversation"></adSettings>
|
2018-03-28 13:51:05 +00:00
|
|
|
|
<logs ref="logsDialog" :conversation="conversation"></logs>
|
2019-01-03 17:38:17 +00:00
|
|
|
|
<manage-channel ref="manageDialog" v-if="isChannel(conversation)" :channel="conversation.channel"></manage-channel>
|
2019-07-15 16:59:16 +00:00
|
|
|
|
<ad-view ref="adViewer" v-if="isPrivate(conversation) && conversation.character" :character="conversation.character"></ad-view>
|
|
|
|
|
<channel-list ref="channelList" v-if="isPrivate(conversation)" :character="conversation.character"></channel-list>
|
2023-03-12 05:43:58 +00:00
|
|
|
|
<modal :action="l('user.memo.action')" ref="userMemoEditor" @submit="updateMemo" dialogClass="w-100">
|
|
|
|
|
<div style="float:right;text-align:right;">{{getByteLength(editorMemo)}} / 1000</div>
|
|
|
|
|
<textarea class="form-control" v-model="editorMemo" maxlength="1000"></textarea>
|
|
|
|
|
</modal>
|
2017-09-02 01:50:31 +00:00
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script lang="ts">
|
2019-01-03 17:38:17 +00:00
|
|
|
|
import {Component, Hook, Prop, Watch} from '@f-list/vue-ts';
|
2017-09-02 01:50:31 +00:00
|
|
|
|
import Vue from 'vue';
|
|
|
|
|
import {EditorButton, EditorSelection} from '../bbcode/editor';
|
2019-09-17 17:14:14 +00:00
|
|
|
|
import {BBCodeView} from '../bbcode/view';
|
2023-03-12 05:43:58 +00:00
|
|
|
|
import Modal, {isShowing as anyDialogsShown} from '../components/Modal.vue';
|
2018-03-04 02:32:26 +00:00
|
|
|
|
import {Keys} from '../keys';
|
2020-04-03 15:00:38 +00:00
|
|
|
|
import CharacterAdView from './character/CharacterAdView.vue';
|
2019-09-17 17:14:14 +00:00
|
|
|
|
import {Editor} from './bbcode';
|
2017-09-02 01:50:31 +00:00
|
|
|
|
import CommandHelp from './CommandHelp.vue';
|
2023-03-12 05:43:58 +00:00
|
|
|
|
import { characterImage, errorToString, getByteLength, getKey } from './common';
|
2017-09-02 01:50:31 +00:00
|
|
|
|
import ConversationSettings from './ConversationSettings.vue';
|
2020-10-24 19:43:06 +00:00
|
|
|
|
import ConversationAdSettings from './ads/ConversationAdSettings.vue';
|
2017-09-02 01:50:31 +00:00
|
|
|
|
import core from './core';
|
2018-03-28 13:51:05 +00:00
|
|
|
|
import {Channel, channelModes, Character, Conversation, Settings} from './interfaces';
|
2017-09-02 01:50:31 +00:00
|
|
|
|
import l from './localize';
|
|
|
|
|
import Logs from './Logs.vue';
|
|
|
|
|
import ManageChannel from './ManageChannel.vue';
|
|
|
|
|
import MessageView from './message_view';
|
|
|
|
|
import ReportDialog from './ReportDialog.vue';
|
|
|
|
|
import {isCommand} from './slash_commands';
|
2019-07-15 16:59:16 +00:00
|
|
|
|
import UserView from './UserView.vue';
|
2020-04-03 15:00:38 +00:00
|
|
|
|
import CharacterChannelList from './character/CharacterChannelList.vue';
|
2019-12-07 15:23:58 +00:00
|
|
|
|
import * as _ from 'lodash';
|
2020-03-22 18:39:45 +00:00
|
|
|
|
import Dropdown from '../components/Dropdown.vue';
|
2022-12-10 22:42:15 +00:00
|
|
|
|
import { EventBus } from './preview/event-bus';
|
2023-03-12 05:43:58 +00:00
|
|
|
|
// import { CharacterMemo } from '../site/character_page/interfaces';
|
|
|
|
|
import { MemoManager } from './character/memo';
|
|
|
|
|
import { CharacterMemo } from '../site/character_page/interfaces';
|
2017-09-02 01:50:31 +00:00
|
|
|
|
|
|
|
|
|
@Component({
|
|
|
|
|
components: {
|
2022-12-10 22:42:15 +00:00
|
|
|
|
user: UserView,
|
|
|
|
|
'bbcode-editor': Editor,
|
|
|
|
|
'manage-channel': ManageChannel,
|
|
|
|
|
settings: ConversationSettings,
|
|
|
|
|
logs: Logs,
|
|
|
|
|
'message-view': MessageView,
|
|
|
|
|
bbcode: BBCodeView(core.bbCodeParser),
|
|
|
|
|
'command-help': CommandHelp,
|
|
|
|
|
'ad-view': CharacterAdView,
|
|
|
|
|
'channel-list': CharacterChannelList,
|
|
|
|
|
dropdown: Dropdown,
|
2023-03-12 05:43:58 +00:00
|
|
|
|
adSettings: ConversationAdSettings,
|
|
|
|
|
modal: Modal
|
2017-09-02 01:50:31 +00:00
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
export default class ConversationView extends Vue {
|
|
|
|
|
@Prop({required: true})
|
2018-03-04 02:32:26 +00:00
|
|
|
|
readonly reportDialog!: ReportDialog;
|
2017-09-02 01:50:31 +00:00
|
|
|
|
modes = channelModes;
|
|
|
|
|
descriptionExpanded = false;
|
|
|
|
|
l = l;
|
|
|
|
|
extraButtons: EditorButton[] = [];
|
|
|
|
|
getByteLength = getByteLength;
|
|
|
|
|
tabOptions: string[] | undefined;
|
2018-03-04 02:32:26 +00:00
|
|
|
|
tabOptionsIndex!: number;
|
|
|
|
|
tabOptionSelection!: EditorSelection;
|
|
|
|
|
showSearch = false;
|
|
|
|
|
searchInput = '';
|
|
|
|
|
search = '';
|
|
|
|
|
lastSearchInput = 0;
|
2017-09-02 01:50:31 +00:00
|
|
|
|
messageCount = 0;
|
2018-03-04 02:32:26 +00:00
|
|
|
|
searchTimer = 0;
|
2018-07-20 01:12:26 +00:00
|
|
|
|
messageView!: HTMLElement;
|
|
|
|
|
resizeHandler!: EventListener;
|
2018-03-04 02:32:26 +00:00
|
|
|
|
keydownHandler!: EventListener;
|
2018-07-20 01:12:26 +00:00
|
|
|
|
keypressHandler!: EventListener;
|
|
|
|
|
scrolledDown = true;
|
|
|
|
|
scrolledUp = false;
|
2018-08-18 19:37:53 +00:00
|
|
|
|
ignoreScroll = false;
|
2018-08-10 16:59:37 +00:00
|
|
|
|
adCountdown = 0;
|
|
|
|
|
adsMode = l('channel.mode.ads');
|
2019-06-02 23:57:32 +00:00
|
|
|
|
autoPostingUpdater = 0;
|
2019-06-07 19:31:42 +00:00
|
|
|
|
adAutoPostUpdate: string | null = null;
|
|
|
|
|
adAutoPostNextAd: string | null = null;
|
2019-12-07 15:23:58 +00:00
|
|
|
|
adsRequireSetup = false;
|
2019-01-03 17:38:17 +00:00
|
|
|
|
isChannel = Conversation.isChannel;
|
|
|
|
|
isPrivate = Conversation.isPrivate;
|
2019-10-21 22:55:05 +00:00
|
|
|
|
showNonMatchingAds = true;
|
2017-09-02 01:50:31 +00:00
|
|
|
|
|
2023-03-12 05:43:58 +00:00
|
|
|
|
userMemo: string = '';
|
|
|
|
|
editorMemo: string = '';
|
|
|
|
|
memoManager?: MemoManager;
|
|
|
|
|
|
2022-12-10 22:42:15 +00:00
|
|
|
|
ownName?: string;
|
2020-06-18 20:17:00 +00:00
|
|
|
|
|
|
|
|
|
@Hook('beforeMount')
|
|
|
|
|
async onBeforeMount(): Promise<void> {
|
2022-12-10 22:42:15 +00:00
|
|
|
|
this.updateOwnName();
|
|
|
|
|
|
2020-06-18 20:17:00 +00:00
|
|
|
|
this.showNonMatchingAds = !await core.settingsStore.get('hideNonMatchingAds');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-01-03 17:38:17 +00:00
|
|
|
|
@Hook('mounted')
|
2018-07-20 01:12:26 +00:00
|
|
|
|
mounted(): void {
|
2022-12-10 22:42:15 +00:00
|
|
|
|
this.updateOwnName();
|
|
|
|
|
|
2017-09-02 01:50:31 +00:00
|
|
|
|
this.extraButtons = [{
|
|
|
|
|
title: 'Help\n\nClick this button for a quick overview of slash commands.',
|
|
|
|
|
tag: '?',
|
|
|
|
|
icon: 'fa-question',
|
2018-03-28 13:51:05 +00:00
|
|
|
|
handler: () => (<CommandHelp>this.$refs['helpDialog']).show()
|
2017-09-02 01:50:31 +00:00
|
|
|
|
}];
|
2018-08-18 19:37:53 +00:00
|
|
|
|
window.addEventListener('resize', this.resizeHandler = () => this.keepScroll());
|
2018-07-20 01:12:26 +00:00
|
|
|
|
window.addEventListener('keypress', this.keypressHandler = () => {
|
2018-09-28 00:08:10 +00:00
|
|
|
|
const selection = document.getSelection();
|
|
|
|
|
if((selection === null || selection.isCollapsed) && !anyDialogsShown &&
|
|
|
|
|
(document.activeElement === document.body || document.activeElement === null || document.activeElement.tagName === 'A'))
|
2018-07-20 01:12:26 +00:00
|
|
|
|
(<Editor>this.$refs['textBox']).focus();
|
|
|
|
|
});
|
2018-03-04 02:32:26 +00:00
|
|
|
|
window.addEventListener('keydown', this.keydownHandler = ((e: KeyboardEvent) => {
|
|
|
|
|
if(getKey(e) === Keys.KeyF && (e.ctrlKey || e.metaKey) && !e.shiftKey && !e.altKey) {
|
|
|
|
|
this.showSearch = true;
|
|
|
|
|
this.$nextTick(() => (<HTMLElement>this.$refs['searchField']).focus());
|
|
|
|
|
}
|
|
|
|
|
}) as EventListener);
|
|
|
|
|
this.searchTimer = window.setInterval(() => {
|
|
|
|
|
if(Date.now() - this.lastSearchInput > 500 && this.search !== this.searchInput)
|
|
|
|
|
this.search = this.searchInput;
|
|
|
|
|
}, 500);
|
2018-07-20 01:12:26 +00:00
|
|
|
|
this.messageView = <HTMLElement>this.$refs['messages'];
|
2018-08-10 16:59:37 +00:00
|
|
|
|
this.$watch('conversation.nextAd', (value: number) => {
|
|
|
|
|
const setAdCountdown = () => {
|
|
|
|
|
const diff = ((<Conversation.ChannelConversation>this.conversation).nextAd - Date.now()) / 1000;
|
|
|
|
|
if(diff <= 0) {
|
|
|
|
|
if(this.adCountdown !== 0) window.clearInterval(this.adCountdown);
|
|
|
|
|
this.adCountdown = 0;
|
|
|
|
|
this.adsMode = l('channel.mode.ads');
|
|
|
|
|
} else this.adsMode = l('channel.mode.ads.countdown', Math.floor(diff / 60), Math.floor(diff % 60));
|
|
|
|
|
};
|
2018-09-28 00:08:10 +00:00
|
|
|
|
if(Date.now() < value && this.adCountdown === 0)
|
|
|
|
|
this.adCountdown = window.setInterval(setAdCountdown, 1000);
|
|
|
|
|
setAdCountdown();
|
2018-08-10 16:59:37 +00:00
|
|
|
|
});
|
2019-06-02 23:57:32 +00:00
|
|
|
|
|
2019-06-07 19:31:42 +00:00
|
|
|
|
this.$watch(() => this.conversation.adManager.isActive(), () => (this.refreshAutoPostingTimer()));
|
|
|
|
|
this.refreshAutoPostingTimer();
|
2022-12-10 22:42:15 +00:00
|
|
|
|
|
|
|
|
|
this.configUpdateHook = () => this.updateOwnName();
|
|
|
|
|
EventBus.$on('configuration-update', this.configUpdateHook);
|
2023-03-12 05:43:58 +00:00
|
|
|
|
|
|
|
|
|
this.memoUpdateHook = (e: any) => this.refreshMemo(e);
|
|
|
|
|
EventBus.$on('character-memo', this.memoUpdateHook);
|
2018-03-04 02:32:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-12-10 22:42:15 +00:00
|
|
|
|
protected configUpdateHook: any;
|
|
|
|
|
|
2023-03-12 05:43:58 +00:00
|
|
|
|
protected memoUpdateHook: any;
|
|
|
|
|
|
2019-01-03 17:38:17 +00:00
|
|
|
|
@Hook('destroyed')
|
2018-03-04 02:32:26 +00:00
|
|
|
|
destroyed(): void {
|
|
|
|
|
window.removeEventListener('resize', this.resizeHandler);
|
|
|
|
|
window.removeEventListener('keydown', this.keydownHandler);
|
2018-07-20 01:12:26 +00:00
|
|
|
|
window.removeEventListener('keypress', this.keypressHandler);
|
2018-03-04 02:32:26 +00:00
|
|
|
|
clearInterval(this.searchTimer);
|
2019-06-02 23:57:32 +00:00
|
|
|
|
clearInterval(this.autoPostingUpdater);
|
|
|
|
|
clearInterval(this.adCountdown);
|
2022-12-10 22:42:15 +00:00
|
|
|
|
|
|
|
|
|
EventBus.$off('configuration-update', this.configUpdateHook);
|
2023-03-12 05:43:58 +00:00
|
|
|
|
EventBus.$off('character-memo', this.memoUpdateHook);
|
2017-09-02 01:50:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-16 23:14:13 +00:00
|
|
|
|
hideSearch(): void {
|
|
|
|
|
this.showSearch = false;
|
|
|
|
|
this.searchInput = '';
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-10 22:42:15 +00:00
|
|
|
|
updateOwnName(): void {
|
|
|
|
|
this.ownName = core.state.settings.risingShowPortraitNearInput ? core.characters.ownCharacter?.name : undefined;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-02 01:50:31 +00:00
|
|
|
|
get conversation(): Conversation {
|
|
|
|
|
return core.conversations.selectedConversation;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-03 17:38:17 +00:00
|
|
|
|
get messages(): ReadonlyArray<Conversation.Message | Conversation.SFCMessage> {
|
2018-04-08 00:22:32 +00:00
|
|
|
|
if(this.search === '') return this.conversation.messages;
|
|
|
|
|
const filter = new RegExp(this.search.replace(/[^\w]/gi, '\\$&'), 'i');
|
2019-12-07 15:23:58 +00:00
|
|
|
|
return this.conversation.messages.filter((x) => filter.test(x.text) || (filter.test(_.get(x, 'sender.name', '') as string)));
|
2018-04-08 00:22:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-08-18 19:37:53 +00:00
|
|
|
|
async sendButton(): Promise<void> {
|
|
|
|
|
return this.conversation.send();
|
2018-03-04 02:32:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-09-02 01:50:31 +00:00
|
|
|
|
@Watch('conversation')
|
2023-03-12 05:43:58 +00:00
|
|
|
|
async conversationChanged(): Promise<void> {
|
2022-12-10 22:42:15 +00:00
|
|
|
|
this.updateOwnName();
|
|
|
|
|
|
2018-07-20 01:12:26 +00:00
|
|
|
|
if(!anyDialogsShown) (<Editor>this.$refs['textBox']).focus();
|
2018-08-18 19:37:53 +00:00
|
|
|
|
this.$nextTick(() => setTimeout(() => this.messageView.scrollTop = this.messageView.scrollHeight));
|
2018-07-20 01:12:26 +00:00
|
|
|
|
this.scrolledDown = true;
|
2019-06-07 19:31:42 +00:00
|
|
|
|
this.refreshAutoPostingTimer();
|
2023-03-12 05:43:58 +00:00
|
|
|
|
this.userMemo = '';
|
|
|
|
|
|
|
|
|
|
if (this.isPrivate(this.conversation)) {
|
|
|
|
|
const c = await core.cache.profileCache.get(this.conversation.name);
|
|
|
|
|
this.userMemo = c?.character?.memo?.memo || '';
|
|
|
|
|
}
|
2017-09-02 01:50:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Watch('conversation.messages')
|
|
|
|
|
messageAdded(newValue: Conversation.Message[]): void {
|
2018-07-20 01:12:26 +00:00
|
|
|
|
this.keepScroll();
|
|
|
|
|
if(!this.scrolledDown && newValue.length === this.messageCount)
|
|
|
|
|
this.messageView.scrollTop -= (this.messageView.firstElementChild!).clientHeight;
|
2017-09-02 01:50:31 +00:00
|
|
|
|
this.messageCount = newValue.length;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-20 01:12:26 +00:00
|
|
|
|
keepScroll(): void {
|
2018-09-28 00:08:10 +00:00
|
|
|
|
if(this.scrolledDown) {
|
|
|
|
|
this.ignoreScroll = true;
|
2018-08-18 19:37:53 +00:00
|
|
|
|
this.$nextTick(() => setTimeout(() => {
|
|
|
|
|
this.ignoreScroll = true;
|
|
|
|
|
this.messageView.scrollTop = this.messageView.scrollHeight;
|
|
|
|
|
}, 0));
|
2018-09-28 00:08:10 +00:00
|
|
|
|
}
|
2017-09-02 01:50:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMessagesScroll(): void {
|
2018-08-18 19:37:53 +00:00
|
|
|
|
if(this.ignoreScroll) {
|
|
|
|
|
this.ignoreScroll = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2018-08-10 16:59:37 +00:00
|
|
|
|
if(this.messageView.scrollTop < 20) {
|
|
|
|
|
if(!this.scrolledUp) {
|
|
|
|
|
const firstMessage = this.messageView.firstElementChild;
|
2019-09-17 17:14:14 +00:00
|
|
|
|
if(this.conversation.loadMore() && firstMessage !== null) {
|
|
|
|
|
this.messageView.style.overflow = 'hidden';
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
this.messageView.scrollTop = (<HTMLElement>firstMessage).offsetTop;
|
|
|
|
|
this.messageView.style.overflow = 'auto';
|
|
|
|
|
});
|
|
|
|
|
}
|
2018-08-10 16:59:37 +00:00
|
|
|
|
}
|
2018-07-20 01:12:26 +00:00
|
|
|
|
this.scrolledUp = true;
|
|
|
|
|
} else this.scrolledUp = false;
|
|
|
|
|
this.scrolledDown = this.messageView.scrollTop + this.messageView.offsetHeight >= this.messageView.scrollHeight - 15;
|
2017-09-02 01:50:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Watch('conversation.errorText')
|
|
|
|
|
@Watch('conversation.infoText')
|
|
|
|
|
textChanged(newValue: string, oldValue: string): void {
|
|
|
|
|
if(oldValue.length === 0 && newValue.length > 0) this.keepScroll();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Watch('conversation.typingStatus')
|
2019-12-07 15:23:58 +00:00
|
|
|
|
// tslint:disable-next-line: ban-ts-ignore
|
|
|
|
|
// @ts-ignore-next
|
|
|
|
|
typingStatusChanged(str: string, oldValue: string): void {
|
2017-09-02 01:50:31 +00:00
|
|
|
|
if(oldValue === 'clear') this.keepScroll();
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-06 16:14:21 +00:00
|
|
|
|
async onKeyDown(e: KeyboardEvent): Promise<void> {
|
2017-09-02 01:50:31 +00:00
|
|
|
|
const editor = <Editor>this.$refs['textBox'];
|
2018-03-04 02:32:26 +00:00
|
|
|
|
if(getKey(e) === Keys.Tab) {
|
2018-04-11 19:17:58 +00:00
|
|
|
|
if(e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) return;
|
2017-09-02 01:50:31 +00:00
|
|
|
|
e.preventDefault();
|
|
|
|
|
if(this.conversation.enteredText.length === 0 || this.isConsoleTab) return;
|
|
|
|
|
if(this.tabOptions === undefined) {
|
|
|
|
|
const selection = editor.getSelection();
|
|
|
|
|
if(selection.text.length === 0) {
|
|
|
|
|
const match = /\b[\w]+$/.exec(editor.text.substring(0, selection.end));
|
|
|
|
|
if(match === null) return;
|
|
|
|
|
selection.start = match.index < 0 ? 0 : match.index;
|
|
|
|
|
selection.text = editor.text.substring(selection.start, selection.end);
|
|
|
|
|
if(selection.text.length === 0) return;
|
|
|
|
|
}
|
2017-12-05 01:47:27 +00:00
|
|
|
|
const search = new RegExp(`^${selection.text.replace(/[^\w]/gi, '\\$&')}`, 'i');
|
2017-09-02 01:50:31 +00:00
|
|
|
|
const c = (<Conversation.PrivateConversation>this.conversation);
|
|
|
|
|
let options: ReadonlyArray<{character: Character}>;
|
|
|
|
|
options = Conversation.isChannel(this.conversation) ? this.conversation.channel.sortedMembers :
|
|
|
|
|
[{character: c.character}, {character: core.characters.ownCharacter}];
|
|
|
|
|
this.tabOptions = options.filter((x) => search.test(x.character.name)).map((x) => x.character.name);
|
|
|
|
|
this.tabOptionsIndex = 0;
|
|
|
|
|
this.tabOptionSelection = selection;
|
|
|
|
|
}
|
|
|
|
|
if(this.tabOptions.length > 0) {
|
|
|
|
|
const selection = editor.getSelection();
|
|
|
|
|
if(selection.end !== this.tabOptionSelection.end) return;
|
|
|
|
|
if(this.tabOptionsIndex >= this.tabOptions.length) this.tabOptionsIndex = 0;
|
|
|
|
|
const name = this.tabOptions[this.tabOptionsIndex];
|
|
|
|
|
const userName = (isCommand(this.conversation.enteredText) ? name : `[user]${name}[/user]`);
|
|
|
|
|
this.tabOptionSelection.end = this.tabOptionSelection.start + userName.length;
|
|
|
|
|
this.conversation.enteredText = this.conversation.enteredText.substr(0, this.tabOptionSelection.start) + userName +
|
|
|
|
|
this.conversation.enteredText.substr(selection.end);
|
|
|
|
|
++this.tabOptionsIndex;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if(this.tabOptions !== undefined) this.tabOptions = undefined;
|
2018-03-04 02:32:26 +00:00
|
|
|
|
if(getKey(e) === Keys.ArrowUp && this.conversation.enteredText.length === 0
|
2017-12-06 03:34:51 +00:00
|
|
|
|
&& !e.shiftKey && !e.altKey && !e.ctrlKey && !e.metaKey)
|
2017-09-02 01:50:31 +00:00
|
|
|
|
this.conversation.loadLastSent();
|
2018-03-04 02:32:26 +00:00
|
|
|
|
else if(getKey(e) === Keys.Enter) {
|
2018-03-28 13:51:05 +00:00
|
|
|
|
if(e.shiftKey === this.settings.enterSend) return;
|
2017-12-05 01:47:27 +00:00
|
|
|
|
e.preventDefault();
|
2018-08-18 19:37:53 +00:00
|
|
|
|
await this.conversation.send();
|
2017-12-05 01:47:27 +00:00
|
|
|
|
}
|
2017-09-02 01:50:31 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setMode(mode: Channel.Mode): void {
|
|
|
|
|
const conv = (<Conversation.ChannelConversation>this.conversation);
|
|
|
|
|
if(conv.channel.mode === 'both') conv.mode = mode;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-21 22:55:05 +00:00
|
|
|
|
|
2020-06-18 20:17:00 +00:00
|
|
|
|
async toggleNonMatchingAds(): Promise<void> {
|
2019-10-21 22:55:05 +00:00
|
|
|
|
this.showNonMatchingAds = !this.showNonMatchingAds;
|
2020-06-18 20:17:00 +00:00
|
|
|
|
|
|
|
|
|
await core.settingsStore.set('hideNonMatchingAds', !this.showNonMatchingAds);
|
2019-10-21 22:55:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* tslint:disable */
|
|
|
|
|
getMessageWrapperClasses(): any {
|
2022-01-01 00:06:08 +00:00
|
|
|
|
const filter = core.state.settings.risingFilter;
|
|
|
|
|
const classes:any = {};
|
|
|
|
|
|
|
|
|
|
if (this.isPrivate(this.conversation)) {
|
|
|
|
|
classes['filter-channel-messages'] = filter.hidePrivateMessages;
|
|
|
|
|
return classes;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-21 22:55:05 +00:00
|
|
|
|
if (!this.isChannel(this.conversation)) {
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const conv = <Conversation.ChannelConversation>this.conversation;
|
|
|
|
|
|
|
|
|
|
classes['messages-' + conv.mode] = true;
|
|
|
|
|
classes['hide-non-matching'] = !this.showNonMatchingAds;
|
|
|
|
|
|
2022-01-01 00:06:08 +00:00
|
|
|
|
classes['filter-ads'] = filter.hideAds;
|
|
|
|
|
classes['filter-channel-messages'] = conv.channel.owner !== '' ? filter.hidePrivateChannelMessages : filter.hidePublicChannelMessages;
|
|
|
|
|
|
2019-10-21 22:55:05 +00:00
|
|
|
|
return classes;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-02 01:50:31 +00:00
|
|
|
|
acceptReport(sfc: {callid: number}): void {
|
|
|
|
|
core.connection.send('SFC', {action: 'confirm', callid: sfc.callid});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setSendingAds(is: boolean): void {
|
|
|
|
|
const conv = (<Conversation.ChannelConversation>this.conversation);
|
|
|
|
|
if(conv.channel.mode === 'both') {
|
|
|
|
|
conv.isSendingAds = is;
|
|
|
|
|
(<Editor>this.$refs['textBox']).focus();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-03 17:38:17 +00:00
|
|
|
|
showLogs(): void {
|
|
|
|
|
(<Logs>this.$refs['logsDialog']).show();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
showSettings(): void {
|
|
|
|
|
(<ConversationSettings>this.$refs['settingsDialog']).show();
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-22 18:39:45 +00:00
|
|
|
|
showAdSettings(): void {
|
|
|
|
|
(<ConversationAdSettings>this.$refs['adSettingsDialog']).show();
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-03 17:38:17 +00:00
|
|
|
|
showManage(): void {
|
|
|
|
|
(<ManageChannel>this.$refs['manageDialog']).show();
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-08 23:27:14 +00:00
|
|
|
|
showAds(): void {
|
2020-04-03 15:00:38 +00:00
|
|
|
|
(<CharacterAdView>this.$refs['adViewer']).show();
|
2019-07-08 23:27:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-07-15 16:59:16 +00:00
|
|
|
|
showChannels(): void {
|
2020-04-03 15:00:38 +00:00
|
|
|
|
(<CharacterChannelList>this.$refs['channelList']).show();
|
2019-07-15 16:59:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-02 23:57:32 +00:00
|
|
|
|
|
|
|
|
|
isAutopostingAds(): boolean {
|
2019-06-07 19:31:42 +00:00
|
|
|
|
return this.conversation.adManager.isActive();
|
2019-06-02 23:57:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2020-12-31 01:59:56 +00:00
|
|
|
|
skipAd(): void {
|
|
|
|
|
this.conversation.adManager.skipAd();
|
|
|
|
|
this.updateAutoPostingState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-06-07 19:31:42 +00:00
|
|
|
|
stopAutoPostAds(): void {
|
|
|
|
|
this.conversation.adManager.stop();
|
2019-06-02 23:57:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-06-07 19:31:42 +00:00
|
|
|
|
renewAutoPosting(): void {
|
|
|
|
|
this.conversation.adManager.renew();
|
2019-06-02 23:57:32 +00:00
|
|
|
|
|
2019-06-07 19:31:42 +00:00
|
|
|
|
this.refreshAutoPostingTimer();
|
|
|
|
|
}
|
2019-06-02 23:57:32 +00:00
|
|
|
|
|
|
|
|
|
|
2019-06-07 19:31:42 +00:00
|
|
|
|
toggleAutoPostAds(): void {
|
2019-07-06 16:49:19 +00:00
|
|
|
|
if(this.isAutopostingAds())
|
2019-06-07 19:31:42 +00:00
|
|
|
|
this.stopAutoPostAds();
|
2019-07-06 16:49:19 +00:00
|
|
|
|
else
|
2019-06-07 19:31:42 +00:00
|
|
|
|
this.conversation.adManager.start();
|
2019-06-02 23:57:32 +00:00
|
|
|
|
|
|
|
|
|
this.refreshAutoPostingTimer();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2020-12-31 01:59:56 +00:00
|
|
|
|
updateAutoPostingState() {
|
|
|
|
|
const adManager = this.conversation.adManager;
|
|
|
|
|
|
|
|
|
|
this.adAutoPostNextAd = adManager.getNextAd() || null;
|
|
|
|
|
|
|
|
|
|
if(this.adAutoPostNextAd) {
|
|
|
|
|
const diff = ((adManager.getNextPostDue() || new Date()).getTime() - Date.now()) / 1000;
|
|
|
|
|
const expDiff = ((adManager.getExpireDue() || new Date()).getTime() - Date.now()) / 1000;
|
|
|
|
|
|
|
|
|
|
const diffMins = Math.floor(diff / 60);
|
|
|
|
|
const diffSecs = Math.floor(diff % 60);
|
|
|
|
|
const expDiffMins = Math.floor(expDiff / 60);
|
|
|
|
|
const expDiffSecs = Math.floor(expDiff % 60);
|
|
|
|
|
|
|
|
|
|
this.adAutoPostUpdate = l(
|
|
|
|
|
((adManager.getNextPostDue()) && (!adManager.getFirstPost())) ? 'admgr.postingBegins' : 'admgr.nextPostDue',
|
|
|
|
|
diffMins,
|
|
|
|
|
diffSecs
|
|
|
|
|
) + l('admgr.expiresIn', expDiffMins, expDiffSecs);
|
|
|
|
|
|
|
|
|
|
this.adsRequireSetup = false;
|
|
|
|
|
} else {
|
|
|
|
|
this.adAutoPostNextAd = null;
|
|
|
|
|
|
|
|
|
|
this.adAutoPostUpdate = l('admgr.noAds');
|
|
|
|
|
this.adsRequireSetup = true;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2019-07-06 16:49:19 +00:00
|
|
|
|
refreshAutoPostingTimer(): void {
|
|
|
|
|
if (this.autoPostingUpdater)
|
2019-06-02 23:57:32 +00:00
|
|
|
|
window.clearInterval(this.autoPostingUpdater);
|
|
|
|
|
|
2019-07-06 16:49:19 +00:00
|
|
|
|
if (!this.isAutopostingAds()) {
|
2019-06-02 23:57:32 +00:00
|
|
|
|
this.adAutoPostUpdate = null;
|
|
|
|
|
this.adAutoPostNextAd = null;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-31 01:59:56 +00:00
|
|
|
|
this.autoPostingUpdater = window.setInterval(() => this.updateAutoPostingState(), 1000);
|
|
|
|
|
this.updateAutoPostingState();
|
2019-06-02 23:57:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-08 02:26:01 +00:00
|
|
|
|
|
2019-01-03 17:38:17 +00:00
|
|
|
|
hasSFC(message: Conversation.Message): message is Conversation.SFCMessage {
|
2019-07-06 16:49:19 +00:00
|
|
|
|
// noinspection TypeScriptValidateTypes
|
2019-01-03 17:38:17 +00:00
|
|
|
|
return (<Partial<Conversation.SFCMessage>>message).sfc !== undefined;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-12 05:43:58 +00:00
|
|
|
|
updateMemo(): void {
|
|
|
|
|
this.memoManager?.set(this.editorMemo).catch((e: object) => alert(errorToString(e)))
|
|
|
|
|
this.userMemo = this.editorMemo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
refreshMemo(event: { character: string, memo: CharacterMemo }): void {
|
|
|
|
|
this.userMemo = event.memo.memo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async showMemo(): Promise<void> {
|
|
|
|
|
if (this.isPrivate(this.conversation)) {
|
|
|
|
|
const c = this.conversation.character;
|
|
|
|
|
|
|
|
|
|
this.editorMemo = '';
|
|
|
|
|
|
|
|
|
|
(<Modal>this.$refs['userMemoEditor']).show();
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
this.memoManager = new MemoManager(c.name);
|
|
|
|
|
await this.memoManager.load();
|
|
|
|
|
|
|
|
|
|
this.userMemo = this.memoManager.get().memo;
|
|
|
|
|
this.editorMemo = this.userMemo;
|
|
|
|
|
} catch(e) {
|
|
|
|
|
alert(errorToString(e));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-02 01:50:31 +00:00
|
|
|
|
get characterImage(): string {
|
|
|
|
|
return characterImage(this.conversation.name);
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-28 13:51:05 +00:00
|
|
|
|
get settings(): Settings {
|
|
|
|
|
return core.state.settings;
|
2017-09-02 01:50:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get isConsoleTab(): boolean {
|
|
|
|
|
return this.conversation === core.conversations.consoleTab;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get isChannelMod(): boolean {
|
|
|
|
|
if(core.characters.ownCharacter.isChatOp) return true;
|
|
|
|
|
const conv = (<Conversation.ChannelConversation>this.conversation);
|
|
|
|
|
const member = conv.channel.members[core.connection.character];
|
|
|
|
|
return member !== undefined && member.rank > Channel.Rank.Member;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
2018-03-04 02:32:26 +00:00
|
|
|
|
<style lang="scss">
|
|
|
|
|
@import "~bootstrap/scss/functions";
|
|
|
|
|
@import "~bootstrap/scss/variables";
|
|
|
|
|
@import "~bootstrap/scss/mixins/breakpoints";
|
|
|
|
|
|
2017-09-02 01:50:31 +00:00
|
|
|
|
#conversation {
|
|
|
|
|
.header {
|
2018-03-28 13:51:05 +00:00
|
|
|
|
@media (min-width: breakpoint-min(md)) {
|
2017-09-02 01:50:31 +00:00
|
|
|
|
margin-right: 32px;
|
|
|
|
|
}
|
2018-03-28 13:51:05 +00:00
|
|
|
|
.btn {
|
2017-09-02 01:50:31 +00:00
|
|
|
|
padding: 2px 5px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-22 18:39:45 +00:00
|
|
|
|
.btn-toolbar {
|
|
|
|
|
.btn-group {
|
|
|
|
|
margin-right: 0.3rem;
|
|
|
|
|
|
|
|
|
|
&:last-child {
|
|
|
|
|
margin-right: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
a.btn {
|
|
|
|
|
padding-left: 0.5rem;
|
|
|
|
|
padding-right: 0.5rem;
|
2020-04-03 23:48:39 +00:00
|
|
|
|
// color: #cbcbe5;
|
2020-03-22 18:39:45 +00:00
|
|
|
|
|
|
|
|
|
i {
|
|
|
|
|
margin-right: 0.4rem;
|
|
|
|
|
font-size: 90%;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
button::before {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
width: 1.3rem;
|
|
|
|
|
height: 1rem;
|
|
|
|
|
content: '';
|
|
|
|
|
margin-left: -1.3rem;
|
|
|
|
|
margin-right: 0.1rem;
|
|
|
|
|
padding-left: 0.3rem;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
button.selected::before {
|
|
|
|
|
content: '✓';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.views {
|
|
|
|
|
button.selected::before {
|
|
|
|
|
content: '•';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-02 01:50:31 +00:00
|
|
|
|
.send-ads-switcher a {
|
|
|
|
|
padding: 3px 10px;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-07 19:31:42 +00:00
|
|
|
|
|
|
|
|
|
.toggle-autopost {
|
|
|
|
|
margin-left: 1px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-06-02 23:57:32 +00:00
|
|
|
|
.auto-ads {
|
2020-03-22 18:39:45 +00:00
|
|
|
|
background-color: rgb(220, 113, 31);
|
2019-06-02 23:57:32 +00:00
|
|
|
|
padding-left: 10px;
|
|
|
|
|
padding-right: 10px;
|
|
|
|
|
padding-top: 5px;
|
|
|
|
|
padding-bottom: 5px;
|
|
|
|
|
margin: 0;
|
2019-06-07 19:31:42 +00:00
|
|
|
|
position: relative;
|
2020-03-22 18:39:45 +00:00
|
|
|
|
margin-top: 5px;
|
2019-06-07 19:31:42 +00:00
|
|
|
|
|
2020-12-31 01:59:56 +00:00
|
|
|
|
.adAction {
|
|
|
|
|
&:hover {
|
|
|
|
|
color: rgba(255, 255, 255, 0.8);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&:active {
|
|
|
|
|
color: rgba(255, 255, 255, 0.6);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-07 19:31:42 +00:00
|
|
|
|
.renew-autoposts {
|
|
|
|
|
display: block;
|
|
|
|
|
float: right;
|
|
|
|
|
/* margin-top: auto; */
|
|
|
|
|
/* margin-bottom: auto; */
|
|
|
|
|
position: absolute;
|
|
|
|
|
/* bottom: 1px; */
|
|
|
|
|
right: 10px;
|
|
|
|
|
top: 50%;
|
|
|
|
|
transform: translateY(-50%);
|
|
|
|
|
border-color: rgba(255, 255, 255, 0.5);
|
|
|
|
|
color: rgba(255, 255, 255, 0.9);
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
background-color: rgba(255, 255, 255, 0.3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&:active {
|
|
|
|
|
background-color: rgba(255, 255, 255, 0.6);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-06-02 23:57:32 +00:00
|
|
|
|
|
|
|
|
|
h4 {
|
|
|
|
|
font-size: 1.1rem;
|
|
|
|
|
margin: 0;
|
|
|
|
|
line-height: 100%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.update {
|
|
|
|
|
color: rgba(255, 255, 255, 0.6);
|
|
|
|
|
font-size: 13px;
|
2020-03-30 15:40:25 +00:00
|
|
|
|
width: 75%;
|
2019-06-02 23:57:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.next {
|
|
|
|
|
margin-top: 0.5rem;
|
|
|
|
|
color: rgba(255, 255, 255, 0.4);
|
|
|
|
|
font-size: 11px;
|
|
|
|
|
|
|
|
|
|
h5 {
|
|
|
|
|
font-size: 0.8rem;
|
|
|
|
|
margin: 0;
|
|
|
|
|
line-height: 100%;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-28 13:51:05 +00:00
|
|
|
|
@media (max-width: breakpoint-max(sm)) {
|
2017-09-02 01:50:31 +00:00
|
|
|
|
.mode-switcher a {
|
|
|
|
|
padding: 5px 8px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-07-20 01:12:26 +00:00
|
|
|
|
|
|
|
|
|
.chat-info-text {
|
2018-08-10 16:59:37 +00:00
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
flex: 1 51%;
|
2018-07-20 01:12:26 +00:00
|
|
|
|
@media (max-width: breakpoint-max(xs)) {
|
|
|
|
|
flex-basis: 100%;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-07-07 01:37:15 +00:00
|
|
|
|
|
2019-07-08 23:27:14 +00:00
|
|
|
|
.message-time,
|
|
|
|
|
.message .message-time,
|
|
|
|
|
.ad-viewer .message-time {
|
2020-04-03 23:48:39 +00:00
|
|
|
|
background-color: var(--messageTimeBgColor);
|
|
|
|
|
color: var(--messageTimeFgColor);
|
2019-07-08 23:27:14 +00:00
|
|
|
|
border-radius: 3px;
|
|
|
|
|
padding-left: 3px;
|
|
|
|
|
padding-right: 3px;
|
|
|
|
|
padding-bottom: 2px;
|
|
|
|
|
padding-top: 1px;
|
|
|
|
|
margin-right: 3px;
|
|
|
|
|
font-size: 80%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ad-viewer {
|
|
|
|
|
display: block;
|
2019-07-07 01:37:15 +00:00
|
|
|
|
|
2019-07-08 23:27:14 +00:00
|
|
|
|
h3 {
|
|
|
|
|
font-size: 12pt;
|
|
|
|
|
|
|
|
|
|
.message-time {
|
|
|
|
|
padding-bottom: 1px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.border-bottom {
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
border-width: 1px;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-07-07 01:37:15 +00:00
|
|
|
|
|
2019-07-15 16:59:16 +00:00
|
|
|
|
|
|
|
|
|
.user-view {
|
2021-02-01 18:16:30 +00:00
|
|
|
|
.user-rank {
|
|
|
|
|
font-size: 80%;
|
|
|
|
|
margin-right: 2px;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-15 16:59:16 +00:00
|
|
|
|
.match-found {
|
|
|
|
|
margin-left: 3px;
|
|
|
|
|
padding-left: 2px;
|
|
|
|
|
padding-right: 2px;
|
|
|
|
|
border-radius: 3px;
|
|
|
|
|
color: rgba(255, 255, 255, 0.8);
|
|
|
|
|
font-size: 75%;
|
|
|
|
|
text-align: center;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
text-transform: uppercase;
|
2020-11-21 20:41:08 +00:00
|
|
|
|
line-height: 100%;
|
|
|
|
|
padding-top: 2px;
|
|
|
|
|
padding-bottom: 2px;
|
|
|
|
|
|
|
|
|
|
&.unicorn {
|
2020-12-30 04:54:16 +00:00
|
|
|
|
background-color: var(--scoreUnicornMatchBg);
|
|
|
|
|
border: 1px solid var(--scoreUnicornMatchFg);
|
2020-11-21 20:41:08 +00:00
|
|
|
|
box-shadow: 0 0 5px 0 rgba(255, 255, 255, 0.5);
|
|
|
|
|
|
|
|
|
|
&::before {
|
|
|
|
|
content: '🦄';
|
|
|
|
|
padding-right:3px
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-07-15 16:59:16 +00:00
|
|
|
|
|
|
|
|
|
&.match {
|
2020-04-03 23:48:39 +00:00
|
|
|
|
background-color: var(--scoreMatchBg);
|
|
|
|
|
border: solid 1px var(--scoreMatchFg);
|
2019-07-15 16:59:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.weak-match {
|
2020-04-03 23:48:39 +00:00
|
|
|
|
background-color: var(--scoreWeakMatchBg);
|
|
|
|
|
border: 1px solid var(--scoreWeakMatchFg);
|
2019-07-15 16:59:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.weak-mismatch {
|
2020-04-03 23:48:39 +00:00
|
|
|
|
background-color: var(--scoreWeakMismatchBg);
|
|
|
|
|
border: 1px solid var(--scoreWeakMismatchFg);
|
2019-07-15 16:59:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.mismatch {
|
2020-04-03 23:48:39 +00:00
|
|
|
|
background-color: var(--scoreMismatchBg);
|
|
|
|
|
border: 1px solid var(--scoreMismatchFg);
|
2019-07-15 16:59:16 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-21 22:55:05 +00:00
|
|
|
|
|
2022-01-01 00:06:08 +00:00
|
|
|
|
.messages.hide-non-matching .message.message-score,
|
|
|
|
|
{
|
2019-10-21 22:55:05 +00:00
|
|
|
|
&.mismatch {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-01 00:06:08 +00:00
|
|
|
|
.messages.filter-ads {
|
|
|
|
|
.message.filter-match.message-ad {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.messages.filter-channel-messages {
|
|
|
|
|
.message.filter-match.message-message,
|
|
|
|
|
.message.filter-match.message-action {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-07 21:44:32 +00:00
|
|
|
|
.message {
|
2021-01-31 00:46:27 +00:00
|
|
|
|
.message-pre {
|
|
|
|
|
font-size: 75%;
|
|
|
|
|
padding-right: 2px;
|
|
|
|
|
padding-left: 1px;
|
|
|
|
|
opacity: 0.90;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-07 21:44:32 +00:00
|
|
|
|
&.message-event {
|
|
|
|
|
font-size: 85%;
|
|
|
|
|
background-color: rgba(255, 255, 255, 0.1);
|
2019-07-07 01:37:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-07-07 21:44:32 +00:00
|
|
|
|
&.message-score {
|
|
|
|
|
padding-left: 5px;
|
|
|
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
2019-07-07 01:37:15 +00:00
|
|
|
|
|
2019-07-07 21:44:32 +00:00
|
|
|
|
&.match {
|
2020-04-03 23:48:39 +00:00
|
|
|
|
border-left: 12px solid var(--scoreStandoutMatchBorderColor);
|
|
|
|
|
background-color: var(--scoreStandoutMatchBgColor);
|
2019-09-24 17:30:01 +00:00
|
|
|
|
// border-left: 12px solid #027b02;
|
|
|
|
|
// background-color: rgba(1, 115, 1, 0.45);
|
2019-07-07 01:37:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-07-07 21:44:32 +00:00
|
|
|
|
&.weak-match {
|
2020-04-03 23:48:39 +00:00
|
|
|
|
border-left: 12px solid var(--scoreStandoutWeakMatchBorderColor);
|
|
|
|
|
background-color: var(--scoreStandoutWeakMatchBgColor);
|
2019-07-10 00:33:12 +00:00
|
|
|
|
|
|
|
|
|
.bbcode {
|
|
|
|
|
filter: grayscale(0.25);
|
|
|
|
|
opacity: 0.77;
|
|
|
|
|
}
|
2019-07-07 01:37:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-07-08 23:27:14 +00:00
|
|
|
|
&.neutral {
|
2020-04-03 23:48:39 +00:00
|
|
|
|
border-left: 12px solid var(--scoreStandoutNeutralBorderColor);
|
2019-07-08 23:27:14 +00:00
|
|
|
|
|
|
|
|
|
.bbcode {
|
|
|
|
|
filter: grayscale(0.5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.bbcode,
|
|
|
|
|
.user-view,
|
2021-01-31 00:46:27 +00:00
|
|
|
|
.message-time,
|
|
|
|
|
.message-pre,
|
|
|
|
|
.message-post {
|
2019-07-08 23:27:14 +00:00
|
|
|
|
opacity: 0.6;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2019-07-07 21:44:32 +00:00
|
|
|
|
&.weak-mismatch {
|
2020-04-03 23:48:39 +00:00
|
|
|
|
border-left: 12px solid var(--scoreStandoutWeakMismatchBorderColor);
|
|
|
|
|
background-color: var(--scoreStandoutWeakMismatchBgColor);
|
2019-07-07 21:44:32 +00:00
|
|
|
|
|
|
|
|
|
.bbcode {
|
|
|
|
|
filter: grayscale(0.7);
|
|
|
|
|
}
|
2019-07-07 01:37:15 +00:00
|
|
|
|
|
2019-07-07 21:44:32 +00:00
|
|
|
|
.bbcode,
|
|
|
|
|
.user-view,
|
2021-01-31 00:46:27 +00:00
|
|
|
|
.message-time,
|
|
|
|
|
.message-pre,
|
|
|
|
|
.message-post {
|
2019-07-10 00:33:12 +00:00
|
|
|
|
opacity: 0.55;
|
2019-07-07 21:44:32 +00:00
|
|
|
|
}
|
2019-07-07 01:37:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-07-07 21:44:32 +00:00
|
|
|
|
&.mismatch {
|
2020-04-03 23:48:39 +00:00
|
|
|
|
border-left: 12px solid var(--scoreStandoutMismatchBorderColor);
|
2019-07-07 21:44:32 +00:00
|
|
|
|
|
|
|
|
|
.bbcode {
|
|
|
|
|
filter: grayscale(0.8);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.bbcode,
|
|
|
|
|
.user-view,
|
2021-01-31 00:46:27 +00:00
|
|
|
|
.message-time,
|
|
|
|
|
.message-pre,
|
|
|
|
|
.message-post {
|
2019-07-07 21:44:32 +00:00
|
|
|
|
opacity: 0.3;
|
|
|
|
|
}
|
2019-07-07 01:37:15 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-14 19:28:14 +00:00
|
|
|
|
</style>
|