update lexicon site.standard.document

This commit is contained in:
2026-02-19 06:55:36 +09:00
parent 073d69708d
commit 4075f6de45
187 changed files with 1750 additions and 850 deletions

View File

@@ -169,7 +169,6 @@ fn save_chat_local(
output_dir: &str,
did: &str,
content: &str,
author_did: &str,
root_uri: Option<&str>,
parent_uri: Option<&str>,
) -> Result<String> {
@@ -177,11 +176,16 @@ fn save_chat_local(
let now = chrono::Utc::now().format("%Y-%m-%dT%H:%M:%S%.3fZ").to_string();
let uri = format!("at://{}/ai.syui.log.chat/{}", did, rkey);
let site = std::env::var("SITE_URL").unwrap_or_else(|_| "https://syui.ai".to_string());
let mut value = serde_json::json!({
"$type": "ai.syui.log.chat",
"content": content,
"author": author_did,
"createdAt": now,
"site": site,
"title": "",
"content": {
"$type": "ai.syui.log.chat#markdown",
"text": content,
},
"publishedAt": now,
});
if let Some(root) = root_uri {
@@ -246,7 +250,6 @@ async fn process_message(
output_dir,
user_did,
input,
user_did,
session.root_uri.as_deref(),
session.last_uri.as_deref(),
)?;
@@ -270,7 +273,6 @@ async fn process_message(
output_dir,
bot_did,
&response,
bot_did,
session.root_uri.as_deref(),
Some(&user_uri),
)?;

View File

@@ -152,7 +152,6 @@ fn save_chat_record(
output_dir: &str,
did: &str,
content: &str,
author_did: &str,
root_uri: Option<&str>,
parent_uri: Option<&str>,
translations: Option<&std::collections::HashMap<String, Translation>>,
@@ -161,11 +160,16 @@ fn save_chat_record(
let now = chrono::Utc::now().format("%Y-%m-%dT%H:%M:%S%.3fZ").to_string();
let uri = format!("at://{}/ai.syui.log.chat/{}", did, rkey);
let site = std::env::var("SITE_URL").unwrap_or_else(|_| "https://syui.ai".to_string());
let mut value = json!({
"$type": "ai.syui.log.chat",
"content": content,
"author": author_did,
"createdAt": now,
"site": site,
"title": "",
"content": {
"$type": "ai.syui.log.chat#markdown",
"text": content,
},
"publishedAt": now,
});
if let Some(root) = root_uri {
@@ -248,7 +252,6 @@ fn handle_chat_save(params: ChatSaveParams) -> Result<String> {
&output_dir,
&user_did,
&params.user_message,
&user_did,
session.root_uri.as_deref(),
session.last_uri.as_deref(),
params.user_translations.as_ref(),
@@ -264,7 +267,6 @@ fn handle_chat_save(params: ChatSaveParams) -> Result<String> {
&output_dir,
&bot_did,
&params.bot_response,
&bot_did,
session.root_uri.as_deref(),
Some(&user_uri),
params.bot_translations.as_ref(),
@@ -307,8 +309,10 @@ fn handle_chat_list() -> Result<String> {
let file_path = collection_dir.join(format!("{}.json", rkey));
if let Ok(content) = fs::read_to_string(&file_path) {
if let Ok(record) = serde_json::from_str::<Value>(&content) {
if let Some(msg) = record["value"]["content"].as_str() {
messages.push(format!("- {}", msg));
let msg = record["value"]["content"]["text"].as_str()
.or_else(|| record["value"]["content"].as_str());
if let Some(text) = msg {
messages.push(format!("- {}", text));
}
}
}

View File

@@ -5,13 +5,13 @@ import { getCurrentLang } from './mode-tabs'
// Get translated content for a chat message
function getTranslatedContent(msg: ChatMessage): string {
const currentLang = getCurrentLang()
const originalLang = msg.value.lang || 'ja'
const originalLang = msg.value.langs?.[0] || 'ja'
const translations = msg.value.translations
if (translations && currentLang !== originalLang && translations[currentLang]) {
return translations[currentLang].content || msg.value.content
return translations[currentLang].content || msg.value.content.text
}
return msg.value.content
return msg.value.content.text
}
// Escape HTML to prevent XSS
@@ -36,6 +36,11 @@ function getRkeyFromUri(uri: string): string {
return uri.split('/').pop() || ''
}
// Extract DID from AT URI (at://did:plc:xxx/collection/rkey → did:plc:xxx)
function getDidFromUri(uri: string): string {
return uri.replace('at://', '').split('/')[0]
}
// Profile info for authors
interface AuthorInfo {
did: string
@@ -96,7 +101,7 @@ export function renderChatThreadList(
const rootMessages: ChatMessage[] = []
for (const msg of messages) {
if (msg.value.author !== userDid) continue
if (getDidFromUri(msg.uri) !== userDid) continue
if (!msg.value.root) {
// No root = explicit conversation start
@@ -104,7 +109,7 @@ export function renderChatThreadList(
} else if (!allUris.has(msg.value.root)) {
// Orphaned root - keep only the oldest message per orphaned root
const existing = orphanedRootFirstMsg.get(msg.value.root)
if (!existing || new Date(msg.value.createdAt) < new Date(existing.value.createdAt)) {
if (!existing || new Date(msg.value.publishedAt) < new Date(existing.value.publishedAt)) {
orphanedRootFirstMsg.set(msg.value.root, msg)
}
}
@@ -121,14 +126,14 @@ export function renderChatThreadList(
const authors = buildAuthorMap(userDid, userHandle, botDid, botHandle, userProfile, botProfile, pds)
// Sort by createdAt (newest first)
// Sort by publishedAt (newest first)
const sorted = [...rootMessages].sort((a, b) =>
new Date(b.value.createdAt).getTime() - new Date(a.value.createdAt).getTime()
new Date(b.value.publishedAt).getTime() - new Date(a.value.publishedAt).getTime()
)
const items = sorted.map(msg => {
const authorDid = msg.value.author
const time = formatChatTime(msg.value.createdAt)
const authorDid = getDidFromUri(msg.uri)
const time = formatChatTime(msg.value.publishedAt)
const rkey = getRkeyFromUri(msg.uri)
const author = authors.get(authorDid) || { did: authorDid, handle: authorDid.slice(0, 20) + '...' }
@@ -206,14 +211,14 @@ export function renderChatThread(
const authors = buildAuthorMap(userDid, userHandle, botDid, botHandle, userProfile, botProfile, pds)
// Sort by createdAt
// Sort by publishedAt
const sorted = [...threadMessages].sort((a, b) =>
new Date(a.value.createdAt).getTime() - new Date(b.value.createdAt).getTime()
new Date(a.value.publishedAt).getTime() - new Date(b.value.publishedAt).getTime()
)
const items = sorted.map(msg => {
const authorDid = msg.value.author
const time = formatChatTime(msg.value.createdAt)
const authorDid = getDidFromUri(msg.uri)
const time = formatChatTime(msg.value.publishedAt)
const rkey = getRkeyFromUri(msg.uri)
const author = authors.get(authorDid) || { did: authorDid, handle: authorDid.slice(0, 20) + '...' }
@@ -287,7 +292,7 @@ export function renderChatEditForm(
userHandle: string
): string {
const rkey = message.uri.split('/').pop() || ''
const content = message.value.content
const content = message.value.content.text
return `
<div class="chat-edit-container">

View File

@@ -22,8 +22,8 @@ export function renderPostList(posts: Post[], handle: string): string {
const items = posts.map(post => {
const rkey = post.uri.split('/').pop() || ''
const date = formatDate(post.value.createdAt)
const originalLang = post.value.lang || 'ja'
const date = formatDate(post.value.publishedAt)
const originalLang = post.value.langs?.[0] || 'ja'
const translations = post.value.translations
// Use translation if available
@@ -55,7 +55,7 @@ export function renderPostDetail(
appUrl: string = 'https://bsky.app'
): string {
const rkey = post.uri.split('/').pop() || ''
const date = formatDate(post.value.createdAt)
const date = formatDate(post.value.publishedAt)
const jsonUrl = `/@${handle}/at/collection/${collection}/${rkey}`
// Build post URL for discussion search
@@ -66,10 +66,10 @@ export function renderPostDetail(
// Get current language and show appropriate content
const currentLang = getCurrentLang()
const translations = post.value.translations
const originalLang = post.value.lang || 'ja'
const originalLang = post.value.langs?.[0] || 'ja'
let displayTitle = post.value.title
let displayContent = post.value.content
let displayContent = post.value.content.text
// Use translation if available and not original language
if (translations && currentLang !== originalLang && translations[currentLang]) {
@@ -83,7 +83,7 @@ export function renderPostDetail(
const editForm = isOwner ? `
<div class="post-edit-form" id="post-edit-form" style="display: none;">
<input type="text" class="post-edit-title" id="post-edit-title" value="${escapeHtml(post.value.title)}" placeholder="Title">
<textarea class="post-edit-content" id="post-edit-content" rows="15">${escapeHtml(post.value.content)}</textarea>
<textarea class="post-edit-content" id="post-edit-content" rows="15">${escapeHtml(post.value.content.text)}</textarea>
<div class="post-edit-actions">
<button type="button" class="post-edit-cancel" id="post-edit-cancel">Cancel</button>
<button type="button" class="post-edit-save" id="post-edit-save" data-collection="${collection}" data-rkey="${rkey}">Save</button>

View File

@@ -154,7 +154,7 @@ async function getLocalPosts(did: string, collection: string): Promise<Post[]> {
if (res.ok && isJsonResponse(res)) posts.push(await res.json())
}
return posts.sort((a, b) =>
new Date(b.value.createdAt).getTime() - new Date(a.value.createdAt).getTime()
new Date(b.value.publishedAt).getTime() - new Date(a.value.publishedAt).getTime()
)
}
} catch {
@@ -183,7 +183,7 @@ export async function getPosts(did: string, collection: string, localOnly = fals
if (res.ok) {
const data: ListRecordsResponse<Post> = await res.json()
return data.records.sort((a, b) =>
new Date(b.value.createdAt).getTime() - new Date(a.value.createdAt).getTime()
new Date(b.value.publishedAt).getTime() - new Date(a.value.publishedAt).getTime()
)
}
} catch {
@@ -436,9 +436,9 @@ export async function getChatMessages(
const messages = [...userMessages, ...botMessages]
// Sort by createdAt
// Sort by publishedAt
return messages.sort((a, b) =>
new Date(a.value.createdAt).getTime() - new Date(b.value.createdAt).getTime()
new Date(a.value.publishedAt).getTime() - new Date(b.value.publishedAt).getTime()
)
}

View File

@@ -239,9 +239,13 @@ export async function createPost(
collection,
record: {
$type: collection,
site: window.location.origin,
title,
content,
createdAt: new Date().toISOString(),
content: {
$type: `${collection}#markdown`,
text: content,
},
publishedAt: new Date().toISOString(),
},
})
@@ -264,7 +268,7 @@ export async function updatePost(
try {
// Fetch existing record to preserve translations
let existingTranslations: unknown = undefined
let existingCreatedAt: unknown = new Date().toISOString()
let existingPublishedAt: unknown = new Date().toISOString()
try {
const existing = await agent.com.atproto.repo.getRecord({
repo: agent.assertDid,
@@ -274,8 +278,8 @@ export async function updatePost(
if (existing.data.value) {
const value = existing.data.value as Record<string, unknown>
existingTranslations = value.translations
if (value.createdAt) {
existingCreatedAt = value.createdAt
if (value.publishedAt) {
existingPublishedAt = value.publishedAt
}
}
} catch {
@@ -284,9 +288,13 @@ export async function updatePost(
const record: Record<string, unknown> = {
$type: collection,
site: window.location.origin,
title,
content,
createdAt: existingCreatedAt,
content: {
$type: `${collection}#markdown`,
text: content,
},
publishedAt: existingPublishedAt,
}
if (existingTranslations) {

View File

@@ -165,7 +165,7 @@ async function render(route: Route): Promise<void> {
const availableLangs = new Set<string>()
for (const post of posts) {
// Add original language (default: ja for Japanese posts)
const postLang = post.value.lang || 'ja'
const postLang = post.value.langs?.[0] || 'ja'
availableLangs.add(postLang)
// Add translation languages
if (post.value.translations) {
@@ -302,7 +302,7 @@ async function render(route: Route): Promise<void> {
// Collect available languages from chat messages
const chatLangs = new Set<string>()
for (const msg of chatMessages) {
const msgLang = msg.value.lang || 'ja'
const msgLang = msg.value.langs?.[0] || 'ja'
chatLangs.add(msgLang)
if (msg.value.translations) {
for (const lang of Object.keys(msg.value.translations)) {
@@ -337,7 +337,7 @@ async function render(route: Route): Promise<void> {
// Collect available languages from chat messages
const chatLangs = new Set<string>()
for (const msg of chatMessages) {
const msgLang = msg.value.lang || 'ja'
const msgLang = msg.value.langs?.[0] || 'ja'
chatLangs.add(msgLang)
if (msg.value.translations) {
for (const lang of Object.keys(msg.value.translations)) {

View File

@@ -52,15 +52,27 @@ export interface Profile {
}
}
export interface ContentMarkdown {
$type: string
text: string
}
export interface Post {
cid: string
uri: string
value: {
$type: string
site: string
title: string
content: string
createdAt: string
lang?: string
content: ContentMarkdown
publishedAt: string
description?: string
updatedAt?: string
tags?: string[]
path?: string
root?: string
parent?: string
langs?: string[]
translations?: {
[lang: string]: {
title: string
@@ -80,12 +92,17 @@ export interface ChatMessage {
uri: string
value: {
$type: string
content: string
author: string
createdAt: string
site: string
title: string
content: ContentMarkdown
publishedAt: string
description?: string
updatedAt?: string
tags?: string[]
path?: string
root?: string
parent?: string
lang?: string
langs?: string[]
translations?: {
[lang: string]: {
content: string