fix: schedule button, compression visibility, activity log, insights overflow, bookmarks UI
CI / Build & Quality Checks (push) Successful in 10m24s

Schedule message: modal now always opens (even with empty composer);
includes its own message textarea pre-filled from editor content;
removed null-content early-return guard from handleScheduleClick;
fixed error text to use color.Critical.Main not CSS var

Image compression: removed 200KB size threshold — checkbox now shows
for all JPEG/PNG uploads (not just large ones); 'no significant saving'
message handles already-small files gracefully

Activity log: auto-paginate on mount — state events are absent from
initial sync window, so the log was always empty until Load More was
clicked manually

Insights summary: Text size H4→H5 with toLocaleString() formatting and
overflow:ellipsis so large numbers don't push tiles off screen

Bookmarks panel: replaced var(--bg-*) CSS vars (undefined in folds
themes) with color.Surface/SurfaceVariant/Primary folds tokens; added
left accent border on message preview block, count badge, clear button
in search, improved empty state, cleaner button hierarchy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-04 12:07:12 -04:00
parent d4d32e7a5e
commit c8b2de4a08
6 changed files with 202 additions and 91 deletions
+34 -25
View File
@@ -22,7 +22,8 @@ import { scheduleMessage } from '../../utils/scheduledMessages';
interface ScheduleMessageModalProps {
roomId: string;
content: IContent;
/** Pre-fill the message body from the composer. Pass null/undefined to open blank. */
initialBody?: string;
onScheduled: (delayId: string, sendAt: number, content: IContent) => void;
onClose: () => void;
}
@@ -66,11 +67,12 @@ function toLocalDatetimeValue(date: Date): string {
export function ScheduleMessageModal({
roomId,
content,
initialBody,
onScheduled,
onClose,
}: ScheduleMessageModalProps) {
const mx = useMatrixClient();
const [messageText, setMessageText] = useState(initialBody ?? '');
const [submitting, setSubmitting] = useState(false);
const [error, setError] = useState<string | null>(null);
@@ -126,6 +128,12 @@ export function ScheduleMessageModal({
return;
}
if (!messageText.trim()) {
setError('Please enter a message to schedule.');
return;
}
const content: IContent = { body: messageText.trim(), msgtype: 'm.text' };
setError(null);
setSubmitting(true);
try {
@@ -187,31 +195,32 @@ export function ScheduleMessageModal({
{/* Body */}
<Box direction="Column" gap="400" style={{ padding: config.space.S400 }}>
{/* Message preview */}
{typeof content.body === 'string' && content.body.trim() !== '' && (
<Box
direction="Column"
gap="100"
{/* Message input */}
<Box direction="Column" gap="100">
<Text as="label" htmlFor="schedule-message-body" size="L400">
Message
</Text>
<textarea
id="schedule-message-body"
rows={3}
placeholder="Type your message here…"
value={messageText}
onChange={(e) => setMessageText(e.target.value)}
style={{
background: color.SurfaceVariant.Container,
color: color.SurfaceVariant.OnContainer,
border: `${config.borderWidth.B300} solid ${color.SurfaceVariant.ContainerLine}`,
borderRadius: config.radii.R300,
padding: config.space.S200,
padding: `${config.space.S200} ${config.space.S300}`,
fontSize: '0.875rem',
width: '100%',
boxSizing: 'border-box',
outline: 'none',
resize: 'vertical',
fontFamily: 'inherit',
}}
>
<Text size="L400">Message</Text>
<Text
size="T300"
style={{
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
opacity: 0.8,
}}
>
{content.body as string}
</Text>
</Box>
)}
/>
</Box>
{/* Datetime picker */}
<Box direction="Column" gap="100">
@@ -249,7 +258,7 @@ export function ScheduleMessageModal({
</Box>
) : (
datetimeValue && (
<Text size="T200" style={{ color: 'var(--tc-danger-normal)' }}>
<Text size="T200" style={{ color: color.Critical.Main }}>
Must be at least 1 minute in the future
</Text>
)
@@ -257,7 +266,7 @@ export function ScheduleMessageModal({
{/* Error */}
{error && (
<Text size="T300" style={{ color: 'var(--tc-danger-normal)' }}>
<Text size="T300" style={{ color: color.Critical.Main }}>
{error}
</Text>
)}