feat(web): redesign chat ui in telegram-like style
All checks were successful
CI / test (push) Successful in 21s
All checks were successful
CI / test (push) Successful in 21s
- update overall layout for desktop/mobile chat navigation - restyle dialogs list, message bubbles and composer - add atmospheric background and unified panel styling
This commit is contained in:
@@ -238,11 +238,26 @@ export function MessageComposer() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="border-t border-slate-700 bg-panel p-3">
|
||||
<div className="mb-2 flex gap-2">
|
||||
<div className="border-t border-slate-700/50 bg-slate-900/55 p-3">
|
||||
<div className="mb-2 flex items-center gap-2">
|
||||
<label className="cursor-pointer rounded-full bg-slate-700/80 px-3 py-2 text-xs font-semibold hover:bg-slate-700">
|
||||
+
|
||||
<input
|
||||
className="hidden"
|
||||
type="file"
|
||||
disabled={isUploading}
|
||||
onChange={(e) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (file) {
|
||||
selectFile(file);
|
||||
}
|
||||
e.currentTarget.value = "";
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
<input
|
||||
className="flex-1 rounded bg-slate-800 px-3 py-2"
|
||||
placeholder="Type message..."
|
||||
className="flex-1 rounded-full border border-slate-700/80 bg-slate-800/80 px-4 py-2.5 text-sm outline-none placeholder:text-slate-400 focus:border-sky-500"
|
||||
placeholder="Write a message..."
|
||||
value={text}
|
||||
onChange={(e) => {
|
||||
setText(e.target.value);
|
||||
@@ -252,12 +267,12 @@ export function MessageComposer() {
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<button className="rounded bg-accent px-3 py-2 font-semibold text-black" onClick={handleSend}>
|
||||
<button className="rounded-full bg-sky-500 px-4 py-2.5 text-sm font-semibold text-slate-950 hover:bg-sky-400" onClick={handleSend}>
|
||||
Send
|
||||
</button>
|
||||
</div>
|
||||
{selectedFile ? (
|
||||
<div className="mb-2 rounded border border-slate-700 bg-slate-900 p-3 text-sm">
|
||||
<div className="mb-2 rounded-xl border border-slate-700/80 bg-slate-900/95 p-3 text-sm">
|
||||
<div className="mb-2 font-semibold">Ready to send</div>
|
||||
<div className="mb-1 break-all text-slate-300">{selectedFile.name}</div>
|
||||
<div className="mb-2 text-xs text-slate-400">{formatBytes(selectedFile.size)}</div>
|
||||
@@ -277,13 +292,13 @@ export function MessageComposer() {
|
||||
) : null}
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
className="rounded bg-accent px-3 py-1 font-semibold text-black disabled:opacity-50"
|
||||
className="rounded-lg bg-sky-500 px-3 py-1 font-semibold text-slate-950 disabled:opacity-50"
|
||||
onClick={() => void sendSelectedFile()}
|
||||
disabled={isUploading}
|
||||
>
|
||||
Send media
|
||||
</button>
|
||||
<button className="rounded bg-slate-700 px-3 py-1 disabled:opacity-50" onClick={cancelSelectedFile} disabled={isUploading}>
|
||||
<button className="rounded-lg bg-slate-700 px-3 py-1 disabled:opacity-50" onClick={cancelSelectedFile} disabled={isUploading}>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
@@ -291,25 +306,10 @@ export function MessageComposer() {
|
||||
) : null}
|
||||
{uploadError ? <div className="mb-2 text-sm text-red-400">{uploadError}</div> : null}
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<label className="cursor-pointer rounded bg-slate-700 px-3 py-1">
|
||||
Upload
|
||||
<input
|
||||
className="hidden"
|
||||
type="file"
|
||||
disabled={isUploading}
|
||||
onChange={(e) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (file) {
|
||||
selectFile(file);
|
||||
}
|
||||
e.currentTarget.value = "";
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
<button className="rounded bg-slate-700 px-3 py-1 disabled:opacity-50" onClick={startRecord} disabled={isUploading || isRecording}>
|
||||
<button className="rounded-lg bg-slate-700/90 px-3 py-1.5 disabled:opacity-50" onClick={startRecord} disabled={isUploading || isRecording}>
|
||||
{isRecording ? "Recording..." : "Record Voice"}
|
||||
</button>
|
||||
<button className="rounded bg-slate-700 px-3 py-1 disabled:opacity-50" onClick={stopRecord} disabled={!isRecording}>
|
||||
<button className="rounded-lg bg-slate-700/90 px-3 py-1.5 disabled:opacity-50" onClick={stopRecord} disabled={!isRecording}>
|
||||
Stop
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user