Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/app/src/app/lib/model-behavior.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ const getVariantDescription = (
if (key === "xhigh" || key === "max") return family === "anthropic"
? t("model_behavior.desc_max_anthropic")
: t("model_behavior.desc_max");
return t("model_behavior.desc_generic", undefined, { label: label.toLowerCase() });
return t("model_behavior.desc_generic", { label: label.toLowerCase() });
};

export const getModelBehaviorOptions = (
Expand Down
6 changes: 3 additions & 3 deletions apps/app/src/app/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,15 +269,15 @@ export function formatRelativeTime(timestampMs: number) {
}

if (delta < 60_000) {
return t("time.seconds_ago", undefined, { count: Math.max(1, Math.round(delta / 1000)) });
return t("time.seconds_ago", { count: Math.max(1, Math.round(delta / 1000)) });
}

if (delta < 60 * 60_000) {
return t("time.minutes_ago", undefined, { count: Math.max(1, Math.round(delta / 60_000)) });
return t("time.minutes_ago", { count: Math.max(1, Math.round(delta / 60_000)) });
}

if (delta < 24 * 60 * 60_000) {
return t("time.hours_ago", undefined, { count: Math.max(1, Math.round(delta / (60 * 60_000))) });
return t("time.hours_ago", { count: Math.max(1, Math.round(delta / (60 * 60_000))) });
}

return new Date(timestampMs).toLocaleDateString();
Expand Down
7 changes: 3 additions & 4 deletions apps/app/src/hooks/use-translate.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import * as React from "react";
import { currentLocale, t } from "@/i18n";
import { t } from "@/i18n";

export function useTranslate() {
const tr = React.useCallback((key: string) => t(key, currentLocale()), []);
const tr = React.useCallback((key: string) => t(key), []);
const tx = React.useCallback(
(key: string, params?: Record<string, string | number>) =>
t(key, currentLocale(), params),
(key: string, params?: Record<string, string | number>) => t(key, params),
[],
);

Expand Down
7 changes: 4 additions & 3 deletions apps/app/src/i18n/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ export const setLocale = (newLocale: Language) => {
* @param localeOverride - Optional locale override (defaults to current locale)
* @returns Translated string or fallback
*/
export const t = (key: string, localeOverride?: Language, params?: Record<string, string | number>): string => {
const loc = localeOverride ?? locale();
export const t = (key: string, params?: Record<string, string | number> & { lng?: Language }): string => {
const loc = params?.lng ?? locale();

// Try target language first
let result: string;
Expand All @@ -116,9 +116,10 @@ export const t = (key: string, localeOverride?: Language, params?: Record<string
return key;
}

// Replace params if provided
// Replace params if provided (skip the lng meta-key)
if (params) {
for (const [k, v] of Object.entries(params)) {
if (k === "lng") continue;
result = result.replace(`{${k}}`, String(v));
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @jsxImportSource react */
import { X } from "lucide-react";

import { currentLocale, t } from "../../i18n";
import { t } from "../../i18n";
import { Button } from "./button";

export type RestrictionNoticeModalProps = {
Expand Down Expand Up @@ -35,7 +35,7 @@ export function RestrictionNoticeModal(props: RestrictionNoticeModalProps) {
<button
type="button"
className="inline-flex h-9 w-9 items-center justify-center rounded-full text-dls-secondary transition-colors hover:bg-dls-hover hover:text-dls-text"
aria-label={t("common.close", currentLocale())}
aria-label={t("common.close")}
onClick={props.onClose}
>
<X size={18} />
Expand All @@ -48,7 +48,7 @@ export function RestrictionNoticeModal(props: RestrictionNoticeModalProps) {
</p>
<div className="mt-6 flex justify-end">
<Button variant="primary" onClick={props.onClose}>
{t("common.close", currentLocale())}
{t("common.close")}
</Button>
</div>
</div>
Expand Down
61 changes: 26 additions & 35 deletions apps/app/src/react-app/domains/bundles/skill-destination-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from "lucide-react";

import type { WorkspaceInfo } from "../../../app/lib/desktop";
import { currentLocale, t } from "../../../i18n";
import { t } from "../../../i18n";
import { isSandboxWorkspace } from "../../../app/utils";
import { Button } from "../../design-system/button";

Expand Down Expand Up @@ -43,7 +43,6 @@ const displayName = (workspace: WorkspaceInfo, fallback: string): string =>
fallback;

export function SkillDestinationModal(props: SkillDestinationModalProps) {
const translate = (key: string) => t(key, currentLocale());
const [selectedWorkspaceId, setSelectedWorkspaceId] = useState<
string | null
>(null);
Expand Down Expand Up @@ -72,26 +71,26 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
if (workspace.workspaceType === "local") {
return (
workspace.path?.trim() ||
translate("share_skill_destination.local_badge")
t("share_skill_destination.local_badge")
);
}
return (
workspace.directory?.trim() ||
workspace.openworkHostUrl?.trim() ||
workspace.baseUrl?.trim() ||
workspace.path?.trim() ||
translate("share_skill_destination.remote_badge")
t("share_skill_destination.remote_badge")
);
};

const workspaceBadge = (workspace: WorkspaceInfo): string => {
if (isSandboxWorkspace(workspace)) {
return translate("share_skill_destination.sandbox_badge");
return t("share_skill_destination.sandbox_badge");
}
if (workspace.workspaceType === "remote") {
return translate("share_skill_destination.remote_badge");
return t("share_skill_destination.remote_badge");
}
return translate("share_skill_destination.local_badge");
return t("share_skill_destination.local_badge");
};

const workspaceCircleClass = (
Expand Down Expand Up @@ -126,7 +125,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
<div className="min-w-0 space-y-3">
<div className="inline-flex items-center gap-2 rounded-full border border-gray-6 bg-gray-2 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-gray-10">
<Sparkles size={12} />
{translate("share_skill_destination.skill_label")}
{t("share_skill_destination.skill_label")}
</div>
<div className="rounded-xl border border-gray-6 bg-gray-2/40 px-4 py-4">
<div className="flex items-start gap-3">
Expand All @@ -135,11 +134,11 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
</div>
<div className="min-w-0 flex-1">
<div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-gray-9">
{translate("share_skill_destination.skill_label")}
{t("share_skill_destination.skill_label")}
</div>
<h3 className="mt-1 text-lg font-semibold text-gray-12 break-words">
{props.skill?.name ??
translate("share_skill_destination.fallback_skill_name")}
t("share_skill_destination.fallback_skill_name")}
</h3>
{props.skill?.description?.trim() ? (
<p className="mt-1 text-sm leading-relaxed text-gray-10 break-words">
Expand All @@ -149,7 +148,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
{props.skill?.trigger?.trim() ? (
<div className="mt-3 inline-flex items-center gap-2 rounded-full border border-gray-6 bg-gray-1 px-3 py-1 text-[11px] text-gray-10">
<span className="font-semibold text-gray-12">
{translate("share_skill_destination.trigger_label")}
{t("share_skill_destination.trigger_label")}
</span>
<span className="font-mono">
{props.skill.trigger.trim()}
Expand All @@ -161,10 +160,10 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
</div>
<div>
<h4 className="text-sm font-medium text-gray-12">
{translate("share_skill_destination.title")}
{t("share_skill_destination.title")}
</h4>
<p className="mt-1 text-sm leading-relaxed text-gray-10">
{translate("share_skill_destination.subtitle")}
{t("share_skill_destination.subtitle")}
</p>
</div>
</div>
Expand All @@ -175,7 +174,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
className={`rounded-full p-2 text-gray-9 transition hover:bg-gray-2 hover:text-gray-12 ${
footerBusy ? "cursor-not-allowed opacity-50" : ""
}`.trim()}
aria-label={translate("common.close")}
aria-label={t("common.close")}
>
<X size={18} />
</button>
Expand All @@ -186,7 +185,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
<div className="space-y-3">
<div className="flex items-center justify-between gap-3">
<div className="text-sm font-medium text-gray-12">
{translate("share_skill_destination.existing_workers")}
{t("share_skill_destination.existing_workers")}
</div>
{props.workspaces.length > 0 ? (
<span className="text-[11px] uppercase tracking-[0.18em] text-gray-9">
Expand All @@ -197,7 +196,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {

{props.workspaces.length === 0 ? (
<div className="rounded-xl border border-dashed border-gray-6 bg-gray-2/20 px-4 py-5 text-sm leading-relaxed text-gray-10">
{translate("share_skill_destination.no_workers")}
{t("share_skill_destination.no_workers")}
</div>
) : (
<div className="space-y-2">
Expand Down Expand Up @@ -240,17 +239,15 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
</div>
{isActive ? (
<span className="rounded-full bg-gray-3 px-2 py-0.5 text-[10px] uppercase tracking-[0.18em] text-gray-11">
{translate("share_skill_destination.current_badge")}
{t("share_skill_destination.current_badge")}
</span>
) : null}
<span className="rounded-full bg-gray-3 px-2 py-0.5 text-[10px] uppercase tracking-[0.18em] text-gray-11">
{workspaceBadge(workspace)}
</span>
{isSelected ? (
<span className="rounded-full bg-indigo-3/60 px-2 py-0.5 text-[10px] uppercase tracking-[0.18em] text-indigo-11">
{translate(
"share_skill_destination.selected_badge",
)}
{t("share_skill_destination.selected_badge")}
</span>
) : null}
</div>
Expand All @@ -260,9 +257,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
</div>
{isSelected ? (
<div className="mt-2 text-xs font-medium text-gray-11">
{translate(
"share_skill_destination.selected_hint",
)}
{t("share_skill_destination.selected_hint")}
</div>
) : null}
</div>
Expand Down Expand Up @@ -290,7 +285,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
{props.onCreateWorker || props.onConnectRemote ? (
<div className="space-y-3 border-t border-gray-6 pt-5">
<div className="text-sm font-medium text-gray-12">
{translate("share_skill_destination.more_options")}
{t("share_skill_destination.more_options")}
</div>
<div className="grid gap-3 md:grid-cols-2">
{props.onCreateWorker ? (
Expand All @@ -308,12 +303,10 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
</div>
<div>
<div className="text-sm font-semibold text-gray-12">
{translate("share_skill_destination.create_worker")}
{t("share_skill_destination.create_worker")}
</div>
<div className="mt-1 text-sm text-gray-10">
{translate(
"share_skill_destination.create_worker_hint",
)}
{t("share_skill_destination.create_worker_hint")}
</div>
</div>
</div>
Expand All @@ -335,12 +328,10 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
</div>
<div>
<div className="text-sm font-semibold text-gray-12">
{translate("share_skill_destination.connect_remote")}
{t("share_skill_destination.connect_remote")}
</div>
<div className="mt-1 text-sm text-gray-10">
{translate(
"share_skill_destination.connect_remote_hint",
)}
{t("share_skill_destination.connect_remote_hint")}
</div>
</div>
</div>
Expand Down Expand Up @@ -371,7 +362,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
onClick={props.onClose}
disabled={footerBusy}
>
{translate("common.cancel")}
{t("common.cancel")}
</Button>
<Button
variant="primary"
Expand All @@ -381,10 +372,10 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
{footerBusy ? (
<span className="inline-flex items-center gap-2">
<Loader2 size={16} className="animate-spin" />
{translate("share_skill_destination.adding")}
{t("share_skill_destination.adding")}
</span>
) : (
translate("share_skill_destination.add_to_workspace")
t("share_skill_destination.add_to_workspace")
)}
</Button>
</div>
Expand Down
Loading
Loading