Better management of accidental parallel message posting
This commit is contained in:
parent
58076f9ab8
commit
f1fbe92dde
|
@ -9,6 +9,8 @@ import l from './localize';
|
||||||
import {CommandContext, isAction, isCommand, isWarn, parse as parseCommand} from './slash_commands';
|
import {CommandContext, isAction, isCommand, isWarn, parse as parseCommand} from './slash_commands';
|
||||||
import MessageType = Interfaces.Message.Type;
|
import MessageType = Interfaces.Message.Type;
|
||||||
import {EventBus} from './preview/event-bus';
|
import {EventBus} from './preview/event-bus';
|
||||||
|
import throat from 'throat';
|
||||||
|
import Bluebird from 'bluebird';
|
||||||
|
|
||||||
function createMessage(this: any, type: MessageType, sender: Character, text: string, time?: Date): Message {
|
function createMessage(this: any, type: MessageType, sender: Character, text: string, time?: Date): Message {
|
||||||
if(type === MessageType.Message && isAction(text)) {
|
if(type === MessageType.Message && isAction(text)) {
|
||||||
|
@ -40,6 +42,8 @@ abstract class Conversation implements Interfaces.Conversation {
|
||||||
private lastSent = '';
|
private lastSent = '';
|
||||||
adManager: AdManager;
|
adManager: AdManager;
|
||||||
|
|
||||||
|
protected static readonly conversationThroat = throat(1); // make sure user posting and ad posting won't get in each others' way
|
||||||
|
|
||||||
constructor(readonly key: string, public _isPinned: boolean) {
|
constructor(readonly key: string, public _isPinned: boolean) {
|
||||||
this.adManager = new AdManager(this);
|
this.adManager = new AdManager(this);
|
||||||
}
|
}
|
||||||
|
@ -124,6 +128,19 @@ abstract class Conversation implements Interfaces.Conversation {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract doSend(): void | Promise<void>;
|
protected abstract doSend(): void | Promise<void>;
|
||||||
|
|
||||||
|
|
||||||
|
protected static readonly POST_DELAY = 1250;
|
||||||
|
|
||||||
|
protected static async testPostDelay(): Promise<void> {
|
||||||
|
const lastPostDelta = Date.now() - core.cache.getLastPost().getTime();
|
||||||
|
|
||||||
|
// console.log('Last Post Delta', lastPostDelta, ((lastPostDelta < Conversation.POST_DELAY) && (lastPostDelta > 0)));
|
||||||
|
|
||||||
|
if ((lastPostDelta < Conversation.POST_DELAY) && (lastPostDelta > 0)) {
|
||||||
|
await Bluebird.delay(Conversation.POST_DELAY - lastPostDelta);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PrivateConversation extends Conversation implements Interfaces.PrivateConversation {
|
class PrivateConversation extends Conversation implements Interfaces.PrivateConversation {
|
||||||
|
@ -200,11 +217,23 @@ class PrivateConversation extends Conversation implements Interfaces.PrivateConv
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
core.connection.send('PRI', {recipient: this.name, message: this.enteredText});
|
const messageText = this.enteredText;
|
||||||
const message = createMessage(MessageType.Message, core.characters.ownCharacter, this.enteredText);
|
|
||||||
this.safeAddMessage(message);
|
|
||||||
if(core.state.settings.logMessages) await core.logs.logMessage(this, message);
|
|
||||||
this.clearText();
|
this.clearText();
|
||||||
|
|
||||||
|
await Conversation.conversationThroat(
|
||||||
|
async() => {
|
||||||
|
await Conversation.testPostDelay();
|
||||||
|
|
||||||
|
core.connection.send('PRI', {recipient: this.name, message: messageText});
|
||||||
|
core.cache.markLastPostTime();
|
||||||
|
|
||||||
|
const message = createMessage(MessageType.Message, core.characters.ownCharacter, messageText);
|
||||||
|
this.safeAddMessage(message);
|
||||||
|
|
||||||
|
if(core.state.settings.logMessages) await core.logs.logMessage(this, message);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private setOwnTyping(status: Interfaces.TypingStatus): void {
|
private setOwnTyping(status: Interfaces.TypingStatus): void {
|
||||||
|
@ -335,30 +364,52 @@ class ChannelConversation extends Conversation implements Interfaces.ChannelConv
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
core.connection.send(isAd ? 'LRP' : 'MSG', {channel: this.channel.id, message: this.enteredText});
|
const message = this.enteredText;
|
||||||
await this.addMessage(
|
|
||||||
createMessage(isAd ? MessageType.Ad : MessageType.Message, core.characters.ownCharacter, this.enteredText, new Date()));
|
|
||||||
if(isAd)
|
|
||||||
this.nextAd = Date.now() + core.connection.vars.lfrp_flood * 1000;
|
|
||||||
else this.clearText();
|
|
||||||
|
|
||||||
core.cache.timeLastPost();
|
if (!isAd) {
|
||||||
|
this.clearText();
|
||||||
|
}
|
||||||
|
|
||||||
|
await Conversation.conversationThroat(
|
||||||
|
async() => {
|
||||||
|
await Conversation.testPostDelay();
|
||||||
|
|
||||||
|
core.connection.send(isAd ? 'LRP' : 'MSG', {channel: this.channel.id, message});
|
||||||
|
core.cache.markLastPostTime();
|
||||||
|
|
||||||
|
await this.addMessage(
|
||||||
|
createMessage(isAd ? MessageType.Ad : MessageType.Message, core.characters.ownCharacter, message, new Date())
|
||||||
|
);
|
||||||
|
|
||||||
|
if(isAd)
|
||||||
|
this.nextAd = Date.now() + core.connection.vars.lfrp_flood * 1000;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async sendAd(text: string): Promise<void> {
|
async sendAd(text: string): Promise<void> {
|
||||||
if (text.length < 1)
|
if (text.length < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
core.connection.send('LRP', {channel: this.channel.id, message: text});
|
await Conversation.conversationThroat(
|
||||||
|
async() => {
|
||||||
|
await Conversation.testPostDelay();
|
||||||
|
|
||||||
await this.addMessage(
|
core.connection.send('LRP', {channel: this.channel.id, message: text});
|
||||||
createMessage(MessageType.Ad, core.characters.ownCharacter, text, new Date())
|
core.cache.markLastPostTime();
|
||||||
|
|
||||||
|
await this.addMessage(
|
||||||
|
createMessage(MessageType.Ad, core.characters.ownCharacter, text, new Date())
|
||||||
|
);
|
||||||
|
|
||||||
|
this.nextAd = Date.now() + core.connection.vars.lfrp_flood * 1000;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
this.nextAd = Date.now() + core.connection.vars.lfrp_flood * 1000;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ConsoleConversation extends Conversation {
|
class ConsoleConversation extends Conversation {
|
||||||
readonly context = CommandContext.Console;
|
readonly context = CommandContext.Console;
|
||||||
readonly name = l('chat.consoleTab');
|
readonly name = l('chat.consoleTab');
|
||||||
|
|
|
@ -40,7 +40,7 @@ export class CacheManager {
|
||||||
protected lastPost: Date = new Date();
|
protected lastPost: Date = new Date();
|
||||||
|
|
||||||
|
|
||||||
timeLastPost(): void {
|
markLastPostTime(): void {
|
||||||
this.lastPost = new Date();
|
this.lastPost = new Date();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
"@f-list/fork-ts-checker-webpack-plugin": "^3.1.1",
|
"@f-list/fork-ts-checker-webpack-plugin": "^3.1.1",
|
||||||
"@f-list/vue-ts": "^1.0.3",
|
"@f-list/vue-ts": "^1.0.3",
|
||||||
"@fortawesome/fontawesome-free": "^5.9.0",
|
"@fortawesome/fontawesome-free": "^5.9.0",
|
||||||
|
"@types/bluebird": "^3.5.30",
|
||||||
"@types/lodash": "^4.14.134",
|
"@types/lodash": "^4.14.134",
|
||||||
"@types/node-fetch": "^2.5.5",
|
"@types/node-fetch": "^2.5.5",
|
||||||
"@types/qs": "^6.9.1",
|
"@types/qs": "^6.9.1",
|
||||||
|
@ -45,6 +46,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cliqz/adblocker-electron": "^1.13.0",
|
"@cliqz/adblocker-electron": "^1.13.0",
|
||||||
|
"bluebird": "^3.7.2",
|
||||||
"jquery": "^3.4.1",
|
"jquery": "^3.4.1",
|
||||||
"keytar": "^5.4.0",
|
"keytar": "^5.4.0",
|
||||||
"node-fetch": "^2.6.0"
|
"node-fetch": "^2.6.0"
|
||||||
|
|
17
readme.md
17
readme.md
|
@ -13,17 +13,18 @@ This repository contains a heavily customized version of the mainline F-Chat 3.0
|
||||||
|
|
||||||
### More Detailed Differences
|
### More Detailed Differences
|
||||||
|
|
||||||
* Ads view
|
* Channel Conversations
|
||||||
* Highlight ads from characters most interesting to you
|
* Highlight ads from characters most interesting to you
|
||||||
* Hide clearly unmatched ads
|
* Hide clearly unmatched ads
|
||||||
* View characters' recent ads
|
* Ad Auto-Posting
|
||||||
* Ad auto-posting
|
|
||||||
* Manage channel ad settings via "Tab Settings"
|
* Manage channel ad settings via "Tab Settings"
|
||||||
* Automatically re-post ads every 11-18 minutes (randomized) for up to 180 minutes
|
* Automatically re-post ads every 11-18 minutes (randomized) for up to 180 minutes
|
||||||
* Rotate multiple ads on a single channel by entering multiple ads in "Ad Settings"
|
* Rotate multiple ads on a single channel by entering multiple ads in "Ad Settings"
|
||||||
* Ad ratings
|
* Ad Ratings
|
||||||
* LFP ads are automatically rated (great/good/maybe/no) and matched against your profile
|
* LFP ads are automatically rated (great/good/maybe/no) and matched against your profile
|
||||||
* Link previews
|
* Private Conversations
|
||||||
|
* View a characters' recent ads
|
||||||
|
* Link Previews
|
||||||
* Hover cursor over any `[url]` to see a preview of it
|
* Hover cursor over any `[url]` to see a preview of it
|
||||||
* Middle click any `[url]` to turn the preview into a sticky / interactive mode
|
* Middle click any `[url]` to turn the preview into a sticky / interactive mode
|
||||||
* Link preview has an ad-blocker to minimize page load times and protect against unfriendly scripts
|
* Link preview has an ad-blocker to minimize page load times and protect against unfriendly scripts
|
||||||
|
@ -45,8 +46,8 @@ This repository contains a heavily customized version of the mainline F-Chat 3.0
|
||||||
* Current search filters are listed in the search dialog
|
* Current search filters are listed in the search dialog
|
||||||
* Search filters can be reset
|
* Search filters can be reset
|
||||||
* Search results can be filtered by species
|
* Search results can be filtered by species
|
||||||
* Last 15 searches are stored and can be accessed from the 'Search' dialog
|
* Last 15 searches are stored and can be accessed from the 'Character search' dialog
|
||||||
* Character status
|
* Character Status Message
|
||||||
* Last 10 status messages are stored and can be accessed from the 'Set status' dialog
|
* Last 10 status messages are stored and can be accessed from the 'Set status' dialog
|
||||||
* General
|
* General
|
||||||
* Character profiles, guestbooks, friend lists, and image lists are cached for faster access
|
* Character profiles, guestbooks, friend lists, and image lists are cached for faster access
|
||||||
|
@ -55,7 +56,7 @@ This repository contains a heavily customized version of the mainline F-Chat 3.0
|
||||||
* PM list shows characters' online status as a colored icon
|
* PM list shows characters' online status as a colored icon
|
||||||
* Technical Details for Nerds
|
* Technical Details for Nerds
|
||||||
* Upgraded to Electron 9.x
|
* Upgraded to Electron 9.x
|
||||||
* Replaced `node-spellchecker` with the built-in spellchecker that ships with Electron 8
|
* Replaced `node-spellchecker` with the built-in spellchecker that ships with Electron 8+
|
||||||
* Multi-language support for spell checking (Windows only – language is autodetected on MacOS)
|
* Multi-language support for spell checking (Windows only – language is autodetected on MacOS)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
true,
|
true,
|
||||||
"array"
|
"array"
|
||||||
],
|
],
|
||||||
"await-promise": [true, "AxiosPromise"],
|
"await-promise": [true, "AxiosPromise", "Bluebird"],
|
||||||
"comment-format": false,
|
"comment-format": false,
|
||||||
"completed-docs": false,
|
"completed-docs": false,
|
||||||
"curly": false,
|
"curly": false,
|
||||||
|
|
|
@ -153,6 +153,11 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
defer-to-connect "^1.0.1"
|
defer-to-connect "^1.0.1"
|
||||||
|
|
||||||
|
"@types/bluebird@^3.5.30":
|
||||||
|
version "3.5.30"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.30.tgz#ee034a0eeea8b84ed868b1aa60d690b08a6cfbc5"
|
||||||
|
integrity sha512-8LhzvcjIoqoi1TghEkRMkbbmM+jhHnBokPGkJWjclMK+Ks0MxEBow3/p2/iFTZ+OIbJHQDSfpgdZEb+af3gfVw==
|
||||||
|
|
||||||
"@types/chrome@^0.0.103":
|
"@types/chrome@^0.0.103":
|
||||||
version "0.0.103"
|
version "0.0.103"
|
||||||
resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.103.tgz#604f3d94ab4465cc8cde302c4916f4955eb7e8b6"
|
resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.103.tgz#604f3d94ab4465cc8cde302c4916f4955eb7e8b6"
|
||||||
|
@ -844,7 +849,7 @@ block-stream@*:
|
||||||
dependencies:
|
dependencies:
|
||||||
inherits "~2.0.0"
|
inherits "~2.0.0"
|
||||||
|
|
||||||
bluebird@^3.1.1, bluebird@^3.5.0, bluebird@^3.5.5:
|
bluebird@^3.1.1, bluebird@^3.5.0, bluebird@^3.5.5, bluebird@^3.7.2:
|
||||||
version "3.7.2"
|
version "3.7.2"
|
||||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
||||||
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
|
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
|
||||||
|
|
Loading…
Reference in New Issue