Shared calendars in the calendar, and no more account switcher
Three things from using it on two real accounts. A calendar shared with you never appeared. Nothing was wrong with the share -- the calendar had nowhere to be shown. Calendars loaded from one account and one only, so the sharer's were reachable solely by switching the whole app to their account, which is the door being closed below. They now sit under "Shared with me" beside the reader's own, in their own colour, with their events in the grid and a click to hide them like any other calendar. Their events go through `instancesIn`, the one funnel every view already reads, so month, week, day and agenda got them without being touched. Events and calendars from another account are keyed by account as well as id, and hiding one is remembered under the same key: an id means nothing outside the account holding it, and two accounts sharing an id is ordinary rather than unlucky. An account that shared nothing was listed in Files as though it had. Every non-personal account was offered on the reasoning that its folders could speak for themselves -- but an account whose *calendar* was shared has no folders to speak with, and appeared as an invitation to open an empty pane. Each is now asked for one file before being listed, and silence is taken for an answer. And the account switcher is gone from the profile menu. It existed to reach what other people shared and was the wrong door: it moved the whole app to somebody else's account, and since Stalwart advertises every capability on a shared account, mail, calendar and contacts went with it and were refused. Everything it was for is now in the module the share belongs to, found without anyone needing to know an account was involved. What this does not prove is that Stalwart delivers a calendar share at all. The mock says the client handles one, which is the half that was missing; whether the server behaves like address books, which work, or like mail folders, which do not, needs the two accounts again.
This commit is contained in:
+12
-16
@@ -6,7 +6,7 @@ import { toggleTarget, useEffectiveTheme, useSettings } from "@/store/settings";
|
||||
import { useMail } from "@/store/mail";
|
||||
import { draftFromMailto, useCompose } from "@/store/compose";
|
||||
import { Avatar, useIsMobile } from "@/ui/misc";
|
||||
import { MenuItem, MenuSep, MenuTitle, Popover, useMenu } from "@/ui/popover";
|
||||
import { MenuItem, MenuSep, Popover, useMenu } from "@/ui/popover";
|
||||
import { SearchBar } from "./SearchBar";
|
||||
import { MailboxTree } from "./mail/MailboxTree";
|
||||
import { FilesTree } from "./files/FilesTree";
|
||||
@@ -14,7 +14,6 @@ import { ContactsSidebar } from "./contacts/ContactsSidebar";
|
||||
import { CalendarSidebar } from "./calendar/CalendarSidebar";
|
||||
import { ShortcutsDialog, useGlobalShortcuts } from "./Shortcuts";
|
||||
import { formatSize } from "@/lib/format";
|
||||
import { CAP } from "@/jmap/client";
|
||||
|
||||
const PUSH_LABEL = {
|
||||
connected: "Live updates connected",
|
||||
@@ -32,8 +31,6 @@ export function AppShell({ children }: { children: ReactNode }) {
|
||||
const openCompose = useCompose((s) => s.open);
|
||||
const pushState = useSession((s) => s.pushState);
|
||||
const session = useSession((s) => s.session);
|
||||
const accountId = useSession((s) => s.accountId);
|
||||
const setAccount = useSession((s) => s.setAccount);
|
||||
const logout = useSession((s) => s.logout);
|
||||
const acctMenu = useMenu();
|
||||
const section = location.split("/")[1] || "mail";
|
||||
@@ -55,8 +52,16 @@ export function AppShell({ children }: { children: ReactNode }) {
|
||||
}
|
||||
}, [openCompose, navigate]);
|
||||
|
||||
const accounts = session ? Object.entries(session.accounts) : [];
|
||||
const mailAccounts = accounts.filter(([, a]) => CAP.mail in (a.accountCapabilities ?? {}));
|
||||
/*
|
||||
* There is no account switcher any more.
|
||||
*
|
||||
* It existed to reach what other people shared, and was the wrong door: it
|
||||
* moved the whole app to somebody else's account, and Stalwart advertises
|
||||
* every capability on a shared account, so mail, calendar and contacts went
|
||||
* with it and were refused. Shares are listed where they belong now -- in
|
||||
* Files and in Contacts, beside the reader's own -- and found without anyone
|
||||
* having to know an account switch was involved.
|
||||
*/
|
||||
|
||||
return (
|
||||
<div className="app">
|
||||
@@ -67,7 +72,7 @@ export function AppShell({ children }: { children: ReactNode }) {
|
||||
<Link href="/mail" className="brand">
|
||||
<img src="/img/logo.png" alt="" />
|
||||
<span className="brand-name">
|
||||
ihasmail{mailAccounts.length > 1 ? "" : ""}
|
||||
ihasmail
|
||||
</span>
|
||||
</Link>
|
||||
<SearchBar />
|
||||
@@ -95,15 +100,6 @@ export function AppShell({ children }: { children: ReactNode }) {
|
||||
<div className="hint truncate">{session?.ihasmail?.loginName}</div>
|
||||
</div>
|
||||
</div>
|
||||
{mailAccounts.length > 1 && (
|
||||
<>
|
||||
<MenuSep />
|
||||
<MenuTitle>Accounts</MenuTitle>
|
||||
{mailAccounts.map(([id, a]) => (
|
||||
<MenuItem key={id} checked={id === accountId} label={a.name} onClick={() => setAccount(id)} />
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
<MenuSep />
|
||||
<MenuItem icon={<Settings size={16} />} label="Settings" onClick={() => navigate("/settings")} />
|
||||
<MenuItem icon={<RefreshCw size={16} />} label="Refresh" onClick={() => window.location.reload()} />
|
||||
|
||||
Reference in New Issue
Block a user