1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-08-14 10:00:53 +00:00
* Added: Custom Chat Commands now have an option to paste their output into chat input rather than immediately sending the message.
* Added: The option to tab-complete emotes without the use of a colon (:). Please note that this feature still has limitations due to limitations in how Twitch's tab-completion system is implemented, and may not work as you expect.
* Added: The number of results from emote tab-completion will now be limited to 25 by default to mitigate its performance impact. This may be disabled in settings.
This commit is contained in:
SirStendec 2019-06-27 23:19:05 -04:00
parent 3120d586d2
commit 86b0b624f7
6 changed files with 59 additions and 12 deletions

View file

@ -1,7 +1,7 @@
{ {
"name": "frankerfacez", "name": "frankerfacez",
"author": "Dan Salvato LLC", "author": "Dan Salvato LLC",
"version": "4.5.5", "version": "4.6.0",
"description": "FrankerFaceZ is a Twitch enhancement suite.", "description": "FrankerFaceZ is a Twitch enhancement suite.",
"license": "Apache-2.0", "license": "Apache-2.0",
"scripts": { "scripts": {

View file

@ -149,13 +149,13 @@ export default class ExperimentManager extends Module {
if ( window.__twilightSettings ) if ( window.__twilightSettings )
return window.__twilightSettings.experiments; return window.__twilightSettings.experiments;
const core = this.resolve('site').getCore(); const core = this.resolve('site')?.getCore();
return core && core.experiments.experiments; return core && core.experiments.experiments;
} }
usingTwitchExperiment(key) { usingTwitchExperiment(key) {
const core = this.resolve('site').getCore(); const core = this.resolve('site')?.getCore();
return core && has(core.experiments.assignments, key) return core && has(core.experiments.assignments, key)
} }
@ -165,7 +165,7 @@ export default class ExperimentManager extends Module {
overrides[key] = value; overrides[key] = value;
Cookie.set(OVERRIDE_COOKIE, overrides, COOKIE_OPTIONS); Cookie.set(OVERRIDE_COOKIE, overrides, COOKIE_OPTIONS);
const core = this.resolve('site').getCore(); const core = this.resolve('site')?.getCore();
if ( core ) if ( core )
core.experiments.overrides[key] = value; core.experiments.overrides[key] = value;
@ -181,7 +181,7 @@ export default class ExperimentManager extends Module {
delete overrides[key]; delete overrides[key];
Cookie.set(OVERRIDE_COOKIE, overrides, COOKIE_OPTIONS); Cookie.set(OVERRIDE_COOKIE, overrides, COOKIE_OPTIONS);
const core = this.resolve('site').getCore(); const core = this.resolve('site')?.getCore();
if ( core ) if ( core )
delete core.experiments.overrides[key]; delete core.experiments.overrides[key];
@ -194,7 +194,7 @@ export default class ExperimentManager extends Module {
} }
getTwitchAssignment(key) { getTwitchAssignment(key) {
const core = this.resolve('site').getCore(), const core = this.resolve('site')?.getCore(),
exps = core && core.experiments; exps = core && core.experiments;
if ( ! exps ) if ( ! exps )
@ -235,7 +235,7 @@ export default class ExperimentManager extends Module {
} }
_rebuildTwitchKey(key, is_set, new_val) { _rebuildTwitchKey(key, is_set, new_val) {
const core = this.resolve('site').getCore(), const core = this.resolve('site')?.getCore(),
exps = core.experiments, exps = core.experiments,
old_val = has(exps.assignments, key) ? old_val = has(exps.assignments, key) ?

View file

@ -1,12 +1,12 @@
<template lang="html"> <template lang="html">
<div class="tw-flex tw-align-items-start"> <div class="tw-flex tw-align-items-start">
<label for="edit_chat" class="tw-mg-y-05"> <label :for="'edit_chat$' + id" class="tw-mg-y-05">
{{ t('setting.actions.chat', 'Chat Command') }} {{ t('setting.actions.chat', 'Chat Command') }}
</label> </label>
<div class="tw-full-width"> <div class="tw-full-width">
<input <input
id="edit_chat" :id="'edit_chat$' + id"
v-model="value.command" v-model="value.command"
:placeholder="defaults.command" :placeholder="defaults.command"
class="tw-border-radius-medium tw-font-size-6 tw-full-width tw-input tw-pd-x-1 tw-pd-y-05 tw-mg-y-05" class="tw-border-radius-medium tw-font-size-6 tw-full-width tw-input tw-pd-x-1 tw-pd-y-05 tw-mg-y-05"
@ -16,14 +16,36 @@
<div class="tw-c-text-alt-2 tw-mg-b-1"> <div class="tw-c-text-alt-2 tw-mg-b-1">
{{ t('setting.actions.variables', 'Available Variables: {vars}', {vars}) }} {{ t('setting.actions.variables', 'Available Variables: {vars}', {vars}) }}
</div> </div>
<div class="tw-checkbox">
<input
:id="'chat-paste$' + id"
v-model="value.paste"
type="checkbox"
class="tw-checkbox__input"
@change="$emit('input', value)"
>
<label :for="'chat-paste$' + id" class="tw-checkbox__label">
{{ t('setting.actions.set-chat', 'Paste this message into chat rather than sending it directly.') }}
</label>
</div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
let last_id = 0;
export default { export default {
props: ['value', 'defaults', 'vars'], props: ['value', 'defaults', 'vars'],
data() {
return {
id: last_id++
}
}
} }
</script> </script>

View file

@ -636,6 +636,11 @@ export default class Actions extends Module {
} }
pasteMessage(room, message) {
return this.resolve('site.chat.input').pasteMessage(room, message);
}
sendMessage(room, message) { sendMessage(room, message) {
return this.resolve('site.chat').sendMessage(room, message); return this.resolve('site.chat').sendMessage(room, message);
} }

View file

@ -63,7 +63,8 @@ export const chat = {
required_context: ['room'], required_context: ['room'],
defaults: { defaults: {
command: '@{{user.login}} HeyGuys' command: '@{{user.login}} HeyGuys',
paste: false
}, },
title: 'Chat Command', title: 'Chat Command',
@ -86,7 +87,10 @@ export const chat = {
click(event, data) { click(event, data) {
const msg = this.replaceVariables(data.options.command, data); const msg = this.replaceVariables(data.options.command, data);
this.sendMessage(data.room.login, msg); if ( data.options.paste )
this.pasteMessage(data.room.login, msg);
else
this.sendMessage(data.room.login, msg);
} }
} }

View file

@ -251,7 +251,7 @@ export default class Input extends Module {
} }
} }
// eslint-disable-next-line class-methods-use-this // eslint-disable-next-line class-methods-use-this
getTwitchEmoteSuggestions(input, inst) { getTwitchEmoteSuggestions(input, inst) {
const hydratedEmotes = inst.hydrateEmotes(inst.props.emotes); const hydratedEmotes = inst.hydrateEmotes(inst.props.emotes);
@ -352,4 +352,20 @@ export default class Input extends Module {
return results; return results;
} }
pasteMessage(room, message) {
for(const inst of this.ChatInput.instances) {
if ( inst?.props?.channelLogin !== room )
continue;
if ( ! inst.autocompleteInputRef || ! inst.state )
return;
if ( inst.state.value )
message = `${inst.state.value} ${message}`;
inst.autocompleteInputRef.setValue(message);
inst.autocompleteInputRef.componentRef?.focus?.();
}
}
} }