Download src/components/LogoV2/Feed.tsx from chenbhao/codev: direct link, hf CLI and curl.
- Browser
- Download file 3.02 kB
-
https://huggingface.co/chenbhao/codev/resolve/main/src/components/LogoV2/Feed.tsx
- Command line
-
hf download hf://chenbhao/codev/src/components/LogoV2/Feed.tsx
-
curl -L -o Feed.tsx https://huggingface.co/chenbhao/codev/resolve/main/src/components/LogoV2/Feed.tsx
3.02 kB
| import * as React from 'react' | |
| import { stringWidth } from '../../ink/stringWidth.js' | |
| import { Box, Text } from '../../ink.js' | |
| import { truncate } from '../../utils/format.js' | |
| export type FeedLine = { | |
| text: string | |
| timestamp?: string | |
| } | |
| export type FeedConfig = { | |
| title: string | |
| lines: FeedLine[] | |
| footer?: string | |
| emptyMessage?: string | |
| customContent?: { content: React.ReactNode; width: number } | |
| } | |
| type FeedProps = { | |
| config: FeedConfig | |
| actualWidth: number | |
| } | |
| export function calculateFeedWidth(config: FeedConfig): number { | |
| const { title, lines, footer, emptyMessage, customContent } = config | |
| let maxWidth = stringWidth(title) | |
| if (customContent !== undefined) { | |
| maxWidth = Math.max(maxWidth, customContent.width) | |
| } else if (lines.length === 0 && emptyMessage) { | |
| maxWidth = Math.max(maxWidth, stringWidth(emptyMessage)) | |
| } else { | |
| const gap = ' ' | |
| const maxTimestampWidth = Math.max( | |
| 0, | |
| ...lines.map(line => (line.timestamp ? stringWidth(line.timestamp) : 0)), | |
| ) | |
| for (const line of lines) { | |
| const timestampWidth = maxTimestampWidth > 0 ? maxTimestampWidth : 0 | |
| const lineWidth = | |
| stringWidth(line.text) + | |
| (timestampWidth > 0 ? timestampWidth + gap.length : 0) | |
| maxWidth = Math.max(maxWidth, lineWidth) | |
| } | |
| } | |
| if (footer) { | |
| maxWidth = Math.max(maxWidth, stringWidth(footer)) | |
| } | |
| return maxWidth | |
| } | |
| export function Feed({ config, actualWidth }: FeedProps): React.ReactNode { | |
| const { title, lines, footer, emptyMessage, customContent } = config | |
| const gap = ' ' | |
| const maxTimestampWidth = Math.max( | |
| 0, | |
| ...lines.map(line => (line.timestamp ? stringWidth(line.timestamp) : 0)), | |
| ) | |
| return ( | |
| <Box flexDirection="column" width={actualWidth}> | |
| <Text bold color="clawd_body"> | |
| {title} | |
| </Text> | |
| {customContent ? ( | |
| <> | |
| {customContent.content} | |
| {footer && ( | |
| <Text dimColor italic> | |
| {truncate(footer, actualWidth)} | |
| </Text> | |
| )} | |
| </> | |
| ) : lines.length === 0 && emptyMessage ? ( | |
| <Text dimColor>{truncate(emptyMessage, actualWidth)}</Text> | |
| ) : ( | |
| <> | |
| {lines.map((line, index) => { | |
| const textWidth = Math.max( | |
| 10, | |
| actualWidth - | |
| (maxTimestampWidth > 0 ? maxTimestampWidth + gap.length : 0), | |
| ) | |
| return ( | |
| <Text key={index}> | |
| {maxTimestampWidth > 0 && ( | |
| <> | |
| <Text dimColor> | |
| {(line.timestamp || '').padEnd(maxTimestampWidth)} | |
| </Text> | |
| {gap} | |
| </> | |
| )} | |
| <Text>{truncate(line.text, textWidth)}</Text> | |
| </Text> | |
| ) | |
| })} | |
| {footer && ( | |
| <Text dimColor italic> | |
| {truncate(footer, actualWidth)} | |
| </Text> | |
| )} | |
| </> | |
| )} | |
| </Box> | |
| ) | |
| } | |