@basictech/react 0.12.0-beta.3 → 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 +22 -0
- package/README.md +145 -12
- package/THIRD_PARTY_NOTICES.md +29 -0
- package/dist/index.d.mts +69 -7
- package/dist/index.d.ts +69 -7
- package/dist/index.js +751 -197
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +729 -180
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +99 -0
- 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,15 +1206,123 @@ 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({});
|
|
1103
1327
|
function accentText(accent) {
|
|
1104
1328
|
if (!/^#([\da-f]{3}|[\da-f]{6})$/i.test(accent)) return "#fff";
|
|
@@ -1125,7 +1349,7 @@ function BasicUIProvider({
|
|
|
1125
1349
|
}) {
|
|
1126
1350
|
const parent = useContext3(AppearanceContext);
|
|
1127
1351
|
const value = { ...parent, ...appearance };
|
|
1128
|
-
return /* @__PURE__ */
|
|
1352
|
+
return /* @__PURE__ */ jsx4(AppearanceContext.Provider, { value, children: /* @__PURE__ */ jsx4(
|
|
1129
1353
|
"div",
|
|
1130
1354
|
{
|
|
1131
1355
|
className: "basic-ui",
|
|
@@ -1146,7 +1370,7 @@ function useAppearanceProps() {
|
|
|
1146
1370
|
}
|
|
1147
1371
|
var BasicButton = forwardRef(
|
|
1148
1372
|
function BasicButton2({ variant = "outline", className = "", type = "button", ...props }, ref) {
|
|
1149
|
-
return /* @__PURE__ */
|
|
1373
|
+
return /* @__PURE__ */ jsx4(
|
|
1150
1374
|
"button",
|
|
1151
1375
|
{
|
|
1152
1376
|
...props,
|
|
@@ -1161,8 +1385,8 @@ var BasicButton = forwardRef(
|
|
|
1161
1385
|
function useAction() {
|
|
1162
1386
|
const [pending, setPending] = useState4(false);
|
|
1163
1387
|
const [error, setError] = useState4(null);
|
|
1164
|
-
const busy =
|
|
1165
|
-
const mounted =
|
|
1388
|
+
const busy = useRef4(false);
|
|
1389
|
+
const mounted = useRef4(true);
|
|
1166
1390
|
useEffect4(() => {
|
|
1167
1391
|
mounted.current = true;
|
|
1168
1392
|
return () => {
|
|
@@ -1179,7 +1403,7 @@ function useAction() {
|
|
|
1179
1403
|
} catch (cause) {
|
|
1180
1404
|
if (mounted.current)
|
|
1181
1405
|
setError(
|
|
1182
|
-
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."
|
|
1183
1407
|
);
|
|
1184
1408
|
} finally {
|
|
1185
1409
|
busy.current = false;
|
|
@@ -1201,8 +1425,8 @@ function AuthButton({
|
|
|
1201
1425
|
const auth = supplied ?? live;
|
|
1202
1426
|
const action = useAction();
|
|
1203
1427
|
const expired = auth.status === "expired";
|
|
1204
|
-
return /* @__PURE__ */
|
|
1205
|
-
/* @__PURE__ */
|
|
1428
|
+
return /* @__PURE__ */ jsxs2("span", { className: "basic-action", children: [
|
|
1429
|
+
/* @__PURE__ */ jsx4(
|
|
1206
1430
|
BasicButton,
|
|
1207
1431
|
{
|
|
1208
1432
|
...props,
|
|
@@ -1218,29 +1442,42 @@ function AuthButton({
|
|
|
1218
1442
|
children: action.pending ? "Please wait\u2026" : children ?? (signOut ? "Sign out" : expired ? "Sign in again" : "Sign in")
|
|
1219
1443
|
}
|
|
1220
1444
|
),
|
|
1221
|
-
/* @__PURE__ */
|
|
1445
|
+
/* @__PURE__ */ jsx4(ActionError, { error: action.error, onClose: action.clearError })
|
|
1222
1446
|
] });
|
|
1223
1447
|
}
|
|
1224
1448
|
function SignInButton(props) {
|
|
1225
|
-
return /* @__PURE__ */
|
|
1449
|
+
return /* @__PURE__ */ jsx4(AuthButton, { ...props });
|
|
1226
1450
|
}
|
|
1227
1451
|
function SignOutButton(props) {
|
|
1228
|
-
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";
|
|
1229
1462
|
}
|
|
1230
1463
|
function UserAvatar({
|
|
1231
1464
|
accounts,
|
|
1232
1465
|
auth,
|
|
1233
1466
|
projectProfile,
|
|
1467
|
+
invites,
|
|
1468
|
+
showInvites,
|
|
1234
1469
|
allowAddAccount,
|
|
1235
1470
|
menuItems,
|
|
1236
1471
|
...avatarProps
|
|
1237
1472
|
}) {
|
|
1238
|
-
return /* @__PURE__ */
|
|
1473
|
+
return /* @__PURE__ */ jsx4(
|
|
1239
1474
|
UserMenu,
|
|
1240
1475
|
{
|
|
1241
1476
|
accounts,
|
|
1242
1477
|
auth,
|
|
1243
1478
|
projectProfile,
|
|
1479
|
+
invites,
|
|
1480
|
+
showInvites,
|
|
1244
1481
|
allowAddAccount,
|
|
1245
1482
|
menuItems,
|
|
1246
1483
|
sync: avatarProps.sync,
|
|
@@ -1254,25 +1491,34 @@ function AccountAvatar({
|
|
|
1254
1491
|
size = 32,
|
|
1255
1492
|
showSyncBadge,
|
|
1256
1493
|
sync,
|
|
1257
|
-
className = "",
|
|
1258
|
-
style,
|
|
1259
1494
|
...props
|
|
1260
1495
|
}) {
|
|
1261
1496
|
const accounts = useAccounts();
|
|
1262
1497
|
const client = useRequiredClient();
|
|
1263
1498
|
const profile = supplied === void 0 ? accounts.activeAccount : supplied;
|
|
1264
|
-
const
|
|
1265
|
-
|
|
1266
|
-
|
|
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(
|
|
1267
1513
|
Avatar.Root,
|
|
1268
1514
|
{
|
|
1269
1515
|
...props,
|
|
1270
1516
|
className: `basic-avatar ${className}`,
|
|
1271
1517
|
style: { width: size, height: size, ...style },
|
|
1272
1518
|
role: "img",
|
|
1273
|
-
"aria-label": props["aria-label"] ??
|
|
1519
|
+
"aria-label": props["aria-label"] ?? accountName(profile),
|
|
1274
1520
|
children: [
|
|
1275
|
-
profile?.picture && /* @__PURE__ */
|
|
1521
|
+
profile?.picture && /* @__PURE__ */ jsx4(
|
|
1276
1522
|
Avatar.Image,
|
|
1277
1523
|
{
|
|
1278
1524
|
src: profile.picture,
|
|
@@ -1281,14 +1527,100 @@ function AccountAvatar({
|
|
|
1281
1527
|
referrerPolicy: "no-referrer"
|
|
1282
1528
|
}
|
|
1283
1529
|
),
|
|
1284
|
-
/* @__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
|
+
)
|
|
1285
1621
|
]
|
|
1286
1622
|
}
|
|
1287
1623
|
);
|
|
1288
|
-
return showSyncBadge ?? client.mode === "sync" ? /* @__PURE__ */ jsxs("span", { className: "basic-avatar-container", children: [
|
|
1289
|
-
avatar,
|
|
1290
|
-
/* @__PURE__ */ jsx3(SyncStatus, { sync, className: "basic-avatar-sync" })
|
|
1291
|
-
] }) : avatar;
|
|
1292
1624
|
}
|
|
1293
1625
|
function AuthStatus({
|
|
1294
1626
|
auth: supplied,
|
|
@@ -1299,7 +1631,7 @@ function AuthStatus({
|
|
|
1299
1631
|
const auth = supplied ?? live;
|
|
1300
1632
|
const expired = auth.status === "expired";
|
|
1301
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";
|
|
1302
|
-
return /* @__PURE__ */
|
|
1634
|
+
return /* @__PURE__ */ jsxs2(
|
|
1303
1635
|
"span",
|
|
1304
1636
|
{
|
|
1305
1637
|
...props,
|
|
@@ -1307,7 +1639,7 @@ function AuthStatus({
|
|
|
1307
1639
|
className: `basic-status ${className}`,
|
|
1308
1640
|
"data-tone": expired || auth.error ? "warning" : auth.isSignedIn ? "success" : "neutral",
|
|
1309
1641
|
children: [
|
|
1310
|
-
/* @__PURE__ */
|
|
1642
|
+
/* @__PURE__ */ jsx4("span", { className: "basic-dot" }),
|
|
1311
1643
|
label
|
|
1312
1644
|
]
|
|
1313
1645
|
}
|
|
@@ -1337,7 +1669,7 @@ function SyncStatus({
|
|
|
1337
1669
|
ended: "Access ended"
|
|
1338
1670
|
};
|
|
1339
1671
|
const label = issues ? `${issues} sync ${issues === 1 ? "issue" : "issues"}` : sync.status === "online" && sync.pendingCount ? "Syncing" : labels[sync.status];
|
|
1340
|
-
return /* @__PURE__ */
|
|
1672
|
+
return /* @__PURE__ */ jsxs2(
|
|
1341
1673
|
"span",
|
|
1342
1674
|
{
|
|
1343
1675
|
...props,
|
|
@@ -1346,7 +1678,7 @@ function SyncStatus({
|
|
|
1346
1678
|
className: `basic-status ${className}`,
|
|
1347
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",
|
|
1348
1680
|
children: [
|
|
1349
|
-
/* @__PURE__ */
|
|
1681
|
+
/* @__PURE__ */ jsx4("span", { className: "basic-dot" }),
|
|
1350
1682
|
label,
|
|
1351
1683
|
sync.pendingCount > 0 && ` \xB7 ${sync.pendingCount} pending`
|
|
1352
1684
|
]
|
|
@@ -1357,7 +1689,7 @@ function displayHandle(handle) {
|
|
|
1357
1689
|
return handle ? `@${handle.replace(/^@+/, "")}` : "";
|
|
1358
1690
|
}
|
|
1359
1691
|
function UserButton(props) {
|
|
1360
|
-
return /* @__PURE__ */
|
|
1692
|
+
return /* @__PURE__ */ jsx4(UserMenu, { ...props, trigger: "button" });
|
|
1361
1693
|
}
|
|
1362
1694
|
function UserMenu({
|
|
1363
1695
|
accounts: supplied,
|
|
@@ -1369,6 +1701,8 @@ function UserMenu({
|
|
|
1369
1701
|
trigger = "avatar",
|
|
1370
1702
|
avatarProps,
|
|
1371
1703
|
projectProfile,
|
|
1704
|
+
invites,
|
|
1705
|
+
showInvites,
|
|
1372
1706
|
allowAddAccount = true,
|
|
1373
1707
|
className = "",
|
|
1374
1708
|
accountSettingsUrl,
|
|
@@ -1381,17 +1715,17 @@ function UserMenu({
|
|
|
1381
1715
|
const action = useAction();
|
|
1382
1716
|
const [settingsOpen, setSettingsOpen] = useState4(false);
|
|
1383
1717
|
const [clearAccountId, setClearAccountId] = useState4(null);
|
|
1384
|
-
const triggerRef =
|
|
1718
|
+
const triggerRef = useRef4(null);
|
|
1385
1719
|
const appearance = useAppearanceProps();
|
|
1386
1720
|
const expired = auth.status === "expired";
|
|
1387
1721
|
const active = accounts.activeAccount;
|
|
1388
1722
|
const otherAccounts = accounts.accounts.filter(
|
|
1389
1723
|
(account) => account.id !== active?.id
|
|
1390
1724
|
);
|
|
1391
|
-
const name = active
|
|
1392
|
-
return /* @__PURE__ */
|
|
1393
|
-
/* @__PURE__ */
|
|
1394
|
-
/* @__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(
|
|
1395
1729
|
Menu.Trigger,
|
|
1396
1730
|
{
|
|
1397
1731
|
ref: triggerRef,
|
|
@@ -1400,7 +1734,7 @@ function UserMenu({
|
|
|
1400
1734
|
disabled: !auth.isReady || action.pending,
|
|
1401
1735
|
"aria-label": "Open user menu",
|
|
1402
1736
|
children: [
|
|
1403
|
-
/* @__PURE__ */
|
|
1737
|
+
/* @__PURE__ */ jsx4(
|
|
1404
1738
|
AccountAvatar,
|
|
1405
1739
|
{
|
|
1406
1740
|
profile: accounts.activeAccount,
|
|
@@ -1409,12 +1743,12 @@ function UserMenu({
|
|
|
1409
1743
|
...avatarProps
|
|
1410
1744
|
}
|
|
1411
1745
|
),
|
|
1412
|
-
trigger === "button" && /* @__PURE__ */
|
|
1413
|
-
/* @__PURE__ */
|
|
1414
|
-
/* @__PURE__ */
|
|
1415
|
-
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) })
|
|
1416
1750
|
] }),
|
|
1417
|
-
/* @__PURE__ */
|
|
1751
|
+
/* @__PURE__ */ jsx4(
|
|
1418
1752
|
"svg",
|
|
1419
1753
|
{
|
|
1420
1754
|
className: "basic-chevron",
|
|
@@ -1427,16 +1761,16 @@ function UserMenu({
|
|
|
1427
1761
|
strokeLinecap: "round",
|
|
1428
1762
|
strokeLinejoin: "round",
|
|
1429
1763
|
"aria-hidden": "true",
|
|
1430
|
-
children: /* @__PURE__ */
|
|
1764
|
+
children: /* @__PURE__ */ jsx4("path", { d: "m6 9 6 6 6-6" })
|
|
1431
1765
|
}
|
|
1432
1766
|
)
|
|
1433
1767
|
] })
|
|
1434
1768
|
]
|
|
1435
1769
|
}
|
|
1436
1770
|
),
|
|
1437
|
-
/* @__PURE__ */
|
|
1438
|
-
/* @__PURE__ */
|
|
1439
|
-
/* @__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(
|
|
1440
1774
|
AccountAvatar,
|
|
1441
1775
|
{
|
|
1442
1776
|
profile: active,
|
|
@@ -1445,16 +1779,16 @@ function UserMenu({
|
|
|
1445
1779
|
showSyncBadge: false
|
|
1446
1780
|
}
|
|
1447
1781
|
),
|
|
1448
|
-
/* @__PURE__ */
|
|
1449
|
-
/* @__PURE__ */
|
|
1450
|
-
active?.kind !== "anon" && active?.handle && /* @__PURE__ */
|
|
1451
|
-
/* @__PURE__ */
|
|
1452
|
-
expired && /* @__PURE__ */
|
|
1453
|
-
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 })
|
|
1454
1788
|
] })
|
|
1455
1789
|
] })
|
|
1456
1790
|
] }),
|
|
1457
|
-
expired && /* @__PURE__ */
|
|
1791
|
+
expired && /* @__PURE__ */ jsx4(
|
|
1458
1792
|
Menu.Item,
|
|
1459
1793
|
{
|
|
1460
1794
|
className: "basic-menu-item basic-menu-reauth",
|
|
@@ -1463,13 +1797,13 @@ function UserMenu({
|
|
|
1463
1797
|
children: "Sign in again"
|
|
1464
1798
|
}
|
|
1465
1799
|
),
|
|
1466
|
-
/* @__PURE__ */
|
|
1800
|
+
/* @__PURE__ */ jsxs2(
|
|
1467
1801
|
Menu.Item,
|
|
1468
1802
|
{
|
|
1469
1803
|
className: "basic-menu-item basic-manage-account",
|
|
1470
1804
|
onClick: () => setSettingsOpen(true),
|
|
1471
1805
|
children: [
|
|
1472
|
-
/* @__PURE__ */
|
|
1806
|
+
/* @__PURE__ */ jsxs2(
|
|
1473
1807
|
"svg",
|
|
1474
1808
|
{
|
|
1475
1809
|
className: "basic-menu-icon",
|
|
@@ -1483,8 +1817,8 @@ function UserMenu({
|
|
|
1483
1817
|
strokeLinejoin: "round",
|
|
1484
1818
|
"aria-hidden": "true",
|
|
1485
1819
|
children: [
|
|
1486
|
-
/* @__PURE__ */
|
|
1487
|
-
/* @__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" })
|
|
1488
1822
|
]
|
|
1489
1823
|
}
|
|
1490
1824
|
),
|
|
@@ -1492,30 +1826,30 @@ function UserMenu({
|
|
|
1492
1826
|
]
|
|
1493
1827
|
}
|
|
1494
1828
|
),
|
|
1495
|
-
menuItems.map((item) => /* @__PURE__ */
|
|
1829
|
+
menuItems.map((item) => /* @__PURE__ */ jsxs2(
|
|
1496
1830
|
Menu.Item,
|
|
1497
1831
|
{
|
|
1498
1832
|
className: "basic-menu-item",
|
|
1499
|
-
render: item.href !== void 0 ? /* @__PURE__ */
|
|
1833
|
+
render: item.href !== void 0 ? /* @__PURE__ */ jsx4("a", { href: item.href }) : void 0,
|
|
1500
1834
|
disabled: item.disabled || action.pending,
|
|
1501
1835
|
onClick: () => {
|
|
1502
1836
|
if (item.onClick) void action.run(item.onClick);
|
|
1503
1837
|
},
|
|
1504
1838
|
children: [
|
|
1505
|
-
/* @__PURE__ */
|
|
1839
|
+
/* @__PURE__ */ jsx4("span", { className: "basic-menu-icon", "aria-hidden": "true", children: item.icon }),
|
|
1506
1840
|
item.label
|
|
1507
1841
|
]
|
|
1508
1842
|
},
|
|
1509
1843
|
item.id
|
|
1510
1844
|
)),
|
|
1511
|
-
(auth.isSignedIn || expired || active?.kind === "anon") && /* @__PURE__ */
|
|
1845
|
+
(auth.isSignedIn || expired || active?.kind === "anon") && /* @__PURE__ */ jsxs2(
|
|
1512
1846
|
Menu.Item,
|
|
1513
1847
|
{
|
|
1514
1848
|
className: "basic-menu-item basic-menu-signout",
|
|
1515
1849
|
disabled: action.pending,
|
|
1516
1850
|
onClick: () => active?.kind === "anon" ? setClearAccountId(active.id) : void action.run(() => auth.signOut()),
|
|
1517
1851
|
children: [
|
|
1518
|
-
/* @__PURE__ */
|
|
1852
|
+
/* @__PURE__ */ jsx4(
|
|
1519
1853
|
"svg",
|
|
1520
1854
|
{
|
|
1521
1855
|
className: "basic-menu-icon",
|
|
@@ -1528,25 +1862,25 @@ function UserMenu({
|
|
|
1528
1862
|
strokeLinecap: "round",
|
|
1529
1863
|
strokeLinejoin: "round",
|
|
1530
1864
|
"aria-hidden": "true",
|
|
1531
|
-
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" })
|
|
1532
1866
|
}
|
|
1533
1867
|
),
|
|
1534
1868
|
active?.kind === "anon" ? "Clear account" : "Sign out"
|
|
1535
1869
|
]
|
|
1536
1870
|
}
|
|
1537
1871
|
),
|
|
1538
|
-
otherAccounts.length > 0 && /* @__PURE__ */
|
|
1539
|
-
/* @__PURE__ */
|
|
1540
|
-
/* @__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" })
|
|
1541
1875
|
] }),
|
|
1542
|
-
otherAccounts.map((account) => /* @__PURE__ */
|
|
1876
|
+
otherAccounts.map((account) => /* @__PURE__ */ jsxs2(
|
|
1543
1877
|
Menu.Item,
|
|
1544
1878
|
{
|
|
1545
1879
|
className: "basic-menu-item",
|
|
1546
1880
|
disabled: action.pending,
|
|
1547
1881
|
onClick: () => void action.run(() => accounts.switchAccount(account.id)),
|
|
1548
1882
|
children: [
|
|
1549
|
-
/* @__PURE__ */
|
|
1883
|
+
/* @__PURE__ */ jsx4(
|
|
1550
1884
|
AccountAvatar,
|
|
1551
1885
|
{
|
|
1552
1886
|
profile: account,
|
|
@@ -1555,16 +1889,16 @@ function UserMenu({
|
|
|
1555
1889
|
showSyncBadge: false
|
|
1556
1890
|
}
|
|
1557
1891
|
),
|
|
1558
|
-
/* @__PURE__ */
|
|
1559
|
-
/* @__PURE__ */
|
|
1560
|
-
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) })
|
|
1561
1895
|
] }),
|
|
1562
|
-
/* @__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 })
|
|
1563
1897
|
]
|
|
1564
1898
|
},
|
|
1565
1899
|
account.id
|
|
1566
1900
|
)),
|
|
1567
|
-
(allowAddAccount || !auth.isSignedIn && !expired) && /* @__PURE__ */
|
|
1901
|
+
(allowAddAccount || !auth.isSignedIn && !expired) && /* @__PURE__ */ jsxs2(
|
|
1568
1902
|
Menu.Item,
|
|
1569
1903
|
{
|
|
1570
1904
|
className: "basic-menu-item",
|
|
@@ -1573,7 +1907,7 @@ function UserMenu({
|
|
|
1573
1907
|
() => allowAddAccount ? accounts.addAccount({ signIn: true }) : auth.signIn()
|
|
1574
1908
|
),
|
|
1575
1909
|
children: [
|
|
1576
|
-
/* @__PURE__ */
|
|
1910
|
+
/* @__PURE__ */ jsx4(
|
|
1577
1911
|
"svg",
|
|
1578
1912
|
{
|
|
1579
1913
|
className: "basic-menu-icon",
|
|
@@ -1585,7 +1919,7 @@ function UserMenu({
|
|
|
1585
1919
|
strokeWidth: "1.75",
|
|
1586
1920
|
strokeLinecap: "round",
|
|
1587
1921
|
"aria-hidden": "true",
|
|
1588
|
-
children: /* @__PURE__ */
|
|
1922
|
+
children: /* @__PURE__ */ jsx4("path", { d: "M12 5v14M5 12h14" })
|
|
1589
1923
|
}
|
|
1590
1924
|
),
|
|
1591
1925
|
"Add account"
|
|
@@ -1594,7 +1928,7 @@ function UserMenu({
|
|
|
1594
1928
|
)
|
|
1595
1929
|
] }) }) })
|
|
1596
1930
|
] }),
|
|
1597
|
-
/* @__PURE__ */
|
|
1931
|
+
/* @__PURE__ */ jsx4(
|
|
1598
1932
|
ActionError,
|
|
1599
1933
|
{
|
|
1600
1934
|
error: action.error,
|
|
@@ -1602,7 +1936,7 @@ function UserMenu({
|
|
|
1602
1936
|
finalFocus: triggerRef
|
|
1603
1937
|
}
|
|
1604
1938
|
),
|
|
1605
|
-
/* @__PURE__ */
|
|
1939
|
+
/* @__PURE__ */ jsx4(
|
|
1606
1940
|
Modal,
|
|
1607
1941
|
{
|
|
1608
1942
|
open: clearAccountId !== null,
|
|
@@ -1613,8 +1947,8 @@ function UserMenu({
|
|
|
1613
1947
|
finalFocus: triggerRef,
|
|
1614
1948
|
title: "Clear local account?",
|
|
1615
1949
|
description: "This deletes this account\u2019s local data, including unsynced changes. This cannot be undone.",
|
|
1616
|
-
children: /* @__PURE__ */
|
|
1617
|
-
/* @__PURE__ */
|
|
1950
|
+
children: /* @__PURE__ */ jsxs2("div", { className: "basic-actions", children: [
|
|
1951
|
+
/* @__PURE__ */ jsx4(
|
|
1618
1952
|
BasicButton,
|
|
1619
1953
|
{
|
|
1620
1954
|
disabled: action.pending,
|
|
@@ -1622,7 +1956,7 @@ function UserMenu({
|
|
|
1622
1956
|
children: "Cancel"
|
|
1623
1957
|
}
|
|
1624
1958
|
),
|
|
1625
|
-
/* @__PURE__ */
|
|
1959
|
+
/* @__PURE__ */ jsx4(
|
|
1626
1960
|
BasicButton,
|
|
1627
1961
|
{
|
|
1628
1962
|
disabled: action.pending,
|
|
@@ -1638,7 +1972,7 @@ function UserMenu({
|
|
|
1638
1972
|
] })
|
|
1639
1973
|
}
|
|
1640
1974
|
),
|
|
1641
|
-
/* @__PURE__ */
|
|
1975
|
+
/* @__PURE__ */ jsx4(
|
|
1642
1976
|
AccountSettingsModal,
|
|
1643
1977
|
{
|
|
1644
1978
|
auth,
|
|
@@ -1649,6 +1983,8 @@ function UserMenu({
|
|
|
1649
1983
|
finalFocus: triggerRef,
|
|
1650
1984
|
accountSettingsUrl,
|
|
1651
1985
|
projectProfile,
|
|
1986
|
+
invites,
|
|
1987
|
+
showInvites,
|
|
1652
1988
|
sync
|
|
1653
1989
|
}
|
|
1654
1990
|
)
|
|
@@ -1659,7 +1995,7 @@ function ActionError({
|
|
|
1659
1995
|
onClose,
|
|
1660
1996
|
finalFocus
|
|
1661
1997
|
}) {
|
|
1662
|
-
return /* @__PURE__ */
|
|
1998
|
+
return /* @__PURE__ */ jsxs2(
|
|
1663
1999
|
Modal,
|
|
1664
2000
|
{
|
|
1665
2001
|
open: !!error,
|
|
@@ -1671,8 +2007,8 @@ function ActionError({
|
|
|
1671
2007
|
title: "Unable to complete action",
|
|
1672
2008
|
description: "Your request could not be completed.",
|
|
1673
2009
|
children: [
|
|
1674
|
-
/* @__PURE__ */
|
|
1675
|
-
/* @__PURE__ */
|
|
2010
|
+
/* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: error }),
|
|
2011
|
+
/* @__PURE__ */ jsx4(BasicButton, { onClick: onClose, children: "Dismiss" })
|
|
1676
2012
|
]
|
|
1677
2013
|
}
|
|
1678
2014
|
);
|
|
@@ -1684,29 +2020,36 @@ function Modal({
|
|
|
1684
2020
|
finalFocus,
|
|
1685
2021
|
title,
|
|
1686
2022
|
description,
|
|
2023
|
+
hideTitle = false,
|
|
1687
2024
|
header,
|
|
1688
2025
|
sectionLabel,
|
|
1689
2026
|
children
|
|
1690
2027
|
}) {
|
|
1691
2028
|
const appearance = useAppearanceProps();
|
|
1692
|
-
return /* @__PURE__ */
|
|
1693
|
-
trigger !== null && (isValidElement(trigger) ? /* @__PURE__ */
|
|
1694
|
-
/* @__PURE__ */
|
|
1695
|
-
/* @__PURE__ */
|
|
1696
|
-
/* @__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(
|
|
1697
2034
|
Dialog.Popup,
|
|
1698
2035
|
{
|
|
1699
2036
|
...appearance,
|
|
1700
2037
|
finalFocus,
|
|
1701
2038
|
className: "basic-ui basic-dialog",
|
|
1702
2039
|
children: [
|
|
1703
|
-
/* @__PURE__ */
|
|
2040
|
+
/* @__PURE__ */ jsxs2(
|
|
1704
2041
|
"div",
|
|
1705
2042
|
{
|
|
1706
|
-
className: `basic-dialog-heading${header ? " basic-dialog-heading-overlay" : ""}`,
|
|
2043
|
+
className: `basic-dialog-heading${header || hideTitle ? " basic-dialog-heading-overlay" : ""}`,
|
|
1707
2044
|
children: [
|
|
1708
|
-
/* @__PURE__ */
|
|
1709
|
-
|
|
2045
|
+
/* @__PURE__ */ jsx4(
|
|
2046
|
+
Dialog.Title,
|
|
2047
|
+
{
|
|
2048
|
+
className: header || hideTitle ? "basic-sr-only" : "basic-title",
|
|
2049
|
+
children: title
|
|
2050
|
+
}
|
|
2051
|
+
),
|
|
2052
|
+
/* @__PURE__ */ jsx4(
|
|
1710
2053
|
Dialog.Close,
|
|
1711
2054
|
{
|
|
1712
2055
|
className: "basic-button",
|
|
@@ -1718,14 +2061,14 @@ function Modal({
|
|
|
1718
2061
|
}
|
|
1719
2062
|
),
|
|
1720
2063
|
header,
|
|
1721
|
-
/* @__PURE__ */
|
|
2064
|
+
description && /* @__PURE__ */ jsx4(
|
|
1722
2065
|
Dialog.Description,
|
|
1723
2066
|
{
|
|
1724
2067
|
className: header ? "basic-sr-only" : "basic-muted",
|
|
1725
2068
|
children: description
|
|
1726
2069
|
}
|
|
1727
2070
|
),
|
|
1728
|
-
sectionLabel && /* @__PURE__ */
|
|
2071
|
+
sectionLabel && /* @__PURE__ */ jsx4("div", { className: "basic-modal-section", children: sectionLabel }),
|
|
1729
2072
|
children
|
|
1730
2073
|
]
|
|
1731
2074
|
}
|
|
@@ -1738,6 +2081,8 @@ function AccountSettingsModal({
|
|
|
1738
2081
|
accounts: suppliedAccounts,
|
|
1739
2082
|
accountSettingsUrl,
|
|
1740
2083
|
projectProfile,
|
|
2084
|
+
invites,
|
|
2085
|
+
showInvites = true,
|
|
1741
2086
|
sync,
|
|
1742
2087
|
children,
|
|
1743
2088
|
...props
|
|
@@ -1776,27 +2121,28 @@ function AccountSettingsModal({
|
|
|
1776
2121
|
["Conflicts", String(syncState.conflicts.length)]
|
|
1777
2122
|
];
|
|
1778
2123
|
const diagnostics = JSON.stringify(Object.fromEntries(details), null, 2);
|
|
1779
|
-
return /* @__PURE__ */
|
|
2124
|
+
return /* @__PURE__ */ jsx4(
|
|
1780
2125
|
Modal,
|
|
1781
2126
|
{
|
|
1782
2127
|
...props,
|
|
1783
2128
|
title: "Account settings",
|
|
1784
2129
|
description: "Your identity and session on this device.",
|
|
1785
|
-
header: /* @__PURE__ */
|
|
1786
|
-
children: /* @__PURE__ */
|
|
1787
|
-
/* @__PURE__ */
|
|
2130
|
+
header: /* @__PURE__ */ jsx4(AccountHeader, { account: accounts.activeAccount, sync }),
|
|
2131
|
+
children: /* @__PURE__ */ jsxs2(Tabs.Root, { defaultValue: "profile", children: [
|
|
2132
|
+
/* @__PURE__ */ jsxs2(
|
|
1788
2133
|
Tabs.List,
|
|
1789
2134
|
{
|
|
1790
2135
|
className: "basic-tabs",
|
|
1791
2136
|
"aria-label": "Account settings sections",
|
|
1792
2137
|
children: [
|
|
1793
|
-
/* @__PURE__ */
|
|
1794
|
-
/* @__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" })
|
|
1795
2141
|
]
|
|
1796
2142
|
}
|
|
1797
2143
|
),
|
|
1798
|
-
/* @__PURE__ */
|
|
1799
|
-
auth.isSignedIn && /* @__PURE__ */
|
|
2144
|
+
/* @__PURE__ */ jsxs2(Tabs.Panel, { value: "profile", keepMounted: true, children: [
|
|
2145
|
+
auth.isSignedIn && /* @__PURE__ */ jsx4(
|
|
1800
2146
|
ProjectProfileEditor,
|
|
1801
2147
|
{
|
|
1802
2148
|
profile: projectProfile,
|
|
@@ -1804,18 +2150,19 @@ function AccountSettingsModal({
|
|
|
1804
2150
|
},
|
|
1805
2151
|
accounts.activeAccount?.id ?? auth.did
|
|
1806
2152
|
),
|
|
1807
|
-
accountSettingsUrl && /* @__PURE__ */
|
|
2153
|
+
accountSettingsUrl && /* @__PURE__ */ jsx4("a", { className: "basic-link", href: accountSettingsUrl, children: "Manage profile and security \u2197" }),
|
|
1808
2154
|
children,
|
|
1809
|
-
!auth.isSignedIn && /* @__PURE__ */
|
|
2155
|
+
!auth.isSignedIn && /* @__PURE__ */ jsx4("div", { className: "basic-actions", children: /* @__PURE__ */ jsx4(SignInButton, { auth }) })
|
|
1810
2156
|
] }),
|
|
1811
|
-
/* @__PURE__ */
|
|
1812
|
-
|
|
1813
|
-
/* @__PURE__ */
|
|
1814
|
-
|
|
1815
|
-
/* @__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 })
|
|
1816
2163
|
] }, label)) }),
|
|
1817
|
-
/* @__PURE__ */
|
|
1818
|
-
/* @__PURE__ */
|
|
2164
|
+
/* @__PURE__ */ jsxs2("div", { className: "basic-actions", children: [
|
|
2165
|
+
/* @__PURE__ */ jsx4(
|
|
1819
2166
|
BasicButton,
|
|
1820
2167
|
{
|
|
1821
2168
|
disabled: copyAction.pending,
|
|
@@ -1831,9 +2178,9 @@ function AccountSettingsModal({
|
|
|
1831
2178
|
children: "Copy to clipboard"
|
|
1832
2179
|
}
|
|
1833
2180
|
),
|
|
1834
|
-
copied === diagnostics && /* @__PURE__ */
|
|
2181
|
+
copied === diagnostics && /* @__PURE__ */ jsx4("span", { role: "status", className: "basic-muted", children: "Copied" })
|
|
1835
2182
|
] }),
|
|
1836
|
-
copyAction.error && /* @__PURE__ */
|
|
2183
|
+
copyAction.error && /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: copyAction.error })
|
|
1837
2184
|
] })
|
|
1838
2185
|
] })
|
|
1839
2186
|
}
|
|
@@ -1843,8 +2190,8 @@ function AccountHeader({
|
|
|
1843
2190
|
account,
|
|
1844
2191
|
sync
|
|
1845
2192
|
}) {
|
|
1846
|
-
return /* @__PURE__ */
|
|
1847
|
-
/* @__PURE__ */
|
|
2193
|
+
return /* @__PURE__ */ jsxs2("div", { className: "basic-profile", children: [
|
|
2194
|
+
/* @__PURE__ */ jsx4(
|
|
1848
2195
|
AccountAvatar,
|
|
1849
2196
|
{
|
|
1850
2197
|
profile: account,
|
|
@@ -1853,10 +2200,10 @@ function AccountHeader({
|
|
|
1853
2200
|
showSyncBadge: false
|
|
1854
2201
|
}
|
|
1855
2202
|
),
|
|
1856
|
-
/* @__PURE__ */
|
|
1857
|
-
/* @__PURE__ */
|
|
1858
|
-
account?.kind !== "anon" && account?.handle && /* @__PURE__ */
|
|
1859
|
-
/* @__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 }) })
|
|
1860
2207
|
] })
|
|
1861
2208
|
] });
|
|
1862
2209
|
}
|
|
@@ -1869,7 +2216,7 @@ function ProjectProfileEditor({
|
|
|
1869
2216
|
const action = useAction();
|
|
1870
2217
|
const [draft, setDraft] = useState4({});
|
|
1871
2218
|
const [saved, setSaved] = useState4(false);
|
|
1872
|
-
return /* @__PURE__ */
|
|
2219
|
+
return /* @__PURE__ */ jsxs2(
|
|
1873
2220
|
"form",
|
|
1874
2221
|
{
|
|
1875
2222
|
className: "basic-profile-editor",
|
|
@@ -1883,15 +2230,15 @@ function ProjectProfileEditor({
|
|
|
1883
2230
|
});
|
|
1884
2231
|
},
|
|
1885
2232
|
children: [
|
|
1886
|
-
/* @__PURE__ */
|
|
1887
|
-
/* @__PURE__ */
|
|
1888
|
-
profile.isLoading ? /* @__PURE__ */
|
|
1889
|
-
/* @__PURE__ */
|
|
1890
|
-
/* @__PURE__ */
|
|
1891
|
-
] }) : profile.data && /* @__PURE__ */
|
|
1892
|
-
/* @__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: [
|
|
1893
2240
|
"Display name",
|
|
1894
|
-
/* @__PURE__ */
|
|
2241
|
+
/* @__PURE__ */ jsx4(
|
|
1895
2242
|
"input",
|
|
1896
2243
|
{
|
|
1897
2244
|
className: "basic-input",
|
|
@@ -1908,8 +2255,8 @@ function ProjectProfileEditor({
|
|
|
1908
2255
|
}
|
|
1909
2256
|
)
|
|
1910
2257
|
] }),
|
|
1911
|
-
/* @__PURE__ */
|
|
1912
|
-
/* @__PURE__ */
|
|
2258
|
+
/* @__PURE__ */ jsxs2("div", { className: "basic-actions basic-modal-footer", children: [
|
|
2259
|
+
/* @__PURE__ */ jsx4(
|
|
1913
2260
|
BasicButton,
|
|
1914
2261
|
{
|
|
1915
2262
|
variant: "ghost",
|
|
@@ -1920,7 +2267,7 @@ function ProjectProfileEditor({
|
|
|
1920
2267
|
children: "Cancel"
|
|
1921
2268
|
}
|
|
1922
2269
|
),
|
|
1923
|
-
/* @__PURE__ */
|
|
2270
|
+
/* @__PURE__ */ jsx4(
|
|
1924
2271
|
BasicButton,
|
|
1925
2272
|
{
|
|
1926
2273
|
type: "submit",
|
|
@@ -1931,17 +2278,205 @@ function ProjectProfileEditor({
|
|
|
1931
2278
|
)
|
|
1932
2279
|
] })
|
|
1933
2280
|
] }),
|
|
1934
|
-
action.error && /* @__PURE__ */
|
|
1935
|
-
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." })
|
|
1936
2283
|
]
|
|
1937
2284
|
}
|
|
1938
2285
|
);
|
|
1939
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
|
+
}
|
|
1940
2474
|
function SharesModal({
|
|
1941
2475
|
auth: supplied,
|
|
1942
2476
|
accounts: suppliedAccounts,
|
|
1943
2477
|
sync,
|
|
1944
2478
|
shares,
|
|
2479
|
+
invites,
|
|
1945
2480
|
scope,
|
|
1946
2481
|
repo = "default",
|
|
1947
2482
|
...props
|
|
@@ -1949,37 +2484,43 @@ function SharesModal({
|
|
|
1949
2484
|
const live = useAuth();
|
|
1950
2485
|
const liveAccounts = useAccounts();
|
|
1951
2486
|
const auth = supplied ?? live;
|
|
1952
|
-
return /* @__PURE__ */
|
|
2487
|
+
return /* @__PURE__ */ jsx4(
|
|
1953
2488
|
Modal,
|
|
1954
2489
|
{
|
|
1955
2490
|
...props,
|
|
1956
2491
|
title: "Shares",
|
|
1957
2492
|
description: "Manage incoming invitations and share access to selected data.",
|
|
1958
|
-
header: /* @__PURE__ */
|
|
2493
|
+
header: /* @__PURE__ */ jsx4(
|
|
1959
2494
|
AccountHeader,
|
|
1960
2495
|
{
|
|
1961
2496
|
account: (suppliedAccounts ?? liveAccounts).activeAccount,
|
|
1962
2497
|
sync
|
|
1963
2498
|
}
|
|
1964
2499
|
),
|
|
1965
|
-
children: !auth.isReady ? /* @__PURE__ */
|
|
1966
|
-
/* @__PURE__ */
|
|
1967
|
-
/* @__PURE__ */
|
|
1968
|
-
] }) : /* @__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(
|
|
1969
2504
|
SharesContent,
|
|
1970
2505
|
{
|
|
1971
2506
|
shares,
|
|
2507
|
+
invites,
|
|
2508
|
+
auth,
|
|
2509
|
+
accounts: suppliedAccounts ?? liveAccounts,
|
|
1972
2510
|
scope,
|
|
1973
2511
|
repo,
|
|
1974
2512
|
canWrite: auth.canWrite
|
|
1975
2513
|
},
|
|
1976
|
-
|
|
2514
|
+
(suppliedAccounts ?? liveAccounts).activeAccount?.id ?? auth.did
|
|
1977
2515
|
)
|
|
1978
2516
|
}
|
|
1979
2517
|
);
|
|
1980
2518
|
}
|
|
1981
2519
|
function SharesContent({
|
|
1982
2520
|
shares: supplied,
|
|
2521
|
+
invites,
|
|
2522
|
+
auth,
|
|
2523
|
+
accounts,
|
|
1983
2524
|
scope,
|
|
1984
2525
|
repo,
|
|
1985
2526
|
canWrite
|
|
@@ -1994,29 +2535,25 @@ function SharesContent({
|
|
|
1994
2535
|
const scopeValid = scope.length > 0 && scope.every(
|
|
1995
2536
|
(item) => item.table.trim() && (item.recordIds === void 0 || item.recordIds.length > 0)
|
|
1996
2537
|
);
|
|
1997
|
-
return /* @__PURE__ */
|
|
1998
|
-
/* @__PURE__ */
|
|
1999
|
-
/* @__PURE__ */
|
|
2000
|
-
/* @__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" })
|
|
2001
2542
|
] }),
|
|
2002
|
-
/* @__PURE__ */
|
|
2003
|
-
|
|
2004
|
-
/* @__PURE__ */
|
|
2005
|
-
/* @__PURE__ */
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
/* @__PURE__ */ jsx3("p", { className: "basic-muted", children: "Revoking access stops future requests. It cannot retract data the recipient already downloaded." }),
|
|
2009
|
-
/* @__PURE__ */ jsxs("div", { className: "basic-scope", children: [
|
|
2010
|
-
/* @__PURE__ */ jsx3("strong", { children: "New invitation permissions" }),
|
|
2011
|
-
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: [
|
|
2012
2549
|
item.table,
|
|
2013
2550
|
" \xB7",
|
|
2014
2551
|
" ",
|
|
2015
2552
|
item.recordIds ? `${item.recordIds.length} selected records` : "all records"
|
|
2016
2553
|
] }, index))
|
|
2017
2554
|
] }),
|
|
2018
|
-
!canWrite && /* @__PURE__ */
|
|
2019
|
-
/* @__PURE__ */
|
|
2555
|
+
!canWrite && /* @__PURE__ */ jsx4("p", { className: "basic-error", children: "This session is read only. Sharing changes are disabled." }),
|
|
2556
|
+
/* @__PURE__ */ jsxs2(
|
|
2020
2557
|
"form",
|
|
2021
2558
|
{
|
|
2022
2559
|
className: "basic-share-form",
|
|
@@ -2036,9 +2573,9 @@ function SharesContent({
|
|
|
2036
2573
|
});
|
|
2037
2574
|
},
|
|
2038
2575
|
children: [
|
|
2039
|
-
/* @__PURE__ */
|
|
2576
|
+
/* @__PURE__ */ jsxs2("label", { className: "basic-field", children: [
|
|
2040
2577
|
"Recipient handle or DID",
|
|
2041
|
-
/* @__PURE__ */
|
|
2578
|
+
/* @__PURE__ */ jsx4(
|
|
2042
2579
|
"input",
|
|
2043
2580
|
{
|
|
2044
2581
|
className: "basic-input",
|
|
@@ -2050,9 +2587,9 @@ function SharesContent({
|
|
|
2050
2587
|
}
|
|
2051
2588
|
)
|
|
2052
2589
|
] }),
|
|
2053
|
-
/* @__PURE__ */
|
|
2590
|
+
/* @__PURE__ */ jsxs2("label", { className: "basic-field", children: [
|
|
2054
2591
|
"Permission",
|
|
2055
|
-
/* @__PURE__ */
|
|
2592
|
+
/* @__PURE__ */ jsxs2(
|
|
2056
2593
|
"select",
|
|
2057
2594
|
{
|
|
2058
2595
|
className: "basic-input",
|
|
@@ -2060,13 +2597,13 @@ function SharesContent({
|
|
|
2060
2597
|
onChange: (event) => setRole(event.target.value),
|
|
2061
2598
|
disabled: action.pending || !canWrite,
|
|
2062
2599
|
children: [
|
|
2063
|
-
/* @__PURE__ */
|
|
2064
|
-
/* @__PURE__ */
|
|
2600
|
+
/* @__PURE__ */ jsx4("option", { value: "viewer", children: "Can view" }),
|
|
2601
|
+
/* @__PURE__ */ jsx4("option", { value: "editor", children: "Can edit" })
|
|
2065
2602
|
]
|
|
2066
2603
|
}
|
|
2067
2604
|
)
|
|
2068
2605
|
] }),
|
|
2069
|
-
/* @__PURE__ */
|
|
2606
|
+
/* @__PURE__ */ jsx4(
|
|
2070
2607
|
BasicButton,
|
|
2071
2608
|
{
|
|
2072
2609
|
type: "submit",
|
|
@@ -2078,12 +2615,12 @@ function SharesContent({
|
|
|
2078
2615
|
]
|
|
2079
2616
|
}
|
|
2080
2617
|
),
|
|
2081
|
-
!scopeValid && /* @__PURE__ */
|
|
2082
|
-
action.error && /* @__PURE__ */
|
|
2083
|
-
message && /* @__PURE__ */
|
|
2084
|
-
/* @__PURE__ */
|
|
2085
|
-
/* @__PURE__ */
|
|
2086
|
-
/* @__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(
|
|
2087
2624
|
BasicButton,
|
|
2088
2625
|
{
|
|
2089
2626
|
disabled: action.pending || shares.isLoading,
|
|
@@ -2092,10 +2629,15 @@ function SharesContent({
|
|
|
2092
2629
|
}
|
|
2093
2630
|
)
|
|
2094
2631
|
] }),
|
|
2095
|
-
shares.isLoading ? /* @__PURE__ */
|
|
2096
|
-
/* @__PURE__ */
|
|
2097
|
-
|
|
2098
|
-
/* @__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: [
|
|
2099
2641
|
share.role === "viewer" ? "Can view" : "Can edit",
|
|
2100
2642
|
" \xB7",
|
|
2101
2643
|
" ",
|
|
@@ -2105,9 +2647,9 @@ function SharesContent({
|
|
|
2105
2647
|
share.scope.map((item) => item.table).join(", ")
|
|
2106
2648
|
] })
|
|
2107
2649
|
] }),
|
|
2108
|
-
share.state !== "ended" && (confirmation === share.id ? /* @__PURE__ */
|
|
2109
|
-
/* @__PURE__ */
|
|
2110
|
-
/* @__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(
|
|
2111
2653
|
BasicButton,
|
|
2112
2654
|
{
|
|
2113
2655
|
disabled: action.pending || !canWrite,
|
|
@@ -2126,7 +2668,7 @@ function SharesContent({
|
|
|
2126
2668
|
]
|
|
2127
2669
|
}
|
|
2128
2670
|
),
|
|
2129
|
-
/* @__PURE__ */
|
|
2671
|
+
/* @__PURE__ */ jsx4(
|
|
2130
2672
|
BasicButton,
|
|
2131
2673
|
{
|
|
2132
2674
|
disabled: action.pending,
|
|
@@ -2134,7 +2676,7 @@ function SharesContent({
|
|
|
2134
2676
|
children: "Keep access"
|
|
2135
2677
|
}
|
|
2136
2678
|
)
|
|
2137
|
-
] }) : /* @__PURE__ */
|
|
2679
|
+
] }) : /* @__PURE__ */ jsx4(
|
|
2138
2680
|
BasicButton,
|
|
2139
2681
|
{
|
|
2140
2682
|
disabled: action.pending || !canWrite,
|
|
@@ -2155,6 +2697,11 @@ export {
|
|
|
2155
2697
|
BrowserKeyValueStorage,
|
|
2156
2698
|
BrowserTokenStore,
|
|
2157
2699
|
PersistenceStore,
|
|
2700
|
+
ShareInvites,
|
|
2701
|
+
ShareInvitesModal,
|
|
2702
|
+
ShareRecipientAvatar,
|
|
2703
|
+
ShareRecipientAvatars,
|
|
2704
|
+
ShareRecipientLabel,
|
|
2158
2705
|
SharesModal,
|
|
2159
2706
|
SignInButton,
|
|
2160
2707
|
SignOutButton,
|
|
@@ -2183,6 +2730,8 @@ export {
|
|
|
2183
2730
|
useQuery,
|
|
2184
2731
|
useRepos,
|
|
2185
2732
|
useSchemaStatus,
|
|
2733
|
+
useShareInvites,
|
|
2734
|
+
useShareRecipients,
|
|
2186
2735
|
useStorageInfo,
|
|
2187
2736
|
useSyncStatus
|
|
2188
2737
|
};
|