Skip to content
Closed
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
13 changes: 12 additions & 1 deletion packages/app/src/components/prompt-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,16 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
const inset = 56
const space = `${inset}px`

const isRtl = createMemo(() => {
if (typeof window === "undefined" || !(window as any).api) return false
const text = prompt
.current()
.map((part) => ("content" in part ? part.content : ""))
.join("")
const rtlRegex = /[\u0590-\u05FF\u0600-\u06FF\u0700-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/
return rtlRegex.test(text)
})

const scrollCursorIntoView = () => {
const container = scrollRef
const selection = window.getSelection()
Expand Down Expand Up @@ -1608,6 +1618,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
"[&_[data-type=agent]]:text-syntax-type": true,
"font-mono!": store.mode === "shell",
}}
style={isRtl() ? { direction: "rtl", "text-align": "right" } : undefined}
/>
<div
data-component={newSession() ? "session-new-design-text" : "session-composer-text"}
Expand Down Expand Up @@ -1811,7 +1822,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
"[&_[data-type=agent]]:text-syntax-type": true,
"font-mono!": store.mode === "shell",
}}
style={{ "padding-bottom": space }}
style={isRtl() ? { direction: "rtl", "text-align": "right", "padding-bottom": space } : { "padding-bottom": space }}
/>
<div
class="absolute top-0 inset-x-0 pl-3 pr-2 pt-2 text-14-regular text-text-weak pointer-events-none whitespace-nowrap truncate"
Expand Down
12 changes: 12 additions & 0 deletions packages/session-ui/src/components/markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,18 @@ function decorate(root: HTMLDivElement, labels: CopyLabels) {
for (const block of blocks) {
ensureCodeWrapper(block, labels)
}

if (typeof window !== "undefined" && (window as any).api) {
const rtlRegex = /[\u0590-\u05FF\u0600-\u06FF\u0700-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/
const elements = root.querySelectorAll("p, td, th, li, h1, h2, h3, h4, h5, h6")
for (const el of Array.from(elements)) {
if (el instanceof HTMLElement && rtlRegex.test(el.textContent ?? "")) {
el.style.direction = "rtl"
el.style.textAlign = "right"
}
}
}

if (!document.body.hasAttribute("data-new-layout")) return
markInlineCode(root)
markCodeLinks(root)
Expand Down
22 changes: 20 additions & 2 deletions packages/session-ui/src/components/message-part.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2550,8 +2550,26 @@ ToolRegistry.register({
const answer = () => answers()[i()] ?? []
return (
<div data-slot="question-answer-item">
<div data-slot="question-text">{q.question}</div>
<div data-slot="answer-text">{answer().join(", ") || i18n.t("ui.question.answer.none")}</div>
<div
data-slot="question-text"
style={
typeof window !== "undefined" && (window as any).api && /[\u0590-\u05FF\u0600-\u06FF\u0700-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/.test(q.question)
? { direction: "rtl", "text-align": "right" }
: undefined
}
>
{q.question}
</div>
<div
data-slot="answer-text"
style={
typeof window !== "undefined" && (window as any).api && /[\u0590-\u05FF\u0600-\u06FF\u0700-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/.test(answer().join(", "))
? { direction: "rtl", "text-align": "right" }
: undefined
}
>
{answer().join(", ") || i18n.t("ui.question.answer.none")}
</div>
</div>
)
}}
Expand Down
Loading