Merge pull request #184 from Coffey-Labs/fix/compose-as-new-on-mobile
Put "compose as new" where a thumb can find it
This commit is contained in:
@@ -642,7 +642,10 @@ a.menu-item:hover { color: var(--fg); }
|
|||||||
.vcard-card { margin: 0 16px 12px; padding: 12px 16px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg-sunken); display: flex; align-items: center; gap: 12px; }
|
.vcard-card { margin: 0 16px 12px; padding: 12px 16px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg-sunken); display: flex; align-items: center; gap: 12px; }
|
||||||
.unsubscribe-row { margin: 0 16px 8px; font-size: .88em; color: var(--fg-muted); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
.unsubscribe-row { margin: 0 16px 8px; font-size: .88em; color: var(--fg-muted); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
||||||
.reply-box { margin: 8px 16px 24px; }
|
.reply-box { margin: 8px 16px 24px; }
|
||||||
.reply-box .reply-prompt { display: flex; gap: 8px; align-items: center; padding: 12px; border: 1px solid var(--border); border-radius: var(--radius); color: var(--fg-muted); }
|
/* Wraps, because it does not fit. Three labelled buttons and an overflow need
|
||||||
|
about 390px of it, which a 430px phone has and a 360px one does not -- and it
|
||||||
|
was already over the line on the smaller ones before the overflow was added. */
|
||||||
|
.reply-box .reply-prompt { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 12px; border: 1px solid var(--border); border-radius: var(--radius); color: var(--fg-muted); }
|
||||||
.reply-box .reply-prompt button { display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; border-radius: 999px; border: 1px solid var(--border-strong); color: var(--fg); font-weight: 500; }
|
.reply-box .reply-prompt button { display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; border-radius: 999px; border: 1px solid var(--border-strong); color: var(--fg); font-weight: 500; }
|
||||||
.reply-box .reply-prompt button:hover { background: var(--bg-hover); }
|
.reply-box .reply-prompt button:hover { background: var(--bg-hover); }
|
||||||
.no-thread { height: 100%; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 8px; color: var(--fg-muted); }
|
.no-thread { height: 100%; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 8px; color: var(--fg-muted); }
|
||||||
@@ -1214,6 +1217,9 @@ button.dp-open:disabled { cursor: default; opacity: .5; }
|
|||||||
.dp-time:hover { background: var(--bg-hover); }
|
.dp-time:hover { background: var(--bg-hover); }
|
||||||
.dp-time.selected { background: var(--accent); color: var(--accent-fg); }
|
.dp-time.selected { background: var(--accent); color: var(--accent-fg); }
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
|
/* The spacer would take the whole of the first line and push the overflow
|
||||||
|
onto a line of its own; packed together they wrap as a group instead. */
|
||||||
|
.reply-box .reply-prompt .spacer { display: none; }
|
||||||
.dp-datetime { flex-wrap: wrap; }
|
.dp-datetime { flex-wrap: wrap; }
|
||||||
.dp-datetime .dp-time-field { flex: 1 1 100%; }
|
.dp-datetime .dp-time-field { flex: 1 1 100%; }
|
||||||
.dp-split { flex-direction: column; }
|
.dp-split { flex-direction: column; }
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { AlertOctagon, Archive, ArrowLeft, ChevronDown, ChevronUp, FolderInput, Forward, Mail, MailOpen, MoreVertical, Printer, Reply, ReplyAll, ShieldCheck, Star, Tag, Trash2, Download } from "lucide-react";
|
import { AlertOctagon, Archive, ArrowLeft, ChevronDown, ChevronUp, FolderInput, Forward, Mail, MailOpen, MailPlus, MoreVertical, Printer, Reply, ReplyAll, ShieldCheck, Star, Tag, Trash2, Download } from "lucide-react";
|
||||||
import { useMail } from "@/store/mail";
|
import { useMail } from "@/store/mail";
|
||||||
import { useSettings } from "@/store/settings";
|
import { useSettings } from "@/store/settings";
|
||||||
import { useCompose } from "@/store/compose";
|
import { useCompose } from "@/store/compose";
|
||||||
@@ -42,6 +42,8 @@ export function ThreadView({ threadId, mailboxId, onBack, actions, onNavigate, h
|
|||||||
const [allExpanded, setAllExpanded] = useState(false);
|
const [allExpanded, setAllExpanded] = useState(false);
|
||||||
const [labelAnchor, setLabelAnchor] = useState<{ x: number; y: number } | null>(null);
|
const [labelAnchor, setLabelAnchor] = useState<{ x: number; y: number } | null>(null);
|
||||||
const moreMenu = useMenu();
|
const moreMenu = useMenu();
|
||||||
|
/** The overflow on the reply strip, which is the only per-message menu a phone offers easily. */
|
||||||
|
const replyMore = useMenu();
|
||||||
const scrollRef = useRef<HTMLDivElement>(null);
|
const scrollRef = useRef<HTMLDivElement>(null);
|
||||||
const markTimer = useRef<number | null>(null);
|
const markTimer = useRef<number | null>(null);
|
||||||
const isTouch = useIsTouch();
|
const isTouch = useIsTouch();
|
||||||
@@ -289,6 +291,19 @@ export function ThreadView({ threadId, mailboxId, onBack, actions, onNavigate, h
|
|||||||
<button onClick={() => void reply(last, "reply")}><Reply size={16} /> {t("Reply")}</button>
|
<button onClick={() => void reply(last, "reply")}><Reply size={16} /> {t("Reply")}</button>
|
||||||
<button onClick={() => void reply(last, "replyAll")}><ReplyAll size={16} /> {t("Reply all")}</button>
|
<button onClick={() => void reply(last, "replyAll")}><ReplyAll size={16} /> {t("Reply all")}</button>
|
||||||
<button onClick={() => void reply(last, "forward")}><Forward size={16} /> {t("Forward")}</button>
|
<button onClick={() => void reply(last, "forward")}><Forward size={16} /> {t("Forward")}</button>
|
||||||
|
{/*
|
||||||
|
On a phone this strip is where a thumb goes, and the per-message
|
||||||
|
menu at the top of a card is not somewhere anybody looks for
|
||||||
|
"send this again" -- which is how compose-as-new came to be
|
||||||
|
reported missing on mobile when it was there all along (#181).
|
||||||
|
A fourth full button does not fit at 500px; this does, and it
|
||||||
|
spells the action out once opened.
|
||||||
|
*/}
|
||||||
|
<span className="spacer" />
|
||||||
|
<button className="icon-btn" onClick={replyMore.open} aria-label={t("More ways to send this")}><MoreVertical size={18} /></button>
|
||||||
|
<Popover anchor={replyMore.anchor} onClose={replyMore.close} align="end" width={220}>
|
||||||
|
<MenuItem icon={<MailPlus size={16} />} label={t("Compose as new")} onClick={() => void useCompose.getState().composeAsNew(last)} />
|
||||||
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user