@remit/web-client 0.0.146 → 0.0.148

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29,8 +29,11 @@ import { Route as SettingsSendersRouteImport } from './routes/settings/senders'
29
29
  import { Route as SettingsSuggestedVipsRouteImport } from './routes/settings/suggested-vips'
30
30
  import { Route as MailMailboxIdIndexRouteImport } from './routes/mail/$mailboxId/index'
31
31
  import { Route as MailBriefIndexRouteImport } from './routes/mail/brief/index'
32
+ import { Route as MailBriefThreadIdRouteImport } from './routes/mail/brief/$threadId'
32
33
  import { Route as MailFlaggedIndexRouteImport } from './routes/mail/flagged/index'
33
34
  import { Route as MailOutboxIndexRouteImport } from './routes/mail/outbox/index'
35
+ import { Route as MailBriefThreadIdIndexRouteImport } from './routes/mail/brief/$threadId/index'
36
+ import { Route as MailBriefThreadIdMessageIdRouteImport } from './routes/mail/brief/$threadId/$messageId'
34
37
 
35
38
  const IndexRoute = IndexRouteImport.update({
36
39
  id: '/',
@@ -132,6 +135,11 @@ const MailBriefIndexRoute = MailBriefIndexRouteImport.update({
132
135
  path: '/',
133
136
  getParentRoute: () => MailBriefRoute,
134
137
  } as any)
138
+ const MailBriefThreadIdRoute = MailBriefThreadIdRouteImport.update({
139
+ id: '/$threadId',
140
+ path: '/$threadId',
141
+ getParentRoute: () => MailBriefRoute,
142
+ } as any)
135
143
  const MailFlaggedIndexRoute = MailFlaggedIndexRouteImport.update({
136
144
  id: '/',
137
145
  path: '/',
@@ -142,6 +150,17 @@ const MailOutboxIndexRoute = MailOutboxIndexRouteImport.update({
142
150
  path: '/',
143
151
  getParentRoute: () => MailOutboxRoute,
144
152
  } as any)
153
+ const MailBriefThreadIdIndexRoute = MailBriefThreadIdIndexRouteImport.update({
154
+ id: '/',
155
+ path: '/',
156
+ getParentRoute: () => MailBriefThreadIdRoute,
157
+ } as any)
158
+ const MailBriefThreadIdMessageIdRoute =
159
+ MailBriefThreadIdMessageIdRouteImport.update({
160
+ id: '/$messageId',
161
+ path: '/$messageId',
162
+ getParentRoute: () => MailBriefThreadIdRoute,
163
+ } as any)
145
164
 
146
165
  export interface FileRoutesByFullPath {
147
166
  '/': typeof IndexRoute
@@ -162,10 +181,13 @@ export interface FileRoutesByFullPath {
162
181
  '/settings/suggested-vips': typeof SettingsSuggestedVipsRoute
163
182
  '/mail/': typeof MailIndexRoute
164
183
  '/settings/': typeof SettingsIndexRoute
184
+ '/mail/brief/$threadId': typeof MailBriefThreadIdRouteWithChildren
165
185
  '/mail/$mailboxId/': typeof MailMailboxIdIndexRoute
166
186
  '/mail/brief/': typeof MailBriefIndexRoute
167
187
  '/mail/flagged/': typeof MailFlaggedIndexRoute
168
188
  '/mail/outbox/': typeof MailOutboxIndexRoute
189
+ '/mail/brief/$threadId/$messageId': typeof MailBriefThreadIdMessageIdRoute
190
+ '/mail/brief/$threadId/': typeof MailBriefThreadIdIndexRoute
169
191
  }
170
192
  export interface FileRoutesByTo {
171
193
  '/': typeof IndexRoute
@@ -184,6 +206,8 @@ export interface FileRoutesByTo {
184
206
  '/mail/brief': typeof MailBriefIndexRoute
185
207
  '/mail/flagged': typeof MailFlaggedIndexRoute
186
208
  '/mail/outbox': typeof MailOutboxIndexRoute
209
+ '/mail/brief/$threadId/$messageId': typeof MailBriefThreadIdMessageIdRoute
210
+ '/mail/brief/$threadId': typeof MailBriefThreadIdIndexRoute
187
211
  }
188
212
  export interface FileRoutesById {
189
213
  __root__: typeof rootRouteImport
@@ -205,10 +229,13 @@ export interface FileRoutesById {
205
229
  '/settings/suggested-vips': typeof SettingsSuggestedVipsRoute
206
230
  '/mail/': typeof MailIndexRoute
207
231
  '/settings/': typeof SettingsIndexRoute
232
+ '/mail/brief/$threadId': typeof MailBriefThreadIdRouteWithChildren
208
233
  '/mail/$mailboxId/': typeof MailMailboxIdIndexRoute
209
234
  '/mail/brief/': typeof MailBriefIndexRoute
210
235
  '/mail/flagged/': typeof MailFlaggedIndexRoute
211
236
  '/mail/outbox/': typeof MailOutboxIndexRoute
237
+ '/mail/brief/$threadId/$messageId': typeof MailBriefThreadIdMessageIdRoute
238
+ '/mail/brief/$threadId/': typeof MailBriefThreadIdIndexRoute
212
239
  }
213
240
  export interface FileRouteTypes {
214
241
  fileRoutesByFullPath: FileRoutesByFullPath
@@ -231,10 +258,13 @@ export interface FileRouteTypes {
231
258
  | '/settings/suggested-vips'
232
259
  | '/mail/'
233
260
  | '/settings/'
261
+ | '/mail/brief/$threadId'
234
262
  | '/mail/$mailboxId/'
235
263
  | '/mail/brief/'
236
264
  | '/mail/flagged/'
237
265
  | '/mail/outbox/'
266
+ | '/mail/brief/$threadId/$messageId'
267
+ | '/mail/brief/$threadId/'
238
268
  fileRoutesByTo: FileRoutesByTo
239
269
  to:
240
270
  | '/'
@@ -253,6 +283,8 @@ export interface FileRouteTypes {
253
283
  | '/mail/brief'
254
284
  | '/mail/flagged'
255
285
  | '/mail/outbox'
286
+ | '/mail/brief/$threadId/$messageId'
287
+ | '/mail/brief/$threadId'
256
288
  id:
257
289
  | '__root__'
258
290
  | '/'
@@ -273,10 +305,13 @@ export interface FileRouteTypes {
273
305
  | '/settings/suggested-vips'
274
306
  | '/mail/'
275
307
  | '/settings/'
308
+ | '/mail/brief/$threadId'
276
309
  | '/mail/$mailboxId/'
277
310
  | '/mail/brief/'
278
311
  | '/mail/flagged/'
279
312
  | '/mail/outbox/'
313
+ | '/mail/brief/$threadId/$messageId'
314
+ | '/mail/brief/$threadId/'
280
315
  fileRoutesById: FileRoutesById
281
316
  }
282
317
  export interface RootRouteChildren {
@@ -428,6 +463,13 @@ declare module '@tanstack/react-router' {
428
463
  preLoaderRoute: typeof MailBriefIndexRouteImport
429
464
  parentRoute: typeof MailBriefRoute
430
465
  }
466
+ '/mail/brief/$threadId': {
467
+ id: '/mail/brief/$threadId'
468
+ path: '/$threadId'
469
+ fullPath: '/mail/brief/$threadId'
470
+ preLoaderRoute: typeof MailBriefThreadIdRouteImport
471
+ parentRoute: typeof MailBriefRoute
472
+ }
431
473
  '/mail/flagged/': {
432
474
  id: '/mail/flagged/'
433
475
  path: '/'
@@ -442,6 +484,20 @@ declare module '@tanstack/react-router' {
442
484
  preLoaderRoute: typeof MailOutboxIndexRouteImport
443
485
  parentRoute: typeof MailOutboxRoute
444
486
  }
487
+ '/mail/brief/$threadId/': {
488
+ id: '/mail/brief/$threadId/'
489
+ path: '/'
490
+ fullPath: '/mail/brief/$threadId/'
491
+ preLoaderRoute: typeof MailBriefThreadIdIndexRouteImport
492
+ parentRoute: typeof MailBriefThreadIdRoute
493
+ }
494
+ '/mail/brief/$threadId/$messageId': {
495
+ id: '/mail/brief/$threadId/$messageId'
496
+ path: '/$messageId'
497
+ fullPath: '/mail/brief/$threadId/$messageId'
498
+ preLoaderRoute: typeof MailBriefThreadIdMessageIdRouteImport
499
+ parentRoute: typeof MailBriefThreadIdRoute
500
+ }
445
501
  }
446
502
  }
447
503
 
@@ -457,11 +513,26 @@ const MailMailboxIdRouteWithChildren = MailMailboxIdRoute._addFileChildren(
457
513
  MailMailboxIdRouteChildren,
458
514
  )
459
515
 
516
+ interface MailBriefThreadIdRouteChildren {
517
+ MailBriefThreadIdMessageIdRoute: typeof MailBriefThreadIdMessageIdRoute
518
+ MailBriefThreadIdIndexRoute: typeof MailBriefThreadIdIndexRoute
519
+ }
520
+
521
+ const MailBriefThreadIdRouteChildren: MailBriefThreadIdRouteChildren = {
522
+ MailBriefThreadIdMessageIdRoute: MailBriefThreadIdMessageIdRoute,
523
+ MailBriefThreadIdIndexRoute: MailBriefThreadIdIndexRoute,
524
+ }
525
+
526
+ const MailBriefThreadIdRouteWithChildren =
527
+ MailBriefThreadIdRoute._addFileChildren(MailBriefThreadIdRouteChildren)
528
+
460
529
  interface MailBriefRouteChildren {
530
+ MailBriefThreadIdRoute: typeof MailBriefThreadIdRouteWithChildren
461
531
  MailBriefIndexRoute: typeof MailBriefIndexRoute
462
532
  }
463
533
 
464
534
  const MailBriefRouteChildren: MailBriefRouteChildren = {
535
+ MailBriefThreadIdRoute: MailBriefThreadIdRouteWithChildren,
465
536
  MailBriefIndexRoute: MailBriefIndexRoute,
466
537
  }
467
538
 
@@ -0,0 +1,19 @@
1
+ /**
2
+ * /mail/brief/$threadId/$messageId — the same conversation, with one of its
3
+ * messages expanded and scrolled to.
4
+ *
5
+ * A message is not addressable on its own: `GET /messages/{messageId}` answers
6
+ * with no thread, so the pane has nothing to fetch by. The segment names which
7
+ * message inside the thread the reader pointed at, and the surface it renders is
8
+ * the thread's.
9
+ */
10
+ import { createFileRoute } from "@tanstack/react-router";
11
+ import { BriefPane } from "@/components/mail/BriefPane";
12
+
13
+ function BriefMessagePane() {
14
+ return <BriefPane.Reading />;
15
+ }
16
+
17
+ export const Route = createFileRoute("/mail/brief/$threadId/$messageId")({
18
+ component: BriefMessagePane,
19
+ });
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The thread with no message named. The pane opens on the newest message, the
3
+ * same as for a thread whose row the reader never pointed at.
4
+ */
5
+ import { createFileRoute } from "@tanstack/react-router";
6
+ import { BriefPane } from "@/components/mail/BriefPane";
7
+
8
+ function BriefThreadPane() {
9
+ return <BriefPane.Reading />;
10
+ }
11
+
12
+ export const Route = createFileRoute("/mail/brief/$threadId/")({
13
+ component: BriefThreadPane,
14
+ });
@@ -0,0 +1,16 @@
1
+ /**
2
+ * /mail/brief/$threadId — a conversation open in the brief's reading pane.
3
+ *
4
+ * The brief is cross-mailbox, and the thread is still the whole address: the
5
+ * folder its mail is filed in comes from the thread's own data, since
6
+ * `GET /threads/{threadId}/messages` answers with rows that each name their
7
+ * mailbox. A segment for the folder would be a second owner of a fact the
8
+ * thread already carries.
9
+ *
10
+ * A layout, because the message segment nests under it.
11
+ */
12
+ import { createFileRoute, Outlet } from "@tanstack/react-router";
13
+
14
+ export const Route = createFileRoute("/mail/brief/$threadId")({
15
+ component: Outlet,
16
+ });
@@ -3,7 +3,9 @@
3
3
  *
4
4
  * The route mounts the list and the shell around it, and the reading pane is
5
5
  * the `Outlet`, so what the pane shows is whatever route is matched under this
6
- * one rather than a decision made somewhere above.
6
+ * one rather than a decision made somewhere above. The open thread and the
7
+ * message inside it are the segments below, which is why nothing here reads a
8
+ * selection out of the query.
7
9
  */
8
10
  import {
9
11
  createFileRoute,
@@ -15,6 +17,7 @@ import { BriefPane } from "@/components/mail/BriefPane";
15
17
  import { ErrorState } from "@/components/ui/ErrorState";
16
18
  import { useSearchMirror } from "@/hooks/useSearchMirror";
17
19
  import { briefSearchSchema } from "@/lib/mail-search";
20
+ import { useBriefThreadPath } from "@/routing";
18
21
 
19
22
  const BriefError = ({ error, reset }: ErrorComponentProps) => (
20
23
  <div className="flex h-full items-center justify-center bg-canvas p-4">
@@ -27,17 +30,17 @@ const BriefError = ({ error, reset }: ErrorComponentProps) => (
27
30
  );
28
31
 
29
32
  function BriefLayout() {
30
- const { selectedMessageId } = Route.useSearch();
33
+ const thread = useBriefThreadPath();
31
34
  useSearchMirror({ to: "/mail/brief" });
32
35
 
33
36
  return (
34
- <BriefPane selectedMessageId={selectedMessageId}>
37
+ <BriefPane thread={thread}>
35
38
  <MailShell
36
39
  phone={<BriefPane.Phone />}
37
40
  list={<BriefPane.List />}
38
41
  reading={<Outlet />}
39
42
  intelligence={<BriefPane.Intelligence />}
40
- hasThread={Boolean(selectedMessageId)}
43
+ hasThread={Boolean(thread)}
41
44
  />
42
45
  </BriefPane>
43
46
  );
@@ -0,0 +1,47 @@
1
+ import { useParams } from "@tanstack/react-router";
2
+ import { useMemo } from "react";
3
+
4
+ /** The conversation the brief has open, as the address states it. */
5
+ export interface BriefThreadPath {
6
+ threadId: string;
7
+ /**
8
+ * Which message inside the thread is expanded and scrolled to. Absent on a
9
+ * bare thread address, where the newest message answers for the conversation.
10
+ */
11
+ messageId: string | undefined;
12
+ }
13
+
14
+ /**
15
+ * A conversation to open. The thread is what the pane fetches by; the message is
16
+ * the row the reader pointed at, so a list always knows both.
17
+ */
18
+ export interface BriefThreadTarget {
19
+ threadId: string;
20
+ messageId: string;
21
+ }
22
+
23
+ /**
24
+ * The thread the brief has open, read off the path.
25
+ *
26
+ * The thread is a child route of the list, and the list layout mounts the pane
27
+ * above the `Outlet` — so it asks the router which of its children matched
28
+ * rather than reading a param it does not own. Each `from` names a real route,
29
+ * so a segment that does not exist fails to compile.
30
+ */
31
+ export function useBriefThreadPath(): BriefThreadPath | undefined {
32
+ const thread = useParams({
33
+ from: "/mail/brief/$threadId",
34
+ shouldThrow: false,
35
+ });
36
+ const message = useParams({
37
+ from: "/mail/brief/$threadId/$messageId",
38
+ shouldThrow: false,
39
+ });
40
+ const threadId = thread?.threadId;
41
+ const messageId = message?.messageId;
42
+
43
+ return useMemo(
44
+ () => (threadId ? { threadId, messageId } : undefined),
45
+ [threadId, messageId],
46
+ );
47
+ }
@@ -1,3 +1,8 @@
1
+ export {
2
+ type BriefThreadPath,
3
+ type BriefThreadTarget,
4
+ useBriefThreadPath,
5
+ } from "./brief-thread";
1
6
  export {
2
7
  type PanelFragment,
3
8
  panelFragments,