feat(nsfw): 使用双行粘性导航条和底部设置表单替换悬浮按钮
This commit is contained in:
1 parent
3a6661c8df
commit
63a0f9188e
3 files changed
+459
-19
No files matched your search
@@ -824,3 +824,230 @@ html[data-theme='dark'] .candidate-meta {
|
||||
grid-column: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================
|
||||
NSFW 工作台 移动端双行 Sticky Bar(<=900px)
|
||||
============================ */
|
||||
@media (max-width: 900px) {
|
||||
body {
|
||||
padding-bottom: 108px !important;
|
||||
}
|
||||
|
||||
.nsfw-sticky-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 200;
|
||||
background: #fff;
|
||||
border-top: 1px solid var(--border);
|
||||
padding: 8px 14px;
|
||||
padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px));
|
||||
box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.07);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.nsfw-sticky-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.nsfw-sticky-row-sep {
|
||||
height: 1px;
|
||||
background: var(--border);
|
||||
margin: 0 -2px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.nsfw-icon-divider {
|
||||
width: 1px;
|
||||
height: 22px;
|
||||
background: var(--border);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.nsfw-icon-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
flex: 1;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.nsfw-icon-btn {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 9px;
|
||||
background: #fff;
|
||||
color: var(--fg);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
transition: background .15s ease;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nsfw-icon-btn:active {
|
||||
background: var(--accents-1);
|
||||
}
|
||||
|
||||
.nsfw-icon-btn--danger {
|
||||
color: #ef4444;
|
||||
border-color: #fecaca;
|
||||
}
|
||||
|
||||
.nsfw-icon-btn--danger:active {
|
||||
background: #fef2f2;
|
||||
}
|
||||
|
||||
.nsfw-main-btn {
|
||||
height: 36px;
|
||||
padding: 0 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
flex-shrink: 0;
|
||||
border-radius: 9px;
|
||||
min-width: 84px;
|
||||
justify-content: center;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.nsfw-main-btn.is-stop {
|
||||
background: #fee2e2 !important;
|
||||
color: #ef4444 !important;
|
||||
border: 1px solid #fecaca !important;
|
||||
}
|
||||
|
||||
/* 视频行 */
|
||||
.nsfw-sticky-row--video {
|
||||
opacity: 0.46;
|
||||
pointer-events: none;
|
||||
transition: opacity .2s ease;
|
||||
}
|
||||
|
||||
.nsfw-sticky-row--video.has-selected {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.nsfw-selected-label {
|
||||
flex: 1;
|
||||
font-size: 11px;
|
||||
color: var(--accents-5);
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.nsfw-sticky-row--video.has-selected .nsfw-selected-label {
|
||||
color: #2563eb;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.nsfw-video-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Settings Overlay */
|
||||
.nsfw-settings-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 300;
|
||||
background: rgba(0, 0, 0, 0.38);
|
||||
backdrop-filter: blur(2px);
|
||||
-webkit-backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
.nsfw-settings-overlay.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Settings Bottom Sheet */
|
||||
.nsfw-settings-sheet {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 301;
|
||||
background: #fff;
|
||||
border-radius: 20px 20px 0 0;
|
||||
padding: 0 16px 24px;
|
||||
padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px));
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
box-shadow: 0 -8px 40px rgba(0, 0, 0, 0.18);
|
||||
transition: transform .28s cubic-bezier(.2, 0, 0, 1);
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
.nsfw-settings-sheet.open {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.nsfw-settings-sheet-handle {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 12px 0 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.nsfw-settings-sheet-handle::after {
|
||||
content: '';
|
||||
width: 36px;
|
||||
height: 4px;
|
||||
border-radius: 999px;
|
||||
background: var(--border);
|
||||
}
|
||||
|
||||
.nsfw-settings-sheet-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--accents-7);
|
||||
margin-bottom: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
/* 暗色主题 */
|
||||
html[data-theme='dark'] .nsfw-sticky-bar {
|
||||
background: #111821;
|
||||
border-top-color: #2b3440;
|
||||
box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
html[data-theme='dark'] .nsfw-icon-btn {
|
||||
background: #1a2330;
|
||||
border-color: #3b4654;
|
||||
color: #c9d6e5;
|
||||
}
|
||||
|
||||
html[data-theme='dark'] .nsfw-icon-btn:active {
|
||||
background: #243244;
|
||||
}
|
||||
|
||||
html[data-theme='dark'] .nsfw-main-btn.is-stop {
|
||||
background: #2d1414 !important;
|
||||
color: #f87171 !important;
|
||||
border-color: #7f1d1d !important;
|
||||
}
|
||||
|
||||
html[data-theme='dark'] .nsfw-settings-sheet {
|
||||
background: #111821;
|
||||
color: #e2e8f0;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
(() => {
|
||||
(() => {
|
||||
const imagePromptInput = document.getElementById('imagePromptInput');
|
||||
const videoPromptInput = document.getElementById('videoPromptInput');
|
||||
const ratioSelect = document.getElementById('ratioSelect');
|
||||
@@ -1818,4 +1818,153 @@
|
||||
updateCounters();
|
||||
updateImageButtons();
|
||||
updateVideoButtons();
|
||||
|
||||
/**
|
||||
* NSFW 工作台 双行 Sticky Bar 初始化
|
||||
*/
|
||||
function initNsfwStickyBar() {
|
||||
/* --- 代理映射 --- */
|
||||
const proxyMap = {
|
||||
imClearImagesBtn: 'clearImagesBtn',
|
||||
imNextBatchBtn: 'nextBatchBtn',
|
||||
imClearVideosBtn: 'clearVideosBtn',
|
||||
};
|
||||
Object.entries(proxyMap).forEach(([sId, oId]) => {
|
||||
const sEl = document.getElementById(sId);
|
||||
const oEl = document.getElementById(oId);
|
||||
if (sEl && oEl) sEl.addEventListener('click', () => oEl.click());
|
||||
});
|
||||
|
||||
/* --- 候选图主按钮:生成6张/停止候选 --- */
|
||||
const imGenBtn = document.getElementById('imGenerateBtn');
|
||||
const genPlayIcon = imGenBtn && imGenBtn.querySelector('.nsfw-btn-play');
|
||||
const genStopIcon = imGenBtn && imGenBtn.querySelector('.nsfw-btn-stop');
|
||||
const genLabel = imGenBtn && imGenBtn.querySelector('.nsfw-btn-label');
|
||||
|
||||
function syncGenBtn() {
|
||||
if (!imGenBtn) return;
|
||||
const isRunning = generateBatchBtn && generateBatchBtn.dataset.running === '1';
|
||||
imGenBtn.classList.toggle('is-stop', isRunning);
|
||||
if (genPlayIcon) genPlayIcon.style.display = isRunning ? 'none' : '';
|
||||
if (genStopIcon) genStopIcon.style.display = isRunning ? '' : 'none';
|
||||
if (genLabel) genLabel.textContent = isRunning ? '停止候选' : '生成 6 张';
|
||||
}
|
||||
|
||||
if (imGenBtn) {
|
||||
imGenBtn.addEventListener('click', () => {
|
||||
const isRunning = generateBatchBtn && generateBatchBtn.dataset.running === '1';
|
||||
(isRunning ? stopBatchBtn : generateBatchBtn) && (isRunning ? stopBatchBtn : generateBatchBtn).click();
|
||||
});
|
||||
}
|
||||
/* 观察 generateBatchBtn 的 data-running 属性和 disabled 状态 */
|
||||
if (generateBatchBtn) {
|
||||
new MutationObserver(syncGenBtn).observe(generateBatchBtn, { attributes: true, attributeFilter: ['data-running', 'disabled'] });
|
||||
}
|
||||
syncGenBtn();
|
||||
|
||||
/* --- 视频主按钮:生成视频/中断视频 --- */
|
||||
const imVideoBtn = document.getElementById('imStartVideoBtn');
|
||||
const vidPlayIcon = imVideoBtn && imVideoBtn.querySelector('.nsfw-btn-play');
|
||||
const vidStopIcon = imVideoBtn && imVideoBtn.querySelector('.nsfw-btn-stop');
|
||||
const vidLabel = imVideoBtn && imVideoBtn.querySelector('.nsfw-btn-label');
|
||||
|
||||
function syncVideoBtn() {
|
||||
if (!imVideoBtn) return;
|
||||
const isRunning = startVideoBtn && startVideoBtn.dataset.running === '1';
|
||||
const hasSelected = startVideoBtn && !startVideoBtn.disabled;
|
||||
imVideoBtn.classList.toggle('is-stop', isRunning);
|
||||
imVideoBtn.disabled = !isRunning && !hasSelected;
|
||||
if (vidPlayIcon) vidPlayIcon.style.display = isRunning ? 'none' : '';
|
||||
if (vidStopIcon) vidStopIcon.style.display = isRunning ? '' : 'none';
|
||||
if (vidLabel) vidLabel.textContent = isRunning ? '中断视频' : '生成视频';
|
||||
}
|
||||
|
||||
if (imVideoBtn) {
|
||||
imVideoBtn.addEventListener('click', () => {
|
||||
const isRunning = startVideoBtn && startVideoBtn.dataset.running === '1';
|
||||
(isRunning ? stopVideoBtn : startVideoBtn) && (isRunning ? stopVideoBtn : startVideoBtn).click();
|
||||
});
|
||||
}
|
||||
if (startVideoBtn) {
|
||||
new MutationObserver(syncVideoBtn).observe(startVideoBtn, { attributes: true, attributeFilter: ['data-running', 'disabled'] });
|
||||
}
|
||||
syncVideoBtn();
|
||||
|
||||
/* --- 候选图已选状态同步 → 第二行高亮 --- */
|
||||
const videoRow = document.getElementById('nsfwVideoRow');
|
||||
const selectedLabel = document.getElementById('nsfwSelectedLabel');
|
||||
|
||||
function syncSelected() {
|
||||
if (!selectedMeta || !videoRow || !selectedLabel) return;
|
||||
const text = String(selectedMeta.textContent || '').trim();
|
||||
const hasSelected = !text.includes('未选择');
|
||||
videoRow.classList.toggle('has-selected', hasSelected);
|
||||
// 截短显示
|
||||
if (hasSelected) {
|
||||
selectedLabel.textContent = text.length > 22 ? text.slice(0, 22) + '…' : text;
|
||||
} else {
|
||||
selectedLabel.textContent = '未选择候选图';
|
||||
}
|
||||
syncVideoBtn();
|
||||
}
|
||||
|
||||
if (selectedMeta) {
|
||||
new MutationObserver(syncSelected).observe(selectedMeta, { characterData: true, childList: true, subtree: true });
|
||||
syncSelected();
|
||||
}
|
||||
|
||||
/* --- 设置 Bottom Sheet(画面比例、并发、分辨率、时长、NSFW) --- */
|
||||
const settingsBtn = document.getElementById('nsfwSettingsBtn');
|
||||
const settingsOverlay = document.getElementById('nsfwSettingsOverlay');
|
||||
|
||||
let settingsSheet = document.getElementById('nsfwSettingsSheet');
|
||||
if (!settingsSheet) {
|
||||
settingsSheet = document.createElement('div');
|
||||
settingsSheet.id = 'nsfwSettingsSheet';
|
||||
settingsSheet.className = 'nsfw-settings-sheet';
|
||||
|
||||
const handle = document.createElement('div');
|
||||
handle.className = 'nsfw-settings-sheet-handle';
|
||||
settingsSheet.appendChild(handle);
|
||||
|
||||
const titleEl = document.createElement('div');
|
||||
titleEl.className = 'nsfw-settings-sheet-title';
|
||||
titleEl.textContent = '生成参数';
|
||||
settingsSheet.appendChild(titleEl);
|
||||
|
||||
// 将参数表单(画面比例、并发、分辨率、时长、NSFW 这些 field,不含 textarea)移入 sheet
|
||||
const formGrid = document.querySelector('.form-grid');
|
||||
if (formGrid) {
|
||||
const nonWideFields = formGrid.querySelectorAll('.field:not(.field-wide)');
|
||||
const sheetGrid = document.createElement('div');
|
||||
sheetGrid.className = 'form-grid';
|
||||
sheetGrid.style.cssText = 'grid-template-columns: 1fr 1fr; gap: 10px 14px;';
|
||||
nonWideFields.forEach(f => sheetGrid.appendChild(f));
|
||||
settingsSheet.appendChild(sheetGrid);
|
||||
}
|
||||
|
||||
document.body.appendChild(settingsSheet);
|
||||
}
|
||||
|
||||
const openSettings = () => {
|
||||
if (!settingsSheet || !settingsOverlay) return;
|
||||
settingsOverlay.classList.add('active');
|
||||
requestAnimationFrame(() => settingsSheet.classList.add('open'));
|
||||
};
|
||||
const closeSettings = () => {
|
||||
if (!settingsSheet || !settingsOverlay) return;
|
||||
settingsSheet.classList.remove('open');
|
||||
settingsOverlay.classList.remove('active');
|
||||
};
|
||||
|
||||
if (settingsBtn) settingsBtn.addEventListener('click', openSettings);
|
||||
if (settingsOverlay) settingsOverlay.addEventListener('click', closeSettings);
|
||||
const sheetHandle = settingsSheet && settingsSheet.querySelector('.nsfw-settings-sheet-handle');
|
||||
if (sheetHandle) sheetHandle.addEventListener('click', closeSettings);
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && settingsSheet && settingsSheet.classList.contains('open')) closeSettings();
|
||||
});
|
||||
}
|
||||
|
||||
initNsfwStickyBar();
|
||||
})();
|
||||
@@ -19,7 +19,7 @@
|
||||
<script src="/static/common/js/theme.js?v=0.1.0"></script>
|
||||
<link href="/static/common/css/common.css?v=0.3.7" rel="stylesheet">
|
||||
<link href="/static/common/css/toast.css" rel="stylesheet">
|
||||
<link href="/static/public/css/nsfw.css?v=0.3.6" rel="stylesheet">
|
||||
<link href="/static/public/css/nsfw.css?v=0.3.7" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body class="public-page min-h-screen flex flex-col" style="background-color: var(--bg);">
|
||||
@@ -132,23 +132,88 @@
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="mobile-fab" data-mobile-fab>
|
||||
<div class="mobile-fab-panel">
|
||||
<div class="mobile-fab-actions">
|
||||
<button class="geist-button" data-proxy-click="#generateBatchBtn" type="button">生成6张</button>
|
||||
<button class="geist-button-outline" data-proxy-click="#stopBatchBtn" type="button">停候选</button>
|
||||
<button class="geist-button-outline" data-proxy-click="#nextBatchBtn" type="button">再来一批</button>
|
||||
<button class="geist-button-outline" data-proxy-click="#clearImagesBtn" type="button">清图片</button>
|
||||
<button class="geist-button" data-proxy-click="#startVideoBtn" type="button">开始视频</button>
|
||||
<button class="geist-button-outline" data-proxy-click="#stopVideoBtn" type="button">停视频</button>
|
||||
<button class="geist-button-outline" data-proxy-click="#clearVideosBtn" type="button">清视频</button>
|
||||
<!-- 移动端设置遮罩(Bottom Sheet) -->
|
||||
<div id="nsfwSettingsOverlay" class="nsfw-settings-overlay"></div>
|
||||
|
||||
<!-- 移动端双行 Sticky Bar -->
|
||||
<div id="nsfwStickyBar" class="nsfw-sticky-bar">
|
||||
<!-- 第一行:候选图操作 -->
|
||||
<div class="nsfw-sticky-row nsfw-sticky-row--image">
|
||||
<!-- 左:设置 -->
|
||||
<button class="nsfw-icon-btn" id="nsfwSettingsBtn" type="button" title="生成参数" aria-label="生成参数">
|
||||
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="nsfw-icon-divider"></div>
|
||||
<!-- 中:图标操作 -->
|
||||
<div class="nsfw-icon-group">
|
||||
<!-- 清空图片 -->
|
||||
<button class="nsfw-icon-btn nsfw-icon-btn--danger" id="imClearImagesBtn" type="button" title="清空图片">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/>
|
||||
<path d="M10 11v6M14 11v6"/><path d="M9 6V4h6v2"/>
|
||||
</svg>
|
||||
</button>
|
||||
<!-- 再来一批 -->
|
||||
<button class="nsfw-icon-btn" id="imNextBatchBtn" type="button" title="再来一批">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<polyline points="1 4 1 10 7 10"/>
|
||||
<path d="M3.51 15a9 9 0 1 0 .49-3.5"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<!-- 右:主按钮(生成6张/停止候选) -->
|
||||
<button id="imGenerateBtn" class="geist-button nsfw-main-btn" type="button">
|
||||
<svg class="nsfw-btn-play" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<polygon points="5 3 19 12 5 21 5 3"/>
|
||||
</svg>
|
||||
<svg class="nsfw-btn-stop" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display:none">
|
||||
<rect x="5" y="5" width="14" height="14"/>
|
||||
</svg>
|
||||
<span class="nsfw-btn-label">生成 6 张</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 行分隔线 -->
|
||||
<div class="nsfw-sticky-row-sep"></div>
|
||||
|
||||
<!-- 第二行:视频操作(候选图已选时高亮) -->
|
||||
<div class="nsfw-sticky-row nsfw-sticky-row--video" id="nsfwVideoRow">
|
||||
<!-- 左:已选图摘要 -->
|
||||
<div class="nsfw-selected-label" id="nsfwSelectedLabel">未选择候选图</div>
|
||||
<!-- 右侧视频操作 -->
|
||||
<div class="nsfw-video-actions">
|
||||
<!-- 清空视频 -->
|
||||
<button class="nsfw-icon-btn nsfw-icon-btn--danger" id="imClearVideosBtn" type="button" title="清空视频结果">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="2" y="2" width="20" height="20" rx="2.18"/><line x1="7" y1="2" x2="7" y2="22"/>
|
||||
<line x1="17" y1="2" x2="17" y2="22"/><line x1="2" y1="12" x2="22" y2="12"/>
|
||||
<line x1="2" y1="7" x2="7" y2="7"/><line x1="2" y1="17" x2="7" y2="17"/>
|
||||
<line x1="17" y1="17" x2="22" y2="17"/><line x1="17" y1="7" x2="22" y2="7"/>
|
||||
</svg>
|
||||
</button>
|
||||
<!-- 生成视频/中断视频 主按钮 -->
|
||||
<button id="imStartVideoBtn" class="geist-button nsfw-main-btn nsfw-main-btn--video" type="button" disabled>
|
||||
<svg class="nsfw-btn-play" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<polygon points="5 3 19 12 5 21 5 3"/>
|
||||
</svg>
|
||||
<svg class="nsfw-btn-stop" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display:none">
|
||||
<rect x="5" y="5" width="14" height="14"/>
|
||||
</svg>
|
||||
<span class="nsfw-btn-label">生成视频</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="mobile-fab-toggle" data-fab-toggle type="button" aria-label="打开操作菜单">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M12 5v14M5 12h14" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="lightbox" class="image-lightbox">
|
||||
@@ -199,11 +264,10 @@
|
||||
<script src="/static/common/js/parentpost-memory.js?v=0.1.0"></script>
|
||||
<script src="/static/common/js/public-header.js?v=0.3.3"></script>
|
||||
<script src="/static/common/js/footer.js?v=0.3.0"></script>
|
||||
<script src="/static/common/js/mobile-fab.js?v=0.1.1"></script>
|
||||
<script src="/static/common/js/toast.js"></script>
|
||||
<script src="/static/common/js/prompt-enhancer.js?v=0.1.15"></script>
|
||||
<script src="/static/common/js/pwa.js?v=0.1.1"></script>
|
||||
<script src="/static/public/js/nsfw.js?v=0.3.5"></script>
|
||||
<script src="/static/public/js/nsfw.js?v=0.3.6"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in new issue
Block a user