@the-portland-company/shell 0.82.0 → 0.85.0
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/CHANGELOG.md +39 -0
- package/dist/app-chrome.cjs +284 -182
- package/dist/app-chrome.cjs.map +1 -1
- package/dist/app-chrome.d.cts +17 -2
- package/dist/app-chrome.d.ts +17 -2
- package/dist/app-chrome.js +63 -14
- package/dist/app-chrome.js.map +1 -1
- package/dist/chrome.css +5 -0
- package/dist/{chunk-VWY6IIAR.js → chunk-OOVS5D2K.js} +3 -3
- package/dist/chunk-OOVS5D2K.js.map +1 -0
- package/dist/{chunk-L73FZKGE.js → chunk-PRZP2SB6.js} +229 -176
- package/dist/chunk-PRZP2SB6.js.map +1 -0
- package/dist/{index-CwTnsR9R.d.ts → index-C31E7M9l.d.ts} +70 -4
- package/dist/{index-C3PFq1hl.d.cts → index-bfbWLC7_.d.cts} +70 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/native.cjs +233 -172
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.cts +1 -1
- package/dist/native.d.ts +1 -1
- package/dist/native.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-L73FZKGE.js.map +0 -1
- package/dist/chunk-VWY6IIAR.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readThemeCookie, THEME_STORAGE_KEY, isThemePreference, applyThemePreference, readPendingThemeChoice, writeThemeCookie, clearPendingThemeChoice, markThemeChoicePending } from './chunk-BHRVZPZ7.js';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
|
-
import { createContext, useState, useEffect, useRef, useContext,
|
|
4
|
+
import { createContext, useState, useEffect, useRef, useContext, useMemo, useCallback, useSyncExternalStore } from 'react';
|
|
5
5
|
import { FiUser, FiSettings, FiMessageSquare, FiMail, FiInfo, FiSun, FiMoon, FiHelpCircle, FiLifeBuoy, FiAlertCircle, FiAlertTriangle, FiBell, FiGrid, FiZap, FiBatteryCharging, FiBattery } from 'react-icons/fi';
|
|
6
6
|
import { createPortal } from 'react-dom';
|
|
7
7
|
|
|
@@ -70,6 +70,81 @@ function resolveBrandGlyph(name) {
|
|
|
70
70
|
return GLYPHS[name.trim().toLowerCase()] ?? null;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
// src/native/credits.ts
|
|
74
|
+
var CREDIT_TYPE_ORDER = [
|
|
75
|
+
"signal",
|
|
76
|
+
"broadcast",
|
|
77
|
+
"ai",
|
|
78
|
+
"enhancement"
|
|
79
|
+
];
|
|
80
|
+
var CREDIT_TYPE_LABELS = {
|
|
81
|
+
signal: "Signal Credits",
|
|
82
|
+
broadcast: "Broadcast Credits",
|
|
83
|
+
ai: "AI Credits",
|
|
84
|
+
enhancement: "Enhancement Credits"
|
|
85
|
+
};
|
|
86
|
+
var RANK = {
|
|
87
|
+
unknown: 0,
|
|
88
|
+
good: 1,
|
|
89
|
+
low: 2,
|
|
90
|
+
out: 3
|
|
91
|
+
};
|
|
92
|
+
function creditsIconState(channels) {
|
|
93
|
+
let worst = "unknown";
|
|
94
|
+
for (const channel of channels) {
|
|
95
|
+
const state = channel?.state ?? null;
|
|
96
|
+
if (state === null || state === "not_in_use") continue;
|
|
97
|
+
if (RANK[state] > RANK[worst]) worst = state;
|
|
98
|
+
}
|
|
99
|
+
return worst;
|
|
100
|
+
}
|
|
101
|
+
function creditGaugeRatio(channel) {
|
|
102
|
+
if (!channel || channel.state == null || channel.state === "not_in_use")
|
|
103
|
+
return null;
|
|
104
|
+
const fullMark = channel.fullMarkUnits ?? 0;
|
|
105
|
+
if (!(fullMark > 0)) return null;
|
|
106
|
+
return Math.min(1, Math.max(0, channel.remainingUnits / fullMark));
|
|
107
|
+
}
|
|
108
|
+
function creditStateWord(state) {
|
|
109
|
+
switch (state) {
|
|
110
|
+
case "good":
|
|
111
|
+
return "Good";
|
|
112
|
+
case "low":
|
|
113
|
+
return "Low";
|
|
114
|
+
case "out":
|
|
115
|
+
return "Out";
|
|
116
|
+
case "not_in_use":
|
|
117
|
+
return "Not in use";
|
|
118
|
+
default:
|
|
119
|
+
return "Unknown";
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function daysPhrase(days) {
|
|
123
|
+
if (days < 1) return "less than a day at your recent pace";
|
|
124
|
+
const rounded = Math.round(days);
|
|
125
|
+
return `about ${rounded} ${rounded === 1 ? "day" : "days"} at your recent pace`;
|
|
126
|
+
}
|
|
127
|
+
function creditTooltipLine(type, channel) {
|
|
128
|
+
const label = CREDIT_TYPE_LABELS[type];
|
|
129
|
+
if (!channel) return `${label}: unavailable`;
|
|
130
|
+
const left = `${Math.max(0, channel.remainingUnits).toLocaleString()} left`;
|
|
131
|
+
if (channel.state === "not_in_use") return `${label}: not in use`;
|
|
132
|
+
if (channel.state == null) return `${label}: ${left}`;
|
|
133
|
+
if (channel.state === "out") return `${label}: ${left}, out`;
|
|
134
|
+
const days = channel.daysOfUseLeft;
|
|
135
|
+
const pace = typeof days === "number" && Number.isFinite(days) ? `, ${daysPhrase(days)}` : "";
|
|
136
|
+
return `${label}: ${left}${pace}`;
|
|
137
|
+
}
|
|
138
|
+
function creditsAriaLabel(channels) {
|
|
139
|
+
const worst = creditsIconState(CREDIT_TYPE_ORDER.map((t) => channels[t]));
|
|
140
|
+
if (worst === "unknown") return "Credits";
|
|
141
|
+
if (worst === "good") return "Credits: all good";
|
|
142
|
+
const named = CREDIT_TYPE_ORDER.filter(
|
|
143
|
+
(t) => channels[t]?.state === worst
|
|
144
|
+
).map((t) => CREDIT_TYPE_LABELS[t]);
|
|
145
|
+
return `Credits: ${worst === "low" ? "low on" : "out of"} ${named.join(", ")}`;
|
|
146
|
+
}
|
|
147
|
+
|
|
73
148
|
// src/notifications/adapter.ts
|
|
74
149
|
function emptyNotificationsFeed() {
|
|
75
150
|
return { notifications: [], badge: 0 };
|
|
@@ -164,7 +239,7 @@ function resolveOrgLogoUrl(url) {
|
|
|
164
239
|
}
|
|
165
240
|
var TOPBAR_GLYPH_SIZE = 17;
|
|
166
241
|
function topBarIconButtonClass(tone = "default") {
|
|
167
|
-
const toneClass = tone === "danger" || tone === "warning" ? "text-[color:var(--chrome-danger)] hover:text-[color:var(--chrome-danger)]" : "text-[color:var(--topbar-icon-color,var(--muted))] hover:text-[color:var(--topbar-icon-hover-color,var(--foreground))] hover:bg-[color:var(--topbar-icon-hover-bg,transparent)]";
|
|
242
|
+
const toneClass = tone === "danger" || tone === "warning" ? "text-[color:var(--chrome-danger)] hover:text-[color:var(--chrome-danger)]" : tone === "ok" ? "text-[color:var(--credits-good,#00783B)] hover:text-[color:var(--credits-good,#00783B)]" : tone === "low" ? "text-[color:var(--credits-low,#B7791F)] hover:text-[color:var(--credits-low,#B7791F)]" : "text-[color:var(--topbar-icon-color,var(--muted))] hover:text-[color:var(--topbar-icon-hover-color,var(--foreground))] hover:bg-[color:var(--topbar-icon-hover-bg,transparent)]";
|
|
168
243
|
return [
|
|
169
244
|
// `group/tbtip` powers the shared <TopBarTooltip> rendered inside the trigger.
|
|
170
245
|
"group/tbtip relative flex items-center justify-center rounded-[var(--topbar-icon-button-radius,5px)] border border-transparent transition",
|
|
@@ -393,6 +468,9 @@ function ValueSkeleton({ className }) {
|
|
|
393
468
|
}
|
|
394
469
|
);
|
|
395
470
|
}
|
|
471
|
+
function IconGlyph({ icon: Icon, size = TOPBAR_GLYPH_SIZE }) {
|
|
472
|
+
return /* @__PURE__ */ jsx(Icon, { size, className: "text-current" });
|
|
473
|
+
}
|
|
396
474
|
function SlotGlyph({
|
|
397
475
|
slot,
|
|
398
476
|
fallback: Fallback,
|
|
@@ -405,9 +483,12 @@ function SlotGlyph({
|
|
|
405
483
|
}
|
|
406
484
|
function TopBarPopover({
|
|
407
485
|
label,
|
|
486
|
+
ariaLabel,
|
|
408
487
|
description,
|
|
488
|
+
tooltip,
|
|
409
489
|
slot,
|
|
410
490
|
fallbackIcon,
|
|
491
|
+
icon,
|
|
411
492
|
badge,
|
|
412
493
|
tone,
|
|
413
494
|
onOpen,
|
|
@@ -457,7 +538,7 @@ function TopBarPopover({
|
|
|
457
538
|
"button",
|
|
458
539
|
{
|
|
459
540
|
type: "button",
|
|
460
|
-
"aria-label": label,
|
|
541
|
+
"aria-label": ariaLabel ?? label,
|
|
461
542
|
"aria-expanded": open,
|
|
462
543
|
className: topBarIconButtonClass(tone),
|
|
463
544
|
onClick: () => {
|
|
@@ -468,9 +549,9 @@ function TopBarPopover({
|
|
|
468
549
|
});
|
|
469
550
|
},
|
|
470
551
|
children: [
|
|
471
|
-
/* @__PURE__ */ jsx(SlotGlyph, { slot, fallback: fallbackIcon }),
|
|
552
|
+
icon ? /* @__PURE__ */ jsx(IconGlyph, { icon }) : /* @__PURE__ */ jsx(SlotGlyph, { slot, fallback: fallbackIcon }),
|
|
472
553
|
typeof badge === "number" ? /* @__PURE__ */ jsx(TopBarCountBadge, { count: badge }) : null,
|
|
473
|
-
!open && !hideTooltip ? /* @__PURE__ */ jsx(TopBarTooltip, { title: label, description }) : null
|
|
554
|
+
!open && !hideTooltip ? /* @__PURE__ */ jsx(TopBarTooltip, { title: label, description: tooltip ?? description }) : null
|
|
474
555
|
]
|
|
475
556
|
}
|
|
476
557
|
),
|
|
@@ -544,147 +625,145 @@ function XGlyph({ size = 14, className }) {
|
|
|
544
625
|
function CheckGlyph({ size = 14, className }) {
|
|
545
626
|
return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round", className, "aria-hidden": true, children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" }) });
|
|
546
627
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
628
|
+
function batteryFillWidth(state) {
|
|
629
|
+
switch (state) {
|
|
630
|
+
case "good":
|
|
631
|
+
return 12;
|
|
632
|
+
case "low":
|
|
633
|
+
return 5;
|
|
634
|
+
default:
|
|
635
|
+
return 0;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
function creditsBatteryGlyph(state) {
|
|
639
|
+
const fill = batteryFillWidth(state);
|
|
640
|
+
const Glyph = ({ size = TOPBAR_GLYPH_SIZE, className }) => /* @__PURE__ */ jsxs(
|
|
641
|
+
"svg",
|
|
642
|
+
{
|
|
643
|
+
width: size,
|
|
644
|
+
height: size,
|
|
645
|
+
viewBox: "0 0 24 24",
|
|
646
|
+
fill: "none",
|
|
647
|
+
stroke: "currentColor",
|
|
648
|
+
strokeWidth: 2,
|
|
649
|
+
strokeLinecap: "round",
|
|
650
|
+
strokeLinejoin: "round",
|
|
651
|
+
className,
|
|
652
|
+
"data-credits-state": state,
|
|
653
|
+
"aria-hidden": true,
|
|
654
|
+
children: [
|
|
655
|
+
/* @__PURE__ */ jsx("rect", { x: "1", y: "6", width: "18", height: "12", rx: "2", ry: "2" }),
|
|
656
|
+
/* @__PURE__ */ jsx("line", { x1: "23", y1: "10", x2: "23", y2: "14" }),
|
|
657
|
+
fill > 0 ? /* @__PURE__ */ jsx("rect", { x: "4", y: "9", width: fill, height: "6", rx: "1", fill: "currentColor", stroke: "none", opacity: 0.35 }) : null,
|
|
658
|
+
/* @__PURE__ */ jsx("path", { d: "M11.5 8 8.5 12.5h3L10.5 16l3.5-4.5h-3L11.5 8z", fill: "currentColor", stroke: "none" })
|
|
659
|
+
]
|
|
660
|
+
}
|
|
661
|
+
);
|
|
662
|
+
Glyph.displayName = `CreditsBatteryGlyph(${state})`;
|
|
663
|
+
return Glyph;
|
|
664
|
+
}
|
|
665
|
+
function stateTone(state) {
|
|
666
|
+
switch (state) {
|
|
667
|
+
case "good":
|
|
668
|
+
return "ok";
|
|
669
|
+
case "low":
|
|
670
|
+
return "low";
|
|
671
|
+
case "out":
|
|
672
|
+
return "danger";
|
|
673
|
+
default:
|
|
674
|
+
return "default";
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
function stateColorVar(state) {
|
|
678
|
+
switch (state) {
|
|
679
|
+
case "good":
|
|
680
|
+
return "var(--credits-good,#00783B)";
|
|
681
|
+
case "low":
|
|
682
|
+
return "var(--credits-low,#B7791F)";
|
|
683
|
+
case "out":
|
|
684
|
+
return "var(--chrome-danger)";
|
|
685
|
+
default:
|
|
686
|
+
return "var(--muted)";
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
function CreditGauge({ channel, className }) {
|
|
690
|
+
const ratio = creditGaugeRatio(channel);
|
|
691
|
+
return /* @__PURE__ */ jsx(
|
|
692
|
+
"div",
|
|
693
|
+
{
|
|
694
|
+
role: "meter",
|
|
695
|
+
"aria-label": `${creditStateWord(channel?.state)} level`,
|
|
696
|
+
"aria-valuemin": 0,
|
|
697
|
+
"aria-valuemax": 100,
|
|
698
|
+
"aria-valuenow": ratio === null ? void 0 : Math.round(ratio * 100),
|
|
699
|
+
className: ["h-1.5 w-full overflow-hidden rounded-full bg-[color:var(--panel)]", className ?? ""].join(" "),
|
|
700
|
+
children: ratio === null ? null : /* @__PURE__ */ jsx(
|
|
701
|
+
"div",
|
|
702
|
+
{
|
|
703
|
+
className: "h-full rounded-full transition-[width]",
|
|
704
|
+
style: { width: `${Math.round(ratio * 100)}%`, backgroundColor: stateColorVar(channel?.state) }
|
|
705
|
+
}
|
|
706
|
+
)
|
|
707
|
+
}
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
function formatGrantDate(iso) {
|
|
711
|
+
if (!iso) return null;
|
|
712
|
+
const t = Date.parse(iso);
|
|
713
|
+
if (!Number.isFinite(t)) return null;
|
|
714
|
+
return new Date(t).toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
715
|
+
}
|
|
716
|
+
function CreditRow({
|
|
717
|
+
type,
|
|
550
718
|
channel,
|
|
551
719
|
loading,
|
|
552
|
-
addHref
|
|
553
|
-
addLabel
|
|
720
|
+
addHref
|
|
554
721
|
}) {
|
|
722
|
+
const label = CREDIT_TYPE_LABELS[type];
|
|
555
723
|
const remaining = channel?.remainingUnits ?? 0;
|
|
556
|
-
const
|
|
557
|
-
const
|
|
558
|
-
const
|
|
559
|
-
|
|
724
|
+
const state = channel?.state ?? null;
|
|
725
|
+
const unavailable = !loading && !channel;
|
|
726
|
+
const nextGrant = formatGrantDate(channel?.nextGrantAt);
|
|
727
|
+
const pools = channel && typeof channel.includedUnits === "number" && typeof channel.purchasedUnits === "number" ? `Included ${channel.includedUnits.toLocaleString()}${nextGrant ? ` (next ${nextGrant})` : ""} \xB7 Purchased ${channel.purchasedUnits.toLocaleString()}` : null;
|
|
728
|
+
return /* @__PURE__ */ jsxs("div", { className: "w-full", "data-credit-type": type, children: [
|
|
560
729
|
/* @__PURE__ */ jsxs("div", { className: "mb-1 flex items-center justify-between gap-2", children: [
|
|
561
730
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-[color:var(--foreground)]", children: label }),
|
|
562
731
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
563
|
-
loading ? /* @__PURE__ */ jsx(ValueSkeleton, { className: "h-3.5 w-14" }) : /* @__PURE__ */ jsxs(
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
" left"
|
|
573
|
-
]
|
|
574
|
-
}
|
|
575
|
-
),
|
|
576
|
-
addHref ? /* @__PURE__ */ jsx(
|
|
732
|
+
loading ? /* @__PURE__ */ jsx(ValueSkeleton, { className: "h-3.5 w-14" }) : unavailable ? /* @__PURE__ */ jsx("span", { className: "text-xs text-[color:var(--muted)]", children: "Unavailable" }) : /* @__PURE__ */ jsxs("span", { className: "text-xs font-semibold tabular-nums", style: { color: stateColorVar(state) }, children: [
|
|
733
|
+
remaining.toLocaleString(),
|
|
734
|
+
" left",
|
|
735
|
+
state === "not_in_use" ? null : /* @__PURE__ */ jsxs("span", { className: "font-normal text-[color:var(--muted)]", children: [
|
|
736
|
+
" \xB7 ",
|
|
737
|
+
creditStateWord(state)
|
|
738
|
+
] })
|
|
739
|
+
] }),
|
|
740
|
+
addHref && !unavailable ? /* @__PURE__ */ jsx(
|
|
577
741
|
"a",
|
|
578
742
|
{
|
|
579
743
|
href: addHref,
|
|
580
|
-
"aria-label":
|
|
744
|
+
"aria-label": `Add ${label}`,
|
|
581
745
|
className: "flex h-5 w-5 items-center justify-center rounded-full border border-[color:var(--line)] text-[color:var(--muted)] transition hover:border-[color:var(--foreground)] hover:text-[color:var(--foreground)]",
|
|
582
746
|
children: /* @__PURE__ */ jsx(PlusGlyph, {})
|
|
583
747
|
}
|
|
584
748
|
) : null
|
|
585
749
|
] })
|
|
586
750
|
] }),
|
|
587
|
-
/* @__PURE__ */ jsx("div", { className: "h-1.5 w-full overflow-hidden rounded-full bg-[color:var(--panel)]", children:
|
|
588
|
-
|
|
589
|
-
{
|
|
590
|
-
className: [
|
|
591
|
-
"h-full rounded-full transition-[width]",
|
|
592
|
-
low ? "bg-[color:var(--chrome-danger)]" : "bg-[color:var(--color-ok,#00783B)]"
|
|
593
|
-
].join(" "),
|
|
594
|
-
style: { width: `${ratio}%` }
|
|
595
|
-
}
|
|
596
|
-
) })
|
|
751
|
+
loading ? /* @__PURE__ */ jsx("div", { className: "h-1.5 w-full overflow-hidden rounded-full bg-[color:var(--panel)]", children: /* @__PURE__ */ jsx("div", { className: "h-full w-full animate-pulse bg-[color:var(--line)]" }) }) : /* @__PURE__ */ jsx(CreditGauge, { channel: unavailable ? null : channel }),
|
|
752
|
+
!loading && state === "not_in_use" ? /* @__PURE__ */ jsx("p", { className: "mt-1 text-[11px] text-[color:var(--muted)]", children: "Not in use" }) : pools ? /* @__PURE__ */ jsx("p", { className: "mt-1 text-[11px] text-[color:var(--muted)]", children: pools }) : null
|
|
597
753
|
] });
|
|
598
754
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
lowFuelHintListeners.add(onChange);
|
|
608
|
-
return () => lowFuelHintListeners.delete(onChange);
|
|
755
|
+
function CreditsTooltip({ fuel }) {
|
|
756
|
+
return /* @__PURE__ */ jsx("span", { className: "flex w-56 flex-col gap-1.5", "data-testid": "credits-tooltip", children: CREDIT_TYPE_ORDER.map((type) => {
|
|
757
|
+
const channel = fuel ? fuel[type] ?? null : null;
|
|
758
|
+
return /* @__PURE__ */ jsxs("span", { className: "flex flex-col gap-0.5", children: [
|
|
759
|
+
/* @__PURE__ */ jsx("span", { children: creditTooltipLine(type, channel) }),
|
|
760
|
+
/* @__PURE__ */ jsx(CreditGauge, { channel, className: "bg-[#FFFFFF]/20" })
|
|
761
|
+
] }, type);
|
|
762
|
+
}) });
|
|
609
763
|
}
|
|
610
|
-
function
|
|
611
|
-
return
|
|
612
|
-
|
|
613
|
-
() => lowFuelHintVisible,
|
|
614
|
-
() => false
|
|
615
|
-
);
|
|
616
|
-
}
|
|
617
|
-
var LOW_FUEL_HINT_CLEARANCE_PX = 96;
|
|
618
|
-
function LowFuelHint({ lowFuel, orgId }) {
|
|
619
|
-
const [dismissed, setDismissed] = useState(() => {
|
|
620
|
-
if (typeof window === "undefined") return false;
|
|
621
|
-
try {
|
|
622
|
-
return window.sessionStorage.getItem(LOW_FUEL_HINT_DISMISSED_KEY) === "1";
|
|
623
|
-
} catch {
|
|
624
|
-
return false;
|
|
625
|
-
}
|
|
626
|
-
});
|
|
627
|
-
useEffect(() => {
|
|
628
|
-
if (lowFuel) return;
|
|
629
|
-
try {
|
|
630
|
-
window.sessionStorage.removeItem(LOW_FUEL_HINT_DISMISSED_KEY);
|
|
631
|
-
} catch {
|
|
632
|
-
}
|
|
633
|
-
}, [lowFuel]);
|
|
634
|
-
const panelOpen = useAnyTopBarPanelOpen();
|
|
635
|
-
const showing = lowFuel && !dismissed && !panelOpen;
|
|
636
|
-
useEffect(() => {
|
|
637
|
-
setLowFuelHintVisible(showing);
|
|
638
|
-
return () => setLowFuelHintVisible(false);
|
|
639
|
-
}, [showing]);
|
|
640
|
-
if (!showing) return null;
|
|
641
|
-
const dismiss = () => {
|
|
642
|
-
try {
|
|
643
|
-
window.sessionStorage.setItem(LOW_FUEL_HINT_DISMISSED_KEY, "1");
|
|
644
|
-
} catch {
|
|
645
|
-
}
|
|
646
|
-
setDismissed(true);
|
|
647
|
-
};
|
|
648
|
-
return /* @__PURE__ */ jsxs(
|
|
649
|
-
"div",
|
|
650
|
-
{
|
|
651
|
-
role: "status",
|
|
652
|
-
className: "absolute right-0 top-[calc(100%+10px)] z-[60] w-60 rounded-lg border border-[color:var(--chrome-danger)] bg-[color:var(--chrome-danger)] px-3 py-2 text-[#FFFFFF] shadow-[var(--shadow-soft)]",
|
|
653
|
-
onClick: (e) => e.stopPropagation(),
|
|
654
|
-
children: [
|
|
655
|
-
/* @__PURE__ */ jsx(
|
|
656
|
-
"span",
|
|
657
|
-
{
|
|
658
|
-
"aria-hidden": true,
|
|
659
|
-
className: "absolute -top-[5px] right-[11px] h-2.5 w-2.5 rotate-45 bg-[color:var(--chrome-danger)]"
|
|
660
|
-
}
|
|
661
|
-
),
|
|
662
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
|
|
663
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
|
|
664
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: "You\u2019re low on fuel" }),
|
|
665
|
-
/* @__PURE__ */ jsx(
|
|
666
|
-
"a",
|
|
667
|
-
{
|
|
668
|
-
href: withOrgParam(CORE_BILLING_URL, orgId),
|
|
669
|
-
className: "mt-1 inline-block text-sm font-bold underline hover:opacity-90",
|
|
670
|
-
children: "Buy More Fuel"
|
|
671
|
-
}
|
|
672
|
-
)
|
|
673
|
-
] }),
|
|
674
|
-
/* @__PURE__ */ jsx(
|
|
675
|
-
"button",
|
|
676
|
-
{
|
|
677
|
-
type: "button",
|
|
678
|
-
"aria-label": "Dismiss low fuel notice",
|
|
679
|
-
onClick: dismiss,
|
|
680
|
-
className: "flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-[#FFFFFF]/90 transition hover:bg-[#FFFFFF]/20",
|
|
681
|
-
children: /* @__PURE__ */ jsx(XGlyph, {})
|
|
682
|
-
}
|
|
683
|
-
)
|
|
684
|
-
] })
|
|
685
|
-
]
|
|
686
|
-
}
|
|
687
|
-
);
|
|
764
|
+
function channelsOf(fuel) {
|
|
765
|
+
if (!fuel) return {};
|
|
766
|
+
return { signal: fuel.signal, broadcast: fuel.broadcast, ai: fuel.ai, enhancement: fuel.enhancement };
|
|
688
767
|
}
|
|
689
768
|
function FuelAction({ orgId }) {
|
|
690
769
|
const { dedupedFetch } = useNavChrome("FuelAction");
|
|
@@ -716,52 +795,28 @@ function FuelAction({ orgId }) {
|
|
|
716
795
|
cancelled = true;
|
|
717
796
|
};
|
|
718
797
|
}, [dedupedFetch, orgId]);
|
|
719
|
-
const
|
|
720
|
-
const
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
FuelRow,
|
|
739
|
-
{
|
|
740
|
-
label: "SMS Signal",
|
|
741
|
-
channel: fuel?.signal ?? null,
|
|
742
|
-
loading,
|
|
743
|
-
addHref: withOrgParam(CORE_BILLING_URL, orgId),
|
|
744
|
-
addLabel: "Add SMS Signal fuel"
|
|
745
|
-
}
|
|
746
|
-
),
|
|
747
|
-
/* @__PURE__ */ jsx(
|
|
748
|
-
FuelRow,
|
|
749
|
-
{
|
|
750
|
-
label: "Email Broadcast",
|
|
751
|
-
channel: fuel?.broadcast ?? null,
|
|
752
|
-
loading,
|
|
753
|
-
addHref: withOrgParam(CORE_BILLING_URL, orgId),
|
|
754
|
-
addLabel: "Add Email Broadcast fuel"
|
|
755
|
-
}
|
|
756
|
-
)
|
|
757
|
-
] })
|
|
758
|
-
] })
|
|
759
|
-
}
|
|
760
|
-
),
|
|
761
|
-
/* @__PURE__ */ jsx(LowFuelHint, { lowFuel: low, orgId })
|
|
762
|
-
] })
|
|
798
|
+
const channels = channelsOf(fuel);
|
|
799
|
+
const iconState = creditsIconState(CREDIT_TYPE_ORDER.map((t) => channels[t]));
|
|
800
|
+
const Glyph = useMemo(() => creditsBatteryGlyph(iconState), [iconState]);
|
|
801
|
+
const addHref = withOrgParam(CORE_BILLING_URL, orgId);
|
|
802
|
+
return /* @__PURE__ */ jsx(
|
|
803
|
+
TopBarPopover,
|
|
804
|
+
{
|
|
805
|
+
label: "Credits",
|
|
806
|
+
ariaLabel: creditsAriaLabel(channels),
|
|
807
|
+
tooltip: /* @__PURE__ */ jsx(CreditsTooltip, { fuel }),
|
|
808
|
+
slot: "comms-fuel",
|
|
809
|
+
fallbackIcon: BatteryGlyph,
|
|
810
|
+
icon: Glyph,
|
|
811
|
+
tone: stateTone(iconState),
|
|
812
|
+
children: /* @__PURE__ */ jsxs("div", { className: "px-4 py-3", children: [
|
|
813
|
+
/* @__PURE__ */ jsx("p", { className: "mb-3 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]", children: "Credits" }),
|
|
814
|
+
error || !loading && !fuel ? /* @__PURE__ */ jsx("p", { className: "text-sm text-[color:var(--muted)]", children: "Credits are unavailable right now." }) : /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3", children: CREDIT_TYPE_ORDER.map((type) => /* @__PURE__ */ jsx(CreditRow, { type, channel: channels[type] ?? null, loading, addHref }, type)) })
|
|
815
|
+
] })
|
|
816
|
+
}
|
|
763
817
|
);
|
|
764
818
|
}
|
|
819
|
+
var CreditsAction = FuelAction;
|
|
765
820
|
function notifStateKey(orgId) {
|
|
766
821
|
return `politogy_chrome_notif_state:${orgId ?? "none"}`;
|
|
767
822
|
}
|
|
@@ -840,7 +895,6 @@ function NewReplyToast({
|
|
|
840
895
|
const [visible, setVisible] = useState(false);
|
|
841
896
|
const onCloseRef = useRef(onClose);
|
|
842
897
|
onCloseRef.current = onClose;
|
|
843
|
-
const lowFuelHintVisible2 = useLowFuelHintVisible();
|
|
844
898
|
useEffect(() => {
|
|
845
899
|
setVisible(true);
|
|
846
900
|
const fadeAt = Math.max(0, ttlMs - 450);
|
|
@@ -870,7 +924,6 @@ function NewReplyToast({
|
|
|
870
924
|
},
|
|
871
925
|
className: "absolute right-[-6px] top-[calc(100%+12px)] z-50 min-w-[240px] max-w-[320px] cursor-pointer rounded-xl bg-[#161616] px-4 py-3 text-[#FFFFFF] shadow-[var(--shadow-soft)]",
|
|
872
926
|
style: {
|
|
873
|
-
top: lowFuelHintVisible2 ? `calc(100% + 12px + ${LOW_FUEL_HINT_CLEARANCE_PX}px)` : void 0,
|
|
874
927
|
opacity: visible ? 1 : 0,
|
|
875
928
|
transform: visible ? "translateY(0px)" : "translateY(-4px)",
|
|
876
929
|
transition: "opacity 250ms ease, transform 250ms ease"
|
|
@@ -1998,6 +2051,6 @@ function SpeculationRulesScript({ items }) {
|
|
|
1998
2051
|
return null;
|
|
1999
2052
|
}
|
|
2000
2053
|
|
|
2001
|
-
export { CORE_APP_ORIGIN, CORE_BILLING_PATH, FormColumn, FuelAction, NAV_DISPLAY_OPTIONS, NavChromeProvider, NavDisplayAction, NavThemeControl, NotificationsAction, SPECS_ORIGIN, SpecOverlayAction, SpeculationRulesScript, SupportAction, TOPBAR_GLYPH_SIZE, TopBarCountBadge, TopBarPanelArrow, TopBarPopover, TopBarTooltip, TopBarWidgetSlot, buildNavSpeculationRules, buildSpeculationRules, collectSiblingAppUrls, createCommsNotificationsAdapter, emptyNotificationsFeed, normalizeNotificationsFeed, resolveBrandGlyph, resolveOrgLogoUrl, topBarIconButtonClass, useChromeMe, useChromeOrgs, useNavChromeDedupedFetch, useNavChromeFetcher, useThemePreference, useTopBarIconSlotGlyph, warnDeprecated };
|
|
2002
|
-
//# sourceMappingURL=chunk-
|
|
2003
|
-
//# sourceMappingURL=chunk-
|
|
2054
|
+
export { CORE_APP_ORIGIN, CORE_BILLING_PATH, CREDIT_TYPE_LABELS, CREDIT_TYPE_ORDER, CreditsAction, FormColumn, FuelAction, NAV_DISPLAY_OPTIONS, NavChromeProvider, NavDisplayAction, NavThemeControl, NotificationsAction, SPECS_ORIGIN, SpecOverlayAction, SpeculationRulesScript, SupportAction, TOPBAR_GLYPH_SIZE, TopBarCountBadge, TopBarPanelArrow, TopBarPopover, TopBarTooltip, TopBarWidgetSlot, buildNavSpeculationRules, buildSpeculationRules, collectSiblingAppUrls, createCommsNotificationsAdapter, creditGaugeRatio, creditStateWord, creditTooltipLine, creditsAriaLabel, creditsIconState, emptyNotificationsFeed, normalizeNotificationsFeed, resolveBrandGlyph, resolveOrgLogoUrl, topBarIconButtonClass, useChromeMe, useChromeOrgs, useNavChromeDedupedFetch, useNavChromeFetcher, useThemePreference, useTopBarIconSlotGlyph, warnDeprecated };
|
|
2055
|
+
//# sourceMappingURL=chunk-PRZP2SB6.js.map
|
|
2056
|
+
//# sourceMappingURL=chunk-PRZP2SB6.js.map
|