sd-webui-infinite-image-bro.../vue/src/page/SplitViewTab/emptyStartup.vue

190 lines
5.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<script lang="ts" setup>
import { useGlobalStore, type TabPane } from '@/store/useGlobalStore'
import { uniqueId } from 'lodash'
import { computed } from 'vue'
import { ID } from 'vue3-ts-util'
import { CloudDownloadOutlined, FileDoneOutlined } from '@/icon'
import { message } from 'ant-design-vue'
const global = useGlobalStore()
const props = defineProps<{ tabIdx: number, paneIdx: number }>()
const compCnMap: Partial<Record<TabPane['type'], string>> = {
"auto-upload": '自动上传',
local: '本地文件',
netdisk: '百度云',
"task-record": '任务记录',
'global-setting': '全局设置'
}
const openInCurrentTab = (type: TabPane['type'], path?: string, walkMode = false) => {
let pane: TabPane
if (type === 'task-record' && global.tabList.map(v => v.panes).flat().find(v => v.type === 'task-record')) {
return message.error('任务记录有且只能有一个如果特殊需求请前往仓库提issue') // 如果允许多个需要处理一些监听器,懒得改后面再说
}
switch (type) {
case 'auto-upload':
case 'task-record':
case 'log-detail':
case 'global-setting':
case 'empty':
pane = { type, name: compCnMap[type]!, key: Date.now() + uniqueId() }
break
case 'local':
case 'netdisk':
pane = { type, name: compCnMap[type]!, key: Date.now() + uniqueId(), target: type, path, walkMode }
}
const tab = global.tabList[props.tabIdx]
tab.panes.splice(props.paneIdx, 1, pane)
tab.key = pane.key
}
const lastRecord = computed(() => global.lastTabListRecord?.[1])
const walkModeSupportedDir = computed(() => global.autoCompletedDirList.filter(({ key: k }) => k === 'outdir_txt2img_samples' || k === 'outdir_img2img_samples' || k === 'outdir_extras_samples' || k === 'outdir_save' || k === 'outdir_samples'))
const canOpenInNewWindow = window.parent !== window
const openInNewWindow = () => window.parent.open('/baidu_netdisk')
</script>
<template>
<div class="container">
<div class="header">
<h1>欢迎</h1>
<div flex-placeholder/>
<div v-if="canOpenInNewWindow" class="last-record" @click="openInNewWindow ">
<a >在新页面打开</a>
</div>
<div class="last-record">
<a v-if="lastRecord?.tabs.length"
@click.prevent="global.tabList = lastRecord!.tabs.map(V => ID(V, true))">还原上次记录</a>
</div>
</div>
<div class="content">
<div class="quick-start">
<h2>启动</h2>
<ul>
<li v-for="comp in Object.keys(compCnMap) as TabPane['type'][]" :key="comp" class="quick-start__item"
@click.prevent="openInCurrentTab(comp)">
<span class="quick-start__text line-clamp-1">{{ compCnMap[comp] }}</span>
</li>
</ul>
</div>
<div class="quick-start">
<h2>使用 Walk 模式浏览图片</h2>
<ul v-if="walkModeSupportedDir.length">
<li v-for="item in walkModeSupportedDir" :key="item.dir" class="quick-start__item">
<AButton @click="openInCurrentTab('local', item.dir, true)" ghost type="primary" block>{{ item.zh }}</AButton>
</li>
</ul>
</div>
<div class="quick-start">
<h2>从快速移动启动</h2>
<ul>
<li v-for="dir in global.autoCompletedDirList" :key="dir.key" class="quick-start__item"
@click.prevent="openInCurrentTab('local', dir.dir)">
<span class="quick-start__text line-clamp-1">{{ dir.zh }}</span>
</li>
</ul>
</div>
<div class="quick-start">
<h2>最近</h2>
<ul>
<li v-for="item in global.recent" :key="item.key" class="quick-start__item"
@click.prevent="openInCurrentTab(item.target as any, item.path)">
<CloudDownloadOutlined class="quick-start__icon" v-if="item.target !== 'local'" />
<FileDoneOutlined class="quick-start__icon" v-else />
<span class="quick-start__text line-clamp-1">{{ item.path
}}</span>
</li>
</ul>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.container {
padding: 20px;
background-color: var(--zp-secondary-background);
height: 100%;
overflow: auto;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.header h1 {
font-size: 28px;
font-weight: bold;
color: var(--zp-primary);
}
.last-record {
margin-left: 8px;
font-size: 14px;
color: var(--zp-tertiary);
}
.last-record a {
text-decoration: none;
color: var(--zp-tertiary);
}
.last-record a:hover {
color: var(--zp-primary);
}
.content {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
grid-gap: 20px;
}
.quick-start {
background-color: var(--zp-primary-background);
border-radius: 8px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
padding: 20px;
ul {
list-style: none;
padding: 4px;
}
}
.quick-start h2 {
margin-top: 0;
margin-bottom: 20px;
font-size: 20px;
font-weight: bold;
color: var(--zp-primary);
}
.quick-start__item {
margin-bottom: 10px;
padding: 4px 8px;
display: flex;
align-items: center;
&:hover {
background: var(--zp-secondary-background);
border-radius: 4px;
color: var(--primary-color);
cursor: pointer;
}
}
.quick-start__text {
flex: 1;
font-size: 16px;
}
.quick-start__icon {
margin-right: 8px;
}
</style>