wip(docs): i18n (#12681)
This commit is contained in:
@@ -1,13 +1,29 @@
|
||||
import type { APIRoute } from "astro"
|
||||
import { getCollection } from "astro:content"
|
||||
|
||||
export const GET: APIRoute = async ({ params }) => {
|
||||
function notFoundText(locals: unknown) {
|
||||
if (typeof locals !== "object" || locals === null || !("t" in locals)) {
|
||||
return "share.not_found"
|
||||
}
|
||||
const t = (locals as { t?: unknown }).t
|
||||
if (typeof t !== "function") {
|
||||
return "share.not_found"
|
||||
}
|
||||
const text = t("share.not_found")
|
||||
if (typeof text === "string" && text.length > 0) {
|
||||
return text
|
||||
}
|
||||
return "share.not_found"
|
||||
}
|
||||
|
||||
export const GET: APIRoute = async ({ params, locals }) => {
|
||||
const slug = params.slug || "index"
|
||||
const docs = await getCollection("docs")
|
||||
const doc = docs.find((d) => d.id === slug)
|
||||
const notFound = notFoundText(locals)
|
||||
|
||||
if (!doc) {
|
||||
return new Response("Not found", { status: 404 })
|
||||
return new Response(notFound, { status: 404, statusText: notFound })
|
||||
}
|
||||
|
||||
return new Response(doc.body, {
|
||||
|
||||
@@ -1,55 +1,112 @@
|
||||
---
|
||||
import { Base64 } from "js-base64";
|
||||
import { Base64 } from "js-base64"
|
||||
import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro"
|
||||
import type { Session } from "opencode/session/index"
|
||||
import config from "../../../config.mjs"
|
||||
import Share from "../../components/Share.tsx"
|
||||
|
||||
import config from '../../../config.mjs'
|
||||
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
|
||||
import Share from "../../components/Share.tsx";
|
||||
const apiUrl = import.meta.env.VITE_API_URL || ""
|
||||
const ta = Astro.locals.t as ((key: string) => string) & {
|
||||
all?: () => Record<string, string>
|
||||
}
|
||||
const all = typeof ta.all === "function" ? ta.all() : {}
|
||||
const locale = Astro.currentLocale || Astro.locals.starlightRoute.locale || "root"
|
||||
const formatLocale = locale === "root" ? "en" : locale
|
||||
const t = ta
|
||||
|
||||
const apiUrl = import.meta.env.VITE_API_URL;
|
||||
function tx(key: string) {
|
||||
const value = all[key]
|
||||
if (typeof value === "string") return value
|
||||
return t(key)
|
||||
}
|
||||
|
||||
const { id } = Astro.params;
|
||||
const res = await fetch(`${apiUrl}/share_data?id=${id}`);
|
||||
const data = await res.json();
|
||||
const messages = {
|
||||
locale: formatLocale,
|
||||
link_to_message: tx("share.link_to_message"),
|
||||
copied: tx("share.copied"),
|
||||
copy: tx("share.copy"),
|
||||
show_more: tx("share.show_more"),
|
||||
show_less: tx("share.show_less"),
|
||||
show_results: tx("share.show_results"),
|
||||
hide_results: tx("share.hide_results"),
|
||||
show_details: tx("share.show_details"),
|
||||
hide_details: tx("share.hide_details"),
|
||||
show_preview: tx("share.show_preview"),
|
||||
hide_preview: tx("share.hide_preview"),
|
||||
show_contents: tx("share.show_contents"),
|
||||
hide_contents: tx("share.hide_contents"),
|
||||
show_output: tx("share.show_output"),
|
||||
hide_output: tx("share.hide_output"),
|
||||
error: tx("share.error"),
|
||||
waiting_for_messages: tx("share.waiting_for_messages"),
|
||||
status_connected_waiting: tx("share.status_connected_waiting"),
|
||||
status_connecting: tx("share.status_connecting"),
|
||||
status_disconnected: tx("share.status_disconnected"),
|
||||
status_reconnecting: tx("share.status_reconnecting"),
|
||||
status_error: tx("share.status_error"),
|
||||
status_unknown: tx("share.status_unknown"),
|
||||
error_id_not_found: tx("share.error_id_not_found"),
|
||||
error_api_url_not_found: tx("share.error_api_url_not_found"),
|
||||
error_connection_failed: tx("share.error_connection_failed"),
|
||||
opencode_version: tx("share.opencode_version"),
|
||||
opencode_name: tx("share.opencode_name"),
|
||||
models: tx("share.models"),
|
||||
cost: tx("share.cost"),
|
||||
input_tokens: tx("share.input_tokens"),
|
||||
output_tokens: tx("share.output_tokens"),
|
||||
reasoning_tokens: tx("share.reasoning_tokens"),
|
||||
scroll_to_bottom: tx("share.scroll_to_bottom"),
|
||||
attachment: tx("share.attachment"),
|
||||
thinking: tx("share.thinking"),
|
||||
thinking_pending: tx("share.thinking_pending"),
|
||||
creating_plan: tx("share.creating_plan"),
|
||||
completing_plan: tx("share.completing_plan"),
|
||||
updating_plan: tx("share.updating_plan"),
|
||||
match_one: tx("share.match_one"),
|
||||
match_other: tx("share.match_other"),
|
||||
result_one: tx("share.result_one"),
|
||||
result_other: tx("share.result_other"),
|
||||
debug_key: tx("share.debug_key"),
|
||||
}
|
||||
|
||||
const id = Astro.params.id || ""
|
||||
const res = await fetch(`${apiUrl}/share_data?id=${id}`)
|
||||
const data = (await res.json()) as {
|
||||
info?: Session.Info
|
||||
messages: Record<string, { role?: string; modelID?: string }>
|
||||
}
|
||||
|
||||
if (!data.info) {
|
||||
return new Response(null, {
|
||||
status: 404,
|
||||
statusText: 'Not found'
|
||||
});
|
||||
statusText: tx("share.not_found"),
|
||||
})
|
||||
}
|
||||
|
||||
const models: Set<string> = new Set();
|
||||
const version = data.info.version ? `v${data.info.version}` : "v0.0.1";
|
||||
const models: Set<string> = new Set()
|
||||
const version = data.info.version ? `v${data.info.version}` : "v0.0.1"
|
||||
|
||||
Object.values(data.messages).forEach((d) => {
|
||||
for (const d of Object.values(data.messages)) {
|
||||
if (d.role === "assistant" && d.modelID) {
|
||||
models.add(d.modelID);
|
||||
models.add(d.modelID)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const encodedTitle = encodeURIComponent(
|
||||
Base64.encode(
|
||||
// Convert to ASCII
|
||||
encodeURIComponent(
|
||||
// Truncate to fit S3's max key size
|
||||
data.info.title.substring(0, 700),
|
||||
)
|
||||
)
|
||||
);
|
||||
encodeURIComponent(data.info.title.substring(0, 700)),
|
||||
),
|
||||
)
|
||||
|
||||
const modelsArray = Array.from(models);
|
||||
let modelParam;
|
||||
if (modelsArray.length === 1) {
|
||||
modelParam = modelsArray[0];
|
||||
}
|
||||
else if (modelsArray.length === 2) {
|
||||
modelParam = encodeURIComponent(`${modelsArray[0]} & ${modelsArray[1]}`);
|
||||
}
|
||||
else {
|
||||
modelParam = encodeURIComponent(`${modelsArray[0]} & ${modelsArray.length - 1} others`);
|
||||
}
|
||||
const modelsArray = Array.from(models)
|
||||
const modelParam =
|
||||
modelsArray.length === 1
|
||||
? modelsArray[0]
|
||||
: modelsArray.length === 2
|
||||
? encodeURIComponent(`${modelsArray[0]} & ${modelsArray[1]}`)
|
||||
: encodeURIComponent(`${modelsArray[0]} & ${modelsArray.length - 1} others`)
|
||||
|
||||
const ogImage = `${config.socialCard}/opencode-share/${encodedTitle}.png?model=${modelParam}&version=${version}&id=${id}`;
|
||||
const ogImage = `${config.socialCard}/opencode-share/${encodedTitle}.png?model=${modelParam}&version=${version}&id=${id}`
|
||||
---
|
||||
<StarlightPage
|
||||
hasSidebar={false}
|
||||
@@ -63,7 +120,7 @@ const ogImage = `${config.socialCard}/opencode-share/${encodedTitle}.png?model=$
|
||||
tag: "meta",
|
||||
attrs: {
|
||||
name: "description",
|
||||
content: "opencode - The AI coding agent built for the terminal.",
|
||||
content: tx("share.meta_description"),
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -90,13 +147,7 @@ const ogImage = `${config.socialCard}/opencode-share/${encodedTitle}.png?model=$
|
||||
],
|
||||
}}
|
||||
>
|
||||
<Share
|
||||
id={id}
|
||||
api={apiUrl}
|
||||
info={data.info}
|
||||
messages={data.messages}
|
||||
client:only="solid"
|
||||
/>
|
||||
<Share id={id} api={apiUrl} info={data.info} messages={messages} client:only="solid" />
|
||||
</StarlightPage>
|
||||
|
||||
<style is:global>
|
||||
|
||||
Reference in New Issue
Block a user