Skip to content

Commit

Permalink
feat: add slider for mobile lifeis app
Browse files Browse the repository at this point in the history
  • Loading branch information
aliakseikrauchanka committed Nov 13, 2024
1 parent 08ace1e commit b2b7480
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 3 deletions.
35 changes: 33 additions & 2 deletions apps/entry-app/src/app/components/agents/agent/agent.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,49 @@
display: flex;
min-width: 300px;
min-height: 200px;
padding: 5px;
margin: 5px;

&-minimized {
min-height: 100px;
min-height: 120px;
}
}

&-input {
flex: 1;
padding: 0 4px;

min-height: 200px;
&-minimized {
min-height: 120px;
}

&-resizer {
width: calc(100% - 30px);
height: 20px;
background: #f0f0f0;
position: absolute;
bottom: 0;
left: 0;
cursor: ns-resize;
touch-action: none; /* Prevent default touch actions */

&-active {
background: #e0e0e0;
}

&::before {
content: '';
display: block;
width: 40px;
height: 5px;
margin: 7px auto;
background: #999;
border-radius: 5px;
}
}
}


&-history-navigation {
width: 30px;

Expand Down
74 changes: 73 additions & 1 deletion apps/entry-app/src/app/components/agents/agent/agent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import { AgentHistoryNavigation } from './components/agent-history-navigation/ag
import { IAgentHistoryItem } from '../../../domains/agent.domain';
import { useStorageContext } from '../../../contexts/storage.context';
import { ImagePreviewFromBuffer } from './components/image-preview-from-buffer';
import { text } from 'stream/consumers';
import { ClassNames } from '@emotion/react';

interface IAgentProps {
type: 'agent' | 'template';
Expand Down Expand Up @@ -61,6 +63,12 @@ export const Agent = ({ id, name, prefix, focused, number, type, userId, isArchi
const [answer, setAnswer] = useState<string>('');
const [isInstructionsOpen, setIsInstructionsOpen] = useState(false);
const textAreaRef = useRef<HTMLTextAreaElement | null>(null);
const textareaWrapperRef = useRef(null);
// resizer
const resizerRef = useRef(null);
const [isResizing, setIsResizing] = useState(false);
const [height, setHeight] = useState(100); // Initial height

const responseRef = useRef<HTMLDivElement | null>(null);
const currentMessageRef = useRef<string>(message);
const theme = useTheme();
Expand Down Expand Up @@ -292,6 +300,50 @@ export const Agent = ({ id, name, prefix, focused, number, type, userId, isArchi
navigator.clipboard.writeText(responseRef.current?.textContent || '');
};

const startResizing = (e: any) => {
e.preventDefault();
setIsResizing(true);
};

const stopResizing = () => {
if (isResizing) {
setIsResizing(false);
}
};

const resize = (e: any) => {
if (!isResizing || !textareaWrapperRef.current) return;

// Support touch and mouse events
const clientY = e.clientY || (e.touches && e.touches[0].clientY);
if (!clientY) return;

const wrapperTop = (textareaWrapperRef.current as any).getBoundingClientRect().top;
const newHeight = clientY - wrapperTop;

// Set minimum and maximum height
const minHeight = 50;
const maxHeight = 500;

if (newHeight > minHeight && newHeight < maxHeight) {
setHeight(newHeight);
}
};

useEffect(() => {
window.addEventListener('mousemove', resize);
window.addEventListener('touchmove', resize);
window.addEventListener('mouseup', stopResizing);
window.addEventListener('touchend', stopResizing);

return () => {
window.removeEventListener('mousemove', resize);
window.removeEventListener('touchmove', resize);
window.removeEventListener('mouseup', stopResizing);
window.removeEventListener('touchend', stopResizing);
};
}, [isResizing]);

return (
<form onSubmit={handleSubmitForm} className={css.agent}>
<header className={css.agentHeader}>
Expand Down Expand Up @@ -343,6 +395,10 @@ export const Agent = ({ id, name, prefix, focused, number, type, userId, isArchi
className={classNames(css.agentInputWrapper, {
[css.agentInputWrapperMinimized]: isMobile,
})}
style={{
height: `${height}px`,
}}
ref={textareaWrapperRef}
>
<textarea
onDrop={handleDrop}
Expand All @@ -351,7 +407,23 @@ export const Agent = ({ id, name, prefix, focused, number, type, userId, isArchi
onChange={(e) => setMessage(e.target.value)}
onPaste={handlePaste}
onKeyPress={handleKeyPress}
className={css.agentInput}
className={classNames(css.agentInput, isMobile && css.agentInputMinimized)}
style={{
height: `${height}px`,
}}
/>
<div
ref={resizerRef}
className={classNames(css.agentInputResizer, isResizing && css.agentInputResizerActive)}
onMouseDown={startResizing}
onTouchStart={startResizing}
tabIndex={0}
role="slider"
aria-valuemin={50}
aria-valuemax={500}
aria-valuenow={height}
aria-orientation="vertical"
aria-label="Resize textarea"
/>
{imageBuffer instanceof ArrayBuffer && (
<ImagePreviewFromBuffer
Expand Down

0 comments on commit b2b7480

Please sign in to comment.