Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/wwwroot/css/genpage.css
Original file line number Diff line number Diff line change
Expand Up @@ -1707,6 +1707,32 @@ body {
font-size: 90%;
height: 1lh;
padding-top: 0 !important;
margin-left: 0.2rem;
}
.trigger-phrase-entry {
display: inline-flex;
align-items: center;
flex-wrap: wrap;
row-gap: 0.2rem;
}
.trigger-phrase-tag {
display: inline-block;
border: 1px solid var(--light-border);
border-radius: 0.3rem;
padding: 0 0.25rem;
cursor: pointer;
user-select: none;
line-height: 1.3;
}
.trigger-phrase-tag:hover {
background-color: var(--emphasis);
}
.trigger-phrase-tag-selected {
border-color: var(--box-selected-border-stronger);
background-color: color-mix(in srgb, var(--box-selected-background) 80%, transparent);
}
.trigger-phrase-separator {
opacity: 0.8;
}
.view_raw_header_modal_content {
max-height: 70vh;
Expand Down
49 changes: 42 additions & 7 deletions src/wwwroot/js/genpage/gentab/models.js
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,37 @@ function cleanModelName(name) {
return name.endsWith('.safetensors') ? name.substring(0, name.length - '.safetensors'.length) : name;
}

function toggleTriggerPhraseTag(elem) {
elem.classList.toggle('trigger-phrase-tag-selected');
}

function copyTriggerPhraseSelection(button) {
let phraseEntry = button.closest('.trigger-phrase-entry');
if (!phraseEntry) {
return;
}
let allTags = [...phraseEntry.querySelectorAll('.trigger-phrase-tag')];
if (allTags.length == 0) {
return;
}
let selectedTags = allTags.filter(tag => tag.classList.contains('trigger-phrase-tag-selected'));
let tagsToCopy = (selectedTags.length > 0 ? selectedTags : allTags)
.map(tag => decodeURIComponent(tag.dataset.phraseTag || ''))
.filter(tag => tag.length > 0);
if (tagsToCopy.length == 0) {
return;
}
let copyValue = tagsToCopy.join(', ');
if (getUserSetting('ui.copytriggerphrasewithtrailingcomma', false) && !copyValue.endsWith(',')) {
copyValue += ', ';
}
copyText(copyValue);
for (let tag of allTags) {
tag.classList.remove('trigger-phrase-tag-selected');
}
doNoticePopover('Copied!', 'notice-pop-green');
}

class ModelBrowserWrapper {
constructor(subType, subIds, container, id, selectOne, extraHeader = '') {
this.subType = subType;
Expand Down Expand Up @@ -614,22 +645,26 @@ class ModelBrowserWrapper {
this.browser.update();
}

createTriggerPhraseTag(tag) {
let encodedTag = encodeURIComponent(tag);
return `<span class="trigger-phrase-tag" data-phrase-tag="${encodedTag}" onclick="toggleTriggerPhraseTag(this)" title="Click to select this tag for copying">${escapeHtml(tag)}</span>`;
}

createCopyableTriggerPhrase(phrase) {
let copyPhrase = phrase;
if (getUserSetting('ui.copytriggerphrasewithtrailingcomma', false) && !phrase.endsWith(',')) {
copyPhrase += ', ';
let tags = phrase.split(',').map(tag => tag.trim()).filter(tag => tag.length > 0);
if (tags.length == 0) {
tags = [phrase.trim()].filter(tag => tag.length > 0);
}
let safePhrase = escapeHtmlNoBr(escapeJsString(phrase));
let safeCopyPhrase = escapeHtmlNoBr(escapeJsString(copyPhrase));
return `${safePhrase}<button title="Click to copy" class="basic-button trigger-phrase-copy-button" onclick="copyText('${safeCopyPhrase}');doNoticePopover('Copied!', 'notice-pop-green');">&#x29C9;</button>`;
let renderedTags = tags.map(tag => this.createTriggerPhraseTag(tag)).join('<span class="trigger-phrase-separator">, </span>');
return `<span class="trigger-phrase-entry">${renderedTags}<button title="Copy selected tags (or all if none selected)" class="basic-button trigger-phrase-copy-button" onclick="copyTriggerPhraseSelection(this)">&#x29C9;</button></span>`;
}

formatTriggerPhrases(val) {
let phrases = val.split(';').map(phrase => phrase.trim()).filter(phrase => phrase.length > 0);
if (phrases.length > 128) {
phrases = phrases.slice(0, 128);
}
return phrases.map(phrase => this.createCopyableTriggerPhrase(phrase)).join('');
return phrases.map(phrase => this.createCopyableTriggerPhrase(phrase)).join('<br>');
}

describeModel(model) {
Expand Down