Improve offline template loading
This commit is contained in:
@@ -3650,6 +3650,32 @@ textarea {
|
||||
background: color-mix(in srgb, var(--color-bg) 70%, var(--color-bg-card));
|
||||
}
|
||||
|
||||
.picture-agent-template-placeholder {
|
||||
width: 100%;
|
||||
height: 102px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
align-content: center;
|
||||
gap: 4px;
|
||||
border-radius: 6px;
|
||||
background:
|
||||
linear-gradient(135deg, color-mix(in srgb, var(--color-primary) 14%, transparent), transparent 56%),
|
||||
color-mix(in srgb, var(--color-bg) 74%, var(--color-bg-card));
|
||||
border: 1px solid color-mix(in srgb, var(--color-border) 72%, transparent);
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.picture-agent-template-placeholder strong {
|
||||
max-width: 100%;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.picture-agent-template-placeholder small {
|
||||
color: var(--color-text-muted);
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.picture-agent-template-card span {
|
||||
display: grid;
|
||||
gap: 3px;
|
||||
|
||||
@@ -57,7 +57,7 @@ type PromptTemplate = {
|
||||
title: string;
|
||||
tag: string;
|
||||
size: string;
|
||||
image: string;
|
||||
image?: string | null;
|
||||
prompt: string;
|
||||
source?: {
|
||||
name?: string;
|
||||
@@ -76,7 +76,6 @@ type GalleryItem = {
|
||||
};
|
||||
|
||||
const DEFAULT_PROMPT = 'A precise editorial product photo of a translucent glass robot painting a small neon city, sharp focus, clean background';
|
||||
const TEMPLATE_GALLERY_JSON_URL = 'https://weiyyin.github.io/linux-do-gpt-image/linux_do_2036927_prompts_images.filtered.json';
|
||||
const TEMPLATE_LIMIT = 144;
|
||||
const QUALITY_OPTIONS = ['auto', 'low', 'medium', 'high'];
|
||||
const ASPECT_OPTIONS = [
|
||||
@@ -282,39 +281,6 @@ function isPictureModel(model: string) {
|
||||
return !chatKeywords.some((keyword) => normalized.includes(keyword));
|
||||
}
|
||||
|
||||
function normalizeGalleryItems(items: GalleryItem[], limit = TEMPLATE_LIMIT): PromptTemplate[] {
|
||||
return items
|
||||
.map<PromptTemplate | null>((item) => {
|
||||
const prompt = (item.prompt || '').trim();
|
||||
const image = (item.images || []).find((value) => value.startsWith('http'))
|
||||
|| (item.image_host_url || '').trim();
|
||||
if (Array.from(prompt).length < 20 || !image.startsWith('http')) return null;
|
||||
return {
|
||||
id: item.post_number ? `linux-do-${item.post_number}` : `linux-do-${templateTitle(prompt)}`,
|
||||
title: templateTitle(prompt, item.post_number),
|
||||
tag: templateTag(prompt),
|
||||
size: templateSize(prompt),
|
||||
image,
|
||||
prompt,
|
||||
source: {
|
||||
name: 'Linux Do GPT Image Gallery',
|
||||
url: 'https://weiyyin.github.io/linux-do-gpt-image/prompt_gallery.html',
|
||||
postNumber: item.post_number,
|
||||
username: item.username,
|
||||
},
|
||||
} satisfies PromptTemplate;
|
||||
})
|
||||
.filter((value): value is PromptTemplate => value !== null)
|
||||
.slice(0, limit);
|
||||
}
|
||||
|
||||
async function loadGalleryTemplatesDirectly(limit = TEMPLATE_LIMIT): Promise<PromptTemplate[]> {
|
||||
const response = await fetch(TEMPLATE_GALLERY_JSON_URL, { cache: 'no-store' });
|
||||
if (!response.ok) throw new Error(`gallery HTTP ${response.status}`);
|
||||
const items = await response.json();
|
||||
return normalizeGalleryItems(Array.isArray(items) ? items : [], limit);
|
||||
}
|
||||
|
||||
export default function PictureAgent() {
|
||||
const location = useLocation();
|
||||
const audience: SessionAudience = location.pathname.startsWith('/user/') ? 'user' : 'admin';
|
||||
@@ -424,11 +390,7 @@ export default function PictureAgent() {
|
||||
const templatePayload = await templatesRes.json();
|
||||
nextTemplates = Array.isArray(templatePayload?.templates) ? templatePayload.templates : [];
|
||||
} else {
|
||||
try {
|
||||
nextTemplates = await loadGalleryTemplatesDirectly(TEMPLATE_LIMIT);
|
||||
} catch {
|
||||
setTemplatesError(await parseError(templatesRes));
|
||||
}
|
||||
setTemplatesError(await parseError(templatesRes));
|
||||
}
|
||||
let nextJobs: PictureJob[] = [];
|
||||
if (jobsRes.ok) {
|
||||
@@ -872,7 +834,7 @@ export default function PictureAgent() {
|
||||
<div className="picture-agent-template-strip">
|
||||
<div className="picture-agent-template-title">
|
||||
<strong>参考模板</strong>
|
||||
<span>{templatesLoading ? '正在刷新模板...' : '每次打开自动获取 Linux Do GPT Image Gallery'}</span>
|
||||
<span>{templatesLoading ? '正在刷新模板...' : '内置模板优先,外部图库可用时自动补充'}</span>
|
||||
</div>
|
||||
<div className="picture-agent-template-list">
|
||||
{templatesError && templates.length === 0 ? (
|
||||
@@ -887,7 +849,14 @@ export default function PictureAgent() {
|
||||
onClick={() => applyTemplate(template)}
|
||||
title={template.prompt}
|
||||
>
|
||||
<img src={template.image} alt="" loading="lazy" referrerPolicy="no-referrer" />
|
||||
{template.image ? (
|
||||
<img src={template.image} alt="" loading="lazy" referrerPolicy="no-referrer" />
|
||||
) : (
|
||||
<div className="picture-agent-template-placeholder">
|
||||
<strong>{template.tag}</strong>
|
||||
<small>{template.size}</small>
|
||||
</div>
|
||||
)}
|
||||
<span>
|
||||
<strong>{template.title}</strong>
|
||||
<em>{template.tag}{template.source?.postNumber ? ` · #${template.source.postNumber}` : ''}</em>
|
||||
|
||||
Reference in New Issue
Block a user