@basictech/react 0.12.0-beta.2 → 0.12.0-beta.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/CHANGELOG.md +35 -0
- package/README.md +201 -21
- package/THIRD_PARTY_NOTICES.md +29 -0
- package/dist/index.d.mts +87 -7
- package/dist/index.d.ts +87 -7
- package/dist/index.js +798 -195
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +776 -178
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +118 -12
- package/dist/styles.css.map +1 -1
- package/package.json +4 -3
package/dist/index.mjs
CHANGED
|
@@ -1046,6 +1046,120 @@ function useProjectProfile(enabled = true) {
|
|
|
1046
1046
|
return useProjectProfileFor(useRequiredClient(), enabled);
|
|
1047
1047
|
}
|
|
1048
1048
|
|
|
1049
|
+
// src/hooks/invites.ts
|
|
1050
|
+
import { useCallback as useCallback6, useRef as useRef3 } from "react";
|
|
1051
|
+
import {
|
|
1052
|
+
BasicError as BasicError6
|
|
1053
|
+
} from "@basictech/core";
|
|
1054
|
+
function useShareInvitesFor(client, enabled = true) {
|
|
1055
|
+
const snapshot = useClientSnapshot(client);
|
|
1056
|
+
const accountId = snapshot.activeAccount?.id;
|
|
1057
|
+
const currentClient = useRef3(client);
|
|
1058
|
+
currentClient.current = client;
|
|
1059
|
+
const gate = useSignInGate(snapshot);
|
|
1060
|
+
const canLoad = enabled && snapshot.isReady && snapshot.isSignedIn;
|
|
1061
|
+
const result = useAsyncResult(
|
|
1062
|
+
async () => {
|
|
1063
|
+
try {
|
|
1064
|
+
return {
|
|
1065
|
+
client,
|
|
1066
|
+
accountId,
|
|
1067
|
+
data: await client.shares.listInvites(),
|
|
1068
|
+
error: null
|
|
1069
|
+
};
|
|
1070
|
+
} catch (error) {
|
|
1071
|
+
return {
|
|
1072
|
+
client,
|
|
1073
|
+
accountId,
|
|
1074
|
+
data: [],
|
|
1075
|
+
error: toBasicError(error)
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
1078
|
+
},
|
|
1079
|
+
null,
|
|
1080
|
+
canLoad,
|
|
1081
|
+
!enabled || snapshot.isReady,
|
|
1082
|
+
[client, accountId]
|
|
1083
|
+
);
|
|
1084
|
+
const current = result.data?.client === client && result.data.accountId === accountId ? result.data : null;
|
|
1085
|
+
const resolveContactHandle = useCallback6(
|
|
1086
|
+
(did) => client.shares.resolveContactHandle(did),
|
|
1087
|
+
[client]
|
|
1088
|
+
);
|
|
1089
|
+
const checkAccount = () => {
|
|
1090
|
+
if (currentClient.current !== client || client.getSnapshot().activeAccount?.id !== accountId)
|
|
1091
|
+
throw new BasicError6("ACCOUNT_CHANGED");
|
|
1092
|
+
};
|
|
1093
|
+
async function run(action, refresh = true) {
|
|
1094
|
+
checkAccount();
|
|
1095
|
+
try {
|
|
1096
|
+
const value = await action();
|
|
1097
|
+
checkAccount();
|
|
1098
|
+
return value;
|
|
1099
|
+
} catch (error) {
|
|
1100
|
+
checkAccount();
|
|
1101
|
+
throw error;
|
|
1102
|
+
} finally {
|
|
1103
|
+
if (refresh && currentClient.current === client && client.getSnapshot().activeAccount?.id === accountId)
|
|
1104
|
+
result.refresh();
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
return {
|
|
1108
|
+
data: canLoad ? current?.data ?? [] : [],
|
|
1109
|
+
isLoading: enabled && (!snapshot.isReady || canLoad && (result.isLoading || !current)),
|
|
1110
|
+
error: enabled ? gate ?? (canLoad ? current?.error ?? null : null) : null,
|
|
1111
|
+
refresh: result.refresh,
|
|
1112
|
+
get: (id) => run(() => client.shares.getInvite(id), false),
|
|
1113
|
+
accept: (id) => run(() => client.shares.acceptInvite(id)),
|
|
1114
|
+
decline: (id) => run(() => client.shares.declineInvite(id)),
|
|
1115
|
+
delete: (id) => run(() => client.shares.deleteInvite(id)),
|
|
1116
|
+
resolveContactHandle
|
|
1117
|
+
};
|
|
1118
|
+
}
|
|
1119
|
+
function useShareInvites(enabled = true) {
|
|
1120
|
+
return useShareInvitesFor(useRequiredClient(), enabled);
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
// src/hooks/recipients.ts
|
|
1124
|
+
function useShareRecipientsFor(client, dids) {
|
|
1125
|
+
const unique = [...new Set(dids)];
|
|
1126
|
+
const key = JSON.stringify(unique);
|
|
1127
|
+
const result = useAsyncResult(
|
|
1128
|
+
async () => {
|
|
1129
|
+
const handles = await Promise.allSettled(
|
|
1130
|
+
unique.map((did) => client.shares.resolveContactHandle(did))
|
|
1131
|
+
);
|
|
1132
|
+
const failed = handles.find((handle) => handle.status === "rejected");
|
|
1133
|
+
return {
|
|
1134
|
+
client,
|
|
1135
|
+
key,
|
|
1136
|
+
data: unique.map((did, index) => {
|
|
1137
|
+
const handle = handles[index];
|
|
1138
|
+
return {
|
|
1139
|
+
did,
|
|
1140
|
+
handle: handle.status === "fulfilled" ? handle.value : null
|
|
1141
|
+
};
|
|
1142
|
+
}),
|
|
1143
|
+
error: failed ? toBasicError(failed.reason) : null
|
|
1144
|
+
};
|
|
1145
|
+
},
|
|
1146
|
+
null,
|
|
1147
|
+
unique.length > 0,
|
|
1148
|
+
true,
|
|
1149
|
+
[client, key]
|
|
1150
|
+
);
|
|
1151
|
+
const current = result.data?.client === client && result.data.key === key ? result.data : null;
|
|
1152
|
+
return {
|
|
1153
|
+
data: current?.data ?? unique.map((did) => ({ did, handle: null })),
|
|
1154
|
+
isLoading: unique.length > 0 && (result.isLoading || !current),
|
|
1155
|
+
error: result.isLoading ? null : current?.error ?? null,
|
|
1156
|
+
refresh: result.refresh
|
|
1157
|
+
};
|
|
1158
|
+
}
|
|
1159
|
+
function useShareRecipients(dids) {
|
|
1160
|
+
return useShareRecipientsFor(useRequiredClient(), dids);
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1049
1163
|
// src/create-basic.tsx
|
|
1050
1164
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
1051
1165
|
function createBasic(config) {
|
|
@@ -1078,7 +1192,9 @@ function createBasic(config) {
|
|
|
1078
1192
|
useFiles: (query = {}, options = {}) => useFilesFor(useBound(), query, options),
|
|
1079
1193
|
useStorageInfo: () => useStorageInfoFor(useBound()),
|
|
1080
1194
|
useMounts: (query = {}) => useMountsFor(useBound(), query),
|
|
1081
|
-
useOutgoingShares: () => useOutgoingSharesFor(useBound())
|
|
1195
|
+
useOutgoingShares: () => useOutgoingSharesFor(useBound()),
|
|
1196
|
+
useShareInvites: (enabled) => useShareInvitesFor(useBound(), enabled),
|
|
1197
|
+
useShareRecipients: (dids) => useShareRecipientsFor(useBound(), dids)
|
|
1082
1198
|
};
|
|
1083
1199
|
}
|
|
1084
1200
|
|
|
@@ -1090,19 +1206,140 @@ import {
|
|
|
1090
1206
|
isValidElement,
|
|
1091
1207
|
useContext as useContext3,
|
|
1092
1208
|
useEffect as useEffect4,
|
|
1093
|
-
useRef as
|
|
1209
|
+
useRef as useRef4,
|
|
1094
1210
|
useState as useState4
|
|
1095
1211
|
} from "react";
|
|
1096
1212
|
import { Avatar } from "@base-ui/react/avatar";
|
|
1097
1213
|
import { Dialog } from "@base-ui/react/dialog";
|
|
1098
1214
|
import { Menu } from "@base-ui/react/menu";
|
|
1099
1215
|
import { Tabs } from "@base-ui/react/tabs";
|
|
1100
|
-
import { BasicError as
|
|
1101
|
-
|
|
1216
|
+
import { BasicError as BasicError7 } from "@basictech/core";
|
|
1217
|
+
|
|
1218
|
+
// src/avatar-marble.tsx
|
|
1219
|
+
import { useId } from "react";
|
|
1220
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
1221
|
+
var ELEMENTS = 3;
|
|
1222
|
+
var SIZE = 80;
|
|
1223
|
+
var COLORS = ["#92A1C6", "#146A7C", "#F0AB3D", "#C271B4", "#C20D90"];
|
|
1224
|
+
function hashCode(value) {
|
|
1225
|
+
let hash = 0;
|
|
1226
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
1227
|
+
hash = (hash << 5) - hash + value.charCodeAt(index);
|
|
1228
|
+
hash &= hash;
|
|
1229
|
+
}
|
|
1230
|
+
return Math.abs(hash);
|
|
1231
|
+
}
|
|
1232
|
+
function getDigit(value, position) {
|
|
1233
|
+
return Math.floor(value / 10 ** position % 10);
|
|
1234
|
+
}
|
|
1235
|
+
function getUnit(value, range, position) {
|
|
1236
|
+
const unit = value % range;
|
|
1237
|
+
return position && getDigit(value, position) % 2 === 0 ? -unit : unit;
|
|
1238
|
+
}
|
|
1239
|
+
function generateProperties(seed) {
|
|
1240
|
+
const value = hashCode(seed);
|
|
1241
|
+
return Array.from({ length: ELEMENTS }, (_, index) => ({
|
|
1242
|
+
color: COLORS[(value + index) % COLORS.length],
|
|
1243
|
+
translateX: getUnit(value * (index + 1), SIZE / 10, 1),
|
|
1244
|
+
translateY: getUnit(value * (index + 1), SIZE / 10, 2),
|
|
1245
|
+
scale: 1.2 + getUnit(value * (index + 1), SIZE / 20) / 10,
|
|
1246
|
+
rotate: getUnit(value * (index + 1), 360, 1)
|
|
1247
|
+
}));
|
|
1248
|
+
}
|
|
1249
|
+
function MarbleAvatar({ seed }) {
|
|
1250
|
+
const properties = generateProperties(seed);
|
|
1251
|
+
const instanceId = useId().replaceAll(":", "");
|
|
1252
|
+
const maskId = `basic-avatar-mask-${instanceId}`;
|
|
1253
|
+
const filterId = `basic-avatar-filter-${instanceId}`;
|
|
1254
|
+
return /* @__PURE__ */ jsxs(
|
|
1255
|
+
"svg",
|
|
1256
|
+
{
|
|
1257
|
+
viewBox: `0 0 ${SIZE} ${SIZE}`,
|
|
1258
|
+
width: "100%",
|
|
1259
|
+
height: "100%",
|
|
1260
|
+
fill: "none",
|
|
1261
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1262
|
+
"aria-hidden": "true",
|
|
1263
|
+
focusable: "false",
|
|
1264
|
+
children: [
|
|
1265
|
+
/* @__PURE__ */ jsx3(
|
|
1266
|
+
"mask",
|
|
1267
|
+
{
|
|
1268
|
+
id: maskId,
|
|
1269
|
+
maskUnits: "userSpaceOnUse",
|
|
1270
|
+
x: "0",
|
|
1271
|
+
y: "0",
|
|
1272
|
+
width: SIZE,
|
|
1273
|
+
height: SIZE,
|
|
1274
|
+
children: /* @__PURE__ */ jsx3("rect", { width: SIZE, height: SIZE, rx: SIZE * 2, fill: "#FFFFFF" })
|
|
1275
|
+
}
|
|
1276
|
+
),
|
|
1277
|
+
/* @__PURE__ */ jsxs("g", { mask: `url(#${maskId})`, children: [
|
|
1278
|
+
/* @__PURE__ */ jsx3("rect", { width: SIZE, height: SIZE, fill: properties[0].color }),
|
|
1279
|
+
/* @__PURE__ */ jsx3(
|
|
1280
|
+
"path",
|
|
1281
|
+
{
|
|
1282
|
+
filter: `url(#${filterId})`,
|
|
1283
|
+
d: "M32.414 59.35L50.376 70.5H72.5v-71H33.728L26.5 13.381l19.057 27.08L32.414 59.35z",
|
|
1284
|
+
fill: properties[1].color,
|
|
1285
|
+
transform: `translate(${properties[1].translateX} ${properties[1].translateY}) rotate(${properties[1].rotate} ${SIZE / 2} ${SIZE / 2}) scale(${properties[2].scale})`
|
|
1286
|
+
}
|
|
1287
|
+
),
|
|
1288
|
+
/* @__PURE__ */ jsx3(
|
|
1289
|
+
"path",
|
|
1290
|
+
{
|
|
1291
|
+
filter: `url(#${filterId})`,
|
|
1292
|
+
style: { mixBlendMode: "overlay" },
|
|
1293
|
+
d: "M22.216 24L0 46.75l14.108 38.129L78 86l-3.081-59.276-22.378 4.005 12.972 20.186-23.35 27.395L22.215 24z",
|
|
1294
|
+
fill: properties[2].color,
|
|
1295
|
+
transform: `translate(${properties[2].translateX} ${properties[2].translateY}) rotate(${properties[2].rotate} ${SIZE / 2} ${SIZE / 2}) scale(${properties[2].scale})`
|
|
1296
|
+
}
|
|
1297
|
+
)
|
|
1298
|
+
] }),
|
|
1299
|
+
/* @__PURE__ */ jsx3("defs", { children: /* @__PURE__ */ jsxs(
|
|
1300
|
+
"filter",
|
|
1301
|
+
{
|
|
1302
|
+
id: filterId,
|
|
1303
|
+
filterUnits: "userSpaceOnUse",
|
|
1304
|
+
colorInterpolationFilters: "sRGB",
|
|
1305
|
+
children: [
|
|
1306
|
+
/* @__PURE__ */ jsx3("feFlood", { floodOpacity: "0", result: "BackgroundImageFix" }),
|
|
1307
|
+
/* @__PURE__ */ jsx3(
|
|
1308
|
+
"feBlend",
|
|
1309
|
+
{
|
|
1310
|
+
in: "SourceGraphic",
|
|
1311
|
+
in2: "BackgroundImageFix",
|
|
1312
|
+
result: "shape"
|
|
1313
|
+
}
|
|
1314
|
+
),
|
|
1315
|
+
/* @__PURE__ */ jsx3("feGaussianBlur", { stdDeviation: "7", result: "effect1_foregroundBlur" })
|
|
1316
|
+
]
|
|
1317
|
+
}
|
|
1318
|
+
) })
|
|
1319
|
+
]
|
|
1320
|
+
}
|
|
1321
|
+
);
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
// src/components.tsx
|
|
1325
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1102
1326
|
var AppearanceContext = createContext2({});
|
|
1327
|
+
function accentText(accent) {
|
|
1328
|
+
if (!/^#([\da-f]{3}|[\da-f]{6})$/i.test(accent)) return "#fff";
|
|
1329
|
+
const hex = accent.length === 4 ? accent.slice(1).split("").map((digit) => digit + digit).join("") : accent.slice(1);
|
|
1330
|
+
const [red, green, blue] = [0, 2, 4].map((offset) => {
|
|
1331
|
+
const channel = parseInt(hex.slice(offset, offset + 2), 16) / 255;
|
|
1332
|
+
return channel <= 0.04045 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4;
|
|
1333
|
+
});
|
|
1334
|
+
return 0.2126 * red + 0.7152 * green + 0.0722 * blue > 0.179 ? "#000" : "#fff";
|
|
1335
|
+
}
|
|
1103
1336
|
function appearanceStyle(appearance) {
|
|
1104
1337
|
return {
|
|
1105
|
-
...appearance.
|
|
1338
|
+
...appearance.base ? { "--basic-surface": appearance.base } : {},
|
|
1339
|
+
...appearance.accent ? {
|
|
1340
|
+
"--basic-accent": appearance.accent,
|
|
1341
|
+
"--basic-accent-text": accentText(appearance.accent)
|
|
1342
|
+
} : {},
|
|
1106
1343
|
...appearance.radius ? { "--basic-radius": appearance.radius } : {}
|
|
1107
1344
|
};
|
|
1108
1345
|
}
|
|
@@ -1112,7 +1349,7 @@ function BasicUIProvider({
|
|
|
1112
1349
|
}) {
|
|
1113
1350
|
const parent = useContext3(AppearanceContext);
|
|
1114
1351
|
const value = { ...parent, ...appearance };
|
|
1115
|
-
return /* @__PURE__ */
|
|
1352
|
+
return /* @__PURE__ */ jsx4(AppearanceContext.Provider, { value, children: /* @__PURE__ */ jsx4(
|
|
1116
1353
|
"div",
|
|
1117
1354
|
{
|
|
1118
1355
|
className: "basic-ui",
|
|
@@ -1133,7 +1370,7 @@ function useAppearanceProps() {
|
|
|
1133
1370
|
}
|
|
1134
1371
|
var BasicButton = forwardRef(
|
|
1135
1372
|
function BasicButton2({ variant = "outline", className = "", type = "button", ...props }, ref) {
|
|
1136
|
-
return /* @__PURE__ */
|
|
1373
|
+
return /* @__PURE__ */ jsx4(
|
|
1137
1374
|
"button",
|
|
1138
1375
|
{
|
|
1139
1376
|
...props,
|
|
@@ -1148,8 +1385,8 @@ var BasicButton = forwardRef(
|
|
|
1148
1385
|
function useAction() {
|
|
1149
1386
|
const [pending, setPending] = useState4(false);
|
|
1150
1387
|
const [error, setError] = useState4(null);
|
|
1151
|
-
const busy =
|
|
1152
|
-
const mounted =
|
|
1388
|
+
const busy = useRef4(false);
|
|
1389
|
+
const mounted = useRef4(true);
|
|
1153
1390
|
useEffect4(() => {
|
|
1154
1391
|
mounted.current = true;
|
|
1155
1392
|
return () => {
|
|
@@ -1166,7 +1403,7 @@ function useAction() {
|
|
|
1166
1403
|
} catch (cause) {
|
|
1167
1404
|
if (mounted.current)
|
|
1168
1405
|
setError(
|
|
1169
|
-
cause instanceof
|
|
1406
|
+
cause instanceof BasicError7 && cause.code === "REDIRECT_URI_NOT_REGISTERED" ? "Sign-in is unavailable on this URL. Ask the app owner to register its callback URL in project settings." : cause instanceof Error ? cause.message : "The action failed. Please try again."
|
|
1170
1407
|
);
|
|
1171
1408
|
} finally {
|
|
1172
1409
|
busy.current = false;
|
|
@@ -1188,8 +1425,8 @@ function AuthButton({
|
|
|
1188
1425
|
const auth = supplied ?? live;
|
|
1189
1426
|
const action = useAction();
|
|
1190
1427
|
const expired = auth.status === "expired";
|
|
1191
|
-
return /* @__PURE__ */
|
|
1192
|
-
/* @__PURE__ */
|
|
1428
|
+
return /* @__PURE__ */ jsxs2("span", { className: "basic-action", children: [
|
|
1429
|
+
/* @__PURE__ */ jsx4(
|
|
1193
1430
|
BasicButton,
|
|
1194
1431
|
{
|
|
1195
1432
|
...props,
|
|
@@ -1205,29 +1442,44 @@ function AuthButton({
|
|
|
1205
1442
|
children: action.pending ? "Please wait\u2026" : children ?? (signOut ? "Sign out" : expired ? "Sign in again" : "Sign in")
|
|
1206
1443
|
}
|
|
1207
1444
|
),
|
|
1208
|
-
/* @__PURE__ */
|
|
1445
|
+
/* @__PURE__ */ jsx4(ActionError, { error: action.error, onClose: action.clearError })
|
|
1209
1446
|
] });
|
|
1210
1447
|
}
|
|
1211
1448
|
function SignInButton(props) {
|
|
1212
|
-
return /* @__PURE__ */
|
|
1449
|
+
return /* @__PURE__ */ jsx4(AuthButton, { ...props });
|
|
1213
1450
|
}
|
|
1214
1451
|
function SignOutButton(props) {
|
|
1215
|
-
return /* @__PURE__ */
|
|
1452
|
+
return /* @__PURE__ */ jsx4(AuthButton, { ...props, signOut: true });
|
|
1453
|
+
}
|
|
1454
|
+
var ANONYMOUS_ACCOUNT_NAME = "Local User";
|
|
1455
|
+
function accountName(profile, emptyFallback = "Guest") {
|
|
1456
|
+
if (!profile) return emptyFallback;
|
|
1457
|
+
return profile.name || (profile.kind === "anon" ? ANONYMOUS_ACCOUNT_NAME : displayHandle(profile.handle) || profile.email || "Account");
|
|
1458
|
+
}
|
|
1459
|
+
function avatarSeed(profile) {
|
|
1460
|
+
if (!profile) return "guest";
|
|
1461
|
+
return profile.did || profile.id && `account:${profile.id}` || profile.handle || profile.email || profile.name || "guest";
|
|
1216
1462
|
}
|
|
1217
1463
|
function UserAvatar({
|
|
1218
1464
|
accounts,
|
|
1219
1465
|
auth,
|
|
1220
1466
|
projectProfile,
|
|
1467
|
+
invites,
|
|
1468
|
+
showInvites,
|
|
1221
1469
|
allowAddAccount,
|
|
1470
|
+
menuItems,
|
|
1222
1471
|
...avatarProps
|
|
1223
1472
|
}) {
|
|
1224
|
-
return /* @__PURE__ */
|
|
1473
|
+
return /* @__PURE__ */ jsx4(
|
|
1225
1474
|
UserMenu,
|
|
1226
1475
|
{
|
|
1227
1476
|
accounts,
|
|
1228
1477
|
auth,
|
|
1229
1478
|
projectProfile,
|
|
1479
|
+
invites,
|
|
1480
|
+
showInvites,
|
|
1230
1481
|
allowAddAccount,
|
|
1482
|
+
menuItems,
|
|
1231
1483
|
sync: avatarProps.sync,
|
|
1232
1484
|
showSyncBadge: avatarProps.showSyncBadge,
|
|
1233
1485
|
avatarProps
|
|
@@ -1239,25 +1491,34 @@ function AccountAvatar({
|
|
|
1239
1491
|
size = 32,
|
|
1240
1492
|
showSyncBadge,
|
|
1241
1493
|
sync,
|
|
1242
|
-
className = "",
|
|
1243
|
-
style,
|
|
1244
1494
|
...props
|
|
1245
1495
|
}) {
|
|
1246
1496
|
const accounts = useAccounts();
|
|
1247
1497
|
const client = useRequiredClient();
|
|
1248
1498
|
const profile = supplied === void 0 ? accounts.activeAccount : supplied;
|
|
1249
|
-
const
|
|
1250
|
-
|
|
1251
|
-
|
|
1499
|
+
const avatar = /* @__PURE__ */ jsx4(ProfileAvatar, { ...props, profile, size });
|
|
1500
|
+
return showSyncBadge ?? client.mode === "sync" ? /* @__PURE__ */ jsxs2("span", { className: "basic-avatar-container", children: [
|
|
1501
|
+
avatar,
|
|
1502
|
+
/* @__PURE__ */ jsx4(SyncStatus, { sync, className: "basic-avatar-sync" })
|
|
1503
|
+
] }) : avatar;
|
|
1504
|
+
}
|
|
1505
|
+
function ProfileAvatar({
|
|
1506
|
+
profile,
|
|
1507
|
+
size = 32,
|
|
1508
|
+
className = "",
|
|
1509
|
+
style,
|
|
1510
|
+
...props
|
|
1511
|
+
}) {
|
|
1512
|
+
return /* @__PURE__ */ jsxs2(
|
|
1252
1513
|
Avatar.Root,
|
|
1253
1514
|
{
|
|
1254
1515
|
...props,
|
|
1255
1516
|
className: `basic-avatar ${className}`,
|
|
1256
1517
|
style: { width: size, height: size, ...style },
|
|
1257
1518
|
role: "img",
|
|
1258
|
-
"aria-label": props["aria-label"] ??
|
|
1519
|
+
"aria-label": props["aria-label"] ?? accountName(profile),
|
|
1259
1520
|
children: [
|
|
1260
|
-
profile?.picture && /* @__PURE__ */
|
|
1521
|
+
profile?.picture && /* @__PURE__ */ jsx4(
|
|
1261
1522
|
Avatar.Image,
|
|
1262
1523
|
{
|
|
1263
1524
|
src: profile.picture,
|
|
@@ -1266,14 +1527,100 @@ function AccountAvatar({
|
|
|
1266
1527
|
referrerPolicy: "no-referrer"
|
|
1267
1528
|
}
|
|
1268
1529
|
),
|
|
1269
|
-
/* @__PURE__ */
|
|
1530
|
+
/* @__PURE__ */ jsx4(Avatar.Fallback, { className: "basic-avatar-fallback", children: /* @__PURE__ */ jsx4(MarbleAvatar, { seed: avatarSeed(profile) }) })
|
|
1531
|
+
]
|
|
1532
|
+
}
|
|
1533
|
+
);
|
|
1534
|
+
}
|
|
1535
|
+
function ShareRecipientAvatar({
|
|
1536
|
+
recipient,
|
|
1537
|
+
...props
|
|
1538
|
+
}) {
|
|
1539
|
+
return /* @__PURE__ */ jsx4(
|
|
1540
|
+
ProfileAvatar,
|
|
1541
|
+
{
|
|
1542
|
+
title: displayHandle(recipient.handle) || recipient.name || recipient.did,
|
|
1543
|
+
...props,
|
|
1544
|
+
profile: {
|
|
1545
|
+
...recipient,
|
|
1546
|
+
name: recipient.name || displayHandle(recipient.handle) || recipient.did,
|
|
1547
|
+
kind: "account"
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
);
|
|
1551
|
+
}
|
|
1552
|
+
function ShareRecipientLabel({
|
|
1553
|
+
recipient,
|
|
1554
|
+
size = 24,
|
|
1555
|
+
className = "",
|
|
1556
|
+
...props
|
|
1557
|
+
}) {
|
|
1558
|
+
const label = displayHandle(recipient.handle) || recipient.name || "Unknown user";
|
|
1559
|
+
return /* @__PURE__ */ jsxs2(
|
|
1560
|
+
"span",
|
|
1561
|
+
{
|
|
1562
|
+
title: recipient.did,
|
|
1563
|
+
...props,
|
|
1564
|
+
className: `basic-recipient-label ${className}`,
|
|
1565
|
+
children: [
|
|
1566
|
+
/* @__PURE__ */ jsx4(
|
|
1567
|
+
ShareRecipientAvatar,
|
|
1568
|
+
{
|
|
1569
|
+
recipient,
|
|
1570
|
+
size,
|
|
1571
|
+
"aria-hidden": "true",
|
|
1572
|
+
title: void 0
|
|
1573
|
+
}
|
|
1574
|
+
),
|
|
1575
|
+
/* @__PURE__ */ jsx4("span", { className: "basic-recipient-handle", children: label })
|
|
1576
|
+
]
|
|
1577
|
+
}
|
|
1578
|
+
);
|
|
1579
|
+
}
|
|
1580
|
+
function ShareRecipientAvatars({
|
|
1581
|
+
recipients,
|
|
1582
|
+
size = 32,
|
|
1583
|
+
max = 4,
|
|
1584
|
+
className = "",
|
|
1585
|
+
...props
|
|
1586
|
+
}) {
|
|
1587
|
+
const unique = [
|
|
1588
|
+
...new Map(
|
|
1589
|
+
recipients.map((recipient) => [recipient.did, recipient])
|
|
1590
|
+
).values()
|
|
1591
|
+
];
|
|
1592
|
+
const visible = unique.slice(0, Math.max(1, max));
|
|
1593
|
+
const remaining = unique.length - visible.length;
|
|
1594
|
+
return /* @__PURE__ */ jsxs2(
|
|
1595
|
+
"span",
|
|
1596
|
+
{
|
|
1597
|
+
...props,
|
|
1598
|
+
className: `basic-recipient-avatars ${className}`,
|
|
1599
|
+
role: "group",
|
|
1600
|
+
"aria-label": props["aria-label"] ?? `Shared with ${unique.length} recipients`,
|
|
1601
|
+
children: [
|
|
1602
|
+
visible.map((recipient) => /* @__PURE__ */ jsx4(
|
|
1603
|
+
ShareRecipientAvatar,
|
|
1604
|
+
{
|
|
1605
|
+
recipient,
|
|
1606
|
+
size
|
|
1607
|
+
},
|
|
1608
|
+
recipient.did
|
|
1609
|
+
)),
|
|
1610
|
+
remaining > 0 && /* @__PURE__ */ jsxs2(
|
|
1611
|
+
"span",
|
|
1612
|
+
{
|
|
1613
|
+
className: "basic-recipient-overflow",
|
|
1614
|
+
"aria-label": `${remaining} more recipients`,
|
|
1615
|
+
children: [
|
|
1616
|
+
"+",
|
|
1617
|
+
remaining
|
|
1618
|
+
]
|
|
1619
|
+
}
|
|
1620
|
+
)
|
|
1270
1621
|
]
|
|
1271
1622
|
}
|
|
1272
1623
|
);
|
|
1273
|
-
return showSyncBadge ?? client.mode === "sync" ? /* @__PURE__ */ jsxs("span", { className: "basic-avatar-container", children: [
|
|
1274
|
-
avatar,
|
|
1275
|
-
/* @__PURE__ */ jsx3(SyncStatus, { sync, className: "basic-avatar-sync" })
|
|
1276
|
-
] }) : avatar;
|
|
1277
1624
|
}
|
|
1278
1625
|
function AuthStatus({
|
|
1279
1626
|
auth: supplied,
|
|
@@ -1284,7 +1631,7 @@ function AuthStatus({
|
|
|
1284
1631
|
const auth = supplied ?? live;
|
|
1285
1632
|
const expired = auth.status === "expired";
|
|
1286
1633
|
const label = !auth.isReady || auth.status === "bootstrapping" ? "Checking session" : expired ? "Session expired" : auth.status === "recovering" ? "Reconnecting session" : auth.isSignedIn ? "Signed in" : auth.isAnonymous ? "Guest \xB7 local only" : "Signed out";
|
|
1287
|
-
return /* @__PURE__ */
|
|
1634
|
+
return /* @__PURE__ */ jsxs2(
|
|
1288
1635
|
"span",
|
|
1289
1636
|
{
|
|
1290
1637
|
...props,
|
|
@@ -1292,7 +1639,7 @@ function AuthStatus({
|
|
|
1292
1639
|
className: `basic-status ${className}`,
|
|
1293
1640
|
"data-tone": expired || auth.error ? "warning" : auth.isSignedIn ? "success" : "neutral",
|
|
1294
1641
|
children: [
|
|
1295
|
-
/* @__PURE__ */
|
|
1642
|
+
/* @__PURE__ */ jsx4("span", { className: "basic-dot" }),
|
|
1296
1643
|
label
|
|
1297
1644
|
]
|
|
1298
1645
|
}
|
|
@@ -1322,7 +1669,7 @@ function SyncStatus({
|
|
|
1322
1669
|
ended: "Access ended"
|
|
1323
1670
|
};
|
|
1324
1671
|
const label = issues ? `${issues} sync ${issues === 1 ? "issue" : "issues"}` : sync.status === "online" && sync.pendingCount ? "Syncing" : labels[sync.status];
|
|
1325
|
-
return /* @__PURE__ */
|
|
1672
|
+
return /* @__PURE__ */ jsxs2(
|
|
1326
1673
|
"span",
|
|
1327
1674
|
{
|
|
1328
1675
|
...props,
|
|
@@ -1331,7 +1678,7 @@ function SyncStatus({
|
|
|
1331
1678
|
className: `basic-status ${className}`,
|
|
1332
1679
|
"data-tone": issues || ["error", "stale", "ended"].includes(sync.status) ? "warning" : sync.status === "online" && !sync.pendingCount ? "success" : ["bootstrapping", "connecting"].includes(sync.status) || sync.status === "online" && sync.pendingCount > 0 ? "progress" : "neutral",
|
|
1333
1680
|
children: [
|
|
1334
|
-
/* @__PURE__ */
|
|
1681
|
+
/* @__PURE__ */ jsx4("span", { className: "basic-dot" }),
|
|
1335
1682
|
label,
|
|
1336
1683
|
sync.pendingCount > 0 && ` \xB7 ${sync.pendingCount} pending`
|
|
1337
1684
|
]
|
|
@@ -1342,7 +1689,7 @@ function displayHandle(handle) {
|
|
|
1342
1689
|
return handle ? `@${handle.replace(/^@+/, "")}` : "";
|
|
1343
1690
|
}
|
|
1344
1691
|
function UserButton(props) {
|
|
1345
|
-
return /* @__PURE__ */
|
|
1692
|
+
return /* @__PURE__ */ jsx4(UserMenu, { ...props, trigger: "button" });
|
|
1346
1693
|
}
|
|
1347
1694
|
function UserMenu({
|
|
1348
1695
|
accounts: supplied,
|
|
@@ -1354,9 +1701,12 @@ function UserMenu({
|
|
|
1354
1701
|
trigger = "avatar",
|
|
1355
1702
|
avatarProps,
|
|
1356
1703
|
projectProfile,
|
|
1704
|
+
invites,
|
|
1705
|
+
showInvites,
|
|
1357
1706
|
allowAddAccount = true,
|
|
1358
1707
|
className = "",
|
|
1359
|
-
accountSettingsUrl
|
|
1708
|
+
accountSettingsUrl,
|
|
1709
|
+
menuItems = []
|
|
1360
1710
|
}) {
|
|
1361
1711
|
const liveAccounts = useAccounts();
|
|
1362
1712
|
const liveAuth = useAuth();
|
|
@@ -1365,17 +1715,17 @@ function UserMenu({
|
|
|
1365
1715
|
const action = useAction();
|
|
1366
1716
|
const [settingsOpen, setSettingsOpen] = useState4(false);
|
|
1367
1717
|
const [clearAccountId, setClearAccountId] = useState4(null);
|
|
1368
|
-
const triggerRef =
|
|
1718
|
+
const triggerRef = useRef4(null);
|
|
1369
1719
|
const appearance = useAppearanceProps();
|
|
1370
1720
|
const expired = auth.status === "expired";
|
|
1371
1721
|
const active = accounts.activeAccount;
|
|
1372
1722
|
const otherAccounts = accounts.accounts.filter(
|
|
1373
1723
|
(account) => account.id !== active?.id
|
|
1374
1724
|
);
|
|
1375
|
-
const name = active
|
|
1376
|
-
return /* @__PURE__ */
|
|
1377
|
-
/* @__PURE__ */
|
|
1378
|
-
/* @__PURE__ */
|
|
1725
|
+
const name = active ? accountName(active) : "Local account";
|
|
1726
|
+
return /* @__PURE__ */ jsxs2("span", { className: `basic-action ${className}`, children: [
|
|
1727
|
+
/* @__PURE__ */ jsxs2(Menu.Root, { children: [
|
|
1728
|
+
/* @__PURE__ */ jsxs2(
|
|
1379
1729
|
Menu.Trigger,
|
|
1380
1730
|
{
|
|
1381
1731
|
ref: triggerRef,
|
|
@@ -1384,7 +1734,7 @@ function UserMenu({
|
|
|
1384
1734
|
disabled: !auth.isReady || action.pending,
|
|
1385
1735
|
"aria-label": "Open user menu",
|
|
1386
1736
|
children: [
|
|
1387
|
-
/* @__PURE__ */
|
|
1737
|
+
/* @__PURE__ */ jsx4(
|
|
1388
1738
|
AccountAvatar,
|
|
1389
1739
|
{
|
|
1390
1740
|
profile: accounts.activeAccount,
|
|
@@ -1393,12 +1743,12 @@ function UserMenu({
|
|
|
1393
1743
|
...avatarProps
|
|
1394
1744
|
}
|
|
1395
1745
|
),
|
|
1396
|
-
trigger === "button" && /* @__PURE__ */
|
|
1397
|
-
/* @__PURE__ */
|
|
1398
|
-
/* @__PURE__ */
|
|
1399
|
-
active?.kind !== "anon" && active?.handle && /* @__PURE__ */
|
|
1746
|
+
trigger === "button" && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1747
|
+
/* @__PURE__ */ jsxs2("span", { className: "basic-identity", children: [
|
|
1748
|
+
/* @__PURE__ */ jsx4("strong", { children: name }),
|
|
1749
|
+
active?.kind !== "anon" && active?.handle && /* @__PURE__ */ jsx4("small", { children: displayHandle(active.handle) })
|
|
1400
1750
|
] }),
|
|
1401
|
-
/* @__PURE__ */
|
|
1751
|
+
/* @__PURE__ */ jsx4(
|
|
1402
1752
|
"svg",
|
|
1403
1753
|
{
|
|
1404
1754
|
className: "basic-chevron",
|
|
@@ -1411,16 +1761,16 @@ function UserMenu({
|
|
|
1411
1761
|
strokeLinecap: "round",
|
|
1412
1762
|
strokeLinejoin: "round",
|
|
1413
1763
|
"aria-hidden": "true",
|
|
1414
|
-
children: /* @__PURE__ */
|
|
1764
|
+
children: /* @__PURE__ */ jsx4("path", { d: "m6 9 6 6 6-6" })
|
|
1415
1765
|
}
|
|
1416
1766
|
)
|
|
1417
1767
|
] })
|
|
1418
1768
|
]
|
|
1419
1769
|
}
|
|
1420
1770
|
),
|
|
1421
|
-
/* @__PURE__ */
|
|
1422
|
-
/* @__PURE__ */
|
|
1423
|
-
/* @__PURE__ */
|
|
1771
|
+
/* @__PURE__ */ jsx4(Menu.Portal, { children: /* @__PURE__ */ jsx4(Menu.Positioner, { sideOffset: 8, className: "basic-positioner", children: /* @__PURE__ */ jsxs2(Menu.Popup, { ...appearance, className: "basic-ui basic-menu", children: [
|
|
1772
|
+
/* @__PURE__ */ jsxs2("div", { className: "basic-menu-profile", children: [
|
|
1773
|
+
/* @__PURE__ */ jsx4(
|
|
1424
1774
|
AccountAvatar,
|
|
1425
1775
|
{
|
|
1426
1776
|
profile: active,
|
|
@@ -1429,16 +1779,16 @@ function UserMenu({
|
|
|
1429
1779
|
showSyncBadge: false
|
|
1430
1780
|
}
|
|
1431
1781
|
),
|
|
1432
|
-
/* @__PURE__ */
|
|
1433
|
-
/* @__PURE__ */
|
|
1434
|
-
active?.kind !== "anon" && active?.handle && /* @__PURE__ */
|
|
1435
|
-
/* @__PURE__ */
|
|
1436
|
-
expired && /* @__PURE__ */
|
|
1437
|
-
showSyncStatus && /* @__PURE__ */
|
|
1782
|
+
/* @__PURE__ */ jsxs2("span", { className: "basic-identity", children: [
|
|
1783
|
+
/* @__PURE__ */ jsx4("strong", { children: active ? name : "No active account" }),
|
|
1784
|
+
active?.kind !== "anon" && active?.handle && /* @__PURE__ */ jsx4("small", { children: displayHandle(active.handle) }),
|
|
1785
|
+
/* @__PURE__ */ jsxs2("span", { className: "basic-account-statuses", children: [
|
|
1786
|
+
expired && /* @__PURE__ */ jsx4("span", { className: "basic-status", "data-tone": "warning", children: "Expired" }),
|
|
1787
|
+
showSyncStatus && /* @__PURE__ */ jsx4(SyncStatus, { sync })
|
|
1438
1788
|
] })
|
|
1439
1789
|
] })
|
|
1440
1790
|
] }),
|
|
1441
|
-
expired && /* @__PURE__ */
|
|
1791
|
+
expired && /* @__PURE__ */ jsx4(
|
|
1442
1792
|
Menu.Item,
|
|
1443
1793
|
{
|
|
1444
1794
|
className: "basic-menu-item basic-menu-reauth",
|
|
@@ -1447,13 +1797,13 @@ function UserMenu({
|
|
|
1447
1797
|
children: "Sign in again"
|
|
1448
1798
|
}
|
|
1449
1799
|
),
|
|
1450
|
-
/* @__PURE__ */
|
|
1800
|
+
/* @__PURE__ */ jsxs2(
|
|
1451
1801
|
Menu.Item,
|
|
1452
1802
|
{
|
|
1453
1803
|
className: "basic-menu-item basic-manage-account",
|
|
1454
1804
|
onClick: () => setSettingsOpen(true),
|
|
1455
1805
|
children: [
|
|
1456
|
-
/* @__PURE__ */
|
|
1806
|
+
/* @__PURE__ */ jsxs2(
|
|
1457
1807
|
"svg",
|
|
1458
1808
|
{
|
|
1459
1809
|
className: "basic-menu-icon",
|
|
@@ -1467,8 +1817,8 @@ function UserMenu({
|
|
|
1467
1817
|
strokeLinejoin: "round",
|
|
1468
1818
|
"aria-hidden": "true",
|
|
1469
1819
|
children: [
|
|
1470
|
-
/* @__PURE__ */
|
|
1471
|
-
/* @__PURE__ */
|
|
1820
|
+
/* @__PURE__ */ jsx4("circle", { cx: "12", cy: "7", r: "4" }),
|
|
1821
|
+
/* @__PURE__ */ jsx4("path", { d: "M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" })
|
|
1472
1822
|
]
|
|
1473
1823
|
}
|
|
1474
1824
|
),
|
|
@@ -1476,14 +1826,30 @@ function UserMenu({
|
|
|
1476
1826
|
]
|
|
1477
1827
|
}
|
|
1478
1828
|
),
|
|
1479
|
-
(
|
|
1829
|
+
menuItems.map((item) => /* @__PURE__ */ jsxs2(
|
|
1830
|
+
Menu.Item,
|
|
1831
|
+
{
|
|
1832
|
+
className: "basic-menu-item",
|
|
1833
|
+
render: item.href !== void 0 ? /* @__PURE__ */ jsx4("a", { href: item.href }) : void 0,
|
|
1834
|
+
disabled: item.disabled || action.pending,
|
|
1835
|
+
onClick: () => {
|
|
1836
|
+
if (item.onClick) void action.run(item.onClick);
|
|
1837
|
+
},
|
|
1838
|
+
children: [
|
|
1839
|
+
/* @__PURE__ */ jsx4("span", { className: "basic-menu-icon", "aria-hidden": "true", children: item.icon }),
|
|
1840
|
+
item.label
|
|
1841
|
+
]
|
|
1842
|
+
},
|
|
1843
|
+
item.id
|
|
1844
|
+
)),
|
|
1845
|
+
(auth.isSignedIn || expired || active?.kind === "anon") && /* @__PURE__ */ jsxs2(
|
|
1480
1846
|
Menu.Item,
|
|
1481
1847
|
{
|
|
1482
1848
|
className: "basic-menu-item basic-menu-signout",
|
|
1483
1849
|
disabled: action.pending,
|
|
1484
1850
|
onClick: () => active?.kind === "anon" ? setClearAccountId(active.id) : void action.run(() => auth.signOut()),
|
|
1485
1851
|
children: [
|
|
1486
|
-
/* @__PURE__ */
|
|
1852
|
+
/* @__PURE__ */ jsx4(
|
|
1487
1853
|
"svg",
|
|
1488
1854
|
{
|
|
1489
1855
|
className: "basic-menu-icon",
|
|
@@ -1496,25 +1862,25 @@ function UserMenu({
|
|
|
1496
1862
|
strokeLinecap: "round",
|
|
1497
1863
|
strokeLinejoin: "round",
|
|
1498
1864
|
"aria-hidden": "true",
|
|
1499
|
-
children: /* @__PURE__ */
|
|
1865
|
+
children: /* @__PURE__ */ jsx4("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9" })
|
|
1500
1866
|
}
|
|
1501
1867
|
),
|
|
1502
1868
|
active?.kind === "anon" ? "Clear account" : "Sign out"
|
|
1503
1869
|
]
|
|
1504
1870
|
}
|
|
1505
1871
|
),
|
|
1506
|
-
otherAccounts.length > 0 && /* @__PURE__ */
|
|
1507
|
-
/* @__PURE__ */
|
|
1508
|
-
/* @__PURE__ */
|
|
1872
|
+
otherAccounts.length > 0 && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1873
|
+
/* @__PURE__ */ jsx4(Menu.Separator, { className: "basic-separator" }),
|
|
1874
|
+
/* @__PURE__ */ jsx4("div", { className: "basic-menu-heading", children: "Switch accounts" })
|
|
1509
1875
|
] }),
|
|
1510
|
-
otherAccounts.map((account) => /* @__PURE__ */
|
|
1876
|
+
otherAccounts.map((account) => /* @__PURE__ */ jsxs2(
|
|
1511
1877
|
Menu.Item,
|
|
1512
1878
|
{
|
|
1513
1879
|
className: "basic-menu-item",
|
|
1514
1880
|
disabled: action.pending,
|
|
1515
1881
|
onClick: () => void action.run(() => accounts.switchAccount(account.id)),
|
|
1516
1882
|
children: [
|
|
1517
|
-
/* @__PURE__ */
|
|
1883
|
+
/* @__PURE__ */ jsx4(
|
|
1518
1884
|
AccountAvatar,
|
|
1519
1885
|
{
|
|
1520
1886
|
profile: account,
|
|
@@ -1523,16 +1889,16 @@ function UserMenu({
|
|
|
1523
1889
|
showSyncBadge: false
|
|
1524
1890
|
}
|
|
1525
1891
|
),
|
|
1526
|
-
/* @__PURE__ */
|
|
1527
|
-
/* @__PURE__ */
|
|
1528
|
-
account.kind !== "anon" && account.handle && /* @__PURE__ */
|
|
1892
|
+
/* @__PURE__ */ jsxs2("span", { className: "basic-identity", children: [
|
|
1893
|
+
/* @__PURE__ */ jsx4("strong", { children: accountName(account, "Account") }),
|
|
1894
|
+
account.kind !== "anon" && account.handle && /* @__PURE__ */ jsx4("small", { children: displayHandle(account.handle) })
|
|
1529
1895
|
] }),
|
|
1530
|
-
/* @__PURE__ */
|
|
1896
|
+
/* @__PURE__ */ jsx4("span", { className: "basic-account-statuses", children: account.auth.status === "expired" ? /* @__PURE__ */ jsx4("span", { className: "basic-status", "data-tone": "warning", children: "Expired" }) : null })
|
|
1531
1897
|
]
|
|
1532
1898
|
},
|
|
1533
1899
|
account.id
|
|
1534
1900
|
)),
|
|
1535
|
-
(allowAddAccount || !auth.isSignedIn && !expired) && /* @__PURE__ */
|
|
1901
|
+
(allowAddAccount || !auth.isSignedIn && !expired) && /* @__PURE__ */ jsxs2(
|
|
1536
1902
|
Menu.Item,
|
|
1537
1903
|
{
|
|
1538
1904
|
className: "basic-menu-item",
|
|
@@ -1540,12 +1906,29 @@ function UserMenu({
|
|
|
1540
1906
|
onClick: () => void action.run(
|
|
1541
1907
|
() => allowAddAccount ? accounts.addAccount({ signIn: true }) : auth.signIn()
|
|
1542
1908
|
),
|
|
1543
|
-
children:
|
|
1909
|
+
children: [
|
|
1910
|
+
/* @__PURE__ */ jsx4(
|
|
1911
|
+
"svg",
|
|
1912
|
+
{
|
|
1913
|
+
className: "basic-menu-icon",
|
|
1914
|
+
width: "16",
|
|
1915
|
+
height: "16",
|
|
1916
|
+
viewBox: "0 0 24 24",
|
|
1917
|
+
fill: "none",
|
|
1918
|
+
stroke: "currentColor",
|
|
1919
|
+
strokeWidth: "1.75",
|
|
1920
|
+
strokeLinecap: "round",
|
|
1921
|
+
"aria-hidden": "true",
|
|
1922
|
+
children: /* @__PURE__ */ jsx4("path", { d: "M12 5v14M5 12h14" })
|
|
1923
|
+
}
|
|
1924
|
+
),
|
|
1925
|
+
"Add account"
|
|
1926
|
+
]
|
|
1544
1927
|
}
|
|
1545
1928
|
)
|
|
1546
1929
|
] }) }) })
|
|
1547
1930
|
] }),
|
|
1548
|
-
/* @__PURE__ */
|
|
1931
|
+
/* @__PURE__ */ jsx4(
|
|
1549
1932
|
ActionError,
|
|
1550
1933
|
{
|
|
1551
1934
|
error: action.error,
|
|
@@ -1553,7 +1936,7 @@ function UserMenu({
|
|
|
1553
1936
|
finalFocus: triggerRef
|
|
1554
1937
|
}
|
|
1555
1938
|
),
|
|
1556
|
-
/* @__PURE__ */
|
|
1939
|
+
/* @__PURE__ */ jsx4(
|
|
1557
1940
|
Modal,
|
|
1558
1941
|
{
|
|
1559
1942
|
open: clearAccountId !== null,
|
|
@@ -1564,8 +1947,8 @@ function UserMenu({
|
|
|
1564
1947
|
finalFocus: triggerRef,
|
|
1565
1948
|
title: "Clear local account?",
|
|
1566
1949
|
description: "This deletes this account\u2019s local data, including unsynced changes. This cannot be undone.",
|
|
1567
|
-
children: /* @__PURE__ */
|
|
1568
|
-
/* @__PURE__ */
|
|
1950
|
+
children: /* @__PURE__ */ jsxs2("div", { className: "basic-actions", children: [
|
|
1951
|
+
/* @__PURE__ */ jsx4(
|
|
1569
1952
|
BasicButton,
|
|
1570
1953
|
{
|
|
1571
1954
|
disabled: action.pending,
|
|
@@ -1573,7 +1956,7 @@ function UserMenu({
|
|
|
1573
1956
|
children: "Cancel"
|
|
1574
1957
|
}
|
|
1575
1958
|
),
|
|
1576
|
-
/* @__PURE__ */
|
|
1959
|
+
/* @__PURE__ */ jsx4(
|
|
1577
1960
|
BasicButton,
|
|
1578
1961
|
{
|
|
1579
1962
|
disabled: action.pending,
|
|
@@ -1589,7 +1972,7 @@ function UserMenu({
|
|
|
1589
1972
|
] })
|
|
1590
1973
|
}
|
|
1591
1974
|
),
|
|
1592
|
-
/* @__PURE__ */
|
|
1975
|
+
/* @__PURE__ */ jsx4(
|
|
1593
1976
|
AccountSettingsModal,
|
|
1594
1977
|
{
|
|
1595
1978
|
auth,
|
|
@@ -1600,6 +1983,8 @@ function UserMenu({
|
|
|
1600
1983
|
finalFocus: triggerRef,
|
|
1601
1984
|
accountSettingsUrl,
|
|
1602
1985
|
projectProfile,
|
|
1986
|
+
invites,
|
|
1987
|
+
showInvites,
|
|
1603
1988
|
sync
|
|
1604
1989
|
}
|
|
1605
1990
|
)
|
|
@@ -1610,7 +1995,7 @@ function ActionError({
|
|
|
1610
1995
|
onClose,
|
|
1611
1996
|
finalFocus
|
|
1612
1997
|
}) {
|
|
1613
|
-
return /* @__PURE__ */
|
|
1998
|
+
return /* @__PURE__ */ jsxs2(
|
|
1614
1999
|
Modal,
|
|
1615
2000
|
{
|
|
1616
2001
|
open: !!error,
|
|
@@ -1622,8 +2007,8 @@ function ActionError({
|
|
|
1622
2007
|
title: "Unable to complete action",
|
|
1623
2008
|
description: "Your request could not be completed.",
|
|
1624
2009
|
children: [
|
|
1625
|
-
/* @__PURE__ */
|
|
1626
|
-
/* @__PURE__ */
|
|
2010
|
+
/* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: error }),
|
|
2011
|
+
/* @__PURE__ */ jsx4(BasicButton, { onClick: onClose, children: "Dismiss" })
|
|
1627
2012
|
]
|
|
1628
2013
|
}
|
|
1629
2014
|
);
|
|
@@ -1635,29 +2020,36 @@ function Modal({
|
|
|
1635
2020
|
finalFocus,
|
|
1636
2021
|
title,
|
|
1637
2022
|
description,
|
|
2023
|
+
hideTitle = false,
|
|
1638
2024
|
header,
|
|
1639
2025
|
sectionLabel,
|
|
1640
2026
|
children
|
|
1641
2027
|
}) {
|
|
1642
2028
|
const appearance = useAppearanceProps();
|
|
1643
|
-
return /* @__PURE__ */
|
|
1644
|
-
trigger !== null && (isValidElement(trigger) ? /* @__PURE__ */
|
|
1645
|
-
/* @__PURE__ */
|
|
1646
|
-
/* @__PURE__ */
|
|
1647
|
-
/* @__PURE__ */
|
|
2029
|
+
return /* @__PURE__ */ jsxs2(Dialog.Root, { open, onOpenChange, children: [
|
|
2030
|
+
trigger !== null && (isValidElement(trigger) ? /* @__PURE__ */ jsx4(Dialog.Trigger, { render: trigger }) : /* @__PURE__ */ jsx4(Dialog.Trigger, { render: /* @__PURE__ */ jsx4(BasicButton, {}), children: trigger ?? title })),
|
|
2031
|
+
/* @__PURE__ */ jsxs2(Dialog.Portal, { children: [
|
|
2032
|
+
/* @__PURE__ */ jsx4(Dialog.Backdrop, { className: "basic-backdrop" }),
|
|
2033
|
+
/* @__PURE__ */ jsxs2(
|
|
1648
2034
|
Dialog.Popup,
|
|
1649
2035
|
{
|
|
1650
2036
|
...appearance,
|
|
1651
2037
|
finalFocus,
|
|
1652
2038
|
className: "basic-ui basic-dialog",
|
|
1653
2039
|
children: [
|
|
1654
|
-
/* @__PURE__ */
|
|
2040
|
+
/* @__PURE__ */ jsxs2(
|
|
1655
2041
|
"div",
|
|
1656
2042
|
{
|
|
1657
|
-
className: `basic-dialog-heading${header ? " basic-dialog-heading-overlay" : ""}`,
|
|
2043
|
+
className: `basic-dialog-heading${header || hideTitle ? " basic-dialog-heading-overlay" : ""}`,
|
|
1658
2044
|
children: [
|
|
1659
|
-
/* @__PURE__ */
|
|
1660
|
-
|
|
2045
|
+
/* @__PURE__ */ jsx4(
|
|
2046
|
+
Dialog.Title,
|
|
2047
|
+
{
|
|
2048
|
+
className: header || hideTitle ? "basic-sr-only" : "basic-title",
|
|
2049
|
+
children: title
|
|
2050
|
+
}
|
|
2051
|
+
),
|
|
2052
|
+
/* @__PURE__ */ jsx4(
|
|
1661
2053
|
Dialog.Close,
|
|
1662
2054
|
{
|
|
1663
2055
|
className: "basic-button",
|
|
@@ -1669,14 +2061,14 @@ function Modal({
|
|
|
1669
2061
|
}
|
|
1670
2062
|
),
|
|
1671
2063
|
header,
|
|
1672
|
-
/* @__PURE__ */
|
|
2064
|
+
description && /* @__PURE__ */ jsx4(
|
|
1673
2065
|
Dialog.Description,
|
|
1674
2066
|
{
|
|
1675
2067
|
className: header ? "basic-sr-only" : "basic-muted",
|
|
1676
2068
|
children: description
|
|
1677
2069
|
}
|
|
1678
2070
|
),
|
|
1679
|
-
sectionLabel && /* @__PURE__ */
|
|
2071
|
+
sectionLabel && /* @__PURE__ */ jsx4("div", { className: "basic-modal-section", children: sectionLabel }),
|
|
1680
2072
|
children
|
|
1681
2073
|
]
|
|
1682
2074
|
}
|
|
@@ -1689,6 +2081,8 @@ function AccountSettingsModal({
|
|
|
1689
2081
|
accounts: suppliedAccounts,
|
|
1690
2082
|
accountSettingsUrl,
|
|
1691
2083
|
projectProfile,
|
|
2084
|
+
invites,
|
|
2085
|
+
showInvites = true,
|
|
1692
2086
|
sync,
|
|
1693
2087
|
children,
|
|
1694
2088
|
...props
|
|
@@ -1727,27 +2121,28 @@ function AccountSettingsModal({
|
|
|
1727
2121
|
["Conflicts", String(syncState.conflicts.length)]
|
|
1728
2122
|
];
|
|
1729
2123
|
const diagnostics = JSON.stringify(Object.fromEntries(details), null, 2);
|
|
1730
|
-
return /* @__PURE__ */
|
|
2124
|
+
return /* @__PURE__ */ jsx4(
|
|
1731
2125
|
Modal,
|
|
1732
2126
|
{
|
|
1733
2127
|
...props,
|
|
1734
2128
|
title: "Account settings",
|
|
1735
2129
|
description: "Your identity and session on this device.",
|
|
1736
|
-
header: /* @__PURE__ */
|
|
1737
|
-
children: /* @__PURE__ */
|
|
1738
|
-
/* @__PURE__ */
|
|
2130
|
+
header: /* @__PURE__ */ jsx4(AccountHeader, { account: accounts.activeAccount, sync }),
|
|
2131
|
+
children: /* @__PURE__ */ jsxs2(Tabs.Root, { defaultValue: "profile", children: [
|
|
2132
|
+
/* @__PURE__ */ jsxs2(
|
|
1739
2133
|
Tabs.List,
|
|
1740
2134
|
{
|
|
1741
2135
|
className: "basic-tabs",
|
|
1742
2136
|
"aria-label": "Account settings sections",
|
|
1743
2137
|
children: [
|
|
1744
|
-
/* @__PURE__ */
|
|
1745
|
-
/* @__PURE__ */
|
|
2138
|
+
/* @__PURE__ */ jsx4(Tabs.Tab, { value: "profile", children: "Profile" }),
|
|
2139
|
+
showInvites && /* @__PURE__ */ jsx4(Tabs.Tab, { value: "invites", children: "Share Invites" }),
|
|
2140
|
+
/* @__PURE__ */ jsx4(Tabs.Tab, { value: "advanced", children: "Advanced" })
|
|
1746
2141
|
]
|
|
1747
2142
|
}
|
|
1748
2143
|
),
|
|
1749
|
-
/* @__PURE__ */
|
|
1750
|
-
auth.isSignedIn && /* @__PURE__ */
|
|
2144
|
+
/* @__PURE__ */ jsxs2(Tabs.Panel, { value: "profile", keepMounted: true, children: [
|
|
2145
|
+
auth.isSignedIn && /* @__PURE__ */ jsx4(
|
|
1751
2146
|
ProjectProfileEditor,
|
|
1752
2147
|
{
|
|
1753
2148
|
profile: projectProfile,
|
|
@@ -1755,18 +2150,19 @@ function AccountSettingsModal({
|
|
|
1755
2150
|
},
|
|
1756
2151
|
accounts.activeAccount?.id ?? auth.did
|
|
1757
2152
|
),
|
|
1758
|
-
accountSettingsUrl && /* @__PURE__ */
|
|
2153
|
+
accountSettingsUrl && /* @__PURE__ */ jsx4("a", { className: "basic-link", href: accountSettingsUrl, children: "Manage profile and security \u2197" }),
|
|
1759
2154
|
children,
|
|
1760
|
-
!auth.isSignedIn && /* @__PURE__ */
|
|
2155
|
+
!auth.isSignedIn && /* @__PURE__ */ jsx4("div", { className: "basic-actions", children: /* @__PURE__ */ jsx4(SignInButton, { auth }) })
|
|
1761
2156
|
] }),
|
|
1762
|
-
/* @__PURE__ */
|
|
1763
|
-
|
|
1764
|
-
/* @__PURE__ */
|
|
1765
|
-
|
|
1766
|
-
/* @__PURE__ */
|
|
2157
|
+
showInvites && /* @__PURE__ */ jsx4(Tabs.Panel, { value: "invites", children: /* @__PURE__ */ jsx4(ShareInvites, { auth, accounts, invites }) }),
|
|
2158
|
+
/* @__PURE__ */ jsxs2(Tabs.Panel, { value: "advanced", children: [
|
|
2159
|
+
/* @__PURE__ */ jsx4("p", { className: "basic-muted", children: "Read-only diagnostics for this account." }),
|
|
2160
|
+
/* @__PURE__ */ jsx4("dl", { className: "basic-details", children: details.map(([label, value]) => /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
2161
|
+
/* @__PURE__ */ jsx4("dt", { children: label }),
|
|
2162
|
+
/* @__PURE__ */ jsx4("dd", { children: value })
|
|
1767
2163
|
] }, label)) }),
|
|
1768
|
-
/* @__PURE__ */
|
|
1769
|
-
/* @__PURE__ */
|
|
2164
|
+
/* @__PURE__ */ jsxs2("div", { className: "basic-actions", children: [
|
|
2165
|
+
/* @__PURE__ */ jsx4(
|
|
1770
2166
|
BasicButton,
|
|
1771
2167
|
{
|
|
1772
2168
|
disabled: copyAction.pending,
|
|
@@ -1782,9 +2178,9 @@ function AccountSettingsModal({
|
|
|
1782
2178
|
children: "Copy to clipboard"
|
|
1783
2179
|
}
|
|
1784
2180
|
),
|
|
1785
|
-
copied === diagnostics && /* @__PURE__ */
|
|
2181
|
+
copied === diagnostics && /* @__PURE__ */ jsx4("span", { role: "status", className: "basic-muted", children: "Copied" })
|
|
1786
2182
|
] }),
|
|
1787
|
-
copyAction.error && /* @__PURE__ */
|
|
2183
|
+
copyAction.error && /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: copyAction.error })
|
|
1788
2184
|
] })
|
|
1789
2185
|
] })
|
|
1790
2186
|
}
|
|
@@ -1794,8 +2190,8 @@ function AccountHeader({
|
|
|
1794
2190
|
account,
|
|
1795
2191
|
sync
|
|
1796
2192
|
}) {
|
|
1797
|
-
return /* @__PURE__ */
|
|
1798
|
-
/* @__PURE__ */
|
|
2193
|
+
return /* @__PURE__ */ jsxs2("div", { className: "basic-profile", children: [
|
|
2194
|
+
/* @__PURE__ */ jsx4(
|
|
1799
2195
|
AccountAvatar,
|
|
1800
2196
|
{
|
|
1801
2197
|
profile: account,
|
|
@@ -1804,10 +2200,10 @@ function AccountHeader({
|
|
|
1804
2200
|
showSyncBadge: false
|
|
1805
2201
|
}
|
|
1806
2202
|
),
|
|
1807
|
-
/* @__PURE__ */
|
|
1808
|
-
/* @__PURE__ */
|
|
1809
|
-
account?.kind !== "anon" && account?.handle && /* @__PURE__ */
|
|
1810
|
-
/* @__PURE__ */
|
|
2203
|
+
/* @__PURE__ */ jsxs2("span", { className: "basic-identity", children: [
|
|
2204
|
+
/* @__PURE__ */ jsx4("strong", { children: account ? accountName(account) : "Local account" }),
|
|
2205
|
+
account?.kind !== "anon" && account?.handle && /* @__PURE__ */ jsx4("small", { children: displayHandle(account.handle) }),
|
|
2206
|
+
/* @__PURE__ */ jsx4("span", { className: "basic-account-statuses", children: /* @__PURE__ */ jsx4(SyncStatus, { sync }) })
|
|
1811
2207
|
] })
|
|
1812
2208
|
] });
|
|
1813
2209
|
}
|
|
@@ -1820,7 +2216,7 @@ function ProjectProfileEditor({
|
|
|
1820
2216
|
const action = useAction();
|
|
1821
2217
|
const [draft, setDraft] = useState4({});
|
|
1822
2218
|
const [saved, setSaved] = useState4(false);
|
|
1823
|
-
return /* @__PURE__ */
|
|
2219
|
+
return /* @__PURE__ */ jsxs2(
|
|
1824
2220
|
"form",
|
|
1825
2221
|
{
|
|
1826
2222
|
className: "basic-profile-editor",
|
|
@@ -1834,15 +2230,15 @@ function ProjectProfileEditor({
|
|
|
1834
2230
|
});
|
|
1835
2231
|
},
|
|
1836
2232
|
children: [
|
|
1837
|
-
/* @__PURE__ */
|
|
1838
|
-
/* @__PURE__ */
|
|
1839
|
-
profile.isLoading ? /* @__PURE__ */
|
|
1840
|
-
/* @__PURE__ */
|
|
1841
|
-
/* @__PURE__ */
|
|
1842
|
-
] }) : profile.data && /* @__PURE__ */
|
|
1843
|
-
/* @__PURE__ */
|
|
2233
|
+
/* @__PURE__ */ jsx4("h3", { className: "basic-section-label", children: "Personal information" }),
|
|
2234
|
+
/* @__PURE__ */ jsx4("p", { className: "basic-muted", children: "Only this app sees these overrides. Clear a field to use your universal profile value." }),
|
|
2235
|
+
profile.isLoading ? /* @__PURE__ */ jsx4("p", { role: "status", children: "Loading project profile\u2026" }) : profile.error ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
2236
|
+
/* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: profile.error.message }),
|
|
2237
|
+
/* @__PURE__ */ jsx4(BasicButton, { onClick: profile.refresh, children: "Retry profile" })
|
|
2238
|
+
] }) : profile.data && /* @__PURE__ */ jsxs2("fieldset", { disabled: !canWrite || action.pending, children: [
|
|
2239
|
+
/* @__PURE__ */ jsxs2("label", { className: "basic-field", children: [
|
|
1844
2240
|
"Display name",
|
|
1845
|
-
/* @__PURE__ */
|
|
2241
|
+
/* @__PURE__ */ jsx4(
|
|
1846
2242
|
"input",
|
|
1847
2243
|
{
|
|
1848
2244
|
className: "basic-input",
|
|
@@ -1859,8 +2255,8 @@ function ProjectProfileEditor({
|
|
|
1859
2255
|
}
|
|
1860
2256
|
)
|
|
1861
2257
|
] }),
|
|
1862
|
-
/* @__PURE__ */
|
|
1863
|
-
/* @__PURE__ */
|
|
2258
|
+
/* @__PURE__ */ jsxs2("div", { className: "basic-actions basic-modal-footer", children: [
|
|
2259
|
+
/* @__PURE__ */ jsx4(
|
|
1864
2260
|
BasicButton,
|
|
1865
2261
|
{
|
|
1866
2262
|
variant: "ghost",
|
|
@@ -1871,7 +2267,7 @@ function ProjectProfileEditor({
|
|
|
1871
2267
|
children: "Cancel"
|
|
1872
2268
|
}
|
|
1873
2269
|
),
|
|
1874
|
-
/* @__PURE__ */
|
|
2270
|
+
/* @__PURE__ */ jsx4(
|
|
1875
2271
|
BasicButton,
|
|
1876
2272
|
{
|
|
1877
2273
|
type: "submit",
|
|
@@ -1882,17 +2278,205 @@ function ProjectProfileEditor({
|
|
|
1882
2278
|
)
|
|
1883
2279
|
] })
|
|
1884
2280
|
] }),
|
|
1885
|
-
action.error && /* @__PURE__ */
|
|
1886
|
-
saved && /* @__PURE__ */
|
|
2281
|
+
action.error && /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: action.error }),
|
|
2282
|
+
saved && /* @__PURE__ */ jsx4("p", { role: "status", children: "Project profile saved." })
|
|
1887
2283
|
]
|
|
1888
2284
|
}
|
|
1889
2285
|
);
|
|
1890
2286
|
}
|
|
2287
|
+
function ShareInvites({
|
|
2288
|
+
auth: suppliedAuth,
|
|
2289
|
+
accounts: suppliedAccounts,
|
|
2290
|
+
invites,
|
|
2291
|
+
className = "",
|
|
2292
|
+
...props
|
|
2293
|
+
}) {
|
|
2294
|
+
const liveAuth = useAuth();
|
|
2295
|
+
const liveAccounts = useAccounts();
|
|
2296
|
+
const auth = suppliedAuth ?? liveAuth;
|
|
2297
|
+
const accounts = suppliedAccounts ?? liveAccounts;
|
|
2298
|
+
return /* @__PURE__ */ jsxs2(
|
|
2299
|
+
"section",
|
|
2300
|
+
{
|
|
2301
|
+
...props,
|
|
2302
|
+
className: `basic-invites ${className}`,
|
|
2303
|
+
"aria-label": props["aria-label"] ?? "Share Invites",
|
|
2304
|
+
children: [
|
|
2305
|
+
(!auth.isReady || !auth.isSignedIn) && /* @__PURE__ */ jsx4("h3", { className: "basic-title", children: "Share Invites" }),
|
|
2306
|
+
!auth.isReady ? /* @__PURE__ */ jsx4("p", { role: "status", children: "Checking session\u2026" }) : !auth.isSignedIn ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
2307
|
+
/* @__PURE__ */ jsx4("p", { className: "basic-muted", children: "Sign in to view invites." }),
|
|
2308
|
+
/* @__PURE__ */ jsx4(SignInButton, { auth })
|
|
2309
|
+
] }) : /* @__PURE__ */ jsx4(
|
|
2310
|
+
ShareInvitesContent,
|
|
2311
|
+
{
|
|
2312
|
+
invites,
|
|
2313
|
+
canWrite: auth.canWrite
|
|
2314
|
+
},
|
|
2315
|
+
accounts.activeAccount?.id ?? auth.did
|
|
2316
|
+
)
|
|
2317
|
+
]
|
|
2318
|
+
}
|
|
2319
|
+
);
|
|
2320
|
+
}
|
|
2321
|
+
function ShareInvitesContent({
|
|
2322
|
+
invites: supplied,
|
|
2323
|
+
canWrite
|
|
2324
|
+
}) {
|
|
2325
|
+
const live = useShareInvites(supplied === void 0);
|
|
2326
|
+
const invites = supplied ?? live;
|
|
2327
|
+
const action = useAction();
|
|
2328
|
+
const [message, setMessage] = useState4("");
|
|
2329
|
+
const visible = invites.data.filter((invite) => invite.state !== "deleted");
|
|
2330
|
+
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
2331
|
+
/* @__PURE__ */ jsxs2("div", { className: "basic-section-heading", children: [
|
|
2332
|
+
/* @__PURE__ */ jsx4("h3", { className: "basic-title", children: "Share Invites" }),
|
|
2333
|
+
/* @__PURE__ */ jsx4(
|
|
2334
|
+
BasicButton,
|
|
2335
|
+
{
|
|
2336
|
+
disabled: invites.isLoading || action.pending,
|
|
2337
|
+
onClick: invites.refresh,
|
|
2338
|
+
children: "Refresh"
|
|
2339
|
+
}
|
|
2340
|
+
)
|
|
2341
|
+
] }),
|
|
2342
|
+
!canWrite && /* @__PURE__ */ jsx4("p", { className: "basic-error", children: "Read-only session. Invite changes are disabled." }),
|
|
2343
|
+
action.error && /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: action.error }),
|
|
2344
|
+
message && /* @__PURE__ */ jsx4("p", { role: "status", children: message }),
|
|
2345
|
+
action.pending && /* @__PURE__ */ jsx4("p", { role: "status", children: "Updating invite\u2026" }),
|
|
2346
|
+
invites.isLoading ? /* @__PURE__ */ jsx4("p", { role: "status", children: "Loading invites\u2026" }) : invites.error ? /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: invites.error.message }) : !visible.length ? /* @__PURE__ */ jsx4("p", { className: "basic-empty", children: "No share invites." }) : /* @__PURE__ */ jsx4("ul", { className: "basic-share-list basic-invite-list", children: visible.map((invite) => {
|
|
2347
|
+
const title = invite.display.shareName || invite.display.repoName || "Shared data";
|
|
2348
|
+
return /* @__PURE__ */ jsx4(
|
|
2349
|
+
ShareInviteRow,
|
|
2350
|
+
{
|
|
2351
|
+
invite,
|
|
2352
|
+
title,
|
|
2353
|
+
resolveContactHandle: invites.resolveContactHandle,
|
|
2354
|
+
disabled: !canWrite || action.pending,
|
|
2355
|
+
onDecision: (decision) => void action.run(async () => {
|
|
2356
|
+
setMessage("");
|
|
2357
|
+
await invites[decision](invite.id);
|
|
2358
|
+
setMessage(
|
|
2359
|
+
`${decision === "accept" ? "Accepted" : "Declined"} \u201C${title}\u201D.`
|
|
2360
|
+
);
|
|
2361
|
+
})
|
|
2362
|
+
},
|
|
2363
|
+
invite.id
|
|
2364
|
+
);
|
|
2365
|
+
}) })
|
|
2366
|
+
] });
|
|
2367
|
+
}
|
|
2368
|
+
function ShareInviteRow({
|
|
2369
|
+
invite,
|
|
2370
|
+
title,
|
|
2371
|
+
resolveContactHandle,
|
|
2372
|
+
disabled,
|
|
2373
|
+
onDecision
|
|
2374
|
+
}) {
|
|
2375
|
+
const did = invite.originOwnerDid;
|
|
2376
|
+
const [sender, setSender] = useState4(null);
|
|
2377
|
+
useEffect4(() => {
|
|
2378
|
+
let active = true;
|
|
2379
|
+
void resolveContactHandle(did).then(
|
|
2380
|
+
(handle2) => {
|
|
2381
|
+
if (active) setSender({ did, handle: handle2 });
|
|
2382
|
+
},
|
|
2383
|
+
() => {
|
|
2384
|
+
if (active) setSender({ did, handle: null });
|
|
2385
|
+
}
|
|
2386
|
+
);
|
|
2387
|
+
return () => {
|
|
2388
|
+
active = false;
|
|
2389
|
+
};
|
|
2390
|
+
}, [did, resolveContactHandle]);
|
|
2391
|
+
const handle = sender?.did === did ? sender.handle : null;
|
|
2392
|
+
const pending = invite.state === "pending";
|
|
2393
|
+
const accepting = invite.state === "accepting";
|
|
2394
|
+
const expiresAt = new Date(invite.acceptBy);
|
|
2395
|
+
const expired = expiresAt.getTime() <= Date.now();
|
|
2396
|
+
const blocked = invite.compatibility.state === "app_connection_required" ? "Connect this app to accept." : invite.compatibility.state === "compatible_repo_required" ? "A compatible repository is required." : null;
|
|
2397
|
+
const status = pending && !expired ? null : (pending || accepting) && expired ? "Expired" : accepting ? "Retry to finish accepting" : invite.state === "accepted" ? "Accepted" : invite.state === "declined" ? "Declined" : "Acceptance rejected";
|
|
2398
|
+
return /* @__PURE__ */ jsxs2("li", { children: [
|
|
2399
|
+
/* @__PURE__ */ jsx4(
|
|
2400
|
+
ShareRecipientAvatar,
|
|
2401
|
+
{
|
|
2402
|
+
recipient: {
|
|
2403
|
+
did,
|
|
2404
|
+
name: handle ? displayHandle(handle) : "Unknown sender"
|
|
2405
|
+
},
|
|
2406
|
+
size: 32
|
|
2407
|
+
}
|
|
2408
|
+
),
|
|
2409
|
+
/* @__PURE__ */ jsxs2("div", { className: "basic-identity", children: [
|
|
2410
|
+
/* @__PURE__ */ jsx4("strong", { children: title }),
|
|
2411
|
+
/* @__PURE__ */ jsx4("small", { children: handle ? displayHandle(handle) : "Unknown sender" }),
|
|
2412
|
+
/* @__PURE__ */ jsx4("small", { children: invite.role === "editor" ? "Can edit" : "Can view" }),
|
|
2413
|
+
status && /* @__PURE__ */ jsx4("span", { className: "basic-invite-state", children: status }),
|
|
2414
|
+
blocked && (pending || accepting) && /* @__PURE__ */ jsx4("p", { className: "basic-error", children: blocked })
|
|
2415
|
+
] }),
|
|
2416
|
+
(pending || accepting) && /* @__PURE__ */ jsxs2("div", { className: "basic-invite-actions", children: [
|
|
2417
|
+
/* @__PURE__ */ jsx4(
|
|
2418
|
+
BasicButton,
|
|
2419
|
+
{
|
|
2420
|
+
variant: "solid",
|
|
2421
|
+
disabled: disabled || expired || !!blocked,
|
|
2422
|
+
onClick: () => onDecision("accept"),
|
|
2423
|
+
children: accepting ? "Retry acceptance" : "Accept"
|
|
2424
|
+
}
|
|
2425
|
+
),
|
|
2426
|
+
pending && /* @__PURE__ */ jsx4(
|
|
2427
|
+
BasicButton,
|
|
2428
|
+
{
|
|
2429
|
+
disabled,
|
|
2430
|
+
onClick: () => onDecision("decline"),
|
|
2431
|
+
children: "Decline"
|
|
2432
|
+
}
|
|
2433
|
+
)
|
|
2434
|
+
] }),
|
|
2435
|
+
/* @__PURE__ */ jsxs2("details", { className: "basic-invite-details", children: [
|
|
2436
|
+
/* @__PURE__ */ jsx4("summary", { children: "Details" }),
|
|
2437
|
+
/* @__PURE__ */ jsxs2("div", { className: "basic-invite-scope", children: [
|
|
2438
|
+
invite.scope.map((scope, index) => /* @__PURE__ */ jsxs2("div", { children: [
|
|
2439
|
+
/* @__PURE__ */ jsx4("strong", { children: scope.table }),
|
|
2440
|
+
" \xB7",
|
|
2441
|
+
" ",
|
|
2442
|
+
scope.recordIds ? `${scope.recordIds.length} selected records` : "all records",
|
|
2443
|
+
scope.recordIds && /* @__PURE__ */ jsx4("code", { children: scope.recordIds.join(", ") })
|
|
2444
|
+
] }, index)),
|
|
2445
|
+
/* @__PURE__ */ jsxs2("small", { children: [
|
|
2446
|
+
"Sender DID: ",
|
|
2447
|
+
did
|
|
2448
|
+
] }),
|
|
2449
|
+
/* @__PURE__ */ jsxs2("small", { children: [
|
|
2450
|
+
"Expires",
|
|
2451
|
+
" ",
|
|
2452
|
+
/* @__PURE__ */ jsxs2("time", { dateTime: invite.acceptBy, children: [
|
|
2453
|
+
expiresAt.toLocaleString("en-US", {
|
|
2454
|
+
dateStyle: "medium",
|
|
2455
|
+
timeStyle: "short",
|
|
2456
|
+
timeZone: "UTC"
|
|
2457
|
+
}),
|
|
2458
|
+
" ",
|
|
2459
|
+
"UTC"
|
|
2460
|
+
] })
|
|
2461
|
+
] })
|
|
2462
|
+
] })
|
|
2463
|
+
] })
|
|
2464
|
+
] });
|
|
2465
|
+
}
|
|
2466
|
+
function ShareInvitesModal({
|
|
2467
|
+
auth,
|
|
2468
|
+
accounts,
|
|
2469
|
+
invites,
|
|
2470
|
+
...props
|
|
2471
|
+
}) {
|
|
2472
|
+
return /* @__PURE__ */ jsx4(Modal, { ...props, title: "Share Invites", hideTitle: true, children: /* @__PURE__ */ jsx4(ShareInvites, { auth, accounts, invites }) });
|
|
2473
|
+
}
|
|
1891
2474
|
function SharesModal({
|
|
1892
2475
|
auth: supplied,
|
|
1893
2476
|
accounts: suppliedAccounts,
|
|
1894
2477
|
sync,
|
|
1895
2478
|
shares,
|
|
2479
|
+
invites,
|
|
1896
2480
|
scope,
|
|
1897
2481
|
repo = "default",
|
|
1898
2482
|
...props
|
|
@@ -1900,37 +2484,43 @@ function SharesModal({
|
|
|
1900
2484
|
const live = useAuth();
|
|
1901
2485
|
const liveAccounts = useAccounts();
|
|
1902
2486
|
const auth = supplied ?? live;
|
|
1903
|
-
return /* @__PURE__ */
|
|
2487
|
+
return /* @__PURE__ */ jsx4(
|
|
1904
2488
|
Modal,
|
|
1905
2489
|
{
|
|
1906
2490
|
...props,
|
|
1907
2491
|
title: "Shares",
|
|
1908
2492
|
description: "Manage incoming invitations and share access to selected data.",
|
|
1909
|
-
header: /* @__PURE__ */
|
|
2493
|
+
header: /* @__PURE__ */ jsx4(
|
|
1910
2494
|
AccountHeader,
|
|
1911
2495
|
{
|
|
1912
2496
|
account: (suppliedAccounts ?? liveAccounts).activeAccount,
|
|
1913
2497
|
sync
|
|
1914
2498
|
}
|
|
1915
2499
|
),
|
|
1916
|
-
children: !auth.isReady ? /* @__PURE__ */
|
|
1917
|
-
/* @__PURE__ */
|
|
1918
|
-
/* @__PURE__ */
|
|
1919
|
-
] }) : /* @__PURE__ */
|
|
2500
|
+
children: !auth.isReady ? /* @__PURE__ */ jsx4("p", { role: "status", children: "Checking session\u2026" }) : !auth.isSignedIn ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
2501
|
+
/* @__PURE__ */ jsx4("p", { className: "basic-muted", children: "Sign in to share data." }),
|
|
2502
|
+
/* @__PURE__ */ jsx4(SignInButton, { auth })
|
|
2503
|
+
] }) : /* @__PURE__ */ jsx4(
|
|
1920
2504
|
SharesContent,
|
|
1921
2505
|
{
|
|
1922
2506
|
shares,
|
|
2507
|
+
invites,
|
|
2508
|
+
auth,
|
|
2509
|
+
accounts: suppliedAccounts ?? liveAccounts,
|
|
1923
2510
|
scope,
|
|
1924
2511
|
repo,
|
|
1925
2512
|
canWrite: auth.canWrite
|
|
1926
2513
|
},
|
|
1927
|
-
|
|
2514
|
+
(suppliedAccounts ?? liveAccounts).activeAccount?.id ?? auth.did
|
|
1928
2515
|
)
|
|
1929
2516
|
}
|
|
1930
2517
|
);
|
|
1931
2518
|
}
|
|
1932
2519
|
function SharesContent({
|
|
1933
2520
|
shares: supplied,
|
|
2521
|
+
invites,
|
|
2522
|
+
auth,
|
|
2523
|
+
accounts,
|
|
1934
2524
|
scope,
|
|
1935
2525
|
repo,
|
|
1936
2526
|
canWrite
|
|
@@ -1945,29 +2535,25 @@ function SharesContent({
|
|
|
1945
2535
|
const scopeValid = scope.length > 0 && scope.every(
|
|
1946
2536
|
(item) => item.table.trim() && (item.recordIds === void 0 || item.recordIds.length > 0)
|
|
1947
2537
|
);
|
|
1948
|
-
return /* @__PURE__ */
|
|
1949
|
-
/* @__PURE__ */
|
|
1950
|
-
/* @__PURE__ */
|
|
1951
|
-
/* @__PURE__ */
|
|
2538
|
+
return /* @__PURE__ */ jsxs2(Tabs.Root, { defaultValue: "outgoing", className: "basic-shares", children: [
|
|
2539
|
+
/* @__PURE__ */ jsxs2(Tabs.List, { className: "basic-tabs", "aria-label": "Share direction", children: [
|
|
2540
|
+
/* @__PURE__ */ jsx4(Tabs.Tab, { value: "outgoing", children: "Outgoing" }),
|
|
2541
|
+
/* @__PURE__ */ jsx4(Tabs.Tab, { value: "incoming", children: "Share Invites" })
|
|
1952
2542
|
] }),
|
|
1953
|
-
/* @__PURE__ */
|
|
1954
|
-
|
|
1955
|
-
/* @__PURE__ */
|
|
1956
|
-
/* @__PURE__ */
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
/* @__PURE__ */ jsx3("p", { className: "basic-muted", children: "Revoking access stops future requests. It cannot retract data the recipient already downloaded." }),
|
|
1960
|
-
/* @__PURE__ */ jsxs("div", { className: "basic-scope", children: [
|
|
1961
|
-
/* @__PURE__ */ jsx3("strong", { children: "New invitation permissions" }),
|
|
1962
|
-
scope.map((item, index) => /* @__PURE__ */ jsxs("span", { children: [
|
|
2543
|
+
/* @__PURE__ */ jsx4(Tabs.Panel, { value: "incoming", children: /* @__PURE__ */ jsx4(ShareInvites, { invites, auth, accounts }) }),
|
|
2544
|
+
/* @__PURE__ */ jsxs2(Tabs.Panel, { value: "outgoing", children: [
|
|
2545
|
+
/* @__PURE__ */ jsx4("p", { className: "basic-muted", children: "Revoking access stops future requests. It cannot retract data the recipient already downloaded." }),
|
|
2546
|
+
/* @__PURE__ */ jsxs2("div", { className: "basic-scope", children: [
|
|
2547
|
+
/* @__PURE__ */ jsx4("strong", { children: "New invitation permissions" }),
|
|
2548
|
+
scope.map((item, index) => /* @__PURE__ */ jsxs2("span", { children: [
|
|
1963
2549
|
item.table,
|
|
1964
2550
|
" \xB7",
|
|
1965
2551
|
" ",
|
|
1966
2552
|
item.recordIds ? `${item.recordIds.length} selected records` : "all records"
|
|
1967
2553
|
] }, index))
|
|
1968
2554
|
] }),
|
|
1969
|
-
!canWrite && /* @__PURE__ */
|
|
1970
|
-
/* @__PURE__ */
|
|
2555
|
+
!canWrite && /* @__PURE__ */ jsx4("p", { className: "basic-error", children: "This session is read only. Sharing changes are disabled." }),
|
|
2556
|
+
/* @__PURE__ */ jsxs2(
|
|
1971
2557
|
"form",
|
|
1972
2558
|
{
|
|
1973
2559
|
className: "basic-share-form",
|
|
@@ -1987,9 +2573,9 @@ function SharesContent({
|
|
|
1987
2573
|
});
|
|
1988
2574
|
},
|
|
1989
2575
|
children: [
|
|
1990
|
-
/* @__PURE__ */
|
|
2576
|
+
/* @__PURE__ */ jsxs2("label", { className: "basic-field", children: [
|
|
1991
2577
|
"Recipient handle or DID",
|
|
1992
|
-
/* @__PURE__ */
|
|
2578
|
+
/* @__PURE__ */ jsx4(
|
|
1993
2579
|
"input",
|
|
1994
2580
|
{
|
|
1995
2581
|
className: "basic-input",
|
|
@@ -2001,9 +2587,9 @@ function SharesContent({
|
|
|
2001
2587
|
}
|
|
2002
2588
|
)
|
|
2003
2589
|
] }),
|
|
2004
|
-
/* @__PURE__ */
|
|
2590
|
+
/* @__PURE__ */ jsxs2("label", { className: "basic-field", children: [
|
|
2005
2591
|
"Permission",
|
|
2006
|
-
/* @__PURE__ */
|
|
2592
|
+
/* @__PURE__ */ jsxs2(
|
|
2007
2593
|
"select",
|
|
2008
2594
|
{
|
|
2009
2595
|
className: "basic-input",
|
|
@@ -2011,13 +2597,13 @@ function SharesContent({
|
|
|
2011
2597
|
onChange: (event) => setRole(event.target.value),
|
|
2012
2598
|
disabled: action.pending || !canWrite,
|
|
2013
2599
|
children: [
|
|
2014
|
-
/* @__PURE__ */
|
|
2015
|
-
/* @__PURE__ */
|
|
2600
|
+
/* @__PURE__ */ jsx4("option", { value: "viewer", children: "Can view" }),
|
|
2601
|
+
/* @__PURE__ */ jsx4("option", { value: "editor", children: "Can edit" })
|
|
2016
2602
|
]
|
|
2017
2603
|
}
|
|
2018
2604
|
)
|
|
2019
2605
|
] }),
|
|
2020
|
-
/* @__PURE__ */
|
|
2606
|
+
/* @__PURE__ */ jsx4(
|
|
2021
2607
|
BasicButton,
|
|
2022
2608
|
{
|
|
2023
2609
|
type: "submit",
|
|
@@ -2029,12 +2615,12 @@ function SharesContent({
|
|
|
2029
2615
|
]
|
|
2030
2616
|
}
|
|
2031
2617
|
),
|
|
2032
|
-
!scopeValid && /* @__PURE__ */
|
|
2033
|
-
action.error && /* @__PURE__ */
|
|
2034
|
-
message && /* @__PURE__ */
|
|
2035
|
-
/* @__PURE__ */
|
|
2036
|
-
/* @__PURE__ */
|
|
2037
|
-
/* @__PURE__ */
|
|
2618
|
+
!scopeValid && /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: "Select at least one table or record to share." }),
|
|
2619
|
+
action.error && /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: action.error }),
|
|
2620
|
+
message && /* @__PURE__ */ jsx4("p", { role: "status", className: "basic-muted", children: message }),
|
|
2621
|
+
/* @__PURE__ */ jsxs2("div", { className: "basic-section-heading", children: [
|
|
2622
|
+
/* @__PURE__ */ jsx4("h3", { className: "basic-title", children: "Outgoing shares \xB7 all permissions" }),
|
|
2623
|
+
/* @__PURE__ */ jsx4(
|
|
2038
2624
|
BasicButton,
|
|
2039
2625
|
{
|
|
2040
2626
|
disabled: action.pending || shares.isLoading,
|
|
@@ -2043,10 +2629,15 @@ function SharesContent({
|
|
|
2043
2629
|
}
|
|
2044
2630
|
)
|
|
2045
2631
|
] }),
|
|
2046
|
-
shares.isLoading ? /* @__PURE__ */
|
|
2047
|
-
/* @__PURE__ */
|
|
2048
|
-
|
|
2049
|
-
/* @__PURE__ */
|
|
2632
|
+
shares.isLoading ? /* @__PURE__ */ jsx4("p", { role: "status", children: "Loading shares\u2026" }) : shares.error ? /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: shares.error.message }) : !shares.data.length ? /* @__PURE__ */ jsx4("p", { className: "basic-empty", children: "No outgoing shares yet." }) : /* @__PURE__ */ jsx4("ul", { className: "basic-share-list", children: shares.data.map((share) => /* @__PURE__ */ jsxs2("li", { children: [
|
|
2633
|
+
/* @__PURE__ */ jsx4(ShareRecipientAvatar, { recipient: { did: share.recipientDid } }),
|
|
2634
|
+
/* @__PURE__ */ jsxs2("div", { className: "basic-identity", children: [
|
|
2635
|
+
/* @__PURE__ */ jsx4("strong", { children: share.display.shareName || share.recipientDid }),
|
|
2636
|
+
share.display.shareName && /* @__PURE__ */ jsxs2("small", { children: [
|
|
2637
|
+
"To ",
|
|
2638
|
+
share.recipientDid
|
|
2639
|
+
] }),
|
|
2640
|
+
/* @__PURE__ */ jsxs2("small", { children: [
|
|
2050
2641
|
share.role === "viewer" ? "Can view" : "Can edit",
|
|
2051
2642
|
" \xB7",
|
|
2052
2643
|
" ",
|
|
@@ -2056,9 +2647,9 @@ function SharesContent({
|
|
|
2056
2647
|
share.scope.map((item) => item.table).join(", ")
|
|
2057
2648
|
] })
|
|
2058
2649
|
] }),
|
|
2059
|
-
share.state !== "ended" && (confirmation === share.id ? /* @__PURE__ */
|
|
2060
|
-
/* @__PURE__ */
|
|
2061
|
-
/* @__PURE__ */
|
|
2650
|
+
share.state !== "ended" && (confirmation === share.id ? /* @__PURE__ */ jsxs2("div", { className: "basic-actions", children: [
|
|
2651
|
+
/* @__PURE__ */ jsx4("span", { children: "Remove access?" }),
|
|
2652
|
+
/* @__PURE__ */ jsxs2(
|
|
2062
2653
|
BasicButton,
|
|
2063
2654
|
{
|
|
2064
2655
|
disabled: action.pending || !canWrite,
|
|
@@ -2077,7 +2668,7 @@ function SharesContent({
|
|
|
2077
2668
|
]
|
|
2078
2669
|
}
|
|
2079
2670
|
),
|
|
2080
|
-
/* @__PURE__ */
|
|
2671
|
+
/* @__PURE__ */ jsx4(
|
|
2081
2672
|
BasicButton,
|
|
2082
2673
|
{
|
|
2083
2674
|
disabled: action.pending,
|
|
@@ -2085,7 +2676,7 @@ function SharesContent({
|
|
|
2085
2676
|
children: "Keep access"
|
|
2086
2677
|
}
|
|
2087
2678
|
)
|
|
2088
|
-
] }) : /* @__PURE__ */
|
|
2679
|
+
] }) : /* @__PURE__ */ jsx4(
|
|
2089
2680
|
BasicButton,
|
|
2090
2681
|
{
|
|
2091
2682
|
disabled: action.pending || !canWrite,
|
|
@@ -2106,6 +2697,11 @@ export {
|
|
|
2106
2697
|
BrowserKeyValueStorage,
|
|
2107
2698
|
BrowserTokenStore,
|
|
2108
2699
|
PersistenceStore,
|
|
2700
|
+
ShareInvites,
|
|
2701
|
+
ShareInvitesModal,
|
|
2702
|
+
ShareRecipientAvatar,
|
|
2703
|
+
ShareRecipientAvatars,
|
|
2704
|
+
ShareRecipientLabel,
|
|
2109
2705
|
SharesModal,
|
|
2110
2706
|
SignInButton,
|
|
2111
2707
|
SignOutButton,
|
|
@@ -2134,6 +2730,8 @@ export {
|
|
|
2134
2730
|
useQuery,
|
|
2135
2731
|
useRepos,
|
|
2136
2732
|
useSchemaStatus,
|
|
2733
|
+
useShareInvites,
|
|
2734
|
+
useShareRecipients,
|
|
2137
2735
|
useStorageInfo,
|
|
2138
2736
|
useSyncStatus
|
|
2139
2737
|
};
|