Skip to content
Open
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
76 changes: 62 additions & 14 deletions apps/mobile/src/features/threads/PendingUserInputCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ApprovalRequestId, UserInputQuestion } from "@t3tools/contracts";
import { useCallback, useRef } from "react";
import { useMemo, useCallback, useRef } from "react";
import { Platform, Pressable, ScrollView, View, type LayoutChangeEvent } from "react-native";
import Animated, {
Easing,
Expand All @@ -11,6 +11,7 @@ import Animated, {
withTiming,
type SharedValue,
} from "react-native-reanimated";
import { Markdown, type PartialMarkdownTheme } from "react-native-nitro-markdown";

import { USER_INPUT_TOGGLE_DURATION_MS } from "./pendingUserInputLayout";

Expand All @@ -19,6 +20,12 @@ import { AppText as Text, AppTextInput as TextInput } from "../../components/App
import { ControlPill } from "../../components/ControlPill";
import { cn } from "../../lib/cn";
import { useThemeColor } from "../../lib/useThemeColor";
import { useFontFamily } from "../../lib/useFontFamily";
import {
resolveMarkdownFontSizes,
resolveNativeMarkdownTypography,
} from "../../lib/appearancePreferences";
import { useAppearancePreferences } from "../settings/appearance/AppearancePreferencesProvider";
import {
isPendingUserInputOptionSelected,
type PendingUserInput,
Expand Down Expand Up @@ -90,6 +97,54 @@ export function PendingUserInputCard(props: PendingUserInputCardProps) {
const iconSubtle = useThemeColor("--color-icon-subtle");
const questionCount = props.pendingUserInput.questions.length;

const { appearance } = useAppearancePreferences();
const markdownFontSizes = useMemo(
() => resolveMarkdownFontSizes(appearance.baseFontSize),
[appearance.baseFontSize],
);
const regularFontFamily = useFontFamily("regular");
const boldFontFamily = useFontFamily("bold");
const markdownBodyColor = String(useThemeColor("--color-md-body"));
const markdownStrongColor = String(useThemeColor("--color-md-strong"));
const markdownLinkColor = String(useThemeColor("--color-md-link"));
const inlineMarkdownTheme = useMemo<PartialMarkdownTheme>(
() => ({
colors: {
text: markdownBodyColor,
heading: markdownStrongColor,
link: markdownLinkColor,
surface: "transparent",
},
spacing: { xs: 0, s: 0, m: 0, l: 0, xl: 0 },
fontSizes: {
s: markdownFontSizes.s,
m: markdownFontSizes.m,
h1: markdownFontSizes.h1,
h2: markdownFontSizes.h2,
h3: markdownFontSizes.h3,
h4: markdownFontSizes.h4,
h5: markdownFontSizes.h5,
h6: markdownFontSizes.h6,
},
fontFamilies: {
regular: regularFontFamily,
heading: boldFontFamily,
mono: regularFontFamily,
},
headingWeight: "700",
borderRadius: { s: 4, m: 8, l: 12 },
showCodeLanguage: false,
}),
[
markdownBodyColor,
markdownStrongColor,
markdownLinkColor,
markdownFontSizes,
regularFontFamily,
boldFontFamily,
],
);

const cardCoverage = props.cardCoverage;
const barHeightRef = useRef(0);
const cardHeightRef = useRef(0);
Expand Down Expand Up @@ -254,9 +309,9 @@ export function PendingUserInputCard(props: PendingUserInputCardProps) {
<Text className="font-t3-bold text-xs uppercase tracking-[1px] text-neutral-500 dark:text-neutral-500">
{question.header}
</Text>
<Text className="font-sans text-base leading-snug text-neutral-950 dark:text-neutral-50">
<Markdown theme={inlineMarkdownTheme}>
{question.question}
</Text>
</Markdown>
Comment on lines +312 to +314

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve angle-bracket placeholders when rendering Markdown

When a provider asks a question containing a placeholder such as Choose the <branch-name> to deploy, the Markdown parser classifies <branch-name> as html_inline, but the library's default renderer does not render HTML nodes. The placeholder therefore disappears from the question; the same regression affects the newly wrapped option labels and descriptions. Add HTML-node handling that preserves or normalizes their text instead of relying on the default renderer.

Useful? React with 👍 / 👎.

<View className="gap-2">
{question.options.map((option) => {
const selected = isPendingUserInputOptionSelected(draft, option.label);
Expand All @@ -280,20 +335,13 @@ export function PendingUserInputCard(props: PendingUserInputCardProps) {
}
>
<View className="min-w-0 flex-1 gap-0.5">
<Text
className={cn(
"font-t3-bold text-sm",
selected
? "text-sky-700 dark:text-sky-300"
: "text-neutral-700 dark:text-neutral-200",
)}
>
<Markdown theme={inlineMarkdownTheme}>
{option.label}
</Text>
</Markdown>
{description ? (
<Text className="font-sans text-sm leading-5 text-neutral-500 dark:text-neutral-400">
<Markdown theme={inlineMarkdownTheme}>
{description}
</Text>
</Markdown>
) : null}
</View>
</Pressable>
Expand Down
Loading