AI responses can be inaccurate, please double check
`;
}
function show_snackbar(msg){
snack_bar = $('.spro-snackbar');
snack_bar?.text(msg);
snack_bar?.addClass('show');
setTimeout(function(){ snack_bar?.removeClass('show'); }, 3500);
}
function request_soft_ai(e){
e.preventDefault();
let jEle = $(e.target),
ai_prompt = $('#spro_prompt_input').val(),
options_section = jEle.closest('.spro-ai-chat-options-section'),
shortcut = jEle.attr('action'),
spinner = options_section.find('span.spro-spinner'),
response_section = jQuery('.spro-chat-response-section');
if(!ai_prompt && !shortcut){
shortcut = jEle.val();
}
if(!ai_prompt && !shortcut){
alert('Enter a prompt');
return;
}
options_section.addClass('disabled');
// Bringing the response in the view port.
response_section.find('.spro-chat-response')?.last()?.get(0)?.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
spinner.addClass('spro-spinner-active');
// We do not want to add a section when using shortcut
if(!shortcut){
soft_handle_ai_content(ai_prompt, 'prompt');
}
response_section.append('
Softaculous AI Is Thinking
');
$('#spro_prompt_input').val(''); // Unset the prompt textarea
// Making call to get AI reponse
$.ajax({
method : 'POST',
url : soft_ai.ajax_url,
data : {
'nonce' : soft_ai.nonce,
'prompt' : ai_prompt ?? '',
'shortcut' : shortcut ?? '',
'content': soft_ai.content ?? '',
'action' : 'softaculous_ai_generation',
},
success: function(res){
if(!res.success){
show_snackbar(res.data);
return;
}
if(res.data.error){
show_snackbar(res.data.error);
return;
}
// Updating the UI
$('.spro-chat-startup-placeholder').slideUp();
soft_handle_ai_content(res.data.ai, 'assistant');
}
}).always(function(res){
if(res.data && res.data.used_tokens){
update_tokens(res.data.used_tokens, res.data.total_tokens);
}
options_section.removeClass('disabled');
spinner.removeClass('spro-spinner-active');
response_section.find('.soft-ai-chat-loader').remove(); // Removing the loader.
if($('.spro-chat-response-section .spro-chat-response').length){
$('.spro-prompt-shortcuts').show();
}
});
}
function use_ai_content(e){
e.preventDefault();
let jEle = $(e.target);
content = jEle.closest('p').prev().html();
console.log(jEle.closest('p').prev());
content = content.trim();
// We are using markdown because the html responses are not that good, and can have unexpected tags, having markdown makes sure the tags which we will have to handle will be basic which won't cause any issue getting added to WordPress.
/*content = marked.parse(content);
// We need to remove the p tag in li as that breaks the gutenberg editor formatting for list.
content = content.replace(/
(.*?)<\/li>/gs, (match) => {
return match.replace(/<\/?p>( )?/gm, '');
});*/
let blocks = wp.blocks.rawHandler({HTML:content}),
block_id = wp.data.select('core/block-editor').getSelectedBlockClientId();
if(!block_id){
wp.data.dispatch('core/block-editor').insertBlocks(blocks);
} else {
wp.data.dispatch('core/block-editor').replaceBlock(block_id, blocks);
}
}
function toggle_history(e){
let jEle = $(e.target);
chat_wrap = jEle.closest('.spro-chat'),
history_tab = chat_wrap.find('.spro-ai-chat-history'),
chat_response = chat_wrap.find('.spro-chat-response-section'),
chat_options = chat_wrap.find('.spro-ai-chat-options-section');
if(history_tab.css('display') == 'none'){
history_tab.show();
chat_options.hide();
chat_response.hide();
// We dont want to request more if we already have some history.
if($('.spro-chat-history-link').length > 0){
return;
}
history_tab.find('.spro-chat-history-header span.spro-spinner').addClass('spro-spinner-active');
request_history();
return;
}
history_tab.hide();
chat_options.show();
chat_response.show();
}
function show_single_history(response){
html = '';
$('.spro-ai-chat-history-list').hide();
$('.spro-ai-chat-history-view').empty();
if(response.content){
html += `
Content:
${response.content}
`;
}
if(response.prompt){
html += `
Prompt:
${response.prompt}
`;
}
if(response.assistant){
response.assistant = spro_markdown_to_html(response.assistant);
html += `
Assistant:
${response.assistant}
`;
}
$('.spro-ai-chat-history-view').append(html);
$('.spro-ai-history-single-close').css('visibility', 'visible');
}
function marktohtml(mark){
}
function update_tokens(used_tokens, total_tokens){
$('.spro-ai-token-count').text('Tokens used ' + used_tokens+ ' / ' + total_tokens)
}
function request_history(history_id = 0){
let history_links = $('.spro-chat-history-link'),
offset = history_links.length,
total_links = $('.spro-ai-chat-history-list').data('total');
// We should not send ajax request if all the history items are visible.
if(offset == total_links && !history_id){
return;
}
$.ajax({
method : 'POST',
url : soft_ai.ajax_url,
data : {
'nonce' : soft_ai.nonce,
'action' : 'softaculous_ai_history',
'history_id' : history_id,
'offset' : offset,
},
success: function(res){
if(!res.success){
alert(res.message);
return;
}
// In case of single history we want to handle the append in different place
if(history_id != 0){
show_single_history(res.data);
return;
}
// Updating the UI
append_history(res.data);
}
}).always(function(){
$('.spro-chat-history-header span.spro-spinner').removeClass('spro-spinner-active');
});
}
function append_history(history){
let html = '',
total = history['total'];
history = history['history'];
for(let i in history){
let date = history[i]['date'],
date_obj = new Date(date),
current_date = new Date(),
date_string = '';
if(date_obj.getDate() == current_date.getDate() && date_obj.getMonth() == current_date.getMonth()){
date_string = 'Today';
} else if(date_obj.getDate() == (current_date.getDate() - 1) && date_obj.getMonth() == current_date.getMonth()){
date_string = 'Yesterday';
} else {
date_string = date_obj.toLocaleString('en-US', {month:'long'})
}
if(!date_string || old_date_string != date_string){
html += `
${date_string}
`;
}
old_date_string = date_string;
html += `
${history[i]['title']}
`;
}
$('.spro-ai-chat-history-list').append(html);
$('.spro-ai-chat-history-list').attr('data-total', total);
}
function handle_suggestions(e){
e.preventDefault();
let jEle = $(e.target),
suggestion = jEle.data('prompt'),
prompts = {
'p_50': 'Write a 50 word paragraph about topic [write the topic name]',
'desc_title': 'Write a title based on description [write a description you want the title on]',
'create_table': 'Create a table of [topic of the table you want]',
'blog_post': 'Write me a blog post about [write your topic here]',
};
if(!prompts.hasOwnProperty(suggestion)){
return;
}
$('#spro_prompt_input').text(prompts[suggestion]).focus();
}
})(jQuery, soft_ai.i18n)
function soft_handle_ai_content(props, role = 'content'){
let content = '';
if(!props){
return;
}
// Storing the gutenberg object so we can update the content using setAttribute method.
if(role == 'content'){
content = props.attributes.content;
soft_ai.gutenberg = props;
} else {
content = props;
}
response_section = jQuery('.spro-chat-response-section');
// Updating our global
if(content.text){
soft_ai.content = content.text;
} else if(role == 'assistant'){
// We update the content to assistants content as the next we will process the AI generated content.
soft_ai.content = content;
content = spro_markdown_to_html(content);
}
chat_response = `
${role.charAt(0).toUpperCase() + role.slice(1)}:
${content}
${role === 'assistant' ? '':''}
`;
response_section.append(chat_response);
// Bringing the response in the view port.
response_section.find('.spro-chat-response').last().get(0).scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
function spro_markdown_to_html(markdown){
// We are using markdown because the html responses are not that good, and can have unexpected tags, having markdown makes sure the tags which we will have to handle will be basic which won't cause any issue getting added to WordPress.
let content = marked.parse(markdown);
// We need to remove the p tag in li as that breaks the gutenberg editor formatting for list.
content = content.replace(/