[Feature] Displaying Extra Networks in the keyword group

【功能】关键词组中展示Extra Networks
pull/292/head
Physton 2023-09-15 14:06:51 +08:00
parent 033d3e6145
commit 7d785b3182
6 changed files with 315 additions and 61 deletions

View File

@ -832,10 +832,12 @@ export default {
// console.log('setData:groupTags', local, key, en)
}
this.groupTags.forEach((item, index) => {
item.type = item.type || ''
item.tabKey = 'groupTags-' + index
item.groups.forEach((group, subIndex) => {
group.type = group.type || ''
group.tabKey = 'subGroupTags-' + index + '-' + subIndex
if (group.type && group.type == 'wrap') return
if (group.type == 'wrap') return
let key = common.getTagsColorKey(item.name, group.name)
if (!this.groupTagsColor[key]) {
this.groupTagsColor[key] = ref(common.fitterInputColor(group.color))
@ -1084,8 +1086,8 @@ export default {
onUpdateHotkey(data) {
this.hotkey = data
},
onShowExtraNetworks(e, name, useCallback) {
this.$refs.extraNetworksPopup.show(e, name, useCallback)
onShowExtraNetworks(e, name, useCallback, showCheckpoints) {
this.$refs.extraNetworksPopup.show(e, name, useCallback, showCheckpoints)
},
onHideExtraNetworks() {
this.$refs.extraNetworksPopup.hide()

View File

@ -83,7 +83,7 @@ export default {
mounted() {
},
methods: {
show(e, name, useCallback) {
show(e, name, useCallback, showCheckpoints = false) {
this.mouseIn = false
this.eMouseIn = true
this.e = e
@ -112,6 +112,14 @@ export default {
break
}
}
} else if (showCheckpoints && extraNetwork.name === 'checkpoints') {
for (let item of extraNetwork.items) {
if (item.name.toLowerCase() === name) {
this.type = 'checkpoints'
data = item
break
}
}
}
}
if (!this.type) return this.isShow = false

View File

@ -434,51 +434,21 @@
</button>
</div>
</div>
<div v-if="groupTags.length" :class="['show-group-tags', hideGroupTags ? 'hided': '']" @click="onClickHideGroupTags"
<div v-if="groupTagsProcessed.length" :class="['show-group-tags', hideGroupTags ? 'hided': '']" @click="onClickHideGroupTags"
v-tooltip="getLang(hideGroupTags ? 'show_group_tags' : 'hide_group_tags')">
<icon-svg class="hover-scale-120" name="unfold"/>
</div>
<Transition name="fade">
<div class="group-tabs" v-show="!hideGroupTags && groupTags.length">
<div class="group-tabs" v-show="!hideGroupTags && groupTagsProcessed.length">
<div class="group-header" ref="groupTabsHeader">
<div :class="['group-tab', 'favorite' == groupTagsActive ? 'active' : '']"
@click="activeGroupTab('favorite')"
data-name="favorite">{{ getLang('favorite') }}</div>
<div v-for="(item, index) in groupTags"
<div v-for="(item, index) in groupTagsProcessed"
:key="index"
:class="['group-tab', item.tabKey == groupTagsActive ? 'active' : '']"
@click="activeGroupTab(index)"
:data-name="item.name">{{ item.name }}</div>
</div>
<div class="group-body">
<div :class="['group-main', 'favorite' == groupTagsActive ? 'active' : '']">
<div class="sub-group-header" v-if="'favorite' == groupTagsActive">
<div v-for="(item) in getCurrentTypeFavorites()"
:key="item.key"
:class="['sub-group-tab', 'favorite-' + item.key == subGroupTagsActive ? 'active' : '']"
@click="activeSubGroupTab('favorite', item.key)"
:data-name="item.name">{{ getLang(item.name) }}</div>
</div>
<div class="sub-group-body" v-if="'favorite' == groupTagsActive">
<div v-for="(item) in getCurrentTypeFavorites()"
:key="item.key"
:class="['sub-group-main', 'favorite-' + item.key == subGroupTagsActive ? 'active' : '']">
<Transition name="fade">
<div class="group-tags" v-if="'favorite-' + item.key == subGroupTagsActive">
<div class="tag-item" ref="groupTagItem" v-for="(favorite) in item.list"
v-tooltip="getGroupTagTooltip(favorite.name, favorite.prompt)"
@click="onClickGroupTagFavorite(favorite)">
<div class="tag-local">{{ favorite.name == '' ? favorite.prompt : favorite.name }}</div>
<div class="tag-en">{{ favorite.prompt }}</div>
</div>
</div>
</Transition>
</div>
</div>
</div>
<div v-for="(item, index) in groupTags" :key="index" :class="['group-main', item.tabKey == groupTagsActive ? 'active' : '']">
<div v-for="(item, index) in groupTagsProcessed" :key="index" :class="['group-main', item.tabKey == groupTagsActive ? 'active' : '']">
<div class="sub-group-header" v-if="item.tabKey == groupTagsActive">
<div v-for="(group, subIndex) in item.groups"
:key="subIndex"
@ -490,9 +460,22 @@
<div v-for="(group, subIndex) in item.groups" :key="subIndex" :class="['sub-group-main', group.tabKey == subGroupTagsActive ? 'active' : '']">
<Transition name="fade">
<div class="group-tags" v-if="group.tabKey == subGroupTagsActive">
<div class="tag-item" ref="groupTagItem" v-for="(local, en) in group.tags"
<div v-if="group.type === 'extraNetworks'" class="group-extra-network"
v-for="extraData in group.datas" :key="extraData.name"
@click="onClickGroupTagExtraNetwork(extraData, item, group)"
@mouseenter="onGroupExtraNetworkMouseEnter($event, extraData.name)"
@mousemove="onGroupExtraNetworkMouseMove"
@mouseleave="onGroupExtraNetworkMouseLeave"
:style="getGroupTagExtraNetworkStyle(extraData)">
<img class="extra-network-preview" :src="extraData.preview || './file=html/card-no-preview.png'" />
<div class="extra-network-name">{{ extraData.name }}</div>
<div class="extra-network-loading" v-if="extraData.loading">
<icon-svg name="loading"/>
</div>
</div>
<div v-else class="tag-item" ref="groupTagItem" v-for="(local, en) in group.tags"
v-tooltip="getGroupTagTooltip(local, en)"
@click="onClickGroupTag(local, en)">
@click="onClickGroupTag(local, en, item, group)">
<template v-if="local && local != en">
<div class="tag-local" :style="getGroupTagStyle(item.name, group.name, en)">{{ local }}</div>
<div class="tag-en">{{ en }}</div>
@ -501,7 +484,7 @@
</div>
</div>
</Transition>
<div class="tags-footer">
<div class="tags-footer" v-if="item.type !== 'favorite' && item.type !== 'extraNetworks'">
<div class="tags-color">
<div>{{ getLang('tags_color') }}:</div>
<div class="tags-color-picker hover-scale-120"

View File

@ -6,11 +6,13 @@ export default {
return {
groupTagsActive: '',
subGroupTagsActive: '',
groupTagsProcessed: [],
}
},
watch: {
groupTags: {
handler() {
this.genGroup()
if (!this.groupTagsActive || !this.subGroupTagsActive) {
this.groupTagsActive = 'favorite'
this.subGroupTagsActive = 'favorite-' + this.favoriteKey
@ -31,7 +33,14 @@ export default {
},
favorites: {
handler() {
this.genGroup()
},
deep: true,
immediate: true,
},
extraNetworks: {
handler() {
this.genGroup()
},
deep: true,
immediate: true,
@ -46,6 +55,92 @@ export default {
})
},
methods: {
genGroup() {
let processed = []
let favoriteGroup = {
name: this.getLang('favorite'),
tabKey: 'favorite',
type: 'favorite',
groups: [],
}
this.getCurrentTypeFavorites().forEach(item => {
let subGroup = {
color: '',
name: this.getLang(item.name),
tabKey: 'favorite-' + item.key,
type: 'favorite',
tags: {},
ori: {},
}
item.list.forEach(favorite => {
subGroup.tags[favorite.prompt] = favorite.name == '' ? favorite.prompt : favorite.name
subGroup.ori[favorite.prompt] = favorite
})
favoriteGroup.groups.push(subGroup)
})
processed.push(favoriteGroup)
let extraNetworksGroup = {
name: 'Extra Networks',
tabKey: 'extraNetworks',
type: 'extraNetworks',
groups: [],
}
this.extraNetworks.forEach(extraNetwork => {
// if (extraNetwork.name === 'checkpoints') return
let subGroup = {
color: '',
name: extraNetwork.title,
tabKey: 'extraNetworks-' + extraNetwork.name,
type: 'extraNetworks',
subType: extraNetwork.name,
tags: {},
datas: [],
}
extraNetwork.items.forEach(item => {
subGroup.datas.push(item)
})
extraNetworksGroup.groups.push(subGroup)
extraNetwork.items.forEach(item => {
item.dirnameFormat = item.dirname.replaceAll('\\', '/')
})
let dirs = []
let splitArrays = extraNetwork.items.map(item => item.dirnameFormat.split('/'))
let minLength = Math.min(...splitArrays.map(item => item.length))
extraNetwork.items.forEach(item => {
item.base_dirname = item.dirnameFormat.split('/').slice(minLength).join('/')
dirs.push(item.base_dirname)
})
dirs = [...new Set(dirs)]
dirs = dirs.filter(item => item !== '')
if (dirs.length > 1) {
dirs.forEach(dir => {
let subDirGroup = {
color: '',
name: dir,
tabKey: 'extraNetworks-' + extraNetwork.name + '-' + dir,
type: 'extraNetworks',
subType: extraNetwork.name,
tags: {},
datas: [],
}
extraNetwork.items.forEach(item => {
if (item.base_dirname === dir) {
subDirGroup.datas.push(item)
}
})
extraNetworksGroup.groups.push(subDirGroup)
})
}
extraNetworksGroup.groups.push({
type: 'wrap',
})
})
processed.push(extraNetworksGroup)
processed = processed.concat(this.groupTags)
this.groupTagsProcessed = processed
},
saveGroupActive() {
this.gradioAPI.setData('groupTagsActive-' + this.name, {
groupTagsActive: this.groupTagsActive,
@ -53,15 +148,8 @@ export default {
})
},
activeGroupTab(index) {
if (index === 'favorite') {
this.groupTagsActive = 'favorite'
this.subGroupTagsActive = 'favorite-' + this.favoriteKey
index = 0
} else {
this.groupTagsActive = this.groupTags[index].tabKey
this.subGroupTagsActive = this.groupTags[index].groups[0].tabKey
index += 1
}
this.groupTagsActive = this.groupTagsProcessed[index].tabKey
this.subGroupTagsActive = this.groupTagsProcessed[index].groups[0].tabKey
this.saveGroupActive()
let scrollLeft = this.$refs.groupTabsHeader.children[index].offsetLeft - this.$refs.groupTabsHeader.offsetWidth / 2 + this.$refs.groupTabsHeader.children[index].offsetWidth / 2
this.$refs.groupTabsHeader.scrollTo({
@ -71,11 +159,7 @@ export default {
this._setGroupTagItemWidth()
},
activeSubGroupTab(index, subIndex) {
if (index === 'favorite') {
this.subGroupTagsActive = 'favorite-' + subIndex
} else {
this.subGroupTagsActive = this.groupTags[index].groups[subIndex].tabKey
}
this.subGroupTagsActive = this.groupTagsProcessed[index].groups[subIndex].tabKey
this.saveGroupActive()
this._setGroupTagItemWidth()
},
@ -100,7 +184,7 @@ export default {
onClickHideGroupTags() {
this.$emit('update:hideGroupTags', !this.hideGroupTags)
},
onClickGroupTag(local, en) {
onClickGroupTag(local, en, group, subGroup) {
// 判断是否存在 tags 中
let indexes = []
this.tags.forEach((tag, index) => {
@ -112,10 +196,16 @@ export default {
indexes.reverse().forEach((index) => {
this.tags.splice(index, 1)
})
this.updateTags()
} else {
this._appendTag(en, local, false, -1, 'text')
if (group.type === 'favorite') {
let favorite = subGroup.ori[en]
this.onClickGroupTagFavorite(favorite)
} else {
this._appendTag(en, local, false, -1, 'text')
this.updateTags()
}
}
this.updateTags()
},
onClickGroupTagFavorite(favorite) {
favorite.tags.forEach((tag) => {
@ -123,6 +213,46 @@ export default {
})
this.updateTags()
},
onClickGroupTagExtraNetwork(data, group, subGroup) {
if (subGroup.subType === 'checkpoints') {
if (data.loading) return
data.loading = true
let setLoading = (num) => {
if (num > 100) {
data.loading = false
// console.log('超时')
return
}
if (opts && opts.sd_model_checkpoint === data.basename) {
data.loading = false
// console.log('已加载')
return
}
setTimeout(setLoading, 100, num + 1)
}
setLoading(0)
selectCheckpoint(data.basename)
return
}
let indexes = this._groupTagsExtraNetworkTagsIndexes(data)
if (indexes.length) {
indexes.reverse().forEach((index) => {
console.log(index)
this.tags.splice(index, 1)
})
this.updateTags()
} else {
let index = this._appendTag(eval(data.prompt), '', false, -1, 'text')
if (this.autoTranslateToLocal) {
this.translates([index], true, false).finally(() => {
this.updateTags()
})
} else {
this.updateTags()
}
}
},
getGroupTagTooltip(local, en) {
let html = ''
if (local && local !== en) {
@ -154,6 +284,34 @@ export default {
}
return style
},
_groupTagsExtraNetworkTagsIndexes(data) {
let name = data.name
let output_name = data.output_name || undefined
let indexes = []
for (let index in this.tags) {
let tag = this.tags[index]
let find = false
if (tag.isLora) {
find = tag.loraName === name || tag.loraName === output_name
} else if (tag.isLyco) {
find = tag.lycoName === name || tag.lycoName === output_name
} else if (tag.isEmbedding) {
find = tag.embeddingName === name || tag.embeddingName === output_name
} else {
find = tag.originalValue === name || tag.originalValue === output_name
}
if (find) {
indexes.push(index)
}
}
return indexes
},
getGroupTagExtraNetworkStyle(data) {
let indexes = this._groupTagsExtraNetworkTagsIndexes(data)
let style = {}
if (indexes.length) style['filter'] = 'grayscale(1)'
return style
},
getTagsColorKey(groupName, subGroupName) {
return common.getTagsColorKey(groupName, subGroupName)
},
@ -161,7 +319,7 @@ export default {
this.$emit('update:groupTagsColor', this.groupTagsColor)
},
onClickResetTagsColor(key) {
for (let item of this.groupTags) {
for (let item of this.groupTagsProcessed) {
for (let group of item.groups) {
if (group.type && group.typ == 'wrap') continue
let key2 = common.getTagsColorKey(item.name, group.name)
@ -185,5 +343,13 @@ export default {
if (common.isColorTransparent(color)) return {}
return {background: color}
},
onGroupExtraNetworkMouseEnter(e, name) {
this.$emit('showExtraNetworks', e.target, name, this.onLoraPopupUseKeywords, true)
},
onGroupExtraNetworkMouseMove() {
},
onGroupExtraNetworkMouseLeave() {
this.$emit('hideExtraNetworks')
},
}
}

View File

@ -1031,6 +1031,53 @@
--pp-pt-gt-gb-gm-sgm-gt-ti-tagEn-text-overflow: ellipsis;
--pp-pt-gt-gb-gm-sgm-gt-ti-tagEn-overflow: hidden;
// .physton-prompt .prompt-tags .group-tabs .group-body .group-main .sub-group-main .group-extra-network
--pp-pt-gt-gb-gm-sgm-groupExtraNetwork-margin: 4px;
--pp-pt-gt-gb-gm-sgm-groupExtraNetwork-border-radius: 4px;
--pp-pt-gt-gb-gm-sgm-groupExtraNetwork-position: relative;
--pp-pt-gt-gb-gm-sgm-groupExtraNetwork-width: 100px;
--pp-pt-gt-gb-gm-sgm-groupExtraNetwork-height: 120px;
--pp-pt-gt-gb-gm-sgm-groupExtraNetwork-cursor: pointer;
--pp-pt-gt-gb-gm-sgm-groupExtraNetwork-overflow: hidden;
--pp-pt-gt-gb-gm-sgm-groupExtraNetwork-box-shadow: 0 0 1px 1px rgba(143, 143, 143, .8);
// .physton-prompt .prompt-tags .group-tabs .group-body .group-main .sub-group-main .group-extra-network .extra-network-preview
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkPreview-position: absolute;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkPreview-object-fit: cover;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkPreview-width: 100%;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkPreview-height: 100%;
// .physton-prompt .prompt-tags .group-tabs .group-body .group-main .sub-group-main .group-extra-network .extra-network-name
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-position: absolute;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-bottom: 0;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-left: 0;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-right: 0;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-padding: 4px;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-background: rgba(0, 0, 0, .5);
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-box-shadow: 0 0 2px 2px rgba(0, 0, 0, .5);
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-color: #fff;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-font-size: 12px;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-text-align: center;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-z-index: 10;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-word-wrap: break-word;
// .physton-prompt .prompt-tags .group-tabs .group-body .group-main .sub-group-main .group-extra-network .extra-network-loading
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-position: absolute;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-top: 0;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-bottom: 0;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-left: 0;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-right: 0;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-display: flex;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-justify-content: center;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-align-items: center;
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-background: rgba(0, 0, 0, .5);
--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-z-index: 11;
// // .physton-prompt .prompt-tags .group-tabs .group-body .group-main .sub-group-main .group-extra-network .extra-network-loading .icon-svg-loading
--pp-pt-gt-gb-gm-sgm-gen-enl-iconSvgLoading-width: 40px;
--pp-pt-gt-gb-gm-sgm-gen-enl-iconSvgLoading-height: 40px;
--pp-pt-gt-gb-gm-sgm-gen-enl-iconSvgLoading-color: #fff;
// .physton-prompt .prompt-tags .group-tabs .group-body .group-main .sub-group-main .tags-footer
--pp-pt-gt-gb-gm-sgm-tagsFooter-margin-top: 5px;
--pp-pt-gt-gb-gm-sgm-tagsFooter-padding-top: 5px;
@ -3503,6 +3550,54 @@
overflow: var(--pp-pt-gt-gb-gm-sgm-gt-ti-tagEn-overflow);
}
}
.group-extra-network {
margin: var(--pp-pt-gt-gb-gm-sgm-groupExtraNetwork-margin);
border-radius: var(--pp-pt-gt-gb-gm-sgm-groupExtraNetwork-border-radius);
position: var(--pp-pt-gt-gb-gm-sgm-groupExtraNetwork-position);
width: var(--pp-pt-gt-gb-gm-sgm-groupExtraNetwork-width);
height: var(--pp-pt-gt-gb-gm-sgm-groupExtraNetwork-height);
cursor: var(--pp-pt-gt-gb-gm-sgm-groupExtraNetwork-cursor);
overflow: var(--pp-pt-gt-gb-gm-sgm-groupExtraNetwork-overflow);
box-shadow: var(--pp-pt-gt-gb-gm-sgm-groupExtraNetwork-box-shadow);
.extra-network-preview {
position: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkPreview-position);
object-fit: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkPreview-object-fit);
width: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkPreview-width);
height: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkPreview-height);
}
.extra-network-name {
position: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-position);
bottom: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-bottom);
left: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-left);
right: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-right);
padding: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-padding);
background: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-background);
box-shadow: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-box-shadow);
color: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-color);
font-size: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-font-size);
text-align: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-text-align);
z-index: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-z-index);
word-wrap: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkName-word-wrap);
}
.extra-network-loading {
position: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-position);
top: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-top);
bottom: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-bottom);
left: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-left);
right: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-right);
display: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-display);
justify-content: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-justify-content);
align-items: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-align-items);
background: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-background);
z-index: var(--pp-pt-gt-gb-gm-sgm-gen-extraNetworkLoading-z-index);
.set-icon-svg(var(--pp-pt-gt-gb-gm-sgm-gen-enl-iconSvgLoading-width), var(--pp-pt-gt-gb-gm-sgm-gen-enl-iconSvgLoading-height), var(--pp-pt-gt-gb-gm-sgm-gen-enl-iconSvgLoading-color), icon-svg-loading);
}
}
}
.tags-footer {

2
styles/main.min.css vendored

File diff suppressed because one or more lines are too long