Documentation
¶
Overview ¶
Package mail reads the places HEY keeps postings — a box, a label, a collection, a bundle's unseen threads, a contact's threads — through one Source type and one page read, so a caller never has to know which endpoint a source is served by.
Index ¶
- func TopicIDIn(appURL string) int64
- func TopicIDOf(posting generated.Posting) int64
- type Collection
- type Contact
- type Entry
- type Extenzion
- type Folder
- type Kind
- type Page
- type Posting
- type ReplyPrefill
- type ReplyRecipients
- type Source
- func BoxSource(box *generated.BoxShowResponse) Source
- func BundleSource(postingID int64, contact generated.Contact) Source
- func CollectionSource(collection *generated.CollectionWithPostings) Source
- func ContactSource(contact *generated.ContactDetail) Source
- func FolderSource(folder *generated.FolderWithPostings) Source
- func ListedBoxSource(box generated.Box) Source
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func TopicIDIn ¶
TopicIDIn reads the thread out of a posting's URL, which is the only place HEY's posting JSON says which topic a posting is: `_posting.jbuilder` serves no topic and no topic_id, and the web app follows the URL. A URL that addresses something else — a contact page, a bundle view — has no topic and answers zero.
func TopicIDOf ¶ added in v1.0.0
TopicIDOf resolves the thread a posting opens: its own app_url, or — for a bundle, whose app_url is its sender's contact page — its app_bundle_url. HEY points that at a topic exactly when the bundle holds one unseen thread (haystack's `bundle_posting` route), which is the thread the bundle row opens in the web app. A bundle with several unseen threads opens a bundle view of its own, and one with none opens the contact, so neither names a topic and both answer zero.
Types ¶
type Collection ¶
Collection is a collection a posting's topic belongs to.
type Entry ¶
type Entry struct {
ID int64
CreatedAt time.Time
Creator Contact
AlternativeSenderName string
Summary string
Body htmlutil.Markdown
BodyHTML string
// BodyState is what became of the body when the entry came through threadload:
// hydrated, bodyless, over_limit or failed. Empty for an entry read another way.
BodyState string
}
Entry is one message in a thread. CreatedAt is the time HEY served, not a string of it, for the reason Posting gives: a date formatted and parsed back is a date a reader east of UTC reads as yesterday's.
Body is Markdown, converted once here at the edge, and BodyHTML keeps the HTML HEY served so the image and attachment extractors still have the attributes Markdown drops.
func LoadedEntry ¶
func LoadedEntry(loaded threadload.Entry) Entry
LoadedEntry describes an entry threadload read: the message when there is one, and what became of the body either way.
func NewEntry ¶
NewEntry describes a thread's entry against the message HEY served for it. A topic lists its entries and each message is read on its own, and the two disagree about what they carry: an entry read as part of a bundle has no creator and no timestamp of its own, and a message read directly has a subject where the entry has a summary.
type Page ¶
Page is one page of a source's postings. Cursor is whatever the next read needs to carry on where this page stopped — a geared_pagination cursor for a label or a collection, HEY's own next_history_url for a box — and is empty at the end of the list. Total is HEY's count of everything in the source, zero where it does not say.
func ReadPage ¶
ReadPage reads the page of a source that begins at cursor. An empty cursor reads the first page.
func ReadSeenPage ¶ added in v1.3.0
ReadSeenPage reads a page of the Imbox's Previously Seen postings, which HEY serves on their own route ordered by when they were seen — the Imbox's own pages order seen postings last, which is why the box cannot stand in for this. There is no Source parameter: the route is account-scoped and names the Imbox itself. An empty cursor reads the first page.
type Posting ¶
type Posting struct {
ID int64
// BoxID is the box this row is in, which HEY serves on every posting. A list can
// draw rows from several boxes at once — a search, a label, a contact's threads —
// so the box a thread files out of is the row's own rather than the list's.
BoxID int64
TopicID int64
CreatedAt time.Time
Name string
Summary string
AlternativeSenderName string
Seen bool
// IsBundle marks a row that is a bundle of one contact's unseen threads. It comes
// from the posting's kind — HEY's `bundled` flag means filed *inside* a bundle.
IsBundle bool
BubbledUp bool
Muted bool
VisibleEntryCount int32
Creator Contact
Extenzions []Extenzion
Folders []Folder
Collections []Collection
}
Posting is one row of a source: a thread, a bundle or a single entry as HEY lists it. The timestamps are the ones HEY served, so whatever shows one decides how it reads — formatting a time into a string and parsing it back is how a reader east of UTC ends up looking at yesterday's date.
func NewPosting ¶
NewPosting describes one posting HEY answered with. Its text is sanitized here, once, so that every row, picker and notice that shows a posting shows it inert.
type ReplyPrefill ¶ added in v1.4.0
type ReplyPrefill struct {
Subject string
ActingSenderID int64
Addressed ReplyRecipients
}
ReplyPrefill is how a reply starts out, as HEY prefills it: the "Re: …" subject it goes out under, the sender it goes out as, and who it goes out to. The prefill's quoted content is deliberately not carried: a reply's content is the writer's body alone — the server appends the quoted original at delivery (auto_quoting defaults on), so echoing the prefill's quote back would double it.
func ReplyPrefillFromServer ¶ added in v1.4.0
func ReplyPrefillFromServer(ctx context.Context, client *hey.Client, entryID int64) (ReplyPrefill, bool)
ReplyPrefillFromServer asks HEY how a reply to the entry starts out (GET /entries/{id}/replies/new): the "Re: …" subject the reply carries; the sender it goes out as — resolved from the entry's own to and from addresses, so a thread on a shared or alternate address answers as that address, not the account default, and named only when it differs from the acting user; and its recipients — the entry's sender moved onto the To line and the acting user's own addresses, aliases and catch-alls excluded — the exclusion no client can compute locally, and the reason a reply used to be able to CC its writer back to themselves. A false answer sends the caller to its local fallback: a failed read needs one, and so does an empty recipient list — on a thread with yourself, everyone HEY excludes is everyone there is, and the local list is what keeps that reply addressable. The subject and sender are answered even when the recipients are not — only they need the fallback, not what HEY already supplied.
type ReplyRecipients ¶ added in v1.4.0
ReplyRecipients is who a reply goes out to, in HEY's three kinds of addressing.
type Source ¶
type Source struct {
Kind Kind
ID int64
Name string
BoxKind string
AppURL string
CreatedAt time.Time
UpdatedAt time.Time
}
Source is a place postings are read from. BoxKind carries HEY's own kind for a box (hey.BoxKindImbox and friends), which is what tells the named box routes apart; it is empty for a label or a collection.
func BoxSource ¶
func BoxSource(box *generated.BoxShowResponse) Source
BoxSource describes the box HEY answered with.
func BundleSource ¶ added in v1.4.0
BundleSource describes a bundle posting as a source: the unseen threads it groups, named for the bundled contact. The ID is the bundle row's own box item id, which is what the unseen route is addressed by.
func CollectionSource ¶
func CollectionSource(collection *generated.CollectionWithPostings) Source
CollectionSource describes the collection HEY answered with.
func ContactSource ¶ added in v1.4.0
func ContactSource(contact *generated.ContactDetail) Source
ContactSource describes a contact as a source: every thread they are on, seen and unseen — the list HEY heads with the contact's entries_title.
func FolderSource ¶
func FolderSource(folder *generated.FolderWithPostings) Source
FolderSource describes the label HEY answered with.
func ListedBoxSource ¶
ListedBoxSource describes a box from HEY's list of them, which names the boxes without serving any of their postings or URLs.