mirror of
				https://github.com/SillyTavern/SillyTavern.git
				synced 2025-06-05 21:59:27 +02:00 
			
		
		
		
	add Quick Replies extension
This commit is contained in:
		| @@ -57,6 +57,7 @@ const extension_settings = { | |||||||
|     chromadb: {}, |     chromadb: {}, | ||||||
|     translate: {}, |     translate: {}, | ||||||
|     objective: {}, |     objective: {}, | ||||||
|  |     quickReply: {}, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| let modules = []; | let modules = []; | ||||||
|   | |||||||
							
								
								
									
										174
									
								
								public/scripts/extensions/quick-reply/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								public/scripts/extensions/quick-reply/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,174 @@ | |||||||
|  | import { saveSettingsDebounced } from "../../../script.js"; | ||||||
|  | import { getContext, extension_settings } from "../../extensions.js"; | ||||||
|  | import { initScrollHeight, resetScrollHeight } from "../../utils.js"; | ||||||
|  |  | ||||||
|  | export { MODULE_NAME }; | ||||||
|  |  | ||||||
|  | const MODULE_NAME = 'quick-reply'; | ||||||
|  | const UPDATE_INTERVAL = 1000; | ||||||
|  |  | ||||||
|  | const defaultSettings = { | ||||||
|  |     quickReply1Mes: '', | ||||||
|  |     quickReply1Label: '', | ||||||
|  |     quickReply2Mes: '', | ||||||
|  |     quickReply2Label: '', | ||||||
|  |     quickReply3Mes: '', | ||||||
|  |     quickReply3Label: '', | ||||||
|  |     quickReply4Mes: '', | ||||||
|  |     quickReply4Label: '', | ||||||
|  |     quickReply5Mes: '', | ||||||
|  |     quickReply5Label: '', | ||||||
|  |     quickReplyEnabled: false, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function loadSettings() { | ||||||
|  |     if (Object.keys(extension_settings.quickReply).length === 0) { | ||||||
|  |         Object.assign(extension_settings.quickReply, defaultSettings); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $('#quickReplyEnabled').prop('checked', extension_settings.quickReply.quickReplyEnabled); | ||||||
|  |  | ||||||
|  |     $('#quickReply1Mes').val(extension_settings.quickReply.quickReply1Mes).trigger('input'); | ||||||
|  |     $('#quickReply1Label').val(extension_settings.quickReply.quickReply1Label).trigger('input'); | ||||||
|  |  | ||||||
|  |     $('#quickReply2Mes').val(extension_settings.quickReply.quickReply2Mes).trigger('input'); | ||||||
|  |     $('#quickReply2Label').val(extension_settings.quickReply.quickReply2Label).trigger('input'); | ||||||
|  |  | ||||||
|  |     $('#quickReply3Mes').val(extension_settings.quickReply.quickReply3Mes).trigger('input'); | ||||||
|  |     $('#quickReply3Label').val(extension_settings.quickReply.quickReply3Label).trigger('input'); | ||||||
|  |  | ||||||
|  |     $('#quickReply4Mes').val(extension_settings.quickReply.quickReply4Mes).trigger('input'); | ||||||
|  |     $('#quickReply4Label').val(extension_settings.quickReply.quickReply4Label).trigger('input'); | ||||||
|  |  | ||||||
|  |     $('#quickReply5Mes').val(extension_settings.quickReply.quickReply5Mes).trigger('input'); | ||||||
|  |     $('#quickReply5Label').val(extension_settings.quickReply.quickReply5Label).trigger('input'); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function onQuickReplyInput(id) { | ||||||
|  |     extension_settings.quickReply[`quickReply${id}Mes`] = $(`#quickReply${id}Mes`).val(); | ||||||
|  |     $(`#quickReply${id}`).attr('title', ($(`#quickReply${id}Mes`).val())); | ||||||
|  |     resetScrollHeight($(`#quickReply${id}Mes`)); | ||||||
|  |     saveSettingsDebounced(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function onQuickReplyLabelInput(id) { | ||||||
|  |     extension_settings.quickReply[`quickReply${id}Label`] = $(`#quickReply${id}Label`).val(); | ||||||
|  |     $(`#quickReply${id}`).text($(`#quickReply${id}Label`).val()); | ||||||
|  |     saveSettingsDebounced(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function onQuickReplyEnabledInput() { | ||||||
|  |     let isEnabled = $(this).prop('checked') | ||||||
|  |     extension_settings.quickReply.quickReplyEnabled = !!isEnabled; | ||||||
|  |     if (isEnabled === true) { | ||||||
|  |         $("#quickReplyBar").show(); | ||||||
|  |     } else { $("#quickReplyBar").hide(); } | ||||||
|  |     saveSettingsDebounced(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function sendQuickReply(id) { | ||||||
|  |     var prompt = extension_settings.quickReply[`${id}Mes`]; | ||||||
|  |     $("#send_textarea").val(prompt); | ||||||
|  |     $("#send_but").trigger('click'); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function addQuickReplyBar(numButtons) { | ||||||
|  |     var numButtons = 5; | ||||||
|  |     const quickReplyBarStartHtml = ` | ||||||
|  |     <div id="quickReplyBar" class="flex-container flexGap5"> | ||||||
|  |         <div id="quickReplies"> | ||||||
|  |         `; | ||||||
|  |     let quickReplyButtonHtml = ''; | ||||||
|  |     for (let i = 0; i < numButtons; i++) { | ||||||
|  |         let quickReplyMes = extension_settings.quickReply[`quickReply${i + 1}Mes`]; | ||||||
|  |         let quickReplyLabel = extension_settings.quickReply[`quickReply${i + 1}Label`]; | ||||||
|  |         console.log(quickReplyMes); | ||||||
|  |         quickReplyButtonHtml += `<div title="${quickReplyMes}" class="quickReplyButton" id="quickReply${i + 1}">${quickReplyLabel}</div>`; | ||||||
|  |     } | ||||||
|  |     const quickReplyEndHtml = `</div></div>` | ||||||
|  |     const quickReplyBarFullHtml = [quickReplyBarStartHtml, quickReplyButtonHtml, quickReplyEndHtml].join(''); | ||||||
|  |  | ||||||
|  |     $('#send_form').prepend(quickReplyBarFullHtml); | ||||||
|  |  | ||||||
|  |     $('.quickReplyButton').on('click', function () { | ||||||
|  |         console.log('got quick reply click'); | ||||||
|  |         let quickReplyButtonID = $(this).attr('id'); | ||||||
|  |         sendQuickReply(quickReplyButtonID); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | async function moduleWorker() { | ||||||
|  |     if (extension_settings.quickReply.quickReplyEnabled === true) { | ||||||
|  |         $('#quickReplyBar').toggle(getContext().onlineStatus !== 'no_connection'); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | jQuery(async () => { | ||||||
|  |  | ||||||
|  |     moduleWorker(); | ||||||
|  |     setInterval(moduleWorker, UPDATE_INTERVAL); | ||||||
|  |     const settingsHtml = ` | ||||||
|  |     <div class="quickReplySettings"> | ||||||
|  |         <div class="inline-drawer"> | ||||||
|  |             <div class="inline-drawer-toggle inline-drawer-header"> | ||||||
|  |             <b>Quick Reply</b> | ||||||
|  |             <div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div> | ||||||
|  |         </div> | ||||||
|  |         <div class="inline-drawer-content"> | ||||||
|  |             <label class="checkbox_label"> | ||||||
|  |                 <input id="quickReplyEnabled" type="checkbox" /> | ||||||
|  |                     Enable Quick Replies | ||||||
|  |             </label> | ||||||
|  |             <small><i>Customize your Quick Replies:</i></small><br> | ||||||
|  |             <div class="flex-container"> | ||||||
|  |                 <input class="text_pole widthUnset" id="quickReply1Label" placeholder="(Add a button label)"> | ||||||
|  |                 <textarea id="quickReply1Mes" placeholder="(custom message here)" class="text_pole textarea_compact widthUnset flex1" rows="2"></textarea> | ||||||
|  |             </div> | ||||||
|  |             <div class="flex-container"> | ||||||
|  |                 <input class="text_pole widthUnset" id="quickReply2Label" placeholder="(Add a button label)"> | ||||||
|  |                 <textarea id="quickReply2Mes"  placeholder="(custom message here)" class="text_pole textarea_compact widthUnset flex1" rows="2"></textarea> | ||||||
|  |             </div> | ||||||
|  |             <div class="flex-container"> | ||||||
|  |                 <input class="text_pole widthUnset" id="quickReply3Label" placeholder="(Add a button label)"> | ||||||
|  |                 <textarea id="quickReply3Mes"  placeholder="(custom message here)" class="text_pole textarea_compact widthUnset flex1" rows="2"></textarea> | ||||||
|  |             </div> | ||||||
|  |             <div class="flex-container"> | ||||||
|  |                 <input class="text_pole widthUnset" id="quickReply4Label" placeholder="(Add a button label)"> | ||||||
|  |                 <textarea id="quickReply4Mes"  placeholder="(custom message here)" class="text_pole textarea_compact widthUnset flex1" rows="2"></textarea> | ||||||
|  |             </div> | ||||||
|  |             <div class="flex-container"> | ||||||
|  |                 <input class="text_pole widthUnset" id="quickReply5Label" placeholder="(Add a button label)"> | ||||||
|  |                 <textarea id="quickReply5Mes"  placeholder="(custom message here)" class="text_pole textarea_compact widthUnset flex1" rows="2"></textarea> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div>`; | ||||||
|  |  | ||||||
|  |     $('#extensions_settings').append(settingsHtml); | ||||||
|  |  | ||||||
|  |     $('#quickReply1Mes').on('input', function () { onQuickReplyInput(1); }); | ||||||
|  |     $('#quickReply2Mes').on('input', function () { onQuickReplyInput(2); }); | ||||||
|  |     $('#quickReply3Mes').on('input', function () { onQuickReplyInput(3); }); | ||||||
|  |     $('#quickReply4Mes').on('input', function () { onQuickReplyInput(4); }); | ||||||
|  |     $('#quickReply5Mes').on('input', function () { onQuickReplyInput(5); }); | ||||||
|  |  | ||||||
|  |     $('#quickReply1Label').on('input', function () { onQuickReplyLabelInput(1); }); | ||||||
|  |     $('#quickReply2Label').on('input', function () { onQuickReplyLabelInput(2); }); | ||||||
|  |     $('#quickReply3Label').on('input', function () { onQuickReplyLabelInput(3); }); | ||||||
|  |     $('#quickReply4Label').on('input', function () { onQuickReplyLabelInput(4); }); | ||||||
|  |     $('#quickReply5Label').on('input', function () { onQuickReplyLabelInput(5); }); | ||||||
|  |  | ||||||
|  |     $('#quickReplyEnabled').on('input', onQuickReplyEnabledInput); | ||||||
|  |  | ||||||
|  |     $('.quickReplySettings .inline-drawer-toggle').on('click', function () { | ||||||
|  |         initScrollHeight($("#quickReply1Mes")); | ||||||
|  |         initScrollHeight($("#quickReply2Mes")); | ||||||
|  |         initScrollHeight($("#quickReply3Mes")); | ||||||
|  |         initScrollHeight($("#quickReply4Mes")); | ||||||
|  |         initScrollHeight($("#quickReply5Mes")); | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |     await loadSettings(); | ||||||
|  |     addQuickReplyBar(); | ||||||
|  | }); | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								public/scripts/extensions/quick-reply/manifest.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								public/scripts/extensions/quick-reply/manifest.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | { | ||||||
|  |     "display_name": "Quick Replies", | ||||||
|  |     "loading_order": 12, | ||||||
|  |     "requires": [], | ||||||
|  |     "optional": [], | ||||||
|  |     "js": "index.js", | ||||||
|  |     "css": "style.css", | ||||||
|  |     "author": "RossAscends#1779", | ||||||
|  |     "version": "1.0.0", | ||||||
|  |     "homePage": "https://github.com/SillyTavern/SillyTavern" | ||||||
|  | } | ||||||
							
								
								
									
										47
									
								
								public/scripts/extensions/quick-reply/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								public/scripts/extensions/quick-reply/style.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | |||||||
|  | #quickReplyBar { | ||||||
|  |     outline: none; | ||||||
|  |     padding: 5px 0; | ||||||
|  |     border-bottom: 1px solid var(--black30a); | ||||||
|  |     margin: 0; | ||||||
|  |     transition: 0.3s; | ||||||
|  |     opacity: 0.7; | ||||||
|  |     display: flex; | ||||||
|  |     align-items: center; | ||||||
|  |     justify-content: center; | ||||||
|  |     width: 100%; | ||||||
|  |     display: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #quickReplies { | ||||||
|  |     margin: 0; | ||||||
|  |     padding: 0; | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: center; | ||||||
|  |     flex-wrap: nowrap; | ||||||
|  |     gap: 5px; | ||||||
|  |     width: 100%; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #quickReplies div { | ||||||
|  |     color: var(--SmartThemeBodyColor); | ||||||
|  |     background-color: var(--black50a); | ||||||
|  |     border: 1px solid var(--white30a); | ||||||
|  |     border-radius: 10px; | ||||||
|  |     padding: 3px 5px; | ||||||
|  |     width: min-content; | ||||||
|  |     cursor: pointer; | ||||||
|  |     transition: 0.3s; | ||||||
|  |     display: flex; | ||||||
|  |     align-items: center; | ||||||
|  |     justify-content: center; | ||||||
|  |     text-align: center; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #quickReplies div:hover { | ||||||
|  |     opacity: 1; | ||||||
|  |     filter: brightness(1.2); | ||||||
|  |     cursor: pointer; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -412,6 +412,7 @@ code { | |||||||
|  |  | ||||||
| #send_form { | #send_form { | ||||||
|     display: flex; |     display: flex; | ||||||
|  |     flex-wrap: wrap; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|     width: 100%; |     width: 100%; | ||||||
|     margin: 0 auto 0 auto; |     margin: 0 auto 0 auto; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user