@agent-native/core 0.195.0 → 0.195.1-nightly-20260927210321
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/corpus/README.md +1 -1
- package/corpus/templates/design/actions/generate-home-suggestions.ts +55 -7
- package/corpus/templates/design/app/components/design/design-canvas/LocalNetworkAccessPrompt.tsx +82 -18
- package/corpus/templates/design/app/i18n/en-US.ts +6 -1
- package/corpus/templates/design/changelog/2026-09-27-local-access-setup-shows-chrome-permission-screenshots-and-c.md +6 -0
- package/corpus/templates/design/changelog/2026-09-27-personalized-home-suggestions-work-when-responses-include-ex.md +6 -0
- package/corpus/templates/mail/app/components/email/EmailList.tsx +10 -0
- package/corpus/templates/mail/app/components/email/EmailListItem.tsx +78 -1
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +9 -9
- package/corpus/templates/mail/app/components/layout/SearchBar.tsx +192 -175
- package/corpus/templates/mail/app/components/onboarding/AiInboxSetup.tsx +4 -0
- package/corpus/templates/mail/app/global.css +14 -0
- package/corpus/templates/mail/changelog/2026-09-27-inbox-priority-shows-each-email-s-score-with-quick-feedback-.md +6 -0
- package/corpus/templates/mail/changelog/2026-09-27-mail-setup-waits-for-first-run-onboarding-and-empty-importan.md +6 -0
- package/corpus/templates/mail/changelog/2026-09-27-mobile-inbox-toolbar-scrolls-together.md +6 -0
- package/corpus/templates/slides/actions/generate-home-suggestions.ts +55 -11
- package/corpus/templates/slides/changelog/2026-09-27-personalized-presentation-suggestions-work-when-responses-in.md +6 -0
- package/dist/client/onboarding/first-run-startup-gate.js +3 -2
- package/dist/collab/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/org/auth-policy.js +0 -2
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/provider-api.d.ts +4 -4
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/auth-plugin.js +2 -1
- package/dist/server/auth.js +22 -43
- package/dist/triggers/actions/manage-automation.d.ts +2 -2
- package/dist/vite/agent-native-config-loader.js +4 -2
- package/package.json +3 -3
- package/dist/server/session-email-cache.d.ts +0 -14
- package/dist/server/session-email-cache.js +0 -53
package/corpus/README.md
CHANGED
|
@@ -48,22 +48,70 @@ function roleContext(value: string | null | undefined): string {
|
|
|
48
48
|
return `The user's selected onboarding role is ${JSON.stringify(role)}. Tailor suggestions to that role's typical work and goals.`;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
function findArrayEnd(text: string, start: number): number | undefined {
|
|
52
|
+
let depth = 0;
|
|
53
|
+
let inString = false;
|
|
54
|
+
let escaped = false;
|
|
55
|
+
|
|
56
|
+
for (let index = start; index < text.length; index++) {
|
|
57
|
+
const char = text[index];
|
|
58
|
+
if (inString) {
|
|
59
|
+
if (escaped) escaped = false;
|
|
60
|
+
else if (char === "\\") escaped = true;
|
|
61
|
+
else if (char === '"') inString = false;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (char === '"') inString = true;
|
|
65
|
+
else if (char === "[") depth++;
|
|
66
|
+
else if (char === "]" && --depth === 0) return index;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
51
70
|
function parseSuggestions(text: string) {
|
|
52
71
|
const unwrapped = text
|
|
53
72
|
.trim()
|
|
54
73
|
.replace(/^```(?:json)?\s*/i, "")
|
|
55
74
|
.replace(/\s*```$/i, "");
|
|
56
|
-
let
|
|
75
|
+
let parsedJson: unknown;
|
|
76
|
+
let hasTopLevelJson = false;
|
|
57
77
|
try {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
78
|
+
parsedJson = JSON.parse(unwrapped);
|
|
79
|
+
hasTopLevelJson = true;
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if (!(error instanceof SyntaxError)) throw error;
|
|
82
|
+
}
|
|
83
|
+
if (hasTopLevelJson) {
|
|
84
|
+
const result = suggestionsSchema.safeParse(parsedJson);
|
|
85
|
+
if (!result.success) {
|
|
86
|
+
throw new Error("Home suggestions returned an invalid shape.");
|
|
87
|
+
}
|
|
88
|
+
return result.data;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
let parsedCandidateJson = false;
|
|
92
|
+
for (
|
|
93
|
+
let start = unwrapped.indexOf("[");
|
|
94
|
+
start >= 0;
|
|
95
|
+
start = unwrapped.indexOf("[", start + 1)
|
|
96
|
+
) {
|
|
97
|
+
const end = findArrayEnd(unwrapped, start);
|
|
98
|
+
if (end === undefined) continue;
|
|
99
|
+
|
|
100
|
+
let parsed: unknown;
|
|
101
|
+
try {
|
|
102
|
+
parsed = JSON.parse(unwrapped.slice(start, end + 1));
|
|
103
|
+
} catch (error) {
|
|
104
|
+
if (!(error instanceof SyntaxError)) throw error;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
parsedCandidateJson = true;
|
|
108
|
+
const result = suggestionsSchema.safeParse(parsed);
|
|
109
|
+
if (result.success) return result.data;
|
|
61
110
|
}
|
|
62
|
-
|
|
63
|
-
if (!result.success) {
|
|
111
|
+
if (parsedCandidateJson) {
|
|
64
112
|
throw new Error("Home suggestions returned an invalid shape.");
|
|
65
113
|
}
|
|
66
|
-
|
|
114
|
+
throw new Error("Home suggestions returned invalid JSON.");
|
|
67
115
|
}
|
|
68
116
|
|
|
69
117
|
export default defineAction({
|
package/corpus/templates/design/app/components/design/design-canvas/LocalNetworkAccessPrompt.tsx
CHANGED
|
@@ -4,7 +4,18 @@ import {
|
|
|
4
4
|
IconPlugConnectedX,
|
|
5
5
|
IconX,
|
|
6
6
|
} from "@tabler/icons-react";
|
|
7
|
+
import { useState } from "react";
|
|
7
8
|
|
|
9
|
+
import {
|
|
10
|
+
AlertDialog,
|
|
11
|
+
AlertDialogAction,
|
|
12
|
+
AlertDialogCancel,
|
|
13
|
+
AlertDialogContent,
|
|
14
|
+
AlertDialogDescription,
|
|
15
|
+
AlertDialogFooter,
|
|
16
|
+
AlertDialogHeader,
|
|
17
|
+
AlertDialogTitle,
|
|
18
|
+
} from "@/components/ui/alert-dialog";
|
|
8
19
|
import { Button } from "@/components/ui/button";
|
|
9
20
|
import {
|
|
10
21
|
Dialog,
|
|
@@ -30,6 +41,7 @@ export function LocalNetworkAccessPrompt({
|
|
|
30
41
|
proactive?: boolean;
|
|
31
42
|
}) {
|
|
32
43
|
const t = useT();
|
|
44
|
+
const [confirmClose, setConfirmClose] = useState(false);
|
|
33
45
|
// "unreachable" is the one confident case (permission is confirmed
|
|
34
46
|
// granted, so it's confirmed NOT the cause) — every other kind is
|
|
35
47
|
// deliberately hedged copy, never a diagnosed permission claim. See
|
|
@@ -69,35 +81,87 @@ export function LocalNetworkAccessPrompt({
|
|
|
69
81
|
"designCanvas.localBridge.permissionPromptSettingsInstructions",
|
|
70
82
|
{
|
|
71
83
|
defaultValue:
|
|
72
|
-
"Click the site
|
|
84
|
+
"Click the site controls icon to the left of the address bar, open Site settings, then allow access to apps on your device.",
|
|
73
85
|
},
|
|
74
86
|
);
|
|
75
87
|
const permissionHelp = showPermissionHelp ? (
|
|
76
88
|
<details className="text-xs text-muted-foreground">
|
|
77
89
|
<summary className="cursor-pointer">{noPromptLabel}</summary>
|
|
78
90
|
<p className="mt-2 leading-relaxed">{permissionSettingsInstructions}</p>
|
|
91
|
+
<img
|
|
92
|
+
src="/local-network-access-settings.jpg"
|
|
93
|
+
alt={permissionSettingsInstructions}
|
|
94
|
+
className="mt-3 block w-full rounded-md border border-border"
|
|
95
|
+
width={200}
|
|
96
|
+
height={140}
|
|
97
|
+
loading="lazy"
|
|
98
|
+
/>
|
|
79
99
|
</details>
|
|
80
100
|
) : null;
|
|
81
101
|
|
|
82
102
|
if (proactive) {
|
|
83
103
|
return (
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
104
|
+
<>
|
|
105
|
+
<Dialog
|
|
106
|
+
open
|
|
107
|
+
onOpenChange={(open) => {
|
|
108
|
+
if (!open) setConfirmClose(true);
|
|
109
|
+
}}
|
|
110
|
+
>
|
|
111
|
+
<DialogContent
|
|
112
|
+
className="sm:max-w-md"
|
|
113
|
+
overlayClassName="bg-[color-mix(in_srgb,var(--design-editor-accent-color)_22%,transparent)] backdrop-blur-[2px]"
|
|
114
|
+
>
|
|
115
|
+
<DialogHeader>
|
|
116
|
+
<DialogTitle className="flex items-center gap-2">
|
|
117
|
+
<IconPlugConnected className="size-4" />
|
|
118
|
+
{title}
|
|
119
|
+
</DialogTitle>
|
|
120
|
+
<DialogDescription>{description}</DialogDescription>
|
|
121
|
+
</DialogHeader>
|
|
122
|
+
<img
|
|
123
|
+
src="/local-network-access-permission.jpg"
|
|
124
|
+
alt={description}
|
|
125
|
+
className="block w-full rounded-md border border-border"
|
|
126
|
+
width={240}
|
|
127
|
+
height={150}
|
|
128
|
+
/>
|
|
129
|
+
{permissionHelp}
|
|
130
|
+
</DialogContent>
|
|
131
|
+
</Dialog>
|
|
132
|
+
<AlertDialog open={confirmClose} onOpenChange={setConfirmClose}>
|
|
133
|
+
<AlertDialogContent>
|
|
134
|
+
<AlertDialogHeader>
|
|
135
|
+
<AlertDialogTitle>
|
|
136
|
+
{t("designCanvas.localBridge.permissionCloseTitle", {
|
|
137
|
+
defaultValue: "Close setup?",
|
|
138
|
+
})}
|
|
139
|
+
</AlertDialogTitle>
|
|
140
|
+
<AlertDialogDescription>
|
|
141
|
+
{t("designCanvas.localBridge.permissionCloseDescription", {
|
|
142
|
+
defaultValue:
|
|
143
|
+
"Live editing won't work until you allow access in Chrome.",
|
|
144
|
+
})}
|
|
145
|
+
</AlertDialogDescription>
|
|
146
|
+
</AlertDialogHeader>
|
|
147
|
+
<AlertDialogFooter>
|
|
148
|
+
<AlertDialogCancel>
|
|
149
|
+
{t("designCanvas.localBridge.permissionCloseStay", {
|
|
150
|
+
defaultValue: "Keep setup open",
|
|
151
|
+
})}
|
|
152
|
+
</AlertDialogCancel>
|
|
153
|
+
<AlertDialogAction
|
|
154
|
+
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
|
155
|
+
onClick={onDismiss}
|
|
156
|
+
>
|
|
157
|
+
{t("designCanvas.localBridge.permissionCloseAnyway", {
|
|
158
|
+
defaultValue: "Close anyway",
|
|
159
|
+
})}
|
|
160
|
+
</AlertDialogAction>
|
|
161
|
+
</AlertDialogFooter>
|
|
162
|
+
</AlertDialogContent>
|
|
163
|
+
</AlertDialog>
|
|
164
|
+
</>
|
|
101
165
|
);
|
|
102
166
|
}
|
|
103
167
|
|
|
@@ -1478,7 +1478,12 @@ export default {
|
|
|
1478
1478
|
"Choose Allow in Chrome's prompt to enable live editing.",
|
|
1479
1479
|
permissionPromptNoPrompt: "No Chrome prompt?",
|
|
1480
1480
|
permissionPromptSettingsInstructions:
|
|
1481
|
-
"Click the site
|
|
1481
|
+
"Click the site controls icon to the left of the address bar, open Site settings, then allow access to apps on your device.",
|
|
1482
|
+
permissionCloseTitle: "Close setup?",
|
|
1483
|
+
permissionCloseDescription:
|
|
1484
|
+
"Live editing won't work until you allow access in Chrome.",
|
|
1485
|
+
permissionCloseStay: "Keep setup open",
|
|
1486
|
+
permissionCloseAnyway: "Close anyway",
|
|
1482
1487
|
permissionPromptRetry: "Retry connection",
|
|
1483
1488
|
confirmationRetryExhausted:
|
|
1484
1489
|
"Live editor bridge did not confirm after several attempts.",
|
|
@@ -2672,6 +2672,16 @@ export function EmailList({
|
|
|
2672
2672
|
>
|
|
2673
2673
|
<EmailListItem
|
|
2674
2674
|
email={thread.latestMessage}
|
|
2675
|
+
importanceScore={
|
|
2676
|
+
view === "inbox" && currentSortMode === "priority"
|
|
2677
|
+
? cachedPriorityScores.get(
|
|
2678
|
+
aiPriorityEmailKey(
|
|
2679
|
+
thread.latestMessage.accountEmail,
|
|
2680
|
+
thread.latestMessage.id,
|
|
2681
|
+
),
|
|
2682
|
+
)
|
|
2683
|
+
: undefined
|
|
2684
|
+
}
|
|
2675
2685
|
labelNames={labelNames}
|
|
2676
2686
|
thread={thread}
|
|
2677
2687
|
isSelected={thread.latestMessage.id === threadId}
|
|
@@ -14,10 +14,18 @@ import {
|
|
|
14
14
|
IconSquareCheck,
|
|
15
15
|
IconSend,
|
|
16
16
|
IconX,
|
|
17
|
+
IconThumbDown,
|
|
18
|
+
IconThumbUp,
|
|
17
19
|
} from "@tabler/icons-react";
|
|
18
|
-
import { memo, useRef, useState, useCallback } from "react";
|
|
20
|
+
import { memo, useRef, useState, useCallback, type CSSProperties } from "react";
|
|
21
|
+
import { Link } from "react-router";
|
|
19
22
|
|
|
20
23
|
import { ImportanceFeedbackMenu } from "@/components/email/ImportanceFeedbackMenu";
|
|
24
|
+
import {
|
|
25
|
+
Popover,
|
|
26
|
+
PopoverContent,
|
|
27
|
+
PopoverTrigger,
|
|
28
|
+
} from "@/components/ui/popover";
|
|
21
29
|
import {
|
|
22
30
|
Tooltip,
|
|
23
31
|
TooltipContent,
|
|
@@ -31,6 +39,7 @@ import { cn, formatEmailDate } from "@/lib/utils";
|
|
|
31
39
|
|
|
32
40
|
interface EmailListItemProps {
|
|
33
41
|
email: EmailMessage;
|
|
42
|
+
importanceScore?: number;
|
|
34
43
|
labelNames?: ReadonlyMap<string, string>;
|
|
35
44
|
thread?: ThreadSummary;
|
|
36
45
|
isSelected: boolean;
|
|
@@ -109,6 +118,7 @@ function getAccountColor(
|
|
|
109
118
|
|
|
110
119
|
export const EmailListItem = memo(function EmailListItem({
|
|
111
120
|
email,
|
|
121
|
+
importanceScore,
|
|
112
122
|
labelNames,
|
|
113
123
|
thread,
|
|
114
124
|
isSelected,
|
|
@@ -145,6 +155,8 @@ export const EmailListItem = memo(function EmailListItem({
|
|
|
145
155
|
|
|
146
156
|
const [dragX, setDragX] = useState(0);
|
|
147
157
|
const [isDragging, setIsDragging] = useState(false);
|
|
158
|
+
const [priorityScorePopoverOpen, setPriorityScorePopoverOpen] =
|
|
159
|
+
useState(false);
|
|
148
160
|
const gestureRef = useRef<{
|
|
149
161
|
startX: number;
|
|
150
162
|
startY: number;
|
|
@@ -614,6 +626,71 @@ export const EmailListItem = memo(function EmailListItem({
|
|
|
614
626
|
<span className="row-time text-xs text-muted-foreground tabular-nums sm:text-[12px]">
|
|
615
627
|
{formatEmailDate(email.date)}
|
|
616
628
|
</span>
|
|
629
|
+
{importanceScore !== undefined && (
|
|
630
|
+
<Popover
|
|
631
|
+
open={priorityScorePopoverOpen}
|
|
632
|
+
onOpenChange={setPriorityScorePopoverOpen}
|
|
633
|
+
>
|
|
634
|
+
<PopoverTrigger asChild>
|
|
635
|
+
<button
|
|
636
|
+
type="button"
|
|
637
|
+
onClick={(event) => event.stopPropagation()}
|
|
638
|
+
onKeyDown={(event) => event.stopPropagation()}
|
|
639
|
+
aria-label={`${t("mail.sort.priority")} ${importanceScore.toFixed(2)}`}
|
|
640
|
+
className="email-importance-score mx-1 inline-flex h-6 w-10 shrink-0 items-center justify-end rounded px-1 text-[11px] font-medium tabular-nums hover:bg-accent"
|
|
641
|
+
style={
|
|
642
|
+
{
|
|
643
|
+
"--mail-importance-weight": `${Math.round(importanceScore * 100)}%`,
|
|
644
|
+
} as CSSProperties
|
|
645
|
+
}
|
|
646
|
+
>
|
|
647
|
+
{importanceScore.toFixed(2)}
|
|
648
|
+
</button>
|
|
649
|
+
</PopoverTrigger>
|
|
650
|
+
<PopoverContent
|
|
651
|
+
align="end"
|
|
652
|
+
className="w-56 p-2"
|
|
653
|
+
onClick={(event) => event.stopPropagation()}
|
|
654
|
+
onKeyDown={(event) => event.stopPropagation()}
|
|
655
|
+
onPointerDown={(event) => event.stopPropagation()}
|
|
656
|
+
>
|
|
657
|
+
<div className="mb-1 text-xs font-medium">
|
|
658
|
+
{t("mail.sort.priority")} · {importanceScore.toFixed(2)}
|
|
659
|
+
</div>
|
|
660
|
+
<p className="mb-2 text-xs text-muted-foreground">
|
|
661
|
+
{t("mail.sort.priorityScoreHelp")}
|
|
662
|
+
</p>
|
|
663
|
+
<button
|
|
664
|
+
type="button"
|
|
665
|
+
onClick={() => {
|
|
666
|
+
setPriorityScorePopoverOpen(false);
|
|
667
|
+
onImportanceFeedback?.("important");
|
|
668
|
+
}}
|
|
669
|
+
className="flex w-full items-center gap-2 whitespace-nowrap rounded px-2 py-1.5 text-xs hover:bg-accent"
|
|
670
|
+
>
|
|
671
|
+
<IconThumbUp aria-hidden="true" className="size-3.5" />
|
|
672
|
+
{t("mail.aiFilter.importantMode")}
|
|
673
|
+
</button>
|
|
674
|
+
<button
|
|
675
|
+
type="button"
|
|
676
|
+
onClick={() => {
|
|
677
|
+
setPriorityScorePopoverOpen(false);
|
|
678
|
+
onImportanceFeedback?.("not-important");
|
|
679
|
+
}}
|
|
680
|
+
className="flex w-full items-center gap-2 whitespace-nowrap rounded px-2 py-1.5 text-xs hover:bg-accent"
|
|
681
|
+
>
|
|
682
|
+
<IconThumbDown aria-hidden="true" className="size-3.5" />
|
|
683
|
+
{t("mail.aiFilter.notImportantMode")}
|
|
684
|
+
</button>
|
|
685
|
+
<Link
|
|
686
|
+
to="/settings?section=ai-filter"
|
|
687
|
+
className="mt-1 block border-t border-border/40 px-2 pt-2 text-xs text-muted-foreground hover:text-foreground"
|
|
688
|
+
>
|
|
689
|
+
{t("mail.sort.priorityEditRules")}
|
|
690
|
+
</Link>
|
|
691
|
+
</PopoverContent>
|
|
692
|
+
</Popover>
|
|
693
|
+
)}
|
|
617
694
|
{/* Hover actions overlay the preview while the time stays fixed. */}
|
|
618
695
|
<div className="hover-actions gap-0.5">
|
|
619
696
|
{onToggleRead && (
|
|
@@ -1251,14 +1251,14 @@ function AppLayoutInner({ children }: AppLayoutProps) {
|
|
|
1251
1251
|
<AccountFilterContext.Provider value={accountFilterValue}>
|
|
1252
1252
|
<div className="relative flex flex-1 flex-col overflow-hidden bg-background">
|
|
1253
1253
|
{/* Top nav bar */}
|
|
1254
|
-
<header className="relative z-20 flex h-12 shrink-0 items-center gap-1 border-b border-border/50 bg-card px-2 inbox-zero-header">
|
|
1254
|
+
<header className="relative z-20 flex h-12 shrink-0 items-center gap-1 overflow-x-auto overflow-y-hidden overscroll-x-contain border-b border-border/50 bg-card px-2 inbox-zero-header hide-scrollbar">
|
|
1255
1255
|
<Dialog open={sidebarOpen} onOpenChange={setSidebarOpen}>
|
|
1256
1256
|
{/* Hamburger menu */}
|
|
1257
1257
|
<Tooltip>
|
|
1258
1258
|
<TooltipTrigger asChild>
|
|
1259
1259
|
<DialogTrigger asChild>
|
|
1260
1260
|
<button
|
|
1261
|
-
className="flex h-9 w-9
|
|
1261
|
+
className="sticky start-0 z-10 flex h-9 w-9 shrink-0 items-center justify-center rounded bg-card text-muted-foreground hover:text-foreground hover:bg-accent/50 transition-colors sm:h-7 sm:w-7"
|
|
1262
1262
|
aria-label={t("mail.toolbar.toggleMenu")}
|
|
1263
1263
|
>
|
|
1264
1264
|
<IconMenu2 className="h-4 w-4" />
|
|
@@ -1522,18 +1522,18 @@ function AppLayoutInner({ children }: AppLayoutProps) {
|
|
|
1522
1522
|
{/* Primary tabs stay mounted during search so navigation does not jump. */}
|
|
1523
1523
|
<>
|
|
1524
1524
|
{tabsLoading ? (
|
|
1525
|
-
<nav className="
|
|
1525
|
+
<nav className="flex w-max shrink-0 items-center gap-2 sm:w-auto sm:flex-1 sm:min-w-0 sm:overflow-x-auto sm:hide-scrollbar">
|
|
1526
1526
|
{[1, 2, 3].map((i) => (
|
|
1527
1527
|
<span
|
|
1528
1528
|
key={i}
|
|
1529
|
-
className="h-4 rounded bg-muted animate-pulse"
|
|
1529
|
+
className="h-4 shrink-0 rounded bg-muted animate-pulse"
|
|
1530
1530
|
style={{ width: `${48 + i * 12}px` }}
|
|
1531
1531
|
/>
|
|
1532
1532
|
))}
|
|
1533
1533
|
</nav>
|
|
1534
1534
|
) : (
|
|
1535
1535
|
<nav
|
|
1536
|
-
className="
|
|
1536
|
+
className="flex w-max shrink-0 flex-nowrap items-center gap-1 sm:w-auto sm:flex-1 sm:min-w-0 sm:overflow-x-auto sm:hide-scrollbar"
|
|
1537
1537
|
data-mail-tab-list
|
|
1538
1538
|
>
|
|
1539
1539
|
{topBarTabs.map((tab, tabIndex) => {
|
|
@@ -1637,7 +1637,7 @@ function AppLayoutInner({ children }: AppLayoutProps) {
|
|
|
1637
1637
|
<PopoverTrigger asChild>
|
|
1638
1638
|
<button
|
|
1639
1639
|
className={cn(
|
|
1640
|
-
"flex h-
|
|
1640
|
+
"flex h-9 w-9 items-center justify-center rounded transition-colors sm:h-6 sm:w-6",
|
|
1641
1641
|
tabSettingsOpen
|
|
1642
1642
|
? "text-foreground bg-accent/50"
|
|
1643
1643
|
: "text-muted-foreground hover:text-foreground hover:bg-accent/30",
|
|
@@ -1731,7 +1731,7 @@ function AppLayoutInner({ children }: AppLayoutProps) {
|
|
|
1731
1731
|
<TooltipTrigger asChild>
|
|
1732
1732
|
<button
|
|
1733
1733
|
onClick={() => setSearchFocused(true)}
|
|
1734
|
-
className="flex h-9 w-9
|
|
1734
|
+
className="flex h-9 w-9 shrink-0 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent/50 transition-colors sm:h-7 sm:w-7"
|
|
1735
1735
|
aria-label={t("mail.search.label")}
|
|
1736
1736
|
>
|
|
1737
1737
|
<IconSearch className="h-4 w-4" />
|
|
@@ -1796,7 +1796,7 @@ function AppLayoutInner({ children }: AppLayoutProps) {
|
|
|
1796
1796
|
onClick={handleCompose}
|
|
1797
1797
|
variant="outline"
|
|
1798
1798
|
size="sm"
|
|
1799
|
-
className="h-9
|
|
1799
|
+
className="h-9 shrink-0 px-3 text-[13px] sm:h-7"
|
|
1800
1800
|
aria-label={t("mail.toolbar.composeEmail")}
|
|
1801
1801
|
>
|
|
1802
1802
|
<span>{t("mail.toolbar.compose")}</span>
|
|
@@ -1822,7 +1822,7 @@ function AppLayoutInner({ children }: AppLayoutProps) {
|
|
|
1822
1822
|
<button
|
|
1823
1823
|
type="button"
|
|
1824
1824
|
aria-label={t("mail.toolbar.accounts")}
|
|
1825
|
-
className="flex items-center hover:opacity-90 transition-opacity ms-1"
|
|
1825
|
+
className="flex shrink-0 items-center hover:opacity-90 transition-opacity ms-1"
|
|
1826
1826
|
>
|
|
1827
1827
|
<div
|
|
1828
1828
|
className="flex items-center"
|