The service worker answers app routes from its kept page (#395), and it
kept whatever the mount's root returned at install and whatever HTML a
navigation returned. Where the root is not the app -- demo.ihasmail.com
puts its landing page there -- a returning visitor got the landing page on
every route.
The kept page is now only ever the app page, recognised by the asset list
the build writes into it: install fetches /mail instead of /, a
navigation's page is kept only if it is the app's, and a foreign page left
by the earlier worker is dropped when this one activates. Only the app's
own routes are answered from it; the root and any page in front of the app
go to the network. The reload for a new build primes the kept page from
/mail for the same reason.
* Start at once on a device marked as your own
On a distant link, opening the app waited on four round trips before the
inbox showed: the app page, the session, the folder list, then the folder.
A trusted device now starts from what it kept:
- the service worker answers an app route from its kept page and fetches a
fresh one behind it; the app checks the server's version at start, and a
reload for a new build puts the new page in place first, so it is not
answered with the old one. Assets of the page just replaced are kept one
build longer for a tab still running it.
- the session's public details, so requests for mail go out before the
server has confirmed the session; the answer replaces it, and a session
that has ended lands on the sign-in form as before.
- the folder list and the first page of up to four recently read folders,
list properties only, so the folders and the inbox paint before any reply
and the folder query does not wait on the folder list. The "folder no
longer exists" check still waits for the server's list.
All of it goes through the storage gate: nothing is written or read on a
device not marked as the reader's own, and signing out clears it.
* Show nothing kept before the session is confirmed
Starting from a kept session put the kept inbox on screen before the
server had said the session was still good; a session that had ended
showed mail and then the sign-in form. The spinner stays until the
server answers, as before.
The kept session is gone -- it existed only to start early. The kept
folder list and rows are still applied, from setAccount, which runs once
the session is confirmed: the inbox paints the moment that answer
arrives, and the folder query goes out then without waiting on the
folder list. An unreachable server lands on the sign-in form as before.
Takes the flat module count from 66 to 42, continuing what admin/ and
calendar/ started.
lib/mailbox/ archiveDate, emptyFolder, folderMove, labelTree,
mailboxName, mailboxRoute
lib/sieve/ sieve, sieveApply, sieveFolders
lib/input/ keyboard, swipe, touch, listSelection, dropUpload
lib/notify/ notify, webpush, webpushEnable
lib/sw/ swCache, swFacts, staleBuild
lib/text/ html, markdown, text, emlName
FOUR THINGS THE FILENAMES GET WRONG, each checked by reading the file
rather than trusting what it is called:
- appFolder is not a mailbox. It is the `ihasmail` folder in JMAP
*Files*, where the client keeps signature images and synced settings.
It stays flat.
- format holds no formatting of text. It re-exports the date and clock
formatters, so it belongs with dates/datetime, not with text/.
- preview is the file viewer deciding what it can show without
downloading, and source is where to point someone asking for this
instance's AGPL source. Neither is about text.
- notify is not Web Push. It is the tab title, the favicon badge and
the new-mail sound -- in-app notification, which is why it sits with
webpush rather than under sw/ with the service worker's own concerns.
threadScroll stays flat too: it decides where a conversation opens, which
is view state rather than a gesture, and input/ is honest only if
everything in it interprets something the reader did.
No behavior change. Almost every reference was on the @/ alias; eight
relative imports in files that did not move, or that moved away from a
sibling, needed rewriting by hand.