mirror of https://github.com/buster-so/buster.git
better pill handling
This commit is contained in:
parent
b850a85199
commit
e653d3953b
|
@ -38,6 +38,11 @@ const pillVariants = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const pillPadding = 8; // 4px left + 4px right
|
||||||
|
const pillMargin = 6; // 1.5 * 4 for gap
|
||||||
|
const pillBorder = 1; // 0.5px * 2
|
||||||
|
const font = '11px -apple-system, BlinkMacSystemFont, sans-serif'; // Match your app's font
|
||||||
|
|
||||||
export const PillContainer: React.FC<{
|
export const PillContainer: React.FC<{
|
||||||
pills: BusterChatMessage_thought['thought_pills'];
|
pills: BusterChatMessage_thought['thought_pills'];
|
||||||
isCompletedStream: boolean;
|
isCompletedStream: boolean;
|
||||||
|
@ -49,10 +54,9 @@ export const PillContainer: React.FC<{
|
||||||
const [hasDoneInitialAnimation, setHasDoneInitialAnimation] = useState(false);
|
const [hasDoneInitialAnimation, setHasDoneInitialAnimation] = useState(false);
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const useAnimation = !hasDoneInitialAnimation && !isCompletedStream;
|
const useAnimation = !hasDoneInitialAnimation && !isCompletedStream;
|
||||||
const chatContentWidth = useChatLayoutContextSelector((x) => x.chatContentWidth);
|
|
||||||
|
|
||||||
const size = useSize(containerRef);
|
const size = useSize(containerRef);
|
||||||
const thoughtContainerWidth = size?.width || chatContentWidth - 85;
|
const thoughtContainerWidth = size?.width;
|
||||||
const debouncedWidth = useDebounce(thoughtContainerWidth, {
|
const debouncedWidth = useDebounce(thoughtContainerWidth, {
|
||||||
wait: 150,
|
wait: 150,
|
||||||
leading: true
|
leading: true
|
||||||
|
@ -68,23 +72,19 @@ export const PillContainer: React.FC<{
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
const moreTextWidth = useMemo(() => {
|
||||||
if (!pills) return;
|
return calculateTextWidth('+99 more', font) + pillPadding + pillBorder;
|
||||||
|
}, [font]);
|
||||||
|
|
||||||
const containerWidth = containerRef.current?.offsetWidth || thoughtContainerWidth;
|
useLayoutEffect(() => {
|
||||||
console.log(containerWidth, thoughtContainerWidth, chatContentWidth);
|
if (!pills || !containerRef.current) return;
|
||||||
const pillPadding = 8; // 4px left + 4px right
|
|
||||||
const pillMargin = 6; // 1.5 * 4 for gap
|
const containerWidth = thoughtContainerWidth || 240;
|
||||||
const pillBorder = 1; // 0.5px * 2
|
|
||||||
const font = '11px -apple-system, BlinkMacSystemFont, sans-serif'; // Match your app's font
|
|
||||||
|
|
||||||
let currentLineWidth = 0;
|
let currentLineWidth = 0;
|
||||||
const visible: BusterChatMessage_thoughtPill[] = [];
|
const visible: BusterChatMessage_thoughtPill[] = [];
|
||||||
let hidden = 0;
|
let hidden = 0;
|
||||||
|
|
||||||
// Calculate width needed for "+X more" pill
|
|
||||||
const moreTextWidth = calculateTextWidth('+99 more', font) + pillPadding + pillBorder;
|
|
||||||
|
|
||||||
for (let i = 0; i < pills.length; i++) {
|
for (let i = 0; i < pills.length; i++) {
|
||||||
const pill = pills[i];
|
const pill = pills[i];
|
||||||
const textWidth = calculateTextWidth(pill.text, font);
|
const textWidth = calculateTextWidth(pill.text, font);
|
||||||
|
@ -117,9 +117,7 @@ export const PillContainer: React.FC<{
|
||||||
variants={containerVariants}
|
variants={containerVariants}
|
||||||
initial="hidden"
|
initial="hidden"
|
||||||
animate={pills.length > 0 ? 'visible' : 'hidden'}
|
animate={pills.length > 0 ? 'visible' : 'hidden'}
|
||||||
className={cx(
|
className={cx('flex w-full flex-wrap flex-nowrap gap-1.5 overflow-hidden')}>
|
||||||
'flex w-full flex-wrap flex-nowrap gap-1.5 overflow-hidden border border-red-500'
|
|
||||||
)}>
|
|
||||||
{visiblePills.map((pill) => (
|
{visiblePills.map((pill) => (
|
||||||
<Pill key={pill.id} useAnimation={useAnimation} {...pill} onClick={undefined} />
|
<Pill key={pill.id} useAnimation={useAnimation} {...pill} onClick={undefined} />
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -30,10 +30,8 @@ export const useChatLayout = ({
|
||||||
}: UseChatSplitterProps) => {
|
}: UseChatSplitterProps) => {
|
||||||
const [isPending, startTransition] = useTransition();
|
const [isPending, startTransition] = useTransition();
|
||||||
const onChangePage = useAppLayoutContextSelector((state) => state.onChangePage);
|
const onChangePage = useAppLayoutContextSelector((state) => state.onChangePage);
|
||||||
const chatContentSize = useSize(chatContentRef);
|
|
||||||
const selectedLayout = defaultSelectedLayout;
|
|
||||||
|
|
||||||
const chatContentWidth = chatContentSize?.width || 325;
|
const selectedLayout = defaultSelectedLayout;
|
||||||
|
|
||||||
const animateOpenSplitter = useMemoizedFn((side: 'left' | 'right' | 'both') => {
|
const animateOpenSplitter = useMemoizedFn((side: 'left' | 'right' | 'both') => {
|
||||||
if (appSplitterRef.current) {
|
if (appSplitterRef.current) {
|
||||||
|
@ -84,7 +82,6 @@ export const useChatLayout = ({
|
||||||
selectedLayout,
|
selectedLayout,
|
||||||
isPureFile,
|
isPureFile,
|
||||||
isPureChat,
|
isPureChat,
|
||||||
chatContentWidth,
|
|
||||||
onSetSelectedFile,
|
onSetSelectedFile,
|
||||||
onCollapseFileClick,
|
onCollapseFileClick,
|
||||||
animateOpenSplitter
|
animateOpenSplitter
|
||||||
|
|
|
@ -71,8 +71,8 @@ export const MOCK_CHAT: BusterChat = {
|
||||||
response_messages: [
|
response_messages: [
|
||||||
createMockResponseMessageText(),
|
createMockResponseMessageText(),
|
||||||
createMockResponseMessageThought(),
|
createMockResponseMessageThought(),
|
||||||
createMockResponseMessageThought(),
|
// createMockResponseMessageThought(),
|
||||||
createMockResponseMessageThought(),
|
// createMockResponseMessageThought(),
|
||||||
// createMockResponseMessageThought(),
|
// createMockResponseMessageThought(),
|
||||||
createMockResponseMessageFile(),
|
createMockResponseMessageFile(),
|
||||||
createMockResponseMessageFile()
|
createMockResponseMessageFile()
|
||||||
|
|
Loading…
Reference in New Issue