@remit/web-client 0.0.153 → 0.0.155
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.
- package/package.json +1 -1
- package/src/components/compose/ComposeForm.tsx +7 -0
- package/src/components/compose/ComposeProvider.tsx +7 -29
- package/src/components/compose/compose-clears-open-thread.render.test.ts +32 -22
- package/src/components/compose/compose-spellcheck.test.ts +122 -0
- package/src/components/compose/compose-spellcheck.ts +56 -0
- package/src/components/layout/ComposeFab.tsx +2 -7
- package/src/components/mail/FlaggedList.tsx +45 -15
- package/src/components/mail/FlaggedPane.tsx +106 -54
- package/src/components/mail/MailSidebarAdapter.tsx +1 -1
- package/src/components/mail/MessageActionMenu.tsx +2 -10
- package/src/components/mail/MessageList.tsx +1 -1
- package/src/components/ui/ErrorBanner.tsx +16 -1
- package/src/components/ui/ErrorBannerStack.tsx +1 -0
- package/src/components/ui/error-banners.ts +12 -0
- package/src/hooks/search-mirror-detail.render.test.ts +85 -61
- package/src/hooks/useSearchMirror.ts +3 -11
- package/src/lib/mail-search.ts +3 -4
- package/src/routeTree.gen.ts +72 -0
- package/src/routes/mail/flagged/$threadId/$messageId.tsx +19 -0
- package/src/routes/mail/flagged/$threadId/index.tsx +14 -0
- package/src/routes/mail/flagged/$threadId.tsx +16 -0
- package/src/routes/mail/flagged.tsx +7 -4
- package/src/routing/open-thread.ts +14 -2
|
@@ -31,10 +31,9 @@ export type SearchMirrorTarget =
|
|
|
31
31
|
* When a query *goes* active it also closes the reading pane (#539): an open
|
|
32
32
|
* message from the pre-search list is not meaningful in the search result set.
|
|
33
33
|
* The close is a navigation to the list route, which unmatches the thread that
|
|
34
|
-
* was open under it
|
|
35
|
-
* the
|
|
36
|
-
*
|
|
37
|
-
* one, must not shut the conversation they are reading.
|
|
34
|
+
* was open under it. Any other write keeps the address it found: mirroring a
|
|
35
|
+
* query the reader is editing, or clearing one, must not shut the conversation
|
|
36
|
+
* they are reading.
|
|
38
37
|
*
|
|
39
38
|
* Only on that transition, though — tapping a search result commits the same `q`
|
|
40
39
|
* with the open thread, so when the URL already says the query the conversation
|
|
@@ -71,13 +70,6 @@ export function useSearchMirror(target: SearchMirrorTarget): void {
|
|
|
71
70
|
const search = (prev: Record<string, unknown>) => ({
|
|
72
71
|
...prev,
|
|
73
72
|
q: committedQuery || undefined,
|
|
74
|
-
...(queryGoesActive
|
|
75
|
-
? {
|
|
76
|
-
selectedMessageId: undefined,
|
|
77
|
-
selectedThreadId: undefined,
|
|
78
|
-
selectedMailboxId: undefined,
|
|
79
|
-
}
|
|
80
|
-
: {}),
|
|
81
73
|
});
|
|
82
74
|
if (!queryGoesActive) {
|
|
83
75
|
navigate({ to: ".", search, replace: true });
|
package/src/lib/mail-search.ts
CHANGED
|
@@ -16,13 +16,12 @@ const listSearch = z.object({ q: z.string().optional() });
|
|
|
16
16
|
* The brief's open thread and the message inside it are path segments
|
|
17
17
|
* (`/mail/brief/<thread>/<message>`), so the query carries nothing but the
|
|
18
18
|
* search. An old link's selection params are dropped here, which is what
|
|
19
|
-
* "tolerated and ignored" means
|
|
19
|
+
* "tolerated and ignored" means.
|
|
20
20
|
*/
|
|
21
21
|
export const briefSearchSchema = listSearch.extend({});
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
23
|
+
/** The same, for `/mail/flagged/<thread>/<message>`. */
|
|
24
|
+
export const flaggedSearchSchema = listSearch.extend({});
|
|
26
25
|
|
|
27
26
|
/**
|
|
28
27
|
* The outbox's open message is a path segment
|
package/src/routeTree.gen.ts
CHANGED
|
@@ -32,11 +32,14 @@ import { Route as MailMailboxIdThreadIdRouteImport } from './routes/mail/$mailbo
|
|
|
32
32
|
import { Route as MailBriefIndexRouteImport } from './routes/mail/brief/index'
|
|
33
33
|
import { Route as MailBriefThreadIdRouteImport } from './routes/mail/brief/$threadId'
|
|
34
34
|
import { Route as MailFlaggedIndexRouteImport } from './routes/mail/flagged/index'
|
|
35
|
+
import { Route as MailFlaggedThreadIdRouteImport } from './routes/mail/flagged/$threadId'
|
|
35
36
|
import { Route as MailOutboxIndexRouteImport } from './routes/mail/outbox/index'
|
|
36
37
|
import { Route as MailMailboxIdThreadIdIndexRouteImport } from './routes/mail/$mailboxId/$threadId/index'
|
|
37
38
|
import { Route as MailMailboxIdThreadIdMessageIdRouteImport } from './routes/mail/$mailboxId/$threadId/$messageId'
|
|
38
39
|
import { Route as MailBriefThreadIdIndexRouteImport } from './routes/mail/brief/$threadId/index'
|
|
39
40
|
import { Route as MailBriefThreadIdMessageIdRouteImport } from './routes/mail/brief/$threadId/$messageId'
|
|
41
|
+
import { Route as MailFlaggedThreadIdIndexRouteImport } from './routes/mail/flagged/$threadId/index'
|
|
42
|
+
import { Route as MailFlaggedThreadIdMessageIdRouteImport } from './routes/mail/flagged/$threadId/$messageId'
|
|
40
43
|
import { Route as MailOutboxDraftOutboxMessageIdRouteImport } from './routes/mail/outbox/draft/$outboxMessageId'
|
|
41
44
|
|
|
42
45
|
const IndexRoute = IndexRouteImport.update({
|
|
@@ -154,6 +157,11 @@ const MailFlaggedIndexRoute = MailFlaggedIndexRouteImport.update({
|
|
|
154
157
|
path: '/',
|
|
155
158
|
getParentRoute: () => MailFlaggedRoute,
|
|
156
159
|
} as any)
|
|
160
|
+
const MailFlaggedThreadIdRoute = MailFlaggedThreadIdRouteImport.update({
|
|
161
|
+
id: '/$threadId',
|
|
162
|
+
path: '/$threadId',
|
|
163
|
+
getParentRoute: () => MailFlaggedRoute,
|
|
164
|
+
} as any)
|
|
157
165
|
const MailOutboxIndexRoute = MailOutboxIndexRouteImport.update({
|
|
158
166
|
id: '/',
|
|
159
167
|
path: '/',
|
|
@@ -182,6 +190,18 @@ const MailBriefThreadIdMessageIdRoute =
|
|
|
182
190
|
path: '/$messageId',
|
|
183
191
|
getParentRoute: () => MailBriefThreadIdRoute,
|
|
184
192
|
} as any)
|
|
193
|
+
const MailFlaggedThreadIdIndexRoute =
|
|
194
|
+
MailFlaggedThreadIdIndexRouteImport.update({
|
|
195
|
+
id: '/',
|
|
196
|
+
path: '/',
|
|
197
|
+
getParentRoute: () => MailFlaggedThreadIdRoute,
|
|
198
|
+
} as any)
|
|
199
|
+
const MailFlaggedThreadIdMessageIdRoute =
|
|
200
|
+
MailFlaggedThreadIdMessageIdRouteImport.update({
|
|
201
|
+
id: '/$messageId',
|
|
202
|
+
path: '/$messageId',
|
|
203
|
+
getParentRoute: () => MailFlaggedThreadIdRoute,
|
|
204
|
+
} as any)
|
|
185
205
|
const MailOutboxDraftOutboxMessageIdRoute =
|
|
186
206
|
MailOutboxDraftOutboxMessageIdRouteImport.update({
|
|
187
207
|
id: '/draft/$outboxMessageId',
|
|
@@ -210,15 +230,18 @@ export interface FileRoutesByFullPath {
|
|
|
210
230
|
'/settings/': typeof SettingsIndexRoute
|
|
211
231
|
'/mail/$mailboxId/$threadId': typeof MailMailboxIdThreadIdRouteWithChildren
|
|
212
232
|
'/mail/brief/$threadId': typeof MailBriefThreadIdRouteWithChildren
|
|
233
|
+
'/mail/flagged/$threadId': typeof MailFlaggedThreadIdRouteWithChildren
|
|
213
234
|
'/mail/$mailboxId/': typeof MailMailboxIdIndexRoute
|
|
214
235
|
'/mail/brief/': typeof MailBriefIndexRoute
|
|
215
236
|
'/mail/flagged/': typeof MailFlaggedIndexRoute
|
|
216
237
|
'/mail/outbox/': typeof MailOutboxIndexRoute
|
|
217
238
|
'/mail/$mailboxId/$threadId/$messageId': typeof MailMailboxIdThreadIdMessageIdRoute
|
|
218
239
|
'/mail/brief/$threadId/$messageId': typeof MailBriefThreadIdMessageIdRoute
|
|
240
|
+
'/mail/flagged/$threadId/$messageId': typeof MailFlaggedThreadIdMessageIdRoute
|
|
219
241
|
'/mail/outbox/draft/$outboxMessageId': typeof MailOutboxDraftOutboxMessageIdRoute
|
|
220
242
|
'/mail/$mailboxId/$threadId/': typeof MailMailboxIdThreadIdIndexRoute
|
|
221
243
|
'/mail/brief/$threadId/': typeof MailBriefThreadIdIndexRoute
|
|
244
|
+
'/mail/flagged/$threadId/': typeof MailFlaggedThreadIdIndexRoute
|
|
222
245
|
}
|
|
223
246
|
export interface FileRoutesByTo {
|
|
224
247
|
'/': typeof IndexRoute
|
|
@@ -239,9 +262,11 @@ export interface FileRoutesByTo {
|
|
|
239
262
|
'/mail/outbox': typeof MailOutboxIndexRoute
|
|
240
263
|
'/mail/$mailboxId/$threadId/$messageId': typeof MailMailboxIdThreadIdMessageIdRoute
|
|
241
264
|
'/mail/brief/$threadId/$messageId': typeof MailBriefThreadIdMessageIdRoute
|
|
265
|
+
'/mail/flagged/$threadId/$messageId': typeof MailFlaggedThreadIdMessageIdRoute
|
|
242
266
|
'/mail/outbox/draft/$outboxMessageId': typeof MailOutboxDraftOutboxMessageIdRoute
|
|
243
267
|
'/mail/$mailboxId/$threadId': typeof MailMailboxIdThreadIdIndexRoute
|
|
244
268
|
'/mail/brief/$threadId': typeof MailBriefThreadIdIndexRoute
|
|
269
|
+
'/mail/flagged/$threadId': typeof MailFlaggedThreadIdIndexRoute
|
|
245
270
|
}
|
|
246
271
|
export interface FileRoutesById {
|
|
247
272
|
__root__: typeof rootRouteImport
|
|
@@ -265,15 +290,18 @@ export interface FileRoutesById {
|
|
|
265
290
|
'/settings/': typeof SettingsIndexRoute
|
|
266
291
|
'/mail/$mailboxId/$threadId': typeof MailMailboxIdThreadIdRouteWithChildren
|
|
267
292
|
'/mail/brief/$threadId': typeof MailBriefThreadIdRouteWithChildren
|
|
293
|
+
'/mail/flagged/$threadId': typeof MailFlaggedThreadIdRouteWithChildren
|
|
268
294
|
'/mail/$mailboxId/': typeof MailMailboxIdIndexRoute
|
|
269
295
|
'/mail/brief/': typeof MailBriefIndexRoute
|
|
270
296
|
'/mail/flagged/': typeof MailFlaggedIndexRoute
|
|
271
297
|
'/mail/outbox/': typeof MailOutboxIndexRoute
|
|
272
298
|
'/mail/$mailboxId/$threadId/$messageId': typeof MailMailboxIdThreadIdMessageIdRoute
|
|
273
299
|
'/mail/brief/$threadId/$messageId': typeof MailBriefThreadIdMessageIdRoute
|
|
300
|
+
'/mail/flagged/$threadId/$messageId': typeof MailFlaggedThreadIdMessageIdRoute
|
|
274
301
|
'/mail/outbox/draft/$outboxMessageId': typeof MailOutboxDraftOutboxMessageIdRoute
|
|
275
302
|
'/mail/$mailboxId/$threadId/': typeof MailMailboxIdThreadIdIndexRoute
|
|
276
303
|
'/mail/brief/$threadId/': typeof MailBriefThreadIdIndexRoute
|
|
304
|
+
'/mail/flagged/$threadId/': typeof MailFlaggedThreadIdIndexRoute
|
|
277
305
|
}
|
|
278
306
|
export interface FileRouteTypes {
|
|
279
307
|
fileRoutesByFullPath: FileRoutesByFullPath
|
|
@@ -298,15 +326,18 @@ export interface FileRouteTypes {
|
|
|
298
326
|
| '/settings/'
|
|
299
327
|
| '/mail/$mailboxId/$threadId'
|
|
300
328
|
| '/mail/brief/$threadId'
|
|
329
|
+
| '/mail/flagged/$threadId'
|
|
301
330
|
| '/mail/$mailboxId/'
|
|
302
331
|
| '/mail/brief/'
|
|
303
332
|
| '/mail/flagged/'
|
|
304
333
|
| '/mail/outbox/'
|
|
305
334
|
| '/mail/$mailboxId/$threadId/$messageId'
|
|
306
335
|
| '/mail/brief/$threadId/$messageId'
|
|
336
|
+
| '/mail/flagged/$threadId/$messageId'
|
|
307
337
|
| '/mail/outbox/draft/$outboxMessageId'
|
|
308
338
|
| '/mail/$mailboxId/$threadId/'
|
|
309
339
|
| '/mail/brief/$threadId/'
|
|
340
|
+
| '/mail/flagged/$threadId/'
|
|
310
341
|
fileRoutesByTo: FileRoutesByTo
|
|
311
342
|
to:
|
|
312
343
|
| '/'
|
|
@@ -327,9 +358,11 @@ export interface FileRouteTypes {
|
|
|
327
358
|
| '/mail/outbox'
|
|
328
359
|
| '/mail/$mailboxId/$threadId/$messageId'
|
|
329
360
|
| '/mail/brief/$threadId/$messageId'
|
|
361
|
+
| '/mail/flagged/$threadId/$messageId'
|
|
330
362
|
| '/mail/outbox/draft/$outboxMessageId'
|
|
331
363
|
| '/mail/$mailboxId/$threadId'
|
|
332
364
|
| '/mail/brief/$threadId'
|
|
365
|
+
| '/mail/flagged/$threadId'
|
|
333
366
|
id:
|
|
334
367
|
| '__root__'
|
|
335
368
|
| '/'
|
|
@@ -352,15 +385,18 @@ export interface FileRouteTypes {
|
|
|
352
385
|
| '/settings/'
|
|
353
386
|
| '/mail/$mailboxId/$threadId'
|
|
354
387
|
| '/mail/brief/$threadId'
|
|
388
|
+
| '/mail/flagged/$threadId'
|
|
355
389
|
| '/mail/$mailboxId/'
|
|
356
390
|
| '/mail/brief/'
|
|
357
391
|
| '/mail/flagged/'
|
|
358
392
|
| '/mail/outbox/'
|
|
359
393
|
| '/mail/$mailboxId/$threadId/$messageId'
|
|
360
394
|
| '/mail/brief/$threadId/$messageId'
|
|
395
|
+
| '/mail/flagged/$threadId/$messageId'
|
|
361
396
|
| '/mail/outbox/draft/$outboxMessageId'
|
|
362
397
|
| '/mail/$mailboxId/$threadId/'
|
|
363
398
|
| '/mail/brief/$threadId/'
|
|
399
|
+
| '/mail/flagged/$threadId/'
|
|
364
400
|
fileRoutesById: FileRoutesById
|
|
365
401
|
}
|
|
366
402
|
export interface RootRouteChildren {
|
|
@@ -533,6 +569,13 @@ declare module '@tanstack/react-router' {
|
|
|
533
569
|
preLoaderRoute: typeof MailFlaggedIndexRouteImport
|
|
534
570
|
parentRoute: typeof MailFlaggedRoute
|
|
535
571
|
}
|
|
572
|
+
'/mail/flagged/$threadId': {
|
|
573
|
+
id: '/mail/flagged/$threadId'
|
|
574
|
+
path: '/$threadId'
|
|
575
|
+
fullPath: '/mail/flagged/$threadId'
|
|
576
|
+
preLoaderRoute: typeof MailFlaggedThreadIdRouteImport
|
|
577
|
+
parentRoute: typeof MailFlaggedRoute
|
|
578
|
+
}
|
|
536
579
|
'/mail/outbox/': {
|
|
537
580
|
id: '/mail/outbox/'
|
|
538
581
|
path: '/'
|
|
@@ -568,6 +611,20 @@ declare module '@tanstack/react-router' {
|
|
|
568
611
|
preLoaderRoute: typeof MailBriefThreadIdMessageIdRouteImport
|
|
569
612
|
parentRoute: typeof MailBriefThreadIdRoute
|
|
570
613
|
}
|
|
614
|
+
'/mail/flagged/$threadId/': {
|
|
615
|
+
id: '/mail/flagged/$threadId/'
|
|
616
|
+
path: '/'
|
|
617
|
+
fullPath: '/mail/flagged/$threadId/'
|
|
618
|
+
preLoaderRoute: typeof MailFlaggedThreadIdIndexRouteImport
|
|
619
|
+
parentRoute: typeof MailFlaggedThreadIdRoute
|
|
620
|
+
}
|
|
621
|
+
'/mail/flagged/$threadId/$messageId': {
|
|
622
|
+
id: '/mail/flagged/$threadId/$messageId'
|
|
623
|
+
path: '/$messageId'
|
|
624
|
+
fullPath: '/mail/flagged/$threadId/$messageId'
|
|
625
|
+
preLoaderRoute: typeof MailFlaggedThreadIdMessageIdRouteImport
|
|
626
|
+
parentRoute: typeof MailFlaggedThreadIdRoute
|
|
627
|
+
}
|
|
571
628
|
'/mail/outbox/draft/$outboxMessageId': {
|
|
572
629
|
id: '/mail/outbox/draft/$outboxMessageId'
|
|
573
630
|
path: '/draft/$outboxMessageId'
|
|
@@ -634,11 +691,26 @@ const MailBriefRouteWithChildren = MailBriefRoute._addFileChildren(
|
|
|
634
691
|
MailBriefRouteChildren,
|
|
635
692
|
)
|
|
636
693
|
|
|
694
|
+
interface MailFlaggedThreadIdRouteChildren {
|
|
695
|
+
MailFlaggedThreadIdMessageIdRoute: typeof MailFlaggedThreadIdMessageIdRoute
|
|
696
|
+
MailFlaggedThreadIdIndexRoute: typeof MailFlaggedThreadIdIndexRoute
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
const MailFlaggedThreadIdRouteChildren: MailFlaggedThreadIdRouteChildren = {
|
|
700
|
+
MailFlaggedThreadIdMessageIdRoute: MailFlaggedThreadIdMessageIdRoute,
|
|
701
|
+
MailFlaggedThreadIdIndexRoute: MailFlaggedThreadIdIndexRoute,
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
const MailFlaggedThreadIdRouteWithChildren =
|
|
705
|
+
MailFlaggedThreadIdRoute._addFileChildren(MailFlaggedThreadIdRouteChildren)
|
|
706
|
+
|
|
637
707
|
interface MailFlaggedRouteChildren {
|
|
708
|
+
MailFlaggedThreadIdRoute: typeof MailFlaggedThreadIdRouteWithChildren
|
|
638
709
|
MailFlaggedIndexRoute: typeof MailFlaggedIndexRoute
|
|
639
710
|
}
|
|
640
711
|
|
|
641
712
|
const MailFlaggedRouteChildren: MailFlaggedRouteChildren = {
|
|
713
|
+
MailFlaggedThreadIdRoute: MailFlaggedThreadIdRouteWithChildren,
|
|
642
714
|
MailFlaggedIndexRoute: MailFlaggedIndexRoute,
|
|
643
715
|
}
|
|
644
716
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /mail/flagged/$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 { FlaggedPane } from "@/components/mail/FlaggedPane";
|
|
12
|
+
|
|
13
|
+
function FlaggedMessagePane() {
|
|
14
|
+
return <FlaggedPane.Reading />;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const Route = createFileRoute("/mail/flagged/$threadId/$messageId")({
|
|
18
|
+
component: FlaggedMessagePane,
|
|
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 { FlaggedPane } from "@/components/mail/FlaggedPane";
|
|
7
|
+
|
|
8
|
+
function FlaggedThreadPane() {
|
|
9
|
+
return <FlaggedPane.Reading />;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const Route = createFileRoute("/mail/flagged/$threadId/")({
|
|
13
|
+
component: FlaggedThreadPane,
|
|
14
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /mail/flagged/$threadId — a conversation open in the flagged list's reading
|
|
3
|
+
* pane.
|
|
4
|
+
*
|
|
5
|
+
* Starred mail spans accounts and folders, and the thread is still the whole
|
|
6
|
+
* address: the folder its mail is filed in comes from the thread's own data,
|
|
7
|
+
* since `GET /threads/{threadId}/messages` answers with rows that each name
|
|
8
|
+
* their mailbox.
|
|
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/flagged/$threadId")({
|
|
15
|
+
component: Outlet,
|
|
16
|
+
});
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
* /mail/flagged — the Flagged virtual mailbox, one of the four list layouts.
|
|
3
3
|
*
|
|
4
4
|
* A flat starred list across accounts; same slots as the brief, intelligence
|
|
5
|
-
* rail included.
|
|
5
|
+
* rail included. The reading pane is the `Outlet`, so what it shows is whatever
|
|
6
|
+
* route matched below this one, and the open thread and the message inside it
|
|
7
|
+
* are the segments there rather than a selection read out of the query.
|
|
6
8
|
*/
|
|
7
9
|
import {
|
|
8
10
|
createFileRoute,
|
|
@@ -14,6 +16,7 @@ import { FlaggedPane } from "@/components/mail/FlaggedPane";
|
|
|
14
16
|
import { ErrorState } from "@/components/ui/ErrorState";
|
|
15
17
|
import { useSearchMirror } from "@/hooks/useSearchMirror";
|
|
16
18
|
import { flaggedSearchSchema } from "@/lib/mail-search";
|
|
19
|
+
import { useOpenThreadPath } from "@/routing";
|
|
17
20
|
|
|
18
21
|
const FlaggedError = ({ error, reset }: ErrorComponentProps) => (
|
|
19
22
|
<div className="flex h-full items-center justify-center bg-canvas p-4">
|
|
@@ -26,17 +29,17 @@ const FlaggedError = ({ error, reset }: ErrorComponentProps) => (
|
|
|
26
29
|
);
|
|
27
30
|
|
|
28
31
|
function FlaggedLayout() {
|
|
29
|
-
const
|
|
32
|
+
const thread = useOpenThreadPath();
|
|
30
33
|
useSearchMirror({ to: "/mail/flagged" });
|
|
31
34
|
|
|
32
35
|
return (
|
|
33
|
-
<FlaggedPane
|
|
36
|
+
<FlaggedPane thread={thread}>
|
|
34
37
|
<MailShell
|
|
35
38
|
phone={<FlaggedPane.Phone />}
|
|
36
39
|
list={<FlaggedPane.List />}
|
|
37
40
|
reading={<Outlet />}
|
|
38
41
|
intelligence={<FlaggedPane.Intelligence />}
|
|
39
|
-
hasThread={Boolean(
|
|
42
|
+
hasThread={Boolean(thread)}
|
|
40
43
|
/>
|
|
41
44
|
</FlaggedPane>
|
|
42
45
|
);
|
|
@@ -39,6 +39,14 @@ export function useOpenThreadPath(): OpenThreadPath | undefined {
|
|
|
39
39
|
from: "/mail/brief/$threadId/$messageId",
|
|
40
40
|
shouldThrow: false,
|
|
41
41
|
});
|
|
42
|
+
const flaggedThread = useParams({
|
|
43
|
+
from: "/mail/flagged/$threadId",
|
|
44
|
+
shouldThrow: false,
|
|
45
|
+
});
|
|
46
|
+
const flaggedMessage = useParams({
|
|
47
|
+
from: "/mail/flagged/$threadId/$messageId",
|
|
48
|
+
shouldThrow: false,
|
|
49
|
+
});
|
|
42
50
|
const mailboxThread = useParams({
|
|
43
51
|
from: "/mail/$mailboxId/$threadId",
|
|
44
52
|
shouldThrow: false,
|
|
@@ -48,8 +56,12 @@ export function useOpenThreadPath(): OpenThreadPath | undefined {
|
|
|
48
56
|
shouldThrow: false,
|
|
49
57
|
});
|
|
50
58
|
|
|
51
|
-
const threadId =
|
|
52
|
-
|
|
59
|
+
const threadId =
|
|
60
|
+
briefThread?.threadId ?? flaggedThread?.threadId ?? mailboxThread?.threadId;
|
|
61
|
+
const messageId =
|
|
62
|
+
briefMessage?.messageId ??
|
|
63
|
+
flaggedMessage?.messageId ??
|
|
64
|
+
mailboxMessage?.messageId;
|
|
53
65
|
|
|
54
66
|
return useMemo(
|
|
55
67
|
() => (threadId ? { threadId, messageId } : undefined),
|