Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
0b3c4c1
feat(i18n): add Brazilian Portuguese (pt-BR) translation
diegous1 Mar 21, 2026
a57d346
Merge branch 'different-ai:dev' into dev
diegous1 Mar 23, 2026
83542d0
fix: add missing closing quote in LANGUAGES array
diegous1 Mar 23, 2026
45f0b5b
feat(i18n): traduzir strings hardcoded de Settings e Chat para pt-BR
claude Mar 24, 2026
66cee69
i18n: add new translation keys to en.ts for modals, composer, pages
claude Mar 25, 2026
851dfc5
i18n: add pt-BR translations for all new keys (phase 2)
claude Mar 25, 2026
322ca34
i18n: replace hardcoded strings in create-workspace-modal and questio…
claude Mar 25, 2026
47a76d6
i18n: replace hardcoded strings in mcp-auth, model-picker, provider-a…
claude Mar 25, 2026
3c2532e
i18n: replace hardcoded strings in provider-auth-modal and share-work…
claude Mar 25, 2026
067a101
i18n: additional string replacements in share-workspace-modal, compos…
claude Mar 25, 2026
8c19e75
i18n: replace hardcoded strings in mobile-sidebar-drawer, composer, s…
claude Mar 25, 2026
15a5ab4
i18n: replace hardcoded strings in composer, share-workspace-modal, d…
claude Mar 25, 2026
ea4b5cc
i18n: final string fixes in composer and share-workspace-modal
claude Mar 25, 2026
b137615
Merge pull request #4 from diegous1/claude/openwork-translation-plan-…
diegous1 Mar 30, 2026
e4c6153
Merge remote-tracking branch 'upstream/dev' into dev
diegous1 Mar 30, 2026
e5b2d5d
chore(deps): bump the npm_and_yarn group across 3 directories with 2 …
dependabot[bot] Mar 30, 2026
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
164 changes: 123 additions & 41 deletions apps/app/src/app/components/den-settings-panel.tsx

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions apps/app/src/app/components/mcp-auth-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
statusPoll = window.setInterval(async () => {
if (Date.now() - startedAt >= MCP_AUTH_TIMEOUT_MS) {
stopStatusPolling();
setError("Request timed out.");
setError(translate("mcp.request_timed_out"));
return;
}

Expand Down Expand Up @@ -589,7 +589,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
setStatusChecking(false);
};

const serverName = () => props.entry?.name ?? "MCP Server";
const serverName = () => props.entry?.name ?? translate("mcp.server_fallback");

return (
<Show when={props.open}>
Expand Down Expand Up @@ -694,7 +694,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
<CheckCircle2 size={24} class="text-green-11" />
</div>
<div>
<p class="text-sm font-medium text-gray-12">Already Connected</p>
<p class="text-sm font-medium text-gray-12">{translate("mcp.already_connected")}</p>
<p class="text-xs text-gray-11">
{translate("mcp.auth.already_connected_description", { server: serverName() })}
</p>
Expand Down Expand Up @@ -804,7 +804,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
</div>
<div class="rounded-xl border border-gray-6/70 bg-gray-2/40 px-3 py-2 flex items-center gap-3">
<div class="flex-1 min-w-0">
<div class="text-[10px] uppercase tracking-wide text-gray-8">Authorization link</div>
<div class="text-[10px] uppercase tracking-wide text-gray-8">{translate("mcp.auth_link_label")}</div>
<div class="text-[11px] text-gray-11 font-mono truncate">
{authorizationUrl()}
</div>
Expand All @@ -814,7 +814,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
class="text-xs"
onClick={handleCopyAuthorizationUrl}
>
{authUrlCopied() ? "Copied" : "Copy link"}
{authUrlCopied() ? translate("mcp.copied") : translate("mcp.copy_link")}
</Button>
</div>
<TextInput
Expand Down Expand Up @@ -851,7 +851,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
1
</div>
<div>
<p class="text-sm font-medium text-gray-12">Opening your browser</p>
<p class="text-sm font-medium text-gray-12">{translate("mcp.step_opening_browser")}</p>
<p class="text-xs text-gray-10 mt-1">
{translate("mcp.auth.step1_description", { server: serverName() })}
</p>
Expand All @@ -863,7 +863,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
2
</div>
<div>
<p class="text-sm font-medium text-gray-12">Authorize OpenWork</p>
<p class="text-sm font-medium text-gray-12">{translate("mcp.step_authorize")}</p>
<p class="text-xs text-gray-10 mt-1">
{translate("mcp.auth.step2_description")}
</p>
Expand All @@ -875,7 +875,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
3
</div>
<div>
<p class="text-sm font-medium text-gray-12">Return here when you're done</p>
<p class="text-sm font-medium text-gray-12">{translate("mcp.step_return")}</p>
<p class="text-xs text-gray-10 mt-1">
{translate("mcp.auth.step3_description")}
</p>
Expand Down
4 changes: 3 additions & 1 deletion apps/app/src/app/components/mobile-sidebar-drawer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Show, createEffect, onCleanup } from "solid-js";
import type { JSX } from "solid-js";
import { t, currentLocale } from "../../i18n";

type MobileSidebarDrawerProps = {
open: boolean;
Expand All @@ -8,6 +9,7 @@ type MobileSidebarDrawerProps = {
};

export default function MobileSidebarDrawer(props: MobileSidebarDrawerProps) {
const translate = (key: string) => t(key, currentLocale());
createEffect(() => {
if (!props.open || typeof window === "undefined" || typeof document === "undefined") return;

Expand Down Expand Up @@ -35,7 +37,7 @@ export default function MobileSidebarDrawer(props: MobileSidebarDrawerProps) {
type="button"
class="absolute inset-0 bg-gray-1/60 backdrop-blur-sm"
onClick={props.onClose}
aria-label="Close sidebar"
aria-label={translate("session.close_sidebar")}
/>
<div class="absolute inset-y-0 right-0 w-[min(360px,calc(100vw-20px))] max-w-full border-l border-dls-border bg-dls-sidebar p-3 shadow-2xl">
{props.children}
Expand Down
19 changes: 12 additions & 7 deletions apps/app/src/app/components/model-picker-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,9 @@ export default function ModelPickerModal(props: ModelPickerModalProps) {
<span class="truncate">{provider.title}</span>
</div>
<div class={`mt-0.5 flex items-center gap-3 text-[11px] ${index === activeIndex() ? 'text-gray-10' : 'text-gray-9 group-hover:text-gray-10'}`}>
<span class="truncate">Connect this provider to browse and save models</span>
<span class="truncate">{translate("model_picker.connect_provider")}</span>
<span class="ml-auto opacity-70">
{provider.matchCount} {provider.matchCount === 1 ? "model" : "models"}
{provider.matchCount} {provider.matchCount === 1 ? translate("model_picker.model_singular") : translate("model_picker.model_plural")}
</span>
</div>
</div>
Expand All @@ -324,12 +324,17 @@ export default function ModelPickerModal(props: ModelPickerModalProps) {
<div class="flex items-start justify-between gap-4">
<div>
<h3 class="text-lg font-semibold text-gray-12">
{props.target === "default" ? "Default model" : "Chat model"}
{props.target === "default" ? translate("model_picker.default_label") : translate("model_picker.chat_label")}
</h3>
<p class="text-sm text-gray-11 mt-1">
{props.target === "default"
<<<<<<< HEAD
? translate("model_picker.default_desc")
: translate("model_picker.chat_desc")}
=======
? "Choose the default model for new chats, then fine-tune reasoning profiles on its card before pressing Done."
: "Choose the model for this chat. If a model supports reasoning profiles, configure them on its card."}
>>>>>>> upstream/dev
</p>
</div>
<Button
Expand Down Expand Up @@ -364,7 +369,7 @@ export default function ModelPickerModal(props: ModelPickerModalProps) {
<Show when={recommendedOptions().length > 0}>
<section class="space-y-2">
<div class="px-1 text-[11px] font-semibold uppercase tracking-[0.12em] text-gray-9">
Recommended
{translate("model_picker.recommended")}
</div>
<For each={recommendedOptions()}>{({ opt, index }) => renderOption(opt, index)}</For>
</section>
Expand All @@ -373,7 +378,7 @@ export default function ModelPickerModal(props: ModelPickerModalProps) {
<Show when={otherEnabledOptions().length > 0}>
<section class="space-y-2">
<div class="px-1 text-[11px] font-semibold uppercase tracking-[0.12em] text-gray-9">
Other connected models
{translate("model_picker.other_connected")}
</div>
<For each={otherEnabledOptions()}>{({ opt, index }) => renderOption(opt, index)}</For>
</section>
Expand All @@ -382,7 +387,7 @@ export default function ModelPickerModal(props: ModelPickerModalProps) {
<Show when={otherOptions().length > 0}>
<section class="space-y-2">
<div class="px-1 text-[11px] font-semibold uppercase tracking-[0.12em] text-gray-9">
More providers
{translate("model_picker.more_providers")}
</div>
<For each={otherOptions()}>
{(provider) => renderProviderLink(provider, provider.index)}
Expand All @@ -392,7 +397,7 @@ export default function ModelPickerModal(props: ModelPickerModalProps) {

<Show when={renderedItems().length === 0}>
<div class="rounded-2xl border border-gray-6/70 bg-gray-1/40 px-4 py-6 text-sm text-gray-10">
No models match your search.
{translate("model_picker.no_match")}
</div>
</Show>
</div>
Expand Down
14 changes: 8 additions & 6 deletions apps/app/src/app/components/question-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { createEffect, createMemo, createSignal, For, onCleanup, Show } from "so
import type { QuestionInfo } from "@opencode-ai/sdk/v2/client";

import { Check, ChevronRight, HelpCircle } from "lucide-solid";
import { t, currentLocale } from "../../i18n";

import Button from "./button";

Expand All @@ -14,6 +15,7 @@ export type QuestionModalProps = {
};

export default function QuestionModal(props: QuestionModalProps) {
const translate = (key: string) => t(key, currentLocale());
const [currentIndex, setCurrentIndex] = createSignal(0);
const [answers, setAnswers] = createSignal<string[][]>([]);
const [currentSelection, setCurrentSelection] = createSignal<string[]>([]);
Expand Down Expand Up @@ -138,7 +140,7 @@ export default function QuestionModal(props: QuestionModalProps) {
</div>
<div>
<h3 class="text-lg font-semibold text-gray-12">
{currentQuestion()!.header || "Question"}
{currentQuestion()!.header || translate("question.fallback_header")}
</h3>
<div class="text-xs text-gray-11 font-medium">
Question {currentIndex() + 1} of {props.questions.length}
Expand Down Expand Up @@ -186,14 +188,14 @@ export default function QuestionModal(props: QuestionModalProps) {
<Show when={currentQuestion()!.custom}>
<div class="mt-4 pt-4 border-t border-dls-border">
<label class="block text-xs font-semibold text-dls-secondary mb-2 uppercase tracking-wide">
Or type a custom answer
{translate("question.custom_answer_label")}
</label>
<input
type="text"
value={customInput()}
onInput={(e) => setCustomInput(e.currentTarget.value)}
class="w-full px-4 py-3 rounded-xl bg-dls-surface border border-dls-border focus:border-dls-accent focus:ring-4 focus:ring-[rgba(var(--dls-accent-rgb),0.2)] focus:outline-none text-sm text-dls-text placeholder:text-dls-secondary transition-shadow"
placeholder="Type your answer here..."
placeholder={translate("question.placeholder")}
onKeyDown={(e) => {
if (e.key === "Enter") {
if (e.isComposing || e.keyCode === 229) return;
Expand All @@ -209,15 +211,15 @@ export default function QuestionModal(props: QuestionModalProps) {
<div class="p-6 border-t border-dls-border bg-dls-hover flex justify-between items-center">
<div class="text-xs text-dls-secondary flex items-center gap-2">
<span class="px-1.5 py-0.5 rounded border border-dls-border bg-dls-active font-mono">↑↓</span>
<span>navigate</span>
<span>{translate("question.navigate_hint")}</span>
<span class="px-1.5 py-0.5 rounded border border-gray-6 bg-gray-3 font-mono ml-2">↵</span>
<span>select</span>
<span>{translate("question.select_hint")}</span>
</div>

<div class="flex gap-2">
<Show when={currentQuestion()?.multiple || currentQuestion()?.custom}>
<Button onClick={handleNext} disabled={!canProceed() || props.busy} class="!px-6">
{isLastQuestion() ? "Submit" : "Next"}
{isLastQuestion() ? translate("question.submit") : translate("question.next")}
<Show when={!isLastQuestion()}>
<ChevronRight size={16} class="ml-1 -mr-1 opacity-60" />
</Show>
Expand Down
Loading
Loading