mirror of
https://github.com/stablyai/orca.git
synced 2026-11-02 18:17:36 +00:00
feat(mobile): copy button on each code block in chat (#34039)
Co-authored-by: Radu Toader <radu.m.toader@gmail.com>
This commit is contained in:
co-authored by
Radu Toader
parent
2dd8207369
commit
c4f8fe5f3c
@@ -15,6 +15,7 @@ vi.mock('react-native', () => ({
|
||||
View: 'View'
|
||||
}))
|
||||
vi.mock('./pr-sidebar/MermaidDiagram', () => ({ MermaidDiagram: 'MermaidDiagram' }))
|
||||
vi.mock('./MobileSourceCopyButton', () => ({ MobileSourceCopyButton: 'MobileSourceCopyButton' }))
|
||||
|
||||
function flattenText(node: ReactTestInstance): string {
|
||||
return node.children
|
||||
|
||||
@@ -16,6 +16,7 @@ vi.mock('react-native', () => ({
|
||||
View: 'View'
|
||||
}))
|
||||
vi.mock('./pr-sidebar/MermaidDiagram', () => ({ MermaidDiagram: 'MermaidDiagram' }))
|
||||
vi.mock('./MobileSourceCopyButton', () => ({ MobileSourceCopyButton: 'MobileSourceCopyButton' }))
|
||||
|
||||
let renderer: ReactTestRenderer | null = null
|
||||
|
||||
@@ -127,6 +128,12 @@ describe('MobileMarkdown rendering', () => {
|
||||
expect(texts(render(content))).toEqual(expected)
|
||||
})
|
||||
|
||||
it('gives each code block its own copy button holding only that code', () => {
|
||||
const tree = render('Run this:\n\n```sh\npnpm test\n```\n\nthen:\n\n```\nexit\n```')
|
||||
const buttons = tree.root.findAll((node) => String(node.type) === 'MobileSourceCopyButton')
|
||||
expect(buttons.map((button) => button.props.text)).toEqual(['pnpm test', 'exit'])
|
||||
})
|
||||
|
||||
it('C12: opens a link with brackets in it, and one with a title, at their own address', () => {
|
||||
const tree = render(
|
||||
'[wiki](https://en.wikipedia.org/wiki/Foo_(bar)) and [docs](https://x.com/a "The docs")'
|
||||
|
||||
@@ -15,6 +15,7 @@ vi.mock('react-native', () => ({
|
||||
}))
|
||||
|
||||
vi.mock('./pr-sidebar/MermaidDiagram', () => ({ MermaidDiagram: 'MermaidDiagram' }))
|
||||
vi.mock('./MobileSourceCopyButton', () => ({ MobileSourceCopyButton: 'MobileSourceCopyButton' }))
|
||||
|
||||
const CONTENT = [
|
||||
'# Heading',
|
||||
|
||||
@@ -21,6 +21,7 @@ import { MARKDOWN_TONES, scaledMarkdownText, styles } from './mobile-markdown-st
|
||||
import { MarkdownText } from './mobile-markdown-text'
|
||||
import { codeFenceClosed, plainText } from './mobile-markdown-tree'
|
||||
import { MermaidDiagram } from './pr-sidebar/MermaidDiagram'
|
||||
import { MobileSourceCopyButton } from './MobileSourceCopyButton'
|
||||
|
||||
/** Prose base size — passed to MermaidDiagram fallback mono text. */
|
||||
const MERMAID_BASE = 13
|
||||
@@ -54,13 +55,18 @@ function renderCode(node: Code, key: number, ctx: MarkdownBlockContext): ReactNo
|
||||
}
|
||||
return (
|
||||
<View key={key} style={styles.codeBlock}>
|
||||
{node.lang ? <NativeText style={styles.codeLanguage}>{node.lang}</NativeText> : null}
|
||||
<MarkdownText
|
||||
selectable
|
||||
style={[styles.codeText, scaledMarkdownText(styles.codeText, ctx.textScale)]}
|
||||
>
|
||||
{node.value}
|
||||
</MarkdownText>
|
||||
<View style={styles.codeBody}>
|
||||
{node.lang ? <NativeText style={styles.codeLanguage}>{node.lang}</NativeText> : null}
|
||||
<MarkdownText
|
||||
selectable
|
||||
style={[styles.codeText, scaledMarkdownText(styles.codeText, ctx.textScale)]}
|
||||
>
|
||||
{node.value}
|
||||
</MarkdownText>
|
||||
</View>
|
||||
{node.value ? (
|
||||
<MobileSourceCopyButton text={node.value} accessibilityLabel="Copy code" />
|
||||
) : null}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ vi.mock('react-native', () => ({
|
||||
View: 'View'
|
||||
}))
|
||||
vi.mock('./pr-sidebar/MermaidDiagram', () => ({ MermaidDiagram: 'MermaidDiagram' }))
|
||||
vi.mock('./MobileSourceCopyButton', () => ({ MobileSourceCopyButton: 'MobileSourceCopyButton' }))
|
||||
|
||||
let renderer: ReactTestRenderer | undefined
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ vi.mock('react-native', () => ({
|
||||
}))
|
||||
|
||||
vi.mock('./pr-sidebar/MermaidDiagram', () => ({ MermaidDiagram: 'MermaidDiagram' }))
|
||||
vi.mock('./MobileSourceCopyButton', () => ({ MobileSourceCopyButton: 'MobileSourceCopyButton' }))
|
||||
|
||||
type TestNode = {
|
||||
type: string
|
||||
|
||||
@@ -62,8 +62,12 @@ export const styles = StyleSheet.create({
|
||||
borderWidth: 1,
|
||||
borderColor: colors.borderSubtle,
|
||||
borderRadius: radii.input,
|
||||
padding: spacing.sm
|
||||
padding: spacing.sm,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
gap: spacing.xs
|
||||
},
|
||||
codeBody: { flex: 1 },
|
||||
codeLanguage: {
|
||||
fontSize: 10,
|
||||
color: colors.textMuted,
|
||||
|
||||
@@ -15,6 +15,7 @@ vi.mock('react-native', () => ({
|
||||
}))
|
||||
|
||||
vi.mock('./pr-sidebar/MermaidDiagram', () => ({ MermaidDiagram: 'MermaidDiagram' }))
|
||||
vi.mock('./MobileSourceCopyButton', () => ({ MobileSourceCopyButton: 'MobileSourceCopyButton' }))
|
||||
|
||||
/** Each rendered table row's cell styles, header row first. */
|
||||
function renderTableCellStyles(content: string): unknown[][] {
|
||||
|
||||
Reference in New Issue
Block a user