Merge branch 'MDL-84806-main' of https://github.com/davewoloszyn/moodle
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
define("tiny_aiplacement/generateimage",["exports","tiny_aiplacement/imagemodal","core/ajax","core/str","core/templates","./mediaimage","tiny_aiplacement/options","tiny_aiplacement/generatebase"],(function(_exports,_imagemodal,_ajax,_str,_templates,_mediaimage,_options,_generatebase){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_imagemodal=_interopRequireDefault(_imagemodal),_ajax=_interopRequireDefault(_ajax),_templates=_interopRequireDefault(_templates),_mediaimage=_interopRequireDefault(_mediaimage),_generatebase=_interopRequireDefault(_generatebase);class GenerateImage extends _generatebase.default{constructor(){super(...arguments),_defineProperty(this,"SELECTORS",{GENERATEBUTTON:()=>'[id="'.concat(this.editor.id,'_tiny_aiplacement_generatebutton"]'),PROMPTAREA:()=>'[id="'.concat(this.editor.id,'_tiny_aiplacement_imageprompt"]'),IMAGECONTAINER:()=>'[id="'.concat(this.editor.id,'_tiny_aiplacement_generate_image"]'),GENERATEBTN:'[data-action="generate"]',INSERTBTN:'[data-action="inserter"]',BACKTBTN:'[data-action="back"]',GENERATEDIMAGE:()=>'[id="'.concat(this.editor.id,'_tiny_generated_image"]')}),_defineProperty(this,"imageURL",null)}getModalClass(){return _imagemodal.default}handleContentModalClick(e,root){const actions={generate:()=>this.handleSubmit(root,e.target),inserter:()=>this.handleInsert(),cancel:()=>this.modalObject.destroy(),back:()=>{this.modalObject.destroy(),this.displayContentModal()}},actionKey=Object.keys(actions).find((key=>e.target.closest('[data-action="'.concat(key,'"]'))));actionKey&&(e.preventDefault(),actions[actionKey]())}setupPromptArea(root){const generateBtn=root.querySelector(this.SELECTORS.GENERATEBUTTON()),promptArea=root.querySelector(this.SELECTORS.PROMPTAREA());promptArea.addEventListener("input",(()=>{generateBtn.disabled=""===promptArea.value.trim()}))}async handleSubmit(root,submitBtn){await this.displayLoading(root,submitBtn);const request={methodname:"aiplacement_editor_generate_image",args:this.getDisplayArgs(root)};try{this.responseObj=await _ajax.default.call([request])[0],this.responseObj.error?this.handleGenerationError(root,submitBtn,""):(await this.displayGeneratedImage(root),this.hideLoading(root,submitBtn))}catch(error){this.handleGenerationError(root,submitBtn,"")}}async handleInsert(){const revisedPrompt=this.responseObj.revisedprompt,altTextToUse=revisedPrompt||this.promptText,mediaImage=new _mediaimage.default(this.editor,this.imageURL,altTextToUse);await mediaImage.displayDialogue(),this.modalObject.destroy()}async handleGenerationError(root,submitBtn){let errorMessage=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";errorMessage||(errorMessage=await(0,_str.getString)("errorgeneral","tiny_aiplacement")),this.hideLoading(root,submitBtn),this.modalObject.setBody(_templates.default.render("tiny_aiplacement/modalbodyerror",{errorMessage:errorMessage}));const backBtn=root.querySelector(this.SELECTORS.BACKTBTN),generateBtn=root.querySelector(this.SELECTORS.GENERATEBUTTON());backBtn.classList.remove("hidden"),generateBtn.classList.add("hidden")}async displayGeneratedImage(root){const imageDisplayContainer=root.querySelector(this.SELECTORS.IMAGECONTAINER()),insertBtn=root.querySelector(this.SELECTORS.INSERTBTN);this.imageURL=this.responseObj.drafturl,imageDisplayContainer.innerHTML=await _templates.default.render("tiny_aiplacement/image",{url:this.responseObj.drafturl,elementid:this.editor.id,alt:this.promptText});const imagElement=root.querySelector(this.SELECTORS.GENERATEDIMAGE());return new Promise(((resolve,reject)=>{imagElement.onload=()=>{insertBtn.classList.remove("hidden"),resolve()},imagElement.onerror=error=>{reject(error)}}))}getDisplayArgs(root){const contextId=(0,_options.getContextId)(this.editor),promptText=root.querySelector(this.SELECTORS.PROMPTAREA()).value;this.promptText=promptText;return{contextid:contextId,prompttext:promptText,aspectratio:this.getSelectedRadioValue("aspect-ratio","square"),quality:this.getSelectedRadioValue("quality","standard"),numimages:1}}getSelectedRadioValue(radioName){let defaultValue=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;const radios=document.getElementsByName(radioName);for(const radio of radios)if(radio.checked)return radio.value;return defaultValue}}return _exports.default=GenerateImage,_exports.default}));
|
||||
define("tiny_aiplacement/generateimage",["exports","tiny_aiplacement/imagemodal","core/ajax","core/str","core/templates","./mediaimage","tiny_aiplacement/options","tiny_aiplacement/generatebase"],(function(_exports,_imagemodal,_ajax,_str,_templates,_mediaimage,_options,_generatebase){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_imagemodal=_interopRequireDefault(_imagemodal),_ajax=_interopRequireDefault(_ajax),_templates=_interopRequireDefault(_templates),_mediaimage=_interopRequireDefault(_mediaimage),_generatebase=_interopRequireDefault(_generatebase);class GenerateImage extends _generatebase.default{constructor(){super(...arguments),_defineProperty(this,"SELECTORS",{GENERATEBUTTON:()=>'[id="'.concat(this.editor.id,'_tiny_aiplacement_generatebutton"]'),PROMPTAREA:()=>'[id="'.concat(this.editor.id,'_tiny_aiplacement_imageprompt"]'),IMAGECONTAINER:()=>'[id="'.concat(this.editor.id,'_tiny_aiplacement_generate_image"]'),GENERATEBTN:'[data-action="generate"]',INSERTBTN:'[data-action="inserter"]',BACKTBTN:'[data-action="back"]',GENERATEDIMAGE:()=>'[id="'.concat(this.editor.id,'_tiny_generated_image"]')}),_defineProperty(this,"imageURL",null)}getModalClass(){return _imagemodal.default}handleContentModalClick(e,root){const actions={generate:()=>this.handleSubmit(root,e.target),inserter:()=>this.handleInsert(),cancel:()=>this.modalObject.destroy(),back:()=>{this.modalObject.destroy(),this.displayContentModal()}},actionKey=Object.keys(actions).find((key=>e.target.closest('[data-action="'.concat(key,'"]'))));actionKey&&(e.preventDefault(),actions[actionKey]())}setupPromptArea(root){const generateBtn=root.querySelector(this.SELECTORS.GENERATEBUTTON()),promptArea=root.querySelector(this.SELECTORS.PROMPTAREA());promptArea.addEventListener("input",(()=>{generateBtn.disabled=""===promptArea.value.trim()}))}async handleSubmit(root,submitBtn){await this.displayLoading(root,submitBtn);const request={methodname:"aiplacement_editor_generate_image",args:this.getDisplayArgs(root)};try{if(this.responseObj=await _ajax.default.call([request])[0],this.responseObj.error)this.handleGenerationError(root,submitBtn,"");else{await this.displayGeneratedImage(root),await this.hideLoading(root,submitBtn);root.querySelector(this.SELECTORS.IMAGECONTAINER()).focus()}}catch(error){this.handleGenerationError(root,submitBtn,"")}}async handleInsert(){const revisedPrompt=this.responseObj.revisedprompt,altTextToUse=revisedPrompt||this.promptText,mediaImage=new _mediaimage.default(this.editor,this.imageURL,altTextToUse);await mediaImage.displayDialogue(),this.modalObject.destroy()}async handleGenerationError(root,submitBtn){let errorMessage=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";errorMessage||(errorMessage=await(0,_str.getString)("errorgeneral","tiny_aiplacement")),this.modalObject.setBody(await _templates.default.render("tiny_aiplacement/modalbodyerror",{errorMessage:errorMessage}));const backBtn=root.querySelector(this.SELECTORS.BACKTBTN),generateBtn=root.querySelector(this.SELECTORS.GENERATEBUTTON());backBtn.classList.remove("hidden"),generateBtn.classList.add("hidden"),await this.hideLoading(root,submitBtn),backBtn.focus()}async displayGeneratedImage(root){const imageDisplayContainer=root.querySelector(this.SELECTORS.IMAGECONTAINER()),insertBtn=root.querySelector(this.SELECTORS.INSERTBTN);this.imageURL=this.responseObj.drafturl,imageDisplayContainer.innerHTML=await _templates.default.render("tiny_aiplacement/image",{url:this.responseObj.drafturl,elementid:this.editor.id,alt:this.promptText});const imagElement=root.querySelector(this.SELECTORS.GENERATEDIMAGE());return new Promise(((resolve,reject)=>{imagElement.onload=()=>{insertBtn.classList.remove("hidden"),imagElement.focus(),resolve()},imagElement.onerror=error=>{reject(error)}}))}getDisplayArgs(root){const contextId=(0,_options.getContextId)(this.editor),promptText=root.querySelector(this.SELECTORS.PROMPTAREA()).value;this.promptText=promptText;return{contextid:contextId,prompttext:promptText,aspectratio:this.getSelectedRadioValue("aspect-ratio","square"),quality:this.getSelectedRadioValue("quality","standard"),numimages:1}}getSelectedRadioValue(radioName){let defaultValue=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;const radios=document.getElementsByName(radioName);for(const radio of radios)if(radio.checked)return radio.value;return defaultValue}}return _exports.default=GenerateImage,_exports.default}));
|
||||
|
||||
//# sourceMappingURL=generateimage.min.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -1,3 +1,3 @@
|
||||
define("tiny_aiplacement/generatetext",["exports","./textmodal","core/ajax","core/str","core/templates","core_ai/helper","./options","./textmark","./generatebase"],(function(_exports,_textmodal,_ajax,_str,_templates,_helper,_options,_textmark,_generatebase){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_textmodal=_interopRequireDefault(_textmodal),_ajax=_interopRequireDefault(_ajax),_templates=_interopRequireDefault(_templates),_helper=_interopRequireDefault(_helper),_textmark=_interopRequireDefault(_textmark),_generatebase=_interopRequireDefault(_generatebase);class GenerateText extends _generatebase.default{constructor(){var obj,key,value;super(...arguments),value={GENERATEBUTTON:()=>'[id="'.concat(this.editor.id,'_tiny_aiplacement_generatebutton"]'),PROMPTAREA:()=>'[id="'.concat(this.editor.id,'_tiny_aiplacement_textprompt"]'),RESPONSEWRAPPER:".tiny_aiplacement_textresponse",RESPONSEPLACEHOLDER:".tiny_aiplacement_textresponse_placeholder",GENERATEDRESPONSE:()=>'[id="'.concat(this.editor.id,'_tiny_aiplacement_textresponse"]'),INSERTBTN:'[data-action="inserter"]',BACKTBTN:'[data-action="back"]'},(key="SELECTORS")in(obj=this)?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value}getModalClass(){return _textmodal.default}handleContentModalClick(e,root){const actions={generate:()=>this.handleSubmit(root,e.target),inserter:()=>this.handleInsert(root,e.target),cancel:()=>this.modalObject.destroy(),back:()=>{this.modalObject.destroy(),this.displayContentModal()}},actionKey=Object.keys(actions).find((key=>e.target.closest('[data-action="'.concat(key,'"]'))));actionKey&&(e.preventDefault(),actions[actionKey]())}setupPromptArea(root){const generateBtn=root.querySelector(this.SELECTORS.GENERATEBUTTON()),promptArea=root.querySelector(this.SELECTORS.PROMPTAREA());promptArea.addEventListener("input",(()=>{generateBtn.disabled=""===promptArea.value.trim()}))}async handleSubmit(root,submitBtn){await this.displayLoading(root,submitBtn);const request={methodname:"aiplacement_editor_generate_text",args:this.getRequestArgs(root)};try{this.responseObj=await _ajax.default.call([request])[0],this.responseObj.error?this.handleGenerationError(root,submitBtn,""):(await this.displayGeneratedText(root),this.hideLoading(root,submitBtn))}catch(error){this.handleGenerationError(root,submitBtn,"")}}async handleInsert(root,submitBtn){await this.displayLoading(root,submitBtn);const generatedResponseDiv=root.querySelector(this.SELECTORS.GENERATEDRESPONSE()),wrappedEditedResponse=await _textmark.default.wrapEditedSections(this.responseObj.generatedcontent,generatedResponseDiv.value);this.responseObj.editedtext=_helper.default.formatResponse(wrappedEditedResponse);const formattedResponse=await _templates.default.render("tiny_aiplacement/textinsert",this.responseObj);this.editor.insertContent(formattedResponse),this.editor.execCommand("mceRepaint"),this.editor.windowManager.close(),this.modalObject.hide()}async handleGenerationError(root,submitBtn){let errorMessage=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";errorMessage||(errorMessage=await(0,_str.getString)("errorgeneral","tiny_aiplacement")),this.modalObject.setBody(_templates.default.render("tiny_aiplacement/modalbodyerror",{errorMessage:errorMessage}));const backBtn=root.querySelector(this.SELECTORS.BACKTBTN),generateBtn=root.querySelector(this.SELECTORS.GENERATEBUTTON());backBtn.classList.remove("hidden"),generateBtn.classList.add("hidden"),this.hideLoading(root,submitBtn)}async displayGeneratedText(root){root.querySelector(this.SELECTORS.INSERTBTN).classList.remove("hidden");root.querySelector(this.SELECTORS.GENERATEDRESPONSE()).value=this.responseObj.generatedcontent;root.querySelector(this.SELECTORS.RESPONSEWRAPPER).classList.remove("hidden");root.querySelector(this.SELECTORS.RESPONSEPLACEHOLDER).classList.add("hidden")}getRequestArgs(root){return{contextid:(0,_options.getContextId)(this.editor),prompttext:root.querySelector(this.SELECTORS.PROMPTAREA()).value}}}return _exports.default=GenerateText,_exports.default}));
|
||||
define("tiny_aiplacement/generatetext",["exports","./textmodal","core/ajax","core/str","core/templates","core_ai/helper","./options","./textmark","./generatebase"],(function(_exports,_textmodal,_ajax,_str,_templates,_helper,_options,_textmark,_generatebase){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_textmodal=_interopRequireDefault(_textmodal),_ajax=_interopRequireDefault(_ajax),_templates=_interopRequireDefault(_templates),_helper=_interopRequireDefault(_helper),_textmark=_interopRequireDefault(_textmark),_generatebase=_interopRequireDefault(_generatebase);class GenerateText extends _generatebase.default{constructor(){var obj,key,value;super(...arguments),value={GENERATEBUTTON:()=>'[id="'.concat(this.editor.id,'_tiny_aiplacement_generatebutton"]'),PROMPTAREA:()=>'[id="'.concat(this.editor.id,'_tiny_aiplacement_textprompt"]'),TEXTCONTAINER:()=>'[id="'.concat(this.editor.id,'_tiny_aiplacement_generate_text"]'),GENERATEDRESPONSE:()=>'[id="'.concat(this.editor.id,'_tiny_aiplacement_textresponse"]'),INSERTBTN:'[data-action="inserter"]',BACKTBTN:'[data-action="back"]'},(key="SELECTORS")in(obj=this)?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value}getModalClass(){return _textmodal.default}handleContentModalClick(e,root){const actions={generate:()=>this.handleSubmit(root,e.target),inserter:()=>this.handleInsert(root,e.target),cancel:()=>this.modalObject.destroy(),back:()=>{this.modalObject.destroy(),this.displayContentModal()}},actionKey=Object.keys(actions).find((key=>e.target.closest('[data-action="'.concat(key,'"]'))));actionKey&&(e.preventDefault(),actions[actionKey]())}setupPromptArea(root){const generateBtn=root.querySelector(this.SELECTORS.GENERATEBUTTON()),promptArea=root.querySelector(this.SELECTORS.PROMPTAREA());promptArea.addEventListener("input",(()=>{generateBtn.disabled=""===promptArea.value.trim()}))}async handleSubmit(root,submitBtn){await this.displayLoading(root,submitBtn);const request={methodname:"aiplacement_editor_generate_text",args:this.getRequestArgs(root)};try{if(this.responseObj=await _ajax.default.call([request])[0],this.responseObj.error)this.handleGenerationError(root,submitBtn,"");else{await this.displayGeneratedText(root),await this.hideLoading(root,submitBtn);root.querySelector(this.SELECTORS.TEXTCONTAINER()).focus()}}catch(error){this.handleGenerationError(root,submitBtn,"")}}async handleInsert(root,submitBtn){await this.displayLoading(root,submitBtn);const generatedResponseDiv=root.querySelector(this.SELECTORS.GENERATEDRESPONSE()),wrappedEditedResponse=await _textmark.default.wrapEditedSections(this.responseObj.generatedcontent,generatedResponseDiv.value);this.responseObj.editedtext=_helper.default.formatResponse(wrappedEditedResponse);const formattedResponse=await _templates.default.render("tiny_aiplacement/textinsert",this.responseObj);this.editor.insertContent(formattedResponse),this.editor.execCommand("mceRepaint"),this.editor.windowManager.close(),this.modalObject.hide()}async handleGenerationError(root,submitBtn){let errorMessage=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";errorMessage||(errorMessage=await(0,_str.getString)("errorgeneral","tiny_aiplacement")),this.modalObject.setBody(await _templates.default.render("tiny_aiplacement/modalbodyerror",{errorMessage:errorMessage}));const backBtn=root.querySelector(this.SELECTORS.BACKTBTN),generateBtn=root.querySelector(this.SELECTORS.GENERATEBUTTON());backBtn.classList.remove("hidden"),generateBtn.classList.add("hidden"),await this.hideLoading(root,submitBtn),backBtn.focus()}async displayGeneratedText(root){const textDisplayContainer=root.querySelector(this.SELECTORS.TEXTCONTAINER()),insertBtn=root.querySelector(this.SELECTORS.INSERTBTN);textDisplayContainer.innerHTML=await _templates.default.render("tiny_aiplacement/textarea",{elementid:this.editor.id,text:this.responseObj.generatedcontent});const textareaElement=root.querySelector(this.SELECTORS.GENERATEDRESPONSE());return new Promise(((resolve,reject)=>{textareaElement.textLength>0?(insertBtn.classList.remove("hidden"),textareaElement.focus(),resolve()):reject()}))}getRequestArgs(root){return{contextid:(0,_options.getContextId)(this.editor),prompttext:root.querySelector(this.SELECTORS.PROMPTAREA()).value}}}return _exports.default=GenerateText,_exports.default}));
|
||||
|
||||
//# sourceMappingURL=generatetext.min.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -105,7 +105,10 @@ export default class GenerateImage extends GenerateBase {
|
||||
this.handleGenerationError(root, submitBtn, '');
|
||||
} else {
|
||||
await this.displayGeneratedImage(root);
|
||||
this.hideLoading(root, submitBtn);
|
||||
await this.hideLoading(root, submitBtn);
|
||||
// Focus the container for accessibility.
|
||||
const imageDisplayContainer = root.querySelector(this.SELECTORS.IMAGECONTAINER());
|
||||
imageDisplayContainer.focus();
|
||||
}
|
||||
} catch (error) {
|
||||
this.handleGenerationError(root, submitBtn, '');
|
||||
@@ -137,12 +140,14 @@ export default class GenerateImage extends GenerateBase {
|
||||
// Get the default error message.
|
||||
errorMessage = await getString('errorgeneral', 'tiny_aiplacement');
|
||||
}
|
||||
this.hideLoading(root, submitBtn);
|
||||
this.modalObject.setBody(Templates.render('tiny_aiplacement/modalbodyerror', {'errorMessage': errorMessage}));
|
||||
this.modalObject.setBody(await Templates.render('tiny_aiplacement/modalbodyerror', {'errorMessage': errorMessage}));
|
||||
const backBtn = root.querySelector(this.SELECTORS.BACKTBTN);
|
||||
const generateBtn = root.querySelector(this.SELECTORS.GENERATEBUTTON());
|
||||
backBtn.classList.remove('hidden');
|
||||
generateBtn.classList.add('hidden');
|
||||
await this.hideLoading(root, submitBtn);
|
||||
// Focus the back button for accessibility.
|
||||
backBtn.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,6 +172,7 @@ export default class GenerateImage extends GenerateBase {
|
||||
return new Promise((resolve, reject) => {
|
||||
imagElement.onload = () => {
|
||||
insertBtn.classList.remove('hidden');
|
||||
imagElement.focus();
|
||||
resolve(); // Resolve the promise when the image is loaded.
|
||||
};
|
||||
imagElement.onerror = (error) => {
|
||||
|
||||
@@ -34,8 +34,7 @@ export default class GenerateText extends GenerateBase {
|
||||
SELECTORS = {
|
||||
GENERATEBUTTON: () => `[id="${this.editor.id}_tiny_aiplacement_generatebutton"]`,
|
||||
PROMPTAREA: () => `[id="${this.editor.id}_tiny_aiplacement_textprompt"]`,
|
||||
RESPONSEWRAPPER: '.tiny_aiplacement_textresponse',
|
||||
RESPONSEPLACEHOLDER: '.tiny_aiplacement_textresponse_placeholder',
|
||||
TEXTCONTAINER: () => `[id="${this.editor.id}_tiny_aiplacement_generate_text"]`,
|
||||
GENERATEDRESPONSE: () => `[id="${this.editor.id}_tiny_aiplacement_textresponse"]`,
|
||||
INSERTBTN: '[data-action="inserter"]',
|
||||
BACKTBTN: '[data-action="back"]',
|
||||
@@ -104,7 +103,10 @@ export default class GenerateText extends GenerateBase {
|
||||
this.handleGenerationError(root, submitBtn, '');
|
||||
} else {
|
||||
await this.displayGeneratedText(root);
|
||||
this.hideLoading(root, submitBtn);
|
||||
await this.hideLoading(root, submitBtn);
|
||||
// Focus the container for accessibility.
|
||||
const textDisplayContainer = root.querySelector(this.SELECTORS.TEXTCONTAINER());
|
||||
textDisplayContainer.focus();
|
||||
}
|
||||
} catch (error) {
|
||||
this.handleGenerationError(root, submitBtn, '');
|
||||
@@ -158,30 +160,41 @@ export default class GenerateText extends GenerateBase {
|
||||
// Get the default error message.
|
||||
errorMessage = await getString('errorgeneral', 'tiny_aiplacement');
|
||||
}
|
||||
this.modalObject.setBody(Templates.render('tiny_aiplacement/modalbodyerror', {'errorMessage': errorMessage}));
|
||||
this.modalObject.setBody(await Templates.render('tiny_aiplacement/modalbodyerror', {'errorMessage': errorMessage}));
|
||||
const backBtn = root.querySelector(this.SELECTORS.BACKTBTN);
|
||||
const generateBtn = root.querySelector(this.SELECTORS.GENERATEBUTTON());
|
||||
backBtn.classList.remove('hidden');
|
||||
generateBtn.classList.add('hidden');
|
||||
this.hideLoading(root, submitBtn);
|
||||
await this.hideLoading(root, submitBtn);
|
||||
// Focus the back button for accessibility.
|
||||
backBtn.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the generated image in the modal.
|
||||
* Display the generated text in the modal.
|
||||
*
|
||||
* @param {HTMLElement} root - The root element of the modal.
|
||||
*/
|
||||
async displayGeneratedText(root) {
|
||||
const textDisplayContainer = root.querySelector(this.SELECTORS.TEXTCONTAINER());
|
||||
const insertBtn = root.querySelector(this.SELECTORS.INSERTBTN);
|
||||
insertBtn.classList.remove('hidden');
|
||||
|
||||
// Add generated text to the modal.
|
||||
const generatedResponseDiv = root.querySelector(this.SELECTORS.GENERATEDRESPONSE());
|
||||
generatedResponseDiv.value = this.responseObj.generatedcontent;
|
||||
const responseWrapper = root.querySelector(this.SELECTORS.RESPONSEWRAPPER);
|
||||
responseWrapper.classList.remove('hidden');
|
||||
const responsePlaceholder = root.querySelector(this.SELECTORS.RESPONSEPLACEHOLDER);
|
||||
responsePlaceholder.classList.add('hidden');
|
||||
// Render the textarea template and insert it into the modal.
|
||||
textDisplayContainer.innerHTML = await Templates.render('tiny_aiplacement/textarea', {
|
||||
elementid: this.editor.id,
|
||||
text: this.responseObj.generatedcontent,
|
||||
});
|
||||
const textareaElement = root.querySelector(this.SELECTORS.GENERATEDRESPONSE());
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (textareaElement.textLength > 0) {
|
||||
insertBtn.classList.remove('hidden');
|
||||
textareaElement.focus();
|
||||
resolve();
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
}
|
||||
|
||||
.tiny-aiplacement-generate-image,
|
||||
.tiny_aiplacement_textresponse_placeholder {
|
||||
.tiny-aiplacement-generate-text {
|
||||
border-radius: 15px;
|
||||
border: 2px dashed #bbb;
|
||||
padding: 20px;
|
||||
@@ -55,7 +55,7 @@
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.tiny_aiplacement_textresponse textarea:disabled {
|
||||
.tiny-aiplacement-generate-text textarea:disabled {
|
||||
background-color: unset;
|
||||
}
|
||||
|
||||
@@ -155,28 +155,15 @@
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
|
||||
.tiny-aiplacement-image-display-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
.tiny-aiplacement-fa-text {
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tiny-aiplacement-image-display-container img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.tiny_aiplacement_textresponse_placeholder {
|
||||
width: 100%;
|
||||
background-image: url('[[pix:tiny_aiplacement|sparkles-text]]');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
background-blend-mode: lighten;
|
||||
background-size: 6em 6em;
|
||||
background-size: 100px 100px;
|
||||
}
|
||||
|
||||
.tiny-aiplacement-generate-footer button img {
|
||||
|
||||
@@ -35,4 +35,4 @@
|
||||
"alt": "Example image"
|
||||
}
|
||||
}}
|
||||
<img id="{{elementid}}_tiny_generated_image" alt="{{alt}}" src="{{{url}}}" class="img-fluid mw-100">
|
||||
<img id="{{elementid}}_tiny_generated_image" alt="{{alt}}" src="{{{url}}}" class="img-fluid mw-100" tabindex="-1">
|
||||
|
||||
@@ -36,12 +36,8 @@
|
||||
}}
|
||||
<div id="{{elementid}}_tiny_aiplacement_spinner" class="tiny-aiplacement-loading-spinner-container hidden">
|
||||
<div class="tiny-aiplacement-loading-spinner d-flex justify-content-center align-items-center flex-column">
|
||||
<div class="spinner-border tiny-aiplacement-spinner-style" role="status">
|
||||
<span class="visually-hidden">
|
||||
{{#str}} loading, tiny_aiplacement{{/str}}
|
||||
</span>
|
||||
</div>
|
||||
<div id="{{elementid}}_tiny_aiplacement_loading_text" class="text-center tiny-aiplacement-spinner-text-style">
|
||||
<div class="spinner-border tiny-aiplacement-spinner-style" aria-hidden="true"></div>
|
||||
<div id="{{elementid}}_tiny_aiplacement_loading_text" class="text-center tiny-aiplacement-spinner-text-style" role="status">
|
||||
{{#str}} loading, tiny_aiplacement{{/str}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
}
|
||||
}}
|
||||
<div class="d-flex align-items-center h-100">
|
||||
<div class="tiny-aiplacement-error-display w-50">
|
||||
<div class="tiny-aiplacement-error-display w-50" role="alert">
|
||||
<div class="fw-bold">
|
||||
<i class="icon fa fa-info-circle m-0 text-danger" aria-hidden="true"></i>
|
||||
<span class="d-inline-block">
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
<div class="col-xl-8 col-lg-7">
|
||||
<div id="{{elementid}}_tiny_aiplacement_generate_image" class="tiny-aiplacement-generate-image text-center mt-3 mt-lg-0">
|
||||
<div class="tiny-aiplacement-fa-image"></div>
|
||||
<div id="{{elementid}}_image_display_container" class="tiny-aiplacement-image-display-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -48,18 +48,8 @@
|
||||
rows="12"></textarea>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="tiny_aiplacement_textresponse_placeholder">
|
||||
|
||||
</div>
|
||||
<div class="tiny_aiplacement_textresponse hidden">
|
||||
<textarea
|
||||
class="form-control"
|
||||
id="{{elementid}}_tiny_aiplacement_textresponse"
|
||||
rows="14"
|
||||
placeholder="{{#str}} textresponse_placeholder, tiny_aiplacement {{/str}}"
|
||||
autocomplete="off"
|
||||
disabled
|
||||
></textarea>
|
||||
<div id="{{elementid}}_tiny_aiplacement_generate_text" class="tiny-aiplacement-generate-text text-center mt-3 mt-lg-0">
|
||||
<div class="tiny-aiplacement-fa-text"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
{{!
|
||||
This file is part of Moodle - http://moodle.org/
|
||||
|
||||
Moodle is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Moodle is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}
|
||||
{{!
|
||||
@template tiny_aiplacement/textarea
|
||||
|
||||
Template for the generated text content within the Tiny Editor.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Context variables required for this template:
|
||||
* elementid - The unique element id
|
||||
* text - The generated text
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"elementid": "exampleId",
|
||||
"text": "Example text"
|
||||
}
|
||||
}}
|
||||
<textarea
|
||||
class="form-control h-100"
|
||||
id="{{elementid}}_tiny_aiplacement_textresponse"
|
||||
placeholder="{{#str}} textresponse_placeholder, tiny_aiplacement {{/str}}"
|
||||
aria-label="{{#str}} textresponse_label, tiny_aiplacement {{/str}}"
|
||||
autocomplete="off"
|
||||
>{{text}}</textarea>
|
||||
@@ -31,13 +31,13 @@
|
||||
{
|
||||
"prompttext": "prompt text",
|
||||
"timecreated": "1681901609",
|
||||
"generatedcontent": "returned AI content"
|
||||
"editedtext": "returned AI content"
|
||||
}
|
||||
}}
|
||||
|
||||
<span
|
||||
data-generated="true"
|
||||
data-prompt="{{prompttext}}"
|
||||
data-time-created="{{timecreated}}">
|
||||
data-generated="true"
|
||||
data-prompt="{{prompttext}}"
|
||||
data-time-created="{{timecreated}}">
|
||||
{{{editedtext}}}
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user