152 lines
4.6 KiB
JavaScript
152 lines
4.6 KiB
JavaScript
(() => {
|
|
const STORAGE_KEY = 'grok2api_parent_post_memory_v1';
|
|
const MAX_ITEMS = 300;
|
|
|
|
function nowMs() {
|
|
return Date.now();
|
|
}
|
|
|
|
function isParentPostId(value) {
|
|
return /^[0-9a-fA-F-]{32,36}$/.test(String(value || '').trim());
|
|
}
|
|
|
|
function buildImaginePublicUrl(parentPostId) {
|
|
const id = String(parentPostId || '').trim();
|
|
if (!id) return '';
|
|
return `https://imagine-public.x.ai/imagine-public/images/${id}.jpg`;
|
|
}
|
|
|
|
function extractParentPostId(text) {
|
|
const raw = String(text || '').trim();
|
|
if (!raw) return '';
|
|
if (isParentPostId(raw)) return raw;
|
|
|
|
const patterns = [
|
|
/\/generated\/([0-9a-fA-F-]{32,36})(?:\/|$)/,
|
|
/\/imagine-public\/images\/([0-9a-fA-F-]{32,36})(?:\.jpg|\/|$)/,
|
|
/\/images\/([0-9a-fA-F-]{32,36})(?:\.jpg|\/|$)/,
|
|
];
|
|
for (const pattern of patterns) {
|
|
const match = raw.match(pattern);
|
|
if (match) {
|
|
return match[1];
|
|
}
|
|
}
|
|
|
|
const all = raw.match(/([0-9a-fA-F-]{32,36})/g);
|
|
return all && all.length ? all[all.length - 1] : '';
|
|
}
|
|
|
|
function loadMemory() {
|
|
try {
|
|
const raw = localStorage.getItem(STORAGE_KEY);
|
|
if (!raw) return [];
|
|
const data = JSON.parse(raw);
|
|
if (!Array.isArray(data)) return [];
|
|
return data.filter((item) => item && isParentPostId(item.parentPostId));
|
|
} catch (e) {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
function saveMemory(items) {
|
|
try {
|
|
const normalized = Array.isArray(items) ? items.slice(0, MAX_ITEMS) : [];
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(normalized));
|
|
} catch (e) {
|
|
// ignore
|
|
}
|
|
}
|
|
|
|
function normalizeUrl(value) {
|
|
const raw = String(value || '').trim();
|
|
if (!raw) return '';
|
|
if (raw.startsWith('http://') || raw.startsWith('https://') || raw.startsWith('data:image/')) {
|
|
return raw;
|
|
}
|
|
if (raw.startsWith('/')) {
|
|
return raw;
|
|
}
|
|
return raw;
|
|
}
|
|
|
|
function isImageLikeUrl(value) {
|
|
const raw = normalizeUrl(value);
|
|
if (!raw) return false;
|
|
if (raw.startsWith('data:image/')) return true;
|
|
if (/\/imagine-public\/images\/[0-9a-fA-F-]{32,36}(?:\.[a-z0-9]+|[/?#]|$)/i.test(raw)) return true;
|
|
if (/\/imagine-public\/share-images\/[0-9a-fA-F-]{32,36}(?:\.[a-z0-9]+|[/?#]|$)/i.test(raw)) return true;
|
|
if (/\/v1\/files\/image\//i.test(raw)) return true;
|
|
if (/\/users\/.+\.(?:jpg|jpeg|png|webp|gif)(?:[?#].*)?$/i.test(raw)) return true;
|
|
if (/\.(?:jpg|jpeg|png|webp|gif)(?:[?#].*)?$/i.test(raw)) return true;
|
|
return false;
|
|
}
|
|
|
|
function remember(entry) {
|
|
if (!entry || typeof entry !== 'object') return null;
|
|
|
|
const parentPostId = extractParentPostId(entry.parentPostId || entry.parent_post_id || entry.id || '');
|
|
if (!isParentPostId(parentPostId)) return null;
|
|
|
|
const rawSourceImageUrl = normalizeUrl(entry.sourceImageUrl || entry.source_image_url || '');
|
|
const rawImageUrl = normalizeUrl(entry.imageUrl || entry.image_url || entry.url || '');
|
|
const sourceImageUrl = isImageLikeUrl(rawSourceImageUrl) ? rawSourceImageUrl : '';
|
|
const imageUrl = isImageLikeUrl(rawImageUrl) ? rawImageUrl : '';
|
|
const item = {
|
|
parentPostId,
|
|
sourceImageUrl: sourceImageUrl || imageUrl || buildImaginePublicUrl(parentPostId),
|
|
imageUrl: imageUrl || sourceImageUrl || buildImaginePublicUrl(parentPostId),
|
|
origin: String(entry.origin || 'unknown'),
|
|
updatedAt: Number(entry.updatedAt || nowMs()),
|
|
};
|
|
|
|
const all = loadMemory();
|
|
const idx = all.findIndex((it) => it.parentPostId === parentPostId);
|
|
if (idx >= 0) {
|
|
all.splice(idx, 1);
|
|
}
|
|
all.unshift(item);
|
|
saveMemory(all);
|
|
return item;
|
|
}
|
|
|
|
function getByParentPostId(parentPostId) {
|
|
const id = extractParentPostId(parentPostId);
|
|
if (!isParentPostId(id)) return null;
|
|
const all = loadMemory();
|
|
return all.find((item) => item.parentPostId === id) || null;
|
|
}
|
|
|
|
function list(limit = 50) {
|
|
const n = Math.max(1, Math.min(500, Number(limit) || 50));
|
|
return loadMemory().slice(0, n);
|
|
}
|
|
|
|
function resolveByText(text) {
|
|
const raw = String(text || '').trim();
|
|
const parentPostId = extractParentPostId(raw);
|
|
if (!parentPostId) return null;
|
|
const hit = getByParentPostId(parentPostId);
|
|
if (hit) return hit;
|
|
const fallbackUrl = isImageLikeUrl(raw) ? raw : buildImaginePublicUrl(parentPostId);
|
|
return {
|
|
parentPostId,
|
|
sourceImageUrl: fallbackUrl,
|
|
imageUrl: fallbackUrl,
|
|
origin: 'fallback',
|
|
updatedAt: nowMs(),
|
|
};
|
|
}
|
|
|
|
window.ParentPostMemory = {
|
|
key: STORAGE_KEY,
|
|
extractParentPostId,
|
|
isParentPostId,
|
|
buildImaginePublicUrl,
|
|
remember,
|
|
getByParentPostId,
|
|
list,
|
|
resolveByText,
|
|
};
|
|
})();
|