* add icon selector for the assistant edit.

This commit is contained in:
Chenjianyu
2024-04-02 15:06:21 +08:00
parent b8de3c6683
commit 726503bbe0
7 changed files with 249 additions and 35 deletions
+23 -5
View File
@@ -411,20 +411,33 @@ class ai extends control
if(strtolower($this->server->request_method) == 'post')
{
$assistant = fixer::input('post')->get();
if(empty($assistant->name))
{
dao::$errors['name'][] = sprintf($this->lang->ai->validate->noEmpty, $this->lang->ai->assistants->name);
}
if(empty($assistant->modelId))
{
dao::$errors['modelId'][] = sprintf($this->lang->ai->validate->noEmpty, $this->lang->ai->models->common);
}
if(empty($assistant->systemMessage))
{
dao::$errors['systemMessage'][] = sprintf($this->lang->ai->validate->noEmpty, $this->lang->ai->assistants->systemMessage);
}
if(empty($assistant->greetings))
{
dao::$errors['greetings'][] = sprintf($this->lang->ai->validate->noEmpty, $this->lang->ai->assistants->greetings);
}
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
$exists = $this->ai->checkAssistantDuplicate($assistant->name, $assistant->modelId);
if($exists) return $this->send(array('result' => 'fail', 'message' => array('name' => $this->lang->ai->assistants->duplicateTip)));
$assistant->id = $assistantId;
$exists = $this->ai->checkAssistantDuplicate($assistant->name, $assistant->modelId);
if($exists && $exists->id != $assistantId) return $this->send(array('result' => 'fail', 'message' => array('name' => $this->lang->ai->assistants->duplicateTip)));
$assistant->icon = "$assistant->iconName-$assistant->iconTheme";
unset($assistant->iconName, $assistant->iconTheme);
$this->ai->updateAssistant($assistant);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
@@ -439,9 +452,14 @@ class ai extends control
}, array());
$assistant = $this->ai->getAssistantById($assistantId);
$this->view->models = $models;
list($iconName, $iconTheme) = explode('-', $assistant->icon);
$this->view->models = $models;
$this->view->assistant = $assistant;
$this->view->title = $this->lang->ai->assistants->edit;
$this->view->iconName = $iconName;
$this->view->iconTheme = $iconTheme;
$this->view->title = $this->lang->ai->assistants->edit;
$this->display();
}
+9
View File
@@ -0,0 +1,9 @@
#ai-edit-icon {position: relative; overflow: hidden; display: flex; justify-content: center; align-items: center;}
#ai-edit-icon #edit-icon {display: none; position: absolute; inset: 0; background-color: rgba(230, 240, 255, 0.7);}
#ai-edit-icon:hover {border: 1px solid #EDEEF1;}
#ai-edit-icon:hover #edit-icon {display: flex; justify-content: center; align-items: center;}
#icon-buttons svg {cursor: pointer;}
.theme-checked {display: flex; justify-content: center; align-items: center;}
#ai-edit-icon > svg {width: 30px; height: 30px;}
#preview-icon > svg {width: 30px; height: 30px;}
-26
View File
@@ -15,9 +15,6 @@
});
})();
let selectedIcon;
let selectedTheme;
function changeMiniProgramTheme(event)
{
const $icon = $('#preview-icon');
@@ -53,29 +50,6 @@ function saveMiniProgramIcon()
$('input[name="iconName"]').prop('value', selectedIcon);
}
function saveMiniProgram()
{
$('[name="toNext"]').prop('value', '0');
}
function toConfiguredMiniProgram()
{
$('[name="toNext"]').prop('value', '1');
}
function toEditMiniProgramIcon()
{
const $button = $('#ai-edit-icon');
const iconName = $button.find('svg').prop('id');
const iconTheme = $button.css('background-color');
const $container = $('.icon-setting-container');
$container.find(`#${iconName}`).click();
$container.find('.btn-icon').each(function()
{
if($(this).css('background-color') === iconTheme) $(this).click();
});
}
$(function()
{
$('#theme-buttons button').on('click', changeMiniProgramTheme);
+41
View File
@@ -0,0 +1,41 @@
function changeMiniProgramTheme(event)
{
const $icon = $('#preview-icon');
const $button = $(event.target).closest('button');
const $prev = $('.theme-checked');
$prev.removeClass('theme-checked');
$button.addClass('theme-checked');
$prev.empty();
$button.append(iconCheck);
$icon.css('background-color', $button.css('background-color'));
$icon.css('border', $button.css('border'));
selectedTheme = $button.index();
}
function changeMiniProgramIcon(event)
{
const $icon = $('#preview-icon');
const $svg = $(event.target).closest('svg').clone();
$icon.empty();
$icon.append($svg);
selectedIcon = $svg.prop('id');
}
function saveMiniProgramIcon()
{
const $editIcon = $('#ai-edit-icon');
$editIcon.children().first('svg').remove();
const $icon = $('#preview-icon');
$editIcon.prepend($icon.find('svg').clone());
$editIcon.css('background-color', $icon.css('background-color'));
$editIcon.css('border', $icon.css('border'));
$('input[name="iconTheme"]').prop('value', selectedTheme);
$('input[name="iconName"]').prop('value', selectedIcon);
}
$(function()
{
$('#theme-buttons button').on('click', changeMiniProgramTheme);
$('#icon-buttons svg').on('click', changeMiniProgramIcon);
$('#save-icon-button').on('click', saveMiniProgramIcon);
});
+1 -1
View File
@@ -2830,7 +2830,7 @@ class aiModel extends model
* @param string $AssistantName
* @param int $modelId
* @access public
* @return bool
* @return object
*/
public function checkAssistantDuplicate($AssistantName, $modelId)
{
+2
View File
@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace zin;
jsVar('iconCheck', $config->ai->miniPrograms->iconCheck);
jsVar('iconName', $iconName);
jsVar('iconTheme', $iconTheme);
formPanel
(
+173 -3
View File
@@ -3,6 +3,10 @@ declare(strict_types=1);
namespace zin;
jsVar('iconCheck', $config->ai->miniPrograms->iconCheck);
jsVar('iconName', $iconName);
jsVar('iconTheme', $iconTheme);
formPanel
(
set::title($lang->ai->assistants->edit),
@@ -46,6 +50,7 @@ formPanel
formGroup
(
set::label($lang->ai->assistants->systemMessage),
set::required(true),
textarea
(
set::name('systemMessage'),
@@ -61,12 +66,177 @@ formPanel
textarea
(
set::name('greetings'),
set::required(true),
set::rows(3),
set::placeholder($lang->ai->assistants->greetingsPlaceholder),
set::value($assistant->greetings)
)
)
),
formGroup
(
set::label($lang->ai->miniPrograms->icon),
set::width('1/2'),
set::hight('50px'),
button
(
set('id', 'ai-edit-icon'),
setClass('btn btn-icon'),
setStyle(array(
'width' => '46px',
'height' => '46px',
'border-radius' => '50%',
'border' => "1px solid {$config->ai->miniPrograms->themeList[$iconTheme][1]}",
'background-color' => $config->ai->miniPrograms->themeList[$iconTheme][0],
'padding' => '0',
)),
setData('toggle', 'modal'),
setData('target', '#edit-icon-modal'),
html($config->ai->assistants->iconList[$iconName]),
div
(
setID('edit-icon'),
html($config->ai->miniPrograms->iconEdit)
)
)
),
input
(
set::name('iconName'),
set::type('hidden'),
set::value($iconName)
),
input
(
set::name('iconTheme'),
set::type('hidden'),
set::value($iconTheme)
),
);
render();
$ai = $config->ai;
div(
setClass('modal fade"'),
setData('backdrop', 'static'),
setID('edit-icon-modal'),
div(
setClass('modal-dialog shadow size-sm bd-none'),
div(
setClass('modal-content'),
div(
setClass('modal-header items-center'),
span
(
setStyle(array(
'font-size' => '20px',
'font-weight' => 'bold',
)),
$lang->ai->miniPrograms->iconModification
),
span
(
setClass('text-muted'),
'Emoji icons by Twemoji with CC-BY4.0'
)
),
div(
setClass('modal-body'),
div
(
setStyle(array(
'display' => 'flex',
'gap' => '42px',
)),
div
(
setClass('icon-preview-container p-1'),
button
(
setID('preview-icon'),
setClass('btn btn-icon'),
setStyle(array(
'width' => '46px',
'height' => '46px',
'border-radius' => '50%',
'border' => "1px solid {$ai->miniPrograms->themeList[$iconTheme][1]}",
'background-color' => $ai->miniPrograms->themeList[$iconTheme][0],
'padding' => '0',
)),
setData('toggle', 'modal'),
setData('target', '#edit-icon-modal'),
html($config->ai->assistants->iconList[$iconName])
)
),
div
(
setClass('icon-setting-container'),
div
(
setClass('mb-4'),
$lang->ai->miniPrograms->customBackground
),
div
(
setID('theme-buttons'),
setStyle(array(
'display' => 'flex',
'gap' => '20px',
'width' => '400px'
)
),
array_map(function ($theme) use($iconTheme, $ai)
{
return button
(
setClass('btn btn-icon theme-checked'),
setStyle(array(
'width' => '32px',
'height' => '32px',
'border-radius' => '50%',
'border' => "1px solid {$theme[1]}",
'background-color' => $theme[0],
)),
$ai->miniPrograms->themeList[$iconTheme][0] === $theme[0] ? html($ai->miniPrograms->iconCheck) : null
);
},$config->ai->miniPrograms->themeList)
),
div
(
setClass('mt-6'),
div
(
setClass('mb-4'),
$lang->ai->miniPrograms->customIcon
),
div
(
setID('icon-buttons'),
setStyle(array(
'display' => 'grid',
'column-gap' => '20px',
'row-gap' => '16px',
'grid-template-columns' => 'repeat(8, 1fr)',
'justify-items'=> 'center',
'align-items' => 'center',
)
),
array_map(function ($icon)
{
return html($icon);
},$config->ai->assistants->iconList)
)
)
)
)
),
div(
setClass('modal-footer flex items-center justify-center'),
btn(
setID('save-icon-button'),
setClass('btn btn-wide primary'),
setData('dismiss', 'modal'),
$lang->save
)
)
)
)
);