@tightknitai/block-kitchen 0.9.3 → 0.9.4
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/dist/helpers.d.cts +2 -2
- package/dist/helpers.d.ts +2 -2
- package/dist/index.cjs +232 -88
- 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 +233 -89
- package/dist/index.js.map +1 -1
- package/dist/{palette-DIbvAzRA.d.cts → palette-inX8F01o.d.cts} +9 -1
- package/dist/{palette-DIbvAzRA.d.ts → palette-inX8F01o.d.ts} +9 -1
- package/dist/palette.d.cts +1 -1
- package/dist/palette.d.ts +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/helpers.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as SupportedBlock } from './palette-
|
|
2
|
-
export { U as SupportedBlockType } from './palette-
|
|
1
|
+
import { T as SupportedBlock } from './palette-inX8F01o.cjs';
|
|
2
|
+
export { U as SupportedBlockType } from './palette-inX8F01o.cjs';
|
|
3
3
|
import 'react';
|
|
4
4
|
import 'slack-web-api-client';
|
|
5
5
|
|
package/dist/helpers.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as SupportedBlock } from './palette-
|
|
2
|
-
export { U as SupportedBlockType } from './palette-
|
|
1
|
+
import { T as SupportedBlock } from './palette-inX8F01o.js';
|
|
2
|
+
export { U as SupportedBlockType } from './palette-inX8F01o.js';
|
|
3
3
|
import 'react';
|
|
4
4
|
import 'slack-web-api-client';
|
|
5
5
|
|
package/dist/index.cjs
CHANGED
|
@@ -2647,8 +2647,10 @@ function JsonDrawer({
|
|
|
2647
2647
|
const [value, setValue] = React.useState("");
|
|
2648
2648
|
const [parseError, setParseError] = React.useState(null);
|
|
2649
2649
|
const [validationErrors, setValidationErrors] = React.useState([]);
|
|
2650
|
+
const [copied, setCopied] = React.useState(false);
|
|
2650
2651
|
const textareaRef = React.useRef(null);
|
|
2651
2652
|
const gutterRef = React.useRef(null);
|
|
2653
|
+
const copyResetRef = React.useRef(null);
|
|
2652
2654
|
const blocksRef = React.useRef(blocks);
|
|
2653
2655
|
React.useEffect(() => {
|
|
2654
2656
|
blocksRef.current = blocks;
|
|
@@ -2658,8 +2660,27 @@ function JsonDrawer({
|
|
|
2658
2660
|
setValue(JSON.stringify(blocksRef.current, null, 2));
|
|
2659
2661
|
setParseError(null);
|
|
2660
2662
|
setValidationErrors([]);
|
|
2663
|
+
setCopied(false);
|
|
2661
2664
|
}
|
|
2662
2665
|
}, [open]);
|
|
2666
|
+
React.useEffect(
|
|
2667
|
+
() => () => {
|
|
2668
|
+
if (copyResetRef.current) {
|
|
2669
|
+
clearTimeout(copyResetRef.current);
|
|
2670
|
+
}
|
|
2671
|
+
},
|
|
2672
|
+
[]
|
|
2673
|
+
);
|
|
2674
|
+
const handleCopy = () => {
|
|
2675
|
+
navigator.clipboard?.writeText(value).then(() => {
|
|
2676
|
+
setCopied(true);
|
|
2677
|
+
if (copyResetRef.current) {
|
|
2678
|
+
clearTimeout(copyResetRef.current);
|
|
2679
|
+
}
|
|
2680
|
+
copyResetRef.current = setTimeout(() => setCopied(false), 2e3);
|
|
2681
|
+
}).catch(() => {
|
|
2682
|
+
});
|
|
2683
|
+
};
|
|
2663
2684
|
const handleChange = (next) => {
|
|
2664
2685
|
setValue(next);
|
|
2665
2686
|
if (next.length > MAX_JSON_BYTES) {
|
|
@@ -2706,7 +2727,17 @@ function JsonDrawer({
|
|
|
2706
2727
|
/* @__PURE__ */ jsxRuntime.jsx(SheetTitle, { children: "Block Kit JSON" }),
|
|
2707
2728
|
/* @__PURE__ */ jsxRuntime.jsx(SheetDescription, { children: "Edits update the preview as you type. Parse errors show below." })
|
|
2708
2729
|
] }),
|
|
2709
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 overflow-hidden rounded-md border border-input bg-muted/30 shadow-sm focus-within:ring-1 focus-within:ring-ring", children: [
|
|
2730
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-1 overflow-hidden rounded-md border border-input bg-muted/30 shadow-sm focus-within:ring-1 focus-within:ring-ring", children: [
|
|
2731
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2732
|
+
"button",
|
|
2733
|
+
{
|
|
2734
|
+
type: "button",
|
|
2735
|
+
onClick: handleCopy,
|
|
2736
|
+
"aria-label": copied ? "Copied to clipboard" : "Copy JSON",
|
|
2737
|
+
className: "absolute right-2 top-2 z-10 inline-flex items-center justify-center rounded-md border border-input bg-background/80 p-1.5 text-muted-foreground shadow-sm backdrop-blur transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
2738
|
+
children: copied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5 text-emerald-600" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "h-3.5 w-3.5" })
|
|
2739
|
+
}
|
|
2740
|
+
),
|
|
2710
2741
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2711
2742
|
"div",
|
|
2712
2743
|
{
|
|
@@ -2855,6 +2886,79 @@ var Label = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__
|
|
|
2855
2886
|
}
|
|
2856
2887
|
));
|
|
2857
2888
|
Label.displayName = LabelPrimitive__namespace.Root.displayName;
|
|
2889
|
+
var POLL_INTERVAL_MS = 2500;
|
|
2890
|
+
var MAX_POLLS = 24;
|
|
2891
|
+
function useSlackSignIn(loadStatus, { open, enabled }) {
|
|
2892
|
+
const [userStatus, setUserStatus] = React.useState(null);
|
|
2893
|
+
const [polling, setPolling] = React.useState(false);
|
|
2894
|
+
const loadStatusRef = React.useRef(loadStatus);
|
|
2895
|
+
React.useEffect(() => {
|
|
2896
|
+
loadStatusRef.current = loadStatus;
|
|
2897
|
+
});
|
|
2898
|
+
const refresh = React.useCallback(() => {
|
|
2899
|
+
loadStatusRef.current().then(setUserStatus).catch(() => setUserStatus({ canSendAsUser: false }));
|
|
2900
|
+
}, []);
|
|
2901
|
+
const pollRef = React.useRef(null);
|
|
2902
|
+
const stopPolling = React.useCallback(() => {
|
|
2903
|
+
if (pollRef.current) {
|
|
2904
|
+
clearInterval(pollRef.current);
|
|
2905
|
+
pollRef.current = null;
|
|
2906
|
+
}
|
|
2907
|
+
setPolling(false);
|
|
2908
|
+
}, []);
|
|
2909
|
+
const startSignIn = React.useCallback(() => {
|
|
2910
|
+
const url = userStatus?.oauthUrl;
|
|
2911
|
+
if (!url || !isSafeHref(url)) {
|
|
2912
|
+
return;
|
|
2913
|
+
}
|
|
2914
|
+
window.open(url, "_blank", "noopener,noreferrer");
|
|
2915
|
+
stopPolling();
|
|
2916
|
+
setPolling(true);
|
|
2917
|
+
let tries = 0;
|
|
2918
|
+
pollRef.current = setInterval(() => {
|
|
2919
|
+
tries += 1;
|
|
2920
|
+
loadStatusRef.current().then((next) => {
|
|
2921
|
+
setUserStatus(next);
|
|
2922
|
+
if (next.canSendAsUser) {
|
|
2923
|
+
stopPolling();
|
|
2924
|
+
}
|
|
2925
|
+
}).catch(() => {
|
|
2926
|
+
}).finally(() => {
|
|
2927
|
+
if (tries >= MAX_POLLS) {
|
|
2928
|
+
stopPolling();
|
|
2929
|
+
}
|
|
2930
|
+
});
|
|
2931
|
+
}, POLL_INTERVAL_MS);
|
|
2932
|
+
}, [userStatus, stopPolling]);
|
|
2933
|
+
React.useEffect(() => {
|
|
2934
|
+
if (!open || !enabled) {
|
|
2935
|
+
setUserStatus(null);
|
|
2936
|
+
stopPolling();
|
|
2937
|
+
return;
|
|
2938
|
+
}
|
|
2939
|
+
setUserStatus(null);
|
|
2940
|
+
refresh();
|
|
2941
|
+
return stopPolling;
|
|
2942
|
+
}, [open, enabled, refresh, stopPolling]);
|
|
2943
|
+
React.useEffect(() => {
|
|
2944
|
+
if (!open || !enabled) {
|
|
2945
|
+
return;
|
|
2946
|
+
}
|
|
2947
|
+
const handler = () => refresh();
|
|
2948
|
+
window.addEventListener("focus", handler);
|
|
2949
|
+
return () => window.removeEventListener("focus", handler);
|
|
2950
|
+
}, [open, enabled, refresh]);
|
|
2951
|
+
return { userStatus, polling, startSignIn };
|
|
2952
|
+
}
|
|
2953
|
+
function SlackSignInButton({ onClick, polling }) {
|
|
2954
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "outline", size: "sm", className: "w-fit", onClick, disabled: polling, children: polling ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2955
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "animate-spin" }),
|
|
2956
|
+
" Waiting for Slack\u2026"
|
|
2957
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2958
|
+
"Sign in with Slack ",
|
|
2959
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, {})
|
|
2960
|
+
] }) });
|
|
2961
|
+
}
|
|
2858
2962
|
function recentToResult(msg) {
|
|
2859
2963
|
return {
|
|
2860
2964
|
ok: true,
|
|
@@ -2868,6 +2972,17 @@ function recentToResult(msg) {
|
|
|
2868
2972
|
iconUrl: msg.iconUrl
|
|
2869
2973
|
};
|
|
2870
2974
|
}
|
|
2975
|
+
function previewText(m) {
|
|
2976
|
+
if (m.label) {
|
|
2977
|
+
return m.label;
|
|
2978
|
+
}
|
|
2979
|
+
for (const b of m.blocks) {
|
|
2980
|
+
if ((b.type === "header" || b.type === "section") && "text" in b && b.text && "text" in b.text) {
|
|
2981
|
+
return b.text.text;
|
|
2982
|
+
}
|
|
2983
|
+
}
|
|
2984
|
+
return `${m.blocks.length} block${m.blocks.length === 1 ? "" : "s"}`;
|
|
2985
|
+
}
|
|
2871
2986
|
function LoadMessageDialog({
|
|
2872
2987
|
open,
|
|
2873
2988
|
onOpenChange,
|
|
@@ -2884,7 +2999,10 @@ function LoadMessageDialog({
|
|
|
2884
2999
|
const [channelId, setChannelId] = React.useState("");
|
|
2885
3000
|
const [recent, setRecent] = React.useState(null);
|
|
2886
3001
|
const [recentError, setRecentError] = React.useState(null);
|
|
3002
|
+
const [selectedRecent, setSelectedRecent] = React.useState(null);
|
|
3003
|
+
const [signInPolling, setSignInPolling] = React.useState(false);
|
|
2887
3004
|
const inputRef = React.useRef(null);
|
|
3005
|
+
const signInPollRef = React.useRef(null);
|
|
2888
3006
|
const onLoadMessageRef = React.useRef(onLoadMessage);
|
|
2889
3007
|
const loadRecentMessagesRef = React.useRef(loadRecentMessages);
|
|
2890
3008
|
const loadChannelsRef = React.useRef(loadChannels);
|
|
@@ -2903,6 +3021,7 @@ function LoadMessageDialog({
|
|
|
2903
3021
|
setChannelId("");
|
|
2904
3022
|
setRecent(null);
|
|
2905
3023
|
setRecentError(null);
|
|
3024
|
+
setSelectedRecent(null);
|
|
2906
3025
|
if (!loadRecentMessagesRef.current) {
|
|
2907
3026
|
setChannels([]);
|
|
2908
3027
|
setChannelsError(null);
|
|
@@ -2930,6 +3049,7 @@ function LoadMessageDialog({
|
|
|
2930
3049
|
}
|
|
2931
3050
|
setRecent(null);
|
|
2932
3051
|
setRecentError(null);
|
|
3052
|
+
setSelectedRecent(null);
|
|
2933
3053
|
let cancelled = false;
|
|
2934
3054
|
loadRecentMessagesRef.current(channelId).then((list) => {
|
|
2935
3055
|
if (!cancelled) {
|
|
@@ -2944,7 +3064,25 @@ function LoadMessageDialog({
|
|
|
2944
3064
|
cancelled = true;
|
|
2945
3065
|
};
|
|
2946
3066
|
}, [open, channelId]);
|
|
3067
|
+
const stopSignInPoll = React.useCallback(() => {
|
|
3068
|
+
if (signInPollRef.current) {
|
|
3069
|
+
clearInterval(signInPollRef.current);
|
|
3070
|
+
signInPollRef.current = null;
|
|
3071
|
+
}
|
|
3072
|
+
setSignInPolling(false);
|
|
3073
|
+
}, []);
|
|
3074
|
+
React.useEffect(() => {
|
|
3075
|
+
if (!open) {
|
|
3076
|
+
stopSignInPoll();
|
|
3077
|
+
}
|
|
3078
|
+
return stopSignInPoll;
|
|
3079
|
+
}, [open, stopSignInPoll]);
|
|
2947
3080
|
const handleLoad = async () => {
|
|
3081
|
+
stopSignInPoll();
|
|
3082
|
+
if (selectedRecent) {
|
|
3083
|
+
onLoaded(recentToResult(selectedRecent));
|
|
3084
|
+
return;
|
|
3085
|
+
}
|
|
2948
3086
|
const trimmed = link.trim();
|
|
2949
3087
|
if (!trimmed) {
|
|
2950
3088
|
setStatus({ kind: "error", error: "Paste a Slack message link first." });
|
|
@@ -2957,12 +3095,42 @@ function LoadMessageDialog({
|
|
|
2957
3095
|
onLoaded(result);
|
|
2958
3096
|
return;
|
|
2959
3097
|
}
|
|
2960
|
-
setStatus({ kind: "not-editable", reason: result.reason, blocks: result.blocks });
|
|
3098
|
+
setStatus({ kind: "not-editable", reason: result.reason, blocks: result.blocks, oauthUrl: result.oauthUrl });
|
|
2961
3099
|
} catch (e) {
|
|
2962
3100
|
setStatus({ kind: "error", error: e instanceof Error ? e.message : "Failed to load message." });
|
|
2963
3101
|
}
|
|
2964
3102
|
};
|
|
3103
|
+
const startFindSignIn = (oauthUrl) => {
|
|
3104
|
+
if (!isSafeHref(oauthUrl)) {
|
|
3105
|
+
return;
|
|
3106
|
+
}
|
|
3107
|
+
const trimmed = link.trim();
|
|
3108
|
+
if (!trimmed) {
|
|
3109
|
+
return;
|
|
3110
|
+
}
|
|
3111
|
+
window.open(oauthUrl, "_blank", "noopener,noreferrer");
|
|
3112
|
+
stopSignInPoll();
|
|
3113
|
+
setSignInPolling(true);
|
|
3114
|
+
let tries = 0;
|
|
3115
|
+
const POLL_INTERVAL_MS2 = 2500;
|
|
3116
|
+
const MAX_POLLS2 = 24;
|
|
3117
|
+
signInPollRef.current = setInterval(() => {
|
|
3118
|
+
tries += 1;
|
|
3119
|
+
onLoadMessageRef.current({ link: trimmed }).then((result) => {
|
|
3120
|
+
if (result.ok) {
|
|
3121
|
+
stopSignInPoll();
|
|
3122
|
+
onLoaded(result);
|
|
3123
|
+
}
|
|
3124
|
+
}).catch(() => {
|
|
3125
|
+
}).finally(() => {
|
|
3126
|
+
if (tries >= MAX_POLLS2) {
|
|
3127
|
+
stopSignInPoll();
|
|
3128
|
+
}
|
|
3129
|
+
});
|
|
3130
|
+
}, POLL_INTERVAL_MS2);
|
|
3131
|
+
};
|
|
2965
3132
|
const notEditable = status.kind === "not-editable" ? status : null;
|
|
3133
|
+
const signInUrl = notEditable?.oauthUrl && isSafeHref(notEditable.oauthUrl) ? notEditable.oauthUrl : null;
|
|
2966
3134
|
return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2967
3135
|
DialogContent,
|
|
2968
3136
|
{
|
|
@@ -2973,7 +3141,7 @@ function LoadMessageDialog({
|
|
|
2973
3141
|
},
|
|
2974
3142
|
children: [
|
|
2975
3143
|
/* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
|
|
2976
|
-
/* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "
|
|
3144
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Find an existing message" }),
|
|
2977
3145
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-1.5 text-left", children: [
|
|
2978
3146
|
/* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: hasRecent ? "Paste a Slack message link, or pick a recent message your app posted." : `Paste a Slack message link (Slack's "Copy link") to load its blocks for editing.` }),
|
|
2979
3147
|
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
@@ -3007,6 +3175,8 @@ function LoadMessageDialog({
|
|
|
3007
3175
|
value: link,
|
|
3008
3176
|
onChange: (e) => {
|
|
3009
3177
|
setLink(e.target.value);
|
|
3178
|
+
setSelectedRecent(null);
|
|
3179
|
+
stopSignInPoll();
|
|
3010
3180
|
if (status.kind !== "idle" && status.kind !== "loading") {
|
|
3011
3181
|
setStatus({ kind: "idle" });
|
|
3012
3182
|
}
|
|
@@ -3029,7 +3199,8 @@ function LoadMessageDialog({
|
|
|
3029
3199
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "mt-0.5 h-3.5 w-3.5 shrink-0" }),
|
|
3030
3200
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children: notEditable.reason })
|
|
3031
3201
|
] }),
|
|
3032
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3202
|
+
signInUrl && /* @__PURE__ */ jsxRuntime.jsx(SlackSignInButton, { onClick: () => startFindSignIn(signInUrl), polling: signInPolling }),
|
|
3203
|
+
notEditable.blocks && notEditable.blocks.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3033
3204
|
Button,
|
|
3034
3205
|
{
|
|
3035
3206
|
type: "button",
|
|
@@ -3075,26 +3246,52 @@ function LoadMessageDialog({
|
|
|
3075
3246
|
channelId && recent && recent.length === 0 && !recentError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "No recent messages from this app in this channel." }),
|
|
3076
3247
|
channelId && recent && recent.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex max-h-48 min-w-0 flex-col gap-1 overflow-y-auto", children: recent.map((m) => {
|
|
3077
3248
|
const asUser = (m.editableVia ?? "bot") === "user";
|
|
3249
|
+
const authorName = m.username || (asUser ? "You" : "App bot");
|
|
3250
|
+
const safeIcon = isSafeImageSrc(m.iconUrl) ? m.iconUrl : void 0;
|
|
3251
|
+
const isSelected = selectedRecent?.channelId === m.channelId && selectedRecent?.ts === m.ts;
|
|
3078
3252
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3079
3253
|
"button",
|
|
3080
3254
|
{
|
|
3081
3255
|
type: "button",
|
|
3082
|
-
|
|
3083
|
-
|
|
3256
|
+
"aria-pressed": isSelected,
|
|
3257
|
+
onClick: () => {
|
|
3258
|
+
setSelectedRecent(m);
|
|
3259
|
+
setLink("");
|
|
3260
|
+
if (status.kind !== "idle" && status.kind !== "loading") {
|
|
3261
|
+
setStatus({ kind: "idle" });
|
|
3262
|
+
}
|
|
3263
|
+
},
|
|
3264
|
+
className: cn(
|
|
3265
|
+
// Inset rings so the scroll container's overflow clip
|
|
3266
|
+
// can't shave the corners off the selected outline.
|
|
3267
|
+
"flex min-w-0 items-start gap-2.5 rounded-md border border-input bg-background px-3 py-2 text-left hover:bg-accent focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring",
|
|
3268
|
+
isSelected && "border-primary! bg-accent ring-1 ring-inset ring-primary"
|
|
3269
|
+
),
|
|
3084
3270
|
children: [
|
|
3085
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3271
|
+
safeIcon ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: safeIcon, alt: "", className: "h-9 w-9 shrink-0 rounded-md object-cover" }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
3272
|
+
"span",
|
|
3273
|
+
{
|
|
3274
|
+
"aria-hidden": true,
|
|
3275
|
+
className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-md bg-muted text-sm font-semibold text-muted-foreground",
|
|
3276
|
+
children: authorName.charAt(0).toUpperCase()
|
|
3277
|
+
}
|
|
3278
|
+
),
|
|
3279
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
3280
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-1.5", children: [
|
|
3281
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-sm font-semibold text-foreground", children: authorName }),
|
|
3282
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 rounded border px-1 py-px text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: asUser ? "You" : "Bot" })
|
|
3283
|
+
] }),
|
|
3284
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
3285
|
+
new Date(Number(m.ts) * 1e3).toLocaleString(),
|
|
3089
3286
|
" ",
|
|
3090
3287
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono", children: [
|
|
3091
3288
|
"(",
|
|
3092
3289
|
m.ts,
|
|
3093
3290
|
")"
|
|
3094
3291
|
] })
|
|
3095
|
-
] })
|
|
3096
|
-
|
|
3097
|
-
|
|
3292
|
+
] }),
|
|
3293
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-2 text-sm text-foreground", children: previewText(m) })
|
|
3294
|
+
] })
|
|
3098
3295
|
]
|
|
3099
3296
|
},
|
|
3100
3297
|
`${m.channelId}:${m.ts}`
|
|
@@ -3104,7 +3301,15 @@ function LoadMessageDialog({
|
|
|
3104
3301
|
] }),
|
|
3105
3302
|
/* @__PURE__ */ jsxRuntime.jsxs(DialogFooter, { children: [
|
|
3106
3303
|
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "ghost", onClick: () => onOpenChange(false), children: "Cancel" }),
|
|
3107
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3304
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3305
|
+
Button,
|
|
3306
|
+
{
|
|
3307
|
+
type: "button",
|
|
3308
|
+
onClick: handleLoad,
|
|
3309
|
+
disabled: status.kind === "loading" || !selectedRecent && !link.trim(),
|
|
3310
|
+
children: status.kind === "loading" ? "Loading\u2026" : "Find message"
|
|
3311
|
+
}
|
|
3312
|
+
)
|
|
3108
3313
|
] })
|
|
3109
3314
|
]
|
|
3110
3315
|
}
|
|
@@ -3323,18 +3528,13 @@ function SendDialog({
|
|
|
3323
3528
|
const [channels, setChannels] = React.useState(null);
|
|
3324
3529
|
const [channelsError, setChannelsError] = React.useState(null);
|
|
3325
3530
|
const [channelId, setChannelId] = React.useState("");
|
|
3326
|
-
const [userStatus, setUserStatus] = React.useState(null);
|
|
3327
3531
|
const [sendAs, setSendAs] = React.useState("bot");
|
|
3328
3532
|
const [status, setStatus] = React.useState({ kind: "idle" });
|
|
3533
|
+
const { userStatus, polling, startSignIn } = useSlackSignIn(loadSendAsUserStatus, { open, enabled: true });
|
|
3329
3534
|
const loadChannelsRef = React.useRef(loadChannels);
|
|
3330
|
-
const loadSendAsUserStatusRef = React.useRef(loadSendAsUserStatus);
|
|
3331
3535
|
React.useEffect(() => {
|
|
3332
3536
|
loadChannelsRef.current = loadChannels;
|
|
3333
|
-
loadSendAsUserStatusRef.current = loadSendAsUserStatus;
|
|
3334
3537
|
});
|
|
3335
|
-
const refreshSendAsUser = React.useCallback(() => {
|
|
3336
|
-
loadSendAsUserStatusRef.current().then(setUserStatus).catch(() => setUserStatus({ canSendAsUser: false }));
|
|
3337
|
-
}, []);
|
|
3338
3538
|
React.useEffect(() => {
|
|
3339
3539
|
if (!open) {
|
|
3340
3540
|
return;
|
|
@@ -3342,7 +3542,6 @@ function SendDialog({
|
|
|
3342
3542
|
setStatus({ kind: "idle" });
|
|
3343
3543
|
setChannels(null);
|
|
3344
3544
|
setChannelsError(null);
|
|
3345
|
-
setUserStatus(null);
|
|
3346
3545
|
setChannelId("");
|
|
3347
3546
|
setSendAs("bot");
|
|
3348
3547
|
let cancelled = false;
|
|
@@ -3358,19 +3557,10 @@ function SendDialog({
|
|
|
3358
3557
|
}
|
|
3359
3558
|
setChannelsError(e instanceof Error ? e.message : "Failed to load channels");
|
|
3360
3559
|
});
|
|
3361
|
-
refreshSendAsUser();
|
|
3362
3560
|
return () => {
|
|
3363
3561
|
cancelled = true;
|
|
3364
3562
|
};
|
|
3365
|
-
}, [open
|
|
3366
|
-
React.useEffect(() => {
|
|
3367
|
-
if (!open) {
|
|
3368
|
-
return;
|
|
3369
|
-
}
|
|
3370
|
-
const handler = () => refreshSendAsUser();
|
|
3371
|
-
window.addEventListener("focus", handler);
|
|
3372
|
-
return () => window.removeEventListener("focus", handler);
|
|
3373
|
-
}, [open, refreshSendAsUser]);
|
|
3563
|
+
}, [open]);
|
|
3374
3564
|
const handleSubmit = async () => {
|
|
3375
3565
|
if (!channelId) {
|
|
3376
3566
|
setStatus({ kind: "error", error: "Please pick a channel." });
|
|
@@ -3424,22 +3614,9 @@ function SendDialog({
|
|
|
3424
3614
|
]
|
|
3425
3615
|
}
|
|
3426
3616
|
),
|
|
3427
|
-
userStatus && !userStatus.canSendAsUser && userStatus.oauthUrl && isSafeHref(userStatus.oauthUrl) && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3428
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3429
|
-
|
|
3430
|
-
{
|
|
3431
|
-
href: userStatus.oauthUrl,
|
|
3432
|
-
target: "_blank",
|
|
3433
|
-
rel: "noopener noreferrer",
|
|
3434
|
-
className: "inline-flex items-center gap-1 text-primary hover:underline",
|
|
3435
|
-
children: [
|
|
3436
|
-
"Sign in with Slack ",
|
|
3437
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-3 w-3" })
|
|
3438
|
-
]
|
|
3439
|
-
}
|
|
3440
|
-
),
|
|
3441
|
-
" ",
|
|
3442
|
-
"to post as yourself."
|
|
3617
|
+
userStatus && !userStatus.canSendAsUser && userStatus.oauthUrl && isSafeHref(userStatus.oauthUrl) && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3618
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Connect your Slack account to post as yourself." }),
|
|
3619
|
+
/* @__PURE__ */ jsxRuntime.jsx(SlackSignInButton, { onClick: startSignIn, polling })
|
|
3443
3620
|
] })
|
|
3444
3621
|
] }),
|
|
3445
3622
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
@@ -9213,7 +9390,7 @@ function Toolbar2({
|
|
|
9213
9390
|
onOpenLoad,
|
|
9214
9391
|
onOpenUpdate,
|
|
9215
9392
|
onExitEdit,
|
|
9216
|
-
loadButtonLabel = "
|
|
9393
|
+
loadButtonLabel = "Find message",
|
|
9217
9394
|
updateButtonLabel = "Review & update"
|
|
9218
9395
|
}) {
|
|
9219
9396
|
const activeTheme = THEME_OPTIONS.find((t) => t.value === previewTheme) ?? THEME_OPTIONS[0];
|
|
@@ -9497,33 +9674,13 @@ function UpdateDialog({
|
|
|
9497
9674
|
onShowIssues
|
|
9498
9675
|
}) {
|
|
9499
9676
|
const asUser = target.editableVia === "user";
|
|
9500
|
-
const [userStatus, setUserStatus] = React.useState(null);
|
|
9501
9677
|
const [status, setStatus] = React.useState({ kind: "idle" });
|
|
9502
|
-
const
|
|
9503
|
-
React.useEffect(() => {
|
|
9504
|
-
loadSendAsUserStatusRef.current = loadSendAsUserStatus;
|
|
9505
|
-
});
|
|
9506
|
-
const refreshSendAsUser = React.useCallback(() => {
|
|
9507
|
-
loadSendAsUserStatusRef.current().then(setUserStatus).catch(() => setUserStatus({ canSendAsUser: false }));
|
|
9508
|
-
}, []);
|
|
9678
|
+
const { userStatus, polling, startSignIn } = useSlackSignIn(loadSendAsUserStatus, { open, enabled: asUser });
|
|
9509
9679
|
React.useEffect(() => {
|
|
9510
|
-
if (
|
|
9511
|
-
|
|
9512
|
-
}
|
|
9513
|
-
setStatus({ kind: "idle" });
|
|
9514
|
-
if (asUser) {
|
|
9515
|
-
setUserStatus(null);
|
|
9516
|
-
refreshSendAsUser();
|
|
9517
|
-
}
|
|
9518
|
-
}, [open, asUser, refreshSendAsUser]);
|
|
9519
|
-
React.useEffect(() => {
|
|
9520
|
-
if (!open || !asUser) {
|
|
9521
|
-
return;
|
|
9680
|
+
if (open) {
|
|
9681
|
+
setStatus({ kind: "idle" });
|
|
9522
9682
|
}
|
|
9523
|
-
|
|
9524
|
-
window.addEventListener("focus", handler);
|
|
9525
|
-
return () => window.removeEventListener("focus", handler);
|
|
9526
|
-
}, [open, asUser, refreshSendAsUser]);
|
|
9683
|
+
}, [open]);
|
|
9527
9684
|
const needsSignIn = asUser && userStatus !== null && !userStatus.canSendAsUser;
|
|
9528
9685
|
const handleSubmit = async () => {
|
|
9529
9686
|
setStatus({ kind: "updating" });
|
|
@@ -9558,22 +9715,9 @@ function UpdateDialog({
|
|
|
9558
9715
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
9559
9716
|
/* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Posting as" }),
|
|
9560
9717
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "flex h-9 items-center rounded-md border border-input bg-muted px-3 text-sm text-muted-foreground", children: asUser ? "Your account" : "App bot" }),
|
|
9561
|
-
needsSignIn && userStatus?.oauthUrl && isSafeHref(userStatus.oauthUrl) && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9562
|
-
/* @__PURE__ */ jsxRuntime.
|
|
9563
|
-
|
|
9564
|
-
{
|
|
9565
|
-
href: userStatus.oauthUrl,
|
|
9566
|
-
target: "_blank",
|
|
9567
|
-
rel: "noopener noreferrer",
|
|
9568
|
-
className: "inline-flex items-center gap-1 text-primary hover:underline",
|
|
9569
|
-
children: [
|
|
9570
|
-
"Sign in with Slack ",
|
|
9571
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-3 w-3" })
|
|
9572
|
-
]
|
|
9573
|
-
}
|
|
9574
|
-
),
|
|
9575
|
-
" ",
|
|
9576
|
-
"to update your own message."
|
|
9718
|
+
needsSignIn && userStatus?.oauthUrl && isSafeHref(userStatus.oauthUrl) && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
9719
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Connect your Slack account to edit your own messages." }),
|
|
9720
|
+
/* @__PURE__ */ jsxRuntime.jsx(SlackSignInButton, { onClick: startSignIn, polling })
|
|
9577
9721
|
] }),
|
|
9578
9722
|
needsSignIn && !userStatus?.oauthUrl && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Sign in with Slack to update your own message." })
|
|
9579
9723
|
] }),
|