@comapeo/core-react 6.1.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commonjs/hooks/projects.d.ts +45 -28
- package/dist/commonjs/hooks/projects.js +35 -9
- package/dist/commonjs/index.d.ts +1 -1
- package/dist/commonjs/index.js +2 -1
- package/dist/commonjs/lib/react-query/projects.d.ts +19 -6
- package/dist/commonjs/lib/react-query/projects.js +26 -9
- package/dist/commonjs/lib/urls.d.ts +11 -8
- package/dist/commonjs/lib/urls.js +15 -21
- package/dist/esm/hooks/projects.d.ts +45 -28
- package/dist/esm/hooks/projects.js +35 -10
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/lib/react-query/projects.d.ts +19 -6
- package/dist/esm/lib/react-query/projects.js +23 -7
- package/dist/esm/lib/urls.d.ts +11 -8
- package/dist/esm/lib/urls.js +15 -21
- package/package.json +5 -4
|
@@ -430,6 +430,47 @@ export declare function useUpdateProjectSettings({ projectId }: {
|
|
|
430
430
|
reset: () => void;
|
|
431
431
|
status: "pending" | "success" | "idle";
|
|
432
432
|
};
|
|
433
|
+
/**
|
|
434
|
+
* Change a project member's role.
|
|
435
|
+
*
|
|
436
|
+
* @param opts.projectId Project public ID
|
|
437
|
+
*
|
|
438
|
+
* @example
|
|
439
|
+
* ```tsx
|
|
440
|
+
* function BasicExample() {
|
|
441
|
+
* const { mutate } = useChangeMemberRole({ projectId: '...' })
|
|
442
|
+
* // Use one of: COORDINATOR_ROLE_ID, MEMBER_ROLE_ID, BLOCKED_ROLE_ID
|
|
443
|
+
* mutate({ deviceId: '...', roleId: COORDINATOR_ROLE_ID })
|
|
444
|
+
* }
|
|
445
|
+
* ```
|
|
446
|
+
*/
|
|
447
|
+
export declare function useChangeMemberRole({ projectId }: {
|
|
448
|
+
projectId: string;
|
|
449
|
+
}): {
|
|
450
|
+
error: Error;
|
|
451
|
+
mutate: import("@tanstack/react-query").UseMutateFunction<void, Error, {
|
|
452
|
+
deviceId: string;
|
|
453
|
+
roleId: import("@comapeo/core", { with: { "resolution-mode": "import" } }).MemberApi.RoleIdAssignableToOthers;
|
|
454
|
+
}, unknown>;
|
|
455
|
+
mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<void, Error, {
|
|
456
|
+
deviceId: string;
|
|
457
|
+
roleId: import("@comapeo/core", { with: { "resolution-mode": "import" } }).MemberApi.RoleIdAssignableToOthers;
|
|
458
|
+
}, unknown>;
|
|
459
|
+
reset: () => void;
|
|
460
|
+
status: "error";
|
|
461
|
+
} | {
|
|
462
|
+
error: null;
|
|
463
|
+
mutate: import("@tanstack/react-query").UseMutateFunction<void, Error, {
|
|
464
|
+
deviceId: string;
|
|
465
|
+
roleId: import("@comapeo/core", { with: { "resolution-mode": "import" } }).MemberApi.RoleIdAssignableToOthers;
|
|
466
|
+
}, unknown>;
|
|
467
|
+
mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<void, Error, {
|
|
468
|
+
deviceId: string;
|
|
469
|
+
roleId: import("@comapeo/core", { with: { "resolution-mode": "import" } }).MemberApi.RoleIdAssignableToOthers;
|
|
470
|
+
}, unknown>;
|
|
471
|
+
reset: () => void;
|
|
472
|
+
status: "pending" | "success" | "idle";
|
|
473
|
+
};
|
|
433
474
|
/**
|
|
434
475
|
* Create a blob for a project.
|
|
435
476
|
*
|
|
@@ -626,13 +667,7 @@ export declare function useExportGeoJSON({ projectId }: {
|
|
|
626
667
|
mutate: import("@tanstack/react-query").UseMutateFunction<string, Error, {
|
|
627
668
|
path: string;
|
|
628
669
|
exportOptions: {
|
|
629
|
-
observations
|
|
630
|
-
/**
|
|
631
|
-
* Update the settings of a project.
|
|
632
|
-
*
|
|
633
|
-
* @param opts.projectId Public ID of the project to apply changes to.
|
|
634
|
-
*/
|
|
635
|
-
?: boolean;
|
|
670
|
+
observations?: boolean;
|
|
636
671
|
tracks?: boolean;
|
|
637
672
|
lang?: string;
|
|
638
673
|
};
|
|
@@ -640,13 +675,7 @@ export declare function useExportGeoJSON({ projectId }: {
|
|
|
640
675
|
mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<string, Error, {
|
|
641
676
|
path: string;
|
|
642
677
|
exportOptions: {
|
|
643
|
-
observations
|
|
644
|
-
/**
|
|
645
|
-
* Update the settings of a project.
|
|
646
|
-
*
|
|
647
|
-
* @param opts.projectId Public ID of the project to apply changes to.
|
|
648
|
-
*/
|
|
649
|
-
?: boolean;
|
|
678
|
+
observations?: boolean;
|
|
650
679
|
tracks?: boolean;
|
|
651
680
|
lang?: string;
|
|
652
681
|
};
|
|
@@ -658,13 +687,7 @@ export declare function useExportGeoJSON({ projectId }: {
|
|
|
658
687
|
mutate: import("@tanstack/react-query").UseMutateFunction<string, Error, {
|
|
659
688
|
path: string;
|
|
660
689
|
exportOptions: {
|
|
661
|
-
observations
|
|
662
|
-
/**
|
|
663
|
-
* Update the settings of a project.
|
|
664
|
-
*
|
|
665
|
-
* @param opts.projectId Public ID of the project to apply changes to.
|
|
666
|
-
*/
|
|
667
|
-
?: boolean;
|
|
690
|
+
observations?: boolean;
|
|
668
691
|
tracks?: boolean;
|
|
669
692
|
lang?: string;
|
|
670
693
|
};
|
|
@@ -672,13 +695,7 @@ export declare function useExportGeoJSON({ projectId }: {
|
|
|
672
695
|
mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<string, Error, {
|
|
673
696
|
path: string;
|
|
674
697
|
exportOptions: {
|
|
675
|
-
observations
|
|
676
|
-
/**
|
|
677
|
-
* Update the settings of a project.
|
|
678
|
-
*
|
|
679
|
-
* @param opts.projectId Public ID of the project to apply changes to.
|
|
680
|
-
*/
|
|
681
|
-
?: boolean;
|
|
698
|
+
observations?: boolean;
|
|
682
699
|
tracks?: boolean;
|
|
683
700
|
lang?: string;
|
|
684
701
|
};
|
|
@@ -15,6 +15,7 @@ exports.useCreateProject = useCreateProject;
|
|
|
15
15
|
exports.useLeaveProject = useLeaveProject;
|
|
16
16
|
exports.useImportProjectConfig = useImportProjectConfig;
|
|
17
17
|
exports.useUpdateProjectSettings = useUpdateProjectSettings;
|
|
18
|
+
exports.useChangeMemberRole = useChangeMemberRole;
|
|
18
19
|
exports.useCreateBlob = useCreateBlob;
|
|
19
20
|
exports.useSyncState = useSyncState;
|
|
20
21
|
exports.useDataSyncProgress = useDataSyncProgress;
|
|
@@ -186,9 +187,13 @@ function useManyMembers({ projectId }) {
|
|
|
186
187
|
*/
|
|
187
188
|
function useIconUrl({ projectId, iconId, ...mimeBasedOpts }) {
|
|
188
189
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
189
|
-
const { data:
|
|
190
|
-
const
|
|
191
|
-
|
|
190
|
+
const { data: serverOrigin, error, isRefetching, } = useMediaServerOrigin({ projectApi });
|
|
191
|
+
const iconUrl = (0, urls_js_1.getIconUrl)({
|
|
192
|
+
serverOrigin,
|
|
193
|
+
iconId,
|
|
194
|
+
projectId,
|
|
195
|
+
mimeBasedOpts,
|
|
196
|
+
});
|
|
192
197
|
return { data: iconUrl, error, isRefetching };
|
|
193
198
|
}
|
|
194
199
|
/**
|
|
@@ -244,17 +249,16 @@ function useIconUrl({ projectId, iconId, ...mimeBasedOpts }) {
|
|
|
244
249
|
*/
|
|
245
250
|
function useAttachmentUrl({ projectId, blobId, }) {
|
|
246
251
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
247
|
-
const { data:
|
|
248
|
-
const
|
|
249
|
-
const blobUrl = (0, urls_js_1.getBlobUrl)(baseUrl, blobId);
|
|
252
|
+
const { data: serverOrigin, error, isRefetching, } = useMediaServerOrigin({ projectApi });
|
|
253
|
+
const blobUrl = (0, urls_js_1.getBlobUrl)({ serverOrigin, projectId, blobId });
|
|
250
254
|
return { data: blobUrl, error, isRefetching };
|
|
251
255
|
}
|
|
252
256
|
/**
|
|
253
257
|
* @internal
|
|
254
|
-
* Hack to retrieve the media server
|
|
258
|
+
* Hack to retrieve the media server origin (protocol + host).
|
|
255
259
|
*/
|
|
256
|
-
function
|
|
257
|
-
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)((0, projects_js_1.
|
|
260
|
+
function useMediaServerOrigin({ projectApi }) {
|
|
261
|
+
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)((0, projects_js_1.mediaServerOriginQueryOptions)({
|
|
258
262
|
projectApi,
|
|
259
263
|
}));
|
|
260
264
|
return { data, error, isRefetching };
|
|
@@ -365,6 +369,28 @@ function useUpdateProjectSettings({ projectId }) {
|
|
|
365
369
|
? { error, mutate, mutateAsync, reset, status }
|
|
366
370
|
: { error: null, mutate, mutateAsync, reset, status };
|
|
367
371
|
}
|
|
372
|
+
/**
|
|
373
|
+
* Change a project member's role.
|
|
374
|
+
*
|
|
375
|
+
* @param opts.projectId Project public ID
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* ```tsx
|
|
379
|
+
* function BasicExample() {
|
|
380
|
+
* const { mutate } = useChangeMemberRole({ projectId: '...' })
|
|
381
|
+
* // Use one of: COORDINATOR_ROLE_ID, MEMBER_ROLE_ID, BLOCKED_ROLE_ID
|
|
382
|
+
* mutate({ deviceId: '...', roleId: COORDINATOR_ROLE_ID })
|
|
383
|
+
* }
|
|
384
|
+
* ```
|
|
385
|
+
*/
|
|
386
|
+
function useChangeMemberRole({ projectId }) {
|
|
387
|
+
const queryClient = (0, react_query_1.useQueryClient)();
|
|
388
|
+
const { data: projectApi } = useSingleProject({ projectId });
|
|
389
|
+
const { error, mutate, mutateAsync, reset, status } = (0, react_query_1.useMutation)((0, projects_js_1.changeMemberRoleMutationOptions)({ projectApi, projectId, queryClient }));
|
|
390
|
+
return status === 'error'
|
|
391
|
+
? { error, mutate, mutateAsync, reset, status }
|
|
392
|
+
: { error: null, mutate, mutateAsync, reset, status };
|
|
393
|
+
}
|
|
368
394
|
/**
|
|
369
395
|
* Create a blob for a project.
|
|
370
396
|
*
|
package/dist/commonjs/index.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ export { useClientApi, useIsArchiveDevice, useOwnDeviceInfo, useSetIsArchiveDevi
|
|
|
3
3
|
export { useCreateDocument, useDeleteDocument, useManyDocs, useSingleDocByDocId, useSingleDocByVersionId, useUpdateDocument, } from './hooks/documents.js';
|
|
4
4
|
export { useAcceptInvite, useManyInvites, useRejectInvite, useRequestCancelInvite, useSendInvite, useSetUpInvitesListeners, useSingleInvite, } from './hooks/invites.js';
|
|
5
5
|
export { useMapStyleUrl } from './hooks/maps.js';
|
|
6
|
-
export { useAddServerPeer, useAttachmentUrl, useConnectSyncServers, useCreateBlob, useCreateProject, useDataSyncProgress, useDisconnectSyncServers, useDocumentCreatedBy, useIconUrl, useImportProjectConfig, useLeaveProject, useManyMembers, useManyProjects, useOwnRoleInProject, useProjectSettings, useRemoveServerPeer, useSetAutostopDataSyncTimeout, useSingleMember, useSingleProject, useStartSync, useStopSync, useSyncState, useUpdateProjectSettings, useExportGeoJSON, useExportZipFile, } from './hooks/projects.js';
|
|
6
|
+
export { useAddServerPeer, useAttachmentUrl, useConnectSyncServers, useCreateBlob, useCreateProject, useDataSyncProgress, useDisconnectSyncServers, useDocumentCreatedBy, useIconUrl, useImportProjectConfig, useLeaveProject, useManyMembers, useManyProjects, useOwnRoleInProject, useProjectSettings, useRemoveServerPeer, useSetAutostopDataSyncTimeout, useSingleMember, useSingleProject, useStartSync, useStopSync, useSyncState, useUpdateProjectSettings, useChangeMemberRole, useExportGeoJSON, useExportZipFile, } from './hooks/projects.js';
|
|
7
7
|
export { type SyncState } from './lib/sync.js';
|
|
8
8
|
export { type WriteableDocument, type WriteableDocumentType, type WriteableValue, } from './lib/types.js';
|
package/dist/commonjs/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useExportZipFile = exports.useExportGeoJSON = exports.useUpdateProjectSettings = exports.useSyncState = exports.useStopSync = exports.useStartSync = exports.useSingleProject = exports.useSingleMember = exports.useSetAutostopDataSyncTimeout = exports.useRemoveServerPeer = exports.useProjectSettings = exports.useOwnRoleInProject = exports.useManyProjects = exports.useManyMembers = exports.useLeaveProject = exports.useImportProjectConfig = exports.useIconUrl = exports.useDocumentCreatedBy = exports.useDisconnectSyncServers = exports.useDataSyncProgress = exports.useCreateProject = exports.useCreateBlob = exports.useConnectSyncServers = exports.useAttachmentUrl = exports.useAddServerPeer = exports.useMapStyleUrl = exports.useSingleInvite = exports.useSetUpInvitesListeners = exports.useSendInvite = exports.useRequestCancelInvite = exports.useRejectInvite = exports.useManyInvites = exports.useAcceptInvite = exports.useUpdateDocument = exports.useSingleDocByVersionId = exports.useSingleDocByDocId = exports.useManyDocs = exports.useDeleteDocument = exports.useCreateDocument = exports.useSetOwnDeviceInfo = exports.useSetIsArchiveDevice = exports.useOwnDeviceInfo = exports.useIsArchiveDevice = exports.useClientApi = exports.ClientApiProvider = exports.ClientApiContext = void 0;
|
|
3
|
+
exports.useExportZipFile = exports.useExportGeoJSON = exports.useChangeMemberRole = exports.useUpdateProjectSettings = exports.useSyncState = exports.useStopSync = exports.useStartSync = exports.useSingleProject = exports.useSingleMember = exports.useSetAutostopDataSyncTimeout = exports.useRemoveServerPeer = exports.useProjectSettings = exports.useOwnRoleInProject = exports.useManyProjects = exports.useManyMembers = exports.useLeaveProject = exports.useImportProjectConfig = exports.useIconUrl = exports.useDocumentCreatedBy = exports.useDisconnectSyncServers = exports.useDataSyncProgress = exports.useCreateProject = exports.useCreateBlob = exports.useConnectSyncServers = exports.useAttachmentUrl = exports.useAddServerPeer = exports.useMapStyleUrl = exports.useSingleInvite = exports.useSetUpInvitesListeners = exports.useSendInvite = exports.useRequestCancelInvite = exports.useRejectInvite = exports.useManyInvites = exports.useAcceptInvite = exports.useUpdateDocument = exports.useSingleDocByVersionId = exports.useSingleDocByDocId = exports.useManyDocs = exports.useDeleteDocument = exports.useCreateDocument = exports.useSetOwnDeviceInfo = exports.useSetIsArchiveDevice = exports.useOwnDeviceInfo = exports.useIsArchiveDevice = exports.useClientApi = exports.ClientApiProvider = exports.ClientApiContext = void 0;
|
|
4
4
|
var ClientApi_js_1 = require("./contexts/ClientApi.js");
|
|
5
5
|
Object.defineProperty(exports, "ClientApiContext", { enumerable: true, get: function () { return ClientApi_js_1.ClientApiContext; } });
|
|
6
6
|
Object.defineProperty(exports, "ClientApiProvider", { enumerable: true, get: function () { return ClientApi_js_1.ClientApiProvider; } });
|
|
@@ -51,5 +51,6 @@ Object.defineProperty(exports, "useStartSync", { enumerable: true, get: function
|
|
|
51
51
|
Object.defineProperty(exports, "useStopSync", { enumerable: true, get: function () { return projects_js_1.useStopSync; } });
|
|
52
52
|
Object.defineProperty(exports, "useSyncState", { enumerable: true, get: function () { return projects_js_1.useSyncState; } });
|
|
53
53
|
Object.defineProperty(exports, "useUpdateProjectSettings", { enumerable: true, get: function () { return projects_js_1.useUpdateProjectSettings; } });
|
|
54
|
+
Object.defineProperty(exports, "useChangeMemberRole", { enumerable: true, get: function () { return projects_js_1.useChangeMemberRole; } });
|
|
54
55
|
Object.defineProperty(exports, "useExportGeoJSON", { enumerable: true, get: function () { return projects_js_1.useExportGeoJSON; } });
|
|
55
56
|
Object.defineProperty(exports, "useExportZipFile", { enumerable: true, get: function () { return projects_js_1.useExportZipFile; } });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BlobApi } from '@comapeo/core' with { 'resolution-mode': 'import' };
|
|
1
|
+
import type { BlobApi, MemberApi } from '@comapeo/core' with { 'resolution-mode': 'import' };
|
|
2
2
|
import type { MapeoClientApi, MapeoProjectApi } from '@comapeo/ipc' with { 'resolution-mode': 'import' };
|
|
3
3
|
import type { ProjectSettings } from '@comapeo/schema' with { 'resolution-mode': 'import' };
|
|
4
4
|
import { type QueryClient, type UnusedSkipTokenOptions } from '@tanstack/react-query';
|
|
@@ -28,7 +28,7 @@ export declare function getDocumentCreatedByQueryKey({ projectId, originalVersio
|
|
|
28
28
|
* exposed right now, but it is the same for all projects, so no need for
|
|
29
29
|
* scoping the query key to the project
|
|
30
30
|
*/
|
|
31
|
-
export declare function
|
|
31
|
+
export declare function getMediaServerOriginQueryKey(): readonly ["@comapeo/core-react", "media_server_origin"];
|
|
32
32
|
export declare function projectsQueryOptions({ clientApi, }: {
|
|
33
33
|
clientApi: MapeoClientApi;
|
|
34
34
|
}): import("@tanstack/react-query").OmitKeyof<import("@tanstack/react-query").UseQueryOptions<import("@comapeo/core/dist/mapeo-manager.js", { with: { "resolution-mode": "import" } }).ListedProject[], Error, import("@comapeo/core/dist/mapeo-manager.js", { with: { "resolution-mode": "import" } }).ListedProject[], readonly ["@comapeo/core-react", "projects"]>, "queryFn"> & {
|
|
@@ -100,12 +100,12 @@ export declare function documentCreatedByQueryOptions({ projectApi, projectId, o
|
|
|
100
100
|
[dataTagErrorSymbol]: Error;
|
|
101
101
|
};
|
|
102
102
|
};
|
|
103
|
-
export declare function
|
|
103
|
+
export declare function mediaServerOriginQueryOptions({ projectApi, }: {
|
|
104
104
|
projectApi: MapeoProjectApi;
|
|
105
|
-
}): import("@tanstack/react-query").OmitKeyof<import("@tanstack/react-query").UseQueryOptions<string, Error, string, readonly ["@comapeo/core-react", "
|
|
106
|
-
queryFn?: import("@tanstack/react-query").QueryFunction<string, readonly ["@comapeo/core-react", "
|
|
105
|
+
}): import("@tanstack/react-query").OmitKeyof<import("@tanstack/react-query").UseQueryOptions<string, Error, string, readonly ["@comapeo/core-react", "media_server_origin"]>, "queryFn"> & {
|
|
106
|
+
queryFn?: import("@tanstack/react-query").QueryFunction<string, readonly ["@comapeo/core-react", "media_server_origin"], never> | undefined;
|
|
107
107
|
} & {
|
|
108
|
-
queryKey: readonly ["@comapeo/core-react", "
|
|
108
|
+
queryKey: readonly ["@comapeo/core-react", "media_server_origin"] & {
|
|
109
109
|
[dataTagSymbol]: string;
|
|
110
110
|
[dataTagErrorSymbol]: Error;
|
|
111
111
|
};
|
|
@@ -186,6 +186,19 @@ export declare function updateProjectSettingsMutationOptions({ projectApi, query
|
|
|
186
186
|
networkMode: "always";
|
|
187
187
|
retry: false;
|
|
188
188
|
};
|
|
189
|
+
export declare function changeMemberRoleMutationOptions({ projectApi, projectId, queryClient, }: {
|
|
190
|
+
projectApi: MapeoProjectApi;
|
|
191
|
+
projectId: string;
|
|
192
|
+
queryClient: QueryClient;
|
|
193
|
+
}): {
|
|
194
|
+
mutationFn: ({ deviceId, roleId }: {
|
|
195
|
+
deviceId: string;
|
|
196
|
+
roleId: MemberApi.RoleIdAssignableToOthers;
|
|
197
|
+
}) => Promise<void>;
|
|
198
|
+
onSuccess: () => void;
|
|
199
|
+
networkMode: "always";
|
|
200
|
+
retry: false;
|
|
201
|
+
};
|
|
189
202
|
export declare function createBlobMutationOptions({ projectApi, }: {
|
|
190
203
|
projectApi: MapeoProjectApi;
|
|
191
204
|
}): {
|
|
@@ -7,7 +7,7 @@ exports.getProjectRoleQueryKey = getProjectRoleQueryKey;
|
|
|
7
7
|
exports.getMembersQueryKey = getMembersQueryKey;
|
|
8
8
|
exports.getMemberByIdQueryKey = getMemberByIdQueryKey;
|
|
9
9
|
exports.getDocumentCreatedByQueryKey = getDocumentCreatedByQueryKey;
|
|
10
|
-
exports.
|
|
10
|
+
exports.getMediaServerOriginQueryKey = getMediaServerOriginQueryKey;
|
|
11
11
|
exports.projectsQueryOptions = projectsQueryOptions;
|
|
12
12
|
exports.projectByIdQueryOptions = projectByIdQueryOptions;
|
|
13
13
|
exports.projectSettingsQueryOptions = projectSettingsQueryOptions;
|
|
@@ -15,13 +15,14 @@ exports.projectMembersQueryOptions = projectMembersQueryOptions;
|
|
|
15
15
|
exports.projectMemberByIdQueryOptions = projectMemberByIdQueryOptions;
|
|
16
16
|
exports.projectOwnRoleQueryOptions = projectOwnRoleQueryOptions;
|
|
17
17
|
exports.documentCreatedByQueryOptions = documentCreatedByQueryOptions;
|
|
18
|
-
exports.
|
|
18
|
+
exports.mediaServerOriginQueryOptions = mediaServerOriginQueryOptions;
|
|
19
19
|
exports.addServerPeerMutationOptions = addServerPeerMutationOptions;
|
|
20
20
|
exports.removeServerPeerMutationOptions = removeServerPeerMutationOptions;
|
|
21
21
|
exports.createProjectMutationOptions = createProjectMutationOptions;
|
|
22
22
|
exports.leaveProjectMutationOptions = leaveProjectMutationOptions;
|
|
23
23
|
exports.importProjectConfigMutationOptions = importProjectConfigMutationOptions;
|
|
24
24
|
exports.updateProjectSettingsMutationOptions = updateProjectSettingsMutationOptions;
|
|
25
|
+
exports.changeMemberRoleMutationOptions = changeMemberRoleMutationOptions;
|
|
25
26
|
exports.createBlobMutationOptions = createBlobMutationOptions;
|
|
26
27
|
exports.startSyncMutationOptions = startSyncMutationOptions;
|
|
27
28
|
exports.stopSyncMutationOptions = stopSyncMutationOptions;
|
|
@@ -64,8 +65,8 @@ function getDocumentCreatedByQueryKey({ projectId, originalVersionId, }) {
|
|
|
64
65
|
* exposed right now, but it is the same for all projects, so no need for
|
|
65
66
|
* scoping the query key to the project
|
|
66
67
|
*/
|
|
67
|
-
function
|
|
68
|
-
return [shared_js_1.ROOT_QUERY_KEY, '
|
|
68
|
+
function getMediaServerOriginQueryKey() {
|
|
69
|
+
return [shared_js_1.ROOT_QUERY_KEY, 'media_server_origin'];
|
|
69
70
|
}
|
|
70
71
|
function projectsQueryOptions({ clientApi, }) {
|
|
71
72
|
return (0, react_query_1.queryOptions)({
|
|
@@ -142,17 +143,17 @@ const FAKE_BLOB_ID = {
|
|
|
142
143
|
name: 'name',
|
|
143
144
|
driveId: 'drive-id',
|
|
144
145
|
};
|
|
145
|
-
function
|
|
146
|
+
function mediaServerOriginQueryOptions({ projectApi, }) {
|
|
146
147
|
return (0, react_query_1.queryOptions)({
|
|
147
148
|
...(0, shared_js_1.baseQueryOptions)(),
|
|
148
|
-
// HACK: The server doesn't yet expose a method to get its
|
|
149
|
-
// the existing $blobs.getUrl() to get the
|
|
149
|
+
// HACK: The server doesn't yet expose a method to get its origin, so we use
|
|
150
|
+
// the existing $blobs.getUrl() to get the origin with a fake BlobId. The origin
|
|
150
151
|
// is the same regardless of the blobId, so it's not necessary to include it
|
|
151
152
|
// as a dep for the query key.
|
|
152
|
-
queryKey:
|
|
153
|
+
queryKey: getMediaServerOriginQueryKey(),
|
|
153
154
|
queryFn: async () => {
|
|
154
155
|
const url = await projectApi.$blobs.getUrl(FAKE_BLOB_ID);
|
|
155
|
-
return new URL(url).
|
|
156
|
+
return new URL(url).origin;
|
|
156
157
|
},
|
|
157
158
|
staleTime: 'static',
|
|
158
159
|
gcTime: Infinity,
|
|
@@ -247,6 +248,22 @@ function updateProjectSettingsMutationOptions({ projectApi, queryClient, }) {
|
|
|
247
248
|
},
|
|
248
249
|
};
|
|
249
250
|
}
|
|
251
|
+
function changeMemberRoleMutationOptions({ projectApi, projectId, queryClient, }) {
|
|
252
|
+
return {
|
|
253
|
+
...(0, shared_js_1.baseMutationOptions)(),
|
|
254
|
+
mutationFn: async ({ deviceId, roleId }) => {
|
|
255
|
+
return projectApi.$member.assignRole(deviceId, roleId);
|
|
256
|
+
},
|
|
257
|
+
onSuccess: () => {
|
|
258
|
+
queryClient.invalidateQueries({
|
|
259
|
+
queryKey: getMembersQueryKey({ projectId }),
|
|
260
|
+
});
|
|
261
|
+
queryClient.invalidateQueries({
|
|
262
|
+
queryKey: getProjectRoleQueryKey({ projectId }),
|
|
263
|
+
});
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
}
|
|
250
267
|
function createBlobMutationOptions({ projectApi, }) {
|
|
251
268
|
return {
|
|
252
269
|
...(0, shared_js_1.baseMutationOptions)(),
|
|
@@ -2,11 +2,14 @@ import type { BlobApi, IconApi } from '@comapeo/core';
|
|
|
2
2
|
/**
|
|
3
3
|
* Get a url for a blob based on its BlobId
|
|
4
4
|
*/
|
|
5
|
-
export declare function getBlobUrl(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
export declare function getBlobUrl({ serverOrigin, projectId, blobId, }: {
|
|
6
|
+
serverOrigin: string;
|
|
7
|
+
projectId: string;
|
|
8
|
+
blobId: BlobApi.BlobId;
|
|
9
|
+
}): string;
|
|
10
|
+
export declare function getIconUrl({ serverOrigin, iconId, projectId, mimeBasedOpts, }: {
|
|
11
|
+
serverOrigin: string;
|
|
12
|
+
iconId: string;
|
|
13
|
+
projectId: string;
|
|
14
|
+
mimeBasedOpts: IconApi.BitmapOpts | IconApi.SvgOpts;
|
|
15
|
+
}): string;
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// TODO: Move these into a separate "@comapeo/asset-server" module which can
|
|
3
3
|
// export them to be imported directly in a client.
|
|
4
|
+
//
|
|
5
|
+
// NB: The URL construction is fragile right now - it must match the
|
|
6
|
+
// implementation in the @comapeo/core fastify plugins
|
|
7
|
+
// [blobServerPlugin](https://github.com/digidem/comapeo-core/blob/main/src/fastify-plugins/blobs.js)
|
|
8
|
+
// and
|
|
9
|
+
// [iconServerPlugin](https://github.com/digidem/comapeo-core/blob/main/src/fastify-plugins/icons.js)
|
|
4
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
11
|
exports.getBlobUrl = getBlobUrl;
|
|
6
12
|
exports.getIconUrl = getIconUrl;
|
|
@@ -11,34 +17,22 @@ const MIME_TO_EXTENSION = {
|
|
|
11
17
|
/**
|
|
12
18
|
* Get a url for a blob based on its BlobId
|
|
13
19
|
*/
|
|
14
|
-
function getBlobUrl(
|
|
20
|
+
function getBlobUrl({ serverOrigin, projectId, blobId, }) {
|
|
15
21
|
const { driveId, type, variant, name } = blobId;
|
|
16
|
-
|
|
17
|
-
baseUrl += '/';
|
|
18
|
-
}
|
|
19
|
-
return baseUrl + `${driveId}/${type}/${variant}/${name}`;
|
|
22
|
+
return `${serverOrigin}/blobs/${projectId}/${driveId}/${type}/${variant}/${name}`;
|
|
20
23
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
*
|
|
25
|
-
* @returns {Promise<string>}
|
|
26
|
-
*/
|
|
27
|
-
function getIconUrl(baseUrl, iconId, opts) {
|
|
28
|
-
if (!baseUrl.endsWith('/')) {
|
|
29
|
-
baseUrl += '/';
|
|
30
|
-
}
|
|
31
|
-
const mimeExtension = MIME_TO_EXTENSION[opts.mimeType];
|
|
32
|
-
const pixelDensity = opts.mimeType === 'image/svg+xml' ||
|
|
24
|
+
function getIconUrl({ serverOrigin, iconId, projectId, mimeBasedOpts, }) {
|
|
25
|
+
const mimeExtension = MIME_TO_EXTENSION[mimeBasedOpts.mimeType];
|
|
26
|
+
const pixelDensity = mimeBasedOpts.mimeType === 'image/svg+xml' ||
|
|
33
27
|
// if the pixel density is 1, we can omit the density suffix in the resulting url
|
|
34
28
|
// and assume the pixel density is 1 for applicable mime types when using the url
|
|
35
|
-
|
|
29
|
+
mimeBasedOpts.pixelDensity === 1
|
|
36
30
|
? undefined
|
|
37
|
-
:
|
|
38
|
-
return (
|
|
31
|
+
: mimeBasedOpts.pixelDensity;
|
|
32
|
+
return (`${serverOrigin}/icons/${projectId}/` +
|
|
39
33
|
constructIconPath({
|
|
40
34
|
pixelDensity,
|
|
41
|
-
size:
|
|
35
|
+
size: mimeBasedOpts.size,
|
|
42
36
|
extension: mimeExtension,
|
|
43
37
|
iconId,
|
|
44
38
|
}));
|
|
@@ -430,6 +430,47 @@ export declare function useUpdateProjectSettings({ projectId }: {
|
|
|
430
430
|
reset: () => void;
|
|
431
431
|
status: "pending" | "success" | "idle";
|
|
432
432
|
};
|
|
433
|
+
/**
|
|
434
|
+
* Change a project member's role.
|
|
435
|
+
*
|
|
436
|
+
* @param opts.projectId Project public ID
|
|
437
|
+
*
|
|
438
|
+
* @example
|
|
439
|
+
* ```tsx
|
|
440
|
+
* function BasicExample() {
|
|
441
|
+
* const { mutate } = useChangeMemberRole({ projectId: '...' })
|
|
442
|
+
* // Use one of: COORDINATOR_ROLE_ID, MEMBER_ROLE_ID, BLOCKED_ROLE_ID
|
|
443
|
+
* mutate({ deviceId: '...', roleId: COORDINATOR_ROLE_ID })
|
|
444
|
+
* }
|
|
445
|
+
* ```
|
|
446
|
+
*/
|
|
447
|
+
export declare function useChangeMemberRole({ projectId }: {
|
|
448
|
+
projectId: string;
|
|
449
|
+
}): {
|
|
450
|
+
error: Error;
|
|
451
|
+
mutate: import("@tanstack/react-query").UseMutateFunction<void, Error, {
|
|
452
|
+
deviceId: string;
|
|
453
|
+
roleId: import("@comapeo/core").MemberApi.RoleIdAssignableToOthers;
|
|
454
|
+
}, unknown>;
|
|
455
|
+
mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<void, Error, {
|
|
456
|
+
deviceId: string;
|
|
457
|
+
roleId: import("@comapeo/core").MemberApi.RoleIdAssignableToOthers;
|
|
458
|
+
}, unknown>;
|
|
459
|
+
reset: () => void;
|
|
460
|
+
status: "error";
|
|
461
|
+
} | {
|
|
462
|
+
error: null;
|
|
463
|
+
mutate: import("@tanstack/react-query").UseMutateFunction<void, Error, {
|
|
464
|
+
deviceId: string;
|
|
465
|
+
roleId: import("@comapeo/core").MemberApi.RoleIdAssignableToOthers;
|
|
466
|
+
}, unknown>;
|
|
467
|
+
mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<void, Error, {
|
|
468
|
+
deviceId: string;
|
|
469
|
+
roleId: import("@comapeo/core").MemberApi.RoleIdAssignableToOthers;
|
|
470
|
+
}, unknown>;
|
|
471
|
+
reset: () => void;
|
|
472
|
+
status: "pending" | "success" | "idle";
|
|
473
|
+
};
|
|
433
474
|
/**
|
|
434
475
|
* Create a blob for a project.
|
|
435
476
|
*
|
|
@@ -626,13 +667,7 @@ export declare function useExportGeoJSON({ projectId }: {
|
|
|
626
667
|
mutate: import("@tanstack/react-query").UseMutateFunction<string, Error, {
|
|
627
668
|
path: string;
|
|
628
669
|
exportOptions: {
|
|
629
|
-
observations
|
|
630
|
-
/**
|
|
631
|
-
* Update the settings of a project.
|
|
632
|
-
*
|
|
633
|
-
* @param opts.projectId Public ID of the project to apply changes to.
|
|
634
|
-
*/
|
|
635
|
-
?: boolean;
|
|
670
|
+
observations?: boolean;
|
|
636
671
|
tracks?: boolean;
|
|
637
672
|
lang?: string;
|
|
638
673
|
};
|
|
@@ -640,13 +675,7 @@ export declare function useExportGeoJSON({ projectId }: {
|
|
|
640
675
|
mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<string, Error, {
|
|
641
676
|
path: string;
|
|
642
677
|
exportOptions: {
|
|
643
|
-
observations
|
|
644
|
-
/**
|
|
645
|
-
* Update the settings of a project.
|
|
646
|
-
*
|
|
647
|
-
* @param opts.projectId Public ID of the project to apply changes to.
|
|
648
|
-
*/
|
|
649
|
-
?: boolean;
|
|
678
|
+
observations?: boolean;
|
|
650
679
|
tracks?: boolean;
|
|
651
680
|
lang?: string;
|
|
652
681
|
};
|
|
@@ -658,13 +687,7 @@ export declare function useExportGeoJSON({ projectId }: {
|
|
|
658
687
|
mutate: import("@tanstack/react-query").UseMutateFunction<string, Error, {
|
|
659
688
|
path: string;
|
|
660
689
|
exportOptions: {
|
|
661
|
-
observations
|
|
662
|
-
/**
|
|
663
|
-
* Update the settings of a project.
|
|
664
|
-
*
|
|
665
|
-
* @param opts.projectId Public ID of the project to apply changes to.
|
|
666
|
-
*/
|
|
667
|
-
?: boolean;
|
|
690
|
+
observations?: boolean;
|
|
668
691
|
tracks?: boolean;
|
|
669
692
|
lang?: string;
|
|
670
693
|
};
|
|
@@ -672,13 +695,7 @@ export declare function useExportGeoJSON({ projectId }: {
|
|
|
672
695
|
mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<string, Error, {
|
|
673
696
|
path: string;
|
|
674
697
|
exportOptions: {
|
|
675
|
-
observations
|
|
676
|
-
/**
|
|
677
|
-
* Update the settings of a project.
|
|
678
|
-
*
|
|
679
|
-
* @param opts.projectId Public ID of the project to apply changes to.
|
|
680
|
-
*/
|
|
681
|
-
?: boolean;
|
|
698
|
+
observations?: boolean;
|
|
682
699
|
tracks?: boolean;
|
|
683
700
|
lang?: string;
|
|
684
701
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useMutation, useQueryClient, useSuspenseQuery, } from '@tanstack/react-query';
|
|
2
2
|
import { useSyncExternalStore } from 'react';
|
|
3
|
-
import { addServerPeerMutationOptions, connectSyncServersMutationOptions, createBlobMutationOptions, createProjectMutationOptions, disconnectSyncServersMutationOptions, documentCreatedByQueryOptions, exportGeoJSONMutationOptions, exportZipFileMutationOptions, importProjectConfigMutationOptions, leaveProjectMutationOptions,
|
|
3
|
+
import { addServerPeerMutationOptions, changeMemberRoleMutationOptions, connectSyncServersMutationOptions, createBlobMutationOptions, createProjectMutationOptions, disconnectSyncServersMutationOptions, documentCreatedByQueryOptions, exportGeoJSONMutationOptions, exportZipFileMutationOptions, importProjectConfigMutationOptions, leaveProjectMutationOptions, mediaServerOriginQueryOptions, projectByIdQueryOptions, projectMemberByIdQueryOptions, projectMembersQueryOptions, projectOwnRoleQueryOptions, projectSettingsQueryOptions, projectsQueryOptions, removeServerPeerMutationOptions, setAutostopDataSyncTimeoutMutationOptions, startSyncMutationOptions, stopSyncMutationOptions, updateProjectSettingsMutationOptions, } from '../lib/react-query/projects.js';
|
|
4
4
|
import { SyncStore } from '../lib/sync.js';
|
|
5
5
|
import { getBlobUrl, getIconUrl } from '../lib/urls.js';
|
|
6
6
|
import { useClientApi } from './client.js';
|
|
@@ -159,9 +159,13 @@ export function useManyMembers({ projectId }) {
|
|
|
159
159
|
*/
|
|
160
160
|
export function useIconUrl({ projectId, iconId, ...mimeBasedOpts }) {
|
|
161
161
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
162
|
-
const { data:
|
|
163
|
-
const
|
|
164
|
-
|
|
162
|
+
const { data: serverOrigin, error, isRefetching, } = useMediaServerOrigin({ projectApi });
|
|
163
|
+
const iconUrl = getIconUrl({
|
|
164
|
+
serverOrigin,
|
|
165
|
+
iconId,
|
|
166
|
+
projectId,
|
|
167
|
+
mimeBasedOpts,
|
|
168
|
+
});
|
|
165
169
|
return { data: iconUrl, error, isRefetching };
|
|
166
170
|
}
|
|
167
171
|
/**
|
|
@@ -217,17 +221,16 @@ export function useIconUrl({ projectId, iconId, ...mimeBasedOpts }) {
|
|
|
217
221
|
*/
|
|
218
222
|
export function useAttachmentUrl({ projectId, blobId, }) {
|
|
219
223
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
220
|
-
const { data:
|
|
221
|
-
const
|
|
222
|
-
const blobUrl = getBlobUrl(baseUrl, blobId);
|
|
224
|
+
const { data: serverOrigin, error, isRefetching, } = useMediaServerOrigin({ projectApi });
|
|
225
|
+
const blobUrl = getBlobUrl({ serverOrigin, projectId, blobId });
|
|
223
226
|
return { data: blobUrl, error, isRefetching };
|
|
224
227
|
}
|
|
225
228
|
/**
|
|
226
229
|
* @internal
|
|
227
|
-
* Hack to retrieve the media server
|
|
230
|
+
* Hack to retrieve the media server origin (protocol + host).
|
|
228
231
|
*/
|
|
229
|
-
function
|
|
230
|
-
const { data, error, isRefetching } = useSuspenseQuery(
|
|
232
|
+
function useMediaServerOrigin({ projectApi }) {
|
|
233
|
+
const { data, error, isRefetching } = useSuspenseQuery(mediaServerOriginQueryOptions({
|
|
231
234
|
projectApi,
|
|
232
235
|
}));
|
|
233
236
|
return { data, error, isRefetching };
|
|
@@ -338,6 +341,28 @@ export function useUpdateProjectSettings({ projectId }) {
|
|
|
338
341
|
? { error, mutate, mutateAsync, reset, status }
|
|
339
342
|
: { error: null, mutate, mutateAsync, reset, status };
|
|
340
343
|
}
|
|
344
|
+
/**
|
|
345
|
+
* Change a project member's role.
|
|
346
|
+
*
|
|
347
|
+
* @param opts.projectId Project public ID
|
|
348
|
+
*
|
|
349
|
+
* @example
|
|
350
|
+
* ```tsx
|
|
351
|
+
* function BasicExample() {
|
|
352
|
+
* const { mutate } = useChangeMemberRole({ projectId: '...' })
|
|
353
|
+
* // Use one of: COORDINATOR_ROLE_ID, MEMBER_ROLE_ID, BLOCKED_ROLE_ID
|
|
354
|
+
* mutate({ deviceId: '...', roleId: COORDINATOR_ROLE_ID })
|
|
355
|
+
* }
|
|
356
|
+
* ```
|
|
357
|
+
*/
|
|
358
|
+
export function useChangeMemberRole({ projectId }) {
|
|
359
|
+
const queryClient = useQueryClient();
|
|
360
|
+
const { data: projectApi } = useSingleProject({ projectId });
|
|
361
|
+
const { error, mutate, mutateAsync, reset, status } = useMutation(changeMemberRoleMutationOptions({ projectApi, projectId, queryClient }));
|
|
362
|
+
return status === 'error'
|
|
363
|
+
? { error, mutate, mutateAsync, reset, status }
|
|
364
|
+
: { error: null, mutate, mutateAsync, reset, status };
|
|
365
|
+
}
|
|
341
366
|
/**
|
|
342
367
|
* Create a blob for a project.
|
|
343
368
|
*
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ export { useClientApi, useIsArchiveDevice, useOwnDeviceInfo, useSetIsArchiveDevi
|
|
|
3
3
|
export { useCreateDocument, useDeleteDocument, useManyDocs, useSingleDocByDocId, useSingleDocByVersionId, useUpdateDocument, } from './hooks/documents.js';
|
|
4
4
|
export { useAcceptInvite, useManyInvites, useRejectInvite, useRequestCancelInvite, useSendInvite, useSetUpInvitesListeners, useSingleInvite, } from './hooks/invites.js';
|
|
5
5
|
export { useMapStyleUrl } from './hooks/maps.js';
|
|
6
|
-
export { useAddServerPeer, useAttachmentUrl, useConnectSyncServers, useCreateBlob, useCreateProject, useDataSyncProgress, useDisconnectSyncServers, useDocumentCreatedBy, useIconUrl, useImportProjectConfig, useLeaveProject, useManyMembers, useManyProjects, useOwnRoleInProject, useProjectSettings, useRemoveServerPeer, useSetAutostopDataSyncTimeout, useSingleMember, useSingleProject, useStartSync, useStopSync, useSyncState, useUpdateProjectSettings, useExportGeoJSON, useExportZipFile, } from './hooks/projects.js';
|
|
6
|
+
export { useAddServerPeer, useAttachmentUrl, useConnectSyncServers, useCreateBlob, useCreateProject, useDataSyncProgress, useDisconnectSyncServers, useDocumentCreatedBy, useIconUrl, useImportProjectConfig, useLeaveProject, useManyMembers, useManyProjects, useOwnRoleInProject, useProjectSettings, useRemoveServerPeer, useSetAutostopDataSyncTimeout, useSingleMember, useSingleProject, useStartSync, useStopSync, useSyncState, useUpdateProjectSettings, useChangeMemberRole, useExportGeoJSON, useExportZipFile, } from './hooks/projects.js';
|
|
7
7
|
export { type SyncState } from './lib/sync.js';
|
|
8
8
|
export { type WriteableDocument, type WriteableDocumentType, type WriteableValue, } from './lib/types.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -3,4 +3,4 @@ export { useClientApi, useIsArchiveDevice, useOwnDeviceInfo, useSetIsArchiveDevi
|
|
|
3
3
|
export { useCreateDocument, useDeleteDocument, useManyDocs, useSingleDocByDocId, useSingleDocByVersionId, useUpdateDocument, } from './hooks/documents.js';
|
|
4
4
|
export { useAcceptInvite, useManyInvites, useRejectInvite, useRequestCancelInvite, useSendInvite, useSetUpInvitesListeners, useSingleInvite, } from './hooks/invites.js';
|
|
5
5
|
export { useMapStyleUrl } from './hooks/maps.js';
|
|
6
|
-
export { useAddServerPeer, useAttachmentUrl, useConnectSyncServers, useCreateBlob, useCreateProject, useDataSyncProgress, useDisconnectSyncServers, useDocumentCreatedBy, useIconUrl, useImportProjectConfig, useLeaveProject, useManyMembers, useManyProjects, useOwnRoleInProject, useProjectSettings, useRemoveServerPeer, useSetAutostopDataSyncTimeout, useSingleMember, useSingleProject, useStartSync, useStopSync, useSyncState, useUpdateProjectSettings, useExportGeoJSON, useExportZipFile, } from './hooks/projects.js';
|
|
6
|
+
export { useAddServerPeer, useAttachmentUrl, useConnectSyncServers, useCreateBlob, useCreateProject, useDataSyncProgress, useDisconnectSyncServers, useDocumentCreatedBy, useIconUrl, useImportProjectConfig, useLeaveProject, useManyMembers, useManyProjects, useOwnRoleInProject, useProjectSettings, useRemoveServerPeer, useSetAutostopDataSyncTimeout, useSingleMember, useSingleProject, useStartSync, useStopSync, useSyncState, useUpdateProjectSettings, useChangeMemberRole, useExportGeoJSON, useExportZipFile, } from './hooks/projects.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BlobApi } from '@comapeo/core' with { 'resolution-mode': 'import' };
|
|
1
|
+
import type { BlobApi, MemberApi } from '@comapeo/core' with { 'resolution-mode': 'import' };
|
|
2
2
|
import type { MapeoClientApi, MapeoProjectApi } from '@comapeo/ipc' with { 'resolution-mode': 'import' };
|
|
3
3
|
import type { ProjectSettings } from '@comapeo/schema' with { 'resolution-mode': 'import' };
|
|
4
4
|
import { type QueryClient, type UnusedSkipTokenOptions } from '@tanstack/react-query';
|
|
@@ -28,7 +28,7 @@ export declare function getDocumentCreatedByQueryKey({ projectId, originalVersio
|
|
|
28
28
|
* exposed right now, but it is the same for all projects, so no need for
|
|
29
29
|
* scoping the query key to the project
|
|
30
30
|
*/
|
|
31
|
-
export declare function
|
|
31
|
+
export declare function getMediaServerOriginQueryKey(): readonly ["@comapeo/core-react", "media_server_origin"];
|
|
32
32
|
export declare function projectsQueryOptions({ clientApi, }: {
|
|
33
33
|
clientApi: MapeoClientApi;
|
|
34
34
|
}): import("@tanstack/react-query").OmitKeyof<import("@tanstack/react-query").UseQueryOptions<import("@comapeo/core/dist/mapeo-manager.js").ListedProject[], Error, import("@comapeo/core/dist/mapeo-manager.js").ListedProject[], readonly ["@comapeo/core-react", "projects"]>, "queryFn"> & {
|
|
@@ -100,12 +100,12 @@ export declare function documentCreatedByQueryOptions({ projectApi, projectId, o
|
|
|
100
100
|
[dataTagErrorSymbol]: Error;
|
|
101
101
|
};
|
|
102
102
|
};
|
|
103
|
-
export declare function
|
|
103
|
+
export declare function mediaServerOriginQueryOptions({ projectApi, }: {
|
|
104
104
|
projectApi: MapeoProjectApi;
|
|
105
|
-
}): import("@tanstack/react-query").OmitKeyof<import("@tanstack/react-query").UseQueryOptions<string, Error, string, readonly ["@comapeo/core-react", "
|
|
106
|
-
queryFn?: import("@tanstack/react-query").QueryFunction<string, readonly ["@comapeo/core-react", "
|
|
105
|
+
}): import("@tanstack/react-query").OmitKeyof<import("@tanstack/react-query").UseQueryOptions<string, Error, string, readonly ["@comapeo/core-react", "media_server_origin"]>, "queryFn"> & {
|
|
106
|
+
queryFn?: import("@tanstack/react-query").QueryFunction<string, readonly ["@comapeo/core-react", "media_server_origin"], never> | undefined;
|
|
107
107
|
} & {
|
|
108
|
-
queryKey: readonly ["@comapeo/core-react", "
|
|
108
|
+
queryKey: readonly ["@comapeo/core-react", "media_server_origin"] & {
|
|
109
109
|
[dataTagSymbol]: string;
|
|
110
110
|
[dataTagErrorSymbol]: Error;
|
|
111
111
|
};
|
|
@@ -186,6 +186,19 @@ export declare function updateProjectSettingsMutationOptions({ projectApi, query
|
|
|
186
186
|
networkMode: "always";
|
|
187
187
|
retry: false;
|
|
188
188
|
};
|
|
189
|
+
export declare function changeMemberRoleMutationOptions({ projectApi, projectId, queryClient, }: {
|
|
190
|
+
projectApi: MapeoProjectApi;
|
|
191
|
+
projectId: string;
|
|
192
|
+
queryClient: QueryClient;
|
|
193
|
+
}): {
|
|
194
|
+
mutationFn: ({ deviceId, roleId }: {
|
|
195
|
+
deviceId: string;
|
|
196
|
+
roleId: MemberApi.RoleIdAssignableToOthers;
|
|
197
|
+
}) => Promise<void>;
|
|
198
|
+
onSuccess: () => void;
|
|
199
|
+
networkMode: "always";
|
|
200
|
+
retry: false;
|
|
201
|
+
};
|
|
189
202
|
export declare function createBlobMutationOptions({ projectApi, }: {
|
|
190
203
|
projectApi: MapeoProjectApi;
|
|
191
204
|
}): {
|
|
@@ -32,8 +32,8 @@ export function getDocumentCreatedByQueryKey({ projectId, originalVersionId, })
|
|
|
32
32
|
* exposed right now, but it is the same for all projects, so no need for
|
|
33
33
|
* scoping the query key to the project
|
|
34
34
|
*/
|
|
35
|
-
export function
|
|
36
|
-
return [ROOT_QUERY_KEY, '
|
|
35
|
+
export function getMediaServerOriginQueryKey() {
|
|
36
|
+
return [ROOT_QUERY_KEY, 'media_server_origin'];
|
|
37
37
|
}
|
|
38
38
|
export function projectsQueryOptions({ clientApi, }) {
|
|
39
39
|
return queryOptions({
|
|
@@ -110,17 +110,17 @@ const FAKE_BLOB_ID = {
|
|
|
110
110
|
name: 'name',
|
|
111
111
|
driveId: 'drive-id',
|
|
112
112
|
};
|
|
113
|
-
export function
|
|
113
|
+
export function mediaServerOriginQueryOptions({ projectApi, }) {
|
|
114
114
|
return queryOptions({
|
|
115
115
|
...baseQueryOptions(),
|
|
116
|
-
// HACK: The server doesn't yet expose a method to get its
|
|
117
|
-
// the existing $blobs.getUrl() to get the
|
|
116
|
+
// HACK: The server doesn't yet expose a method to get its origin, so we use
|
|
117
|
+
// the existing $blobs.getUrl() to get the origin with a fake BlobId. The origin
|
|
118
118
|
// is the same regardless of the blobId, so it's not necessary to include it
|
|
119
119
|
// as a dep for the query key.
|
|
120
|
-
queryKey:
|
|
120
|
+
queryKey: getMediaServerOriginQueryKey(),
|
|
121
121
|
queryFn: async () => {
|
|
122
122
|
const url = await projectApi.$blobs.getUrl(FAKE_BLOB_ID);
|
|
123
|
-
return new URL(url).
|
|
123
|
+
return new URL(url).origin;
|
|
124
124
|
},
|
|
125
125
|
staleTime: 'static',
|
|
126
126
|
gcTime: Infinity,
|
|
@@ -215,6 +215,22 @@ export function updateProjectSettingsMutationOptions({ projectApi, queryClient,
|
|
|
215
215
|
},
|
|
216
216
|
};
|
|
217
217
|
}
|
|
218
|
+
export function changeMemberRoleMutationOptions({ projectApi, projectId, queryClient, }) {
|
|
219
|
+
return {
|
|
220
|
+
...baseMutationOptions(),
|
|
221
|
+
mutationFn: async ({ deviceId, roleId }) => {
|
|
222
|
+
return projectApi.$member.assignRole(deviceId, roleId);
|
|
223
|
+
},
|
|
224
|
+
onSuccess: () => {
|
|
225
|
+
queryClient.invalidateQueries({
|
|
226
|
+
queryKey: getMembersQueryKey({ projectId }),
|
|
227
|
+
});
|
|
228
|
+
queryClient.invalidateQueries({
|
|
229
|
+
queryKey: getProjectRoleQueryKey({ projectId }),
|
|
230
|
+
});
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
}
|
|
218
234
|
export function createBlobMutationOptions({ projectApi, }) {
|
|
219
235
|
return {
|
|
220
236
|
...baseMutationOptions(),
|
package/dist/esm/lib/urls.d.ts
CHANGED
|
@@ -2,11 +2,14 @@ import type { BlobApi, IconApi } from '@comapeo/core';
|
|
|
2
2
|
/**
|
|
3
3
|
* Get a url for a blob based on its BlobId
|
|
4
4
|
*/
|
|
5
|
-
export declare function getBlobUrl(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
export declare function getBlobUrl({ serverOrigin, projectId, blobId, }: {
|
|
6
|
+
serverOrigin: string;
|
|
7
|
+
projectId: string;
|
|
8
|
+
blobId: BlobApi.BlobId;
|
|
9
|
+
}): string;
|
|
10
|
+
export declare function getIconUrl({ serverOrigin, iconId, projectId, mimeBasedOpts, }: {
|
|
11
|
+
serverOrigin: string;
|
|
12
|
+
iconId: string;
|
|
13
|
+
projectId: string;
|
|
14
|
+
mimeBasedOpts: IconApi.BitmapOpts | IconApi.SvgOpts;
|
|
15
|
+
}): string;
|
package/dist/esm/lib/urls.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
// TODO: Move these into a separate "@comapeo/asset-server" module which can
|
|
2
2
|
// export them to be imported directly in a client.
|
|
3
|
+
//
|
|
4
|
+
// NB: The URL construction is fragile right now - it must match the
|
|
5
|
+
// implementation in the @comapeo/core fastify plugins
|
|
6
|
+
// [blobServerPlugin](https://github.com/digidem/comapeo-core/blob/main/src/fastify-plugins/blobs.js)
|
|
7
|
+
// and
|
|
8
|
+
// [iconServerPlugin](https://github.com/digidem/comapeo-core/blob/main/src/fastify-plugins/icons.js)
|
|
3
9
|
const MIME_TO_EXTENSION = {
|
|
4
10
|
'image/png': '.png',
|
|
5
11
|
'image/svg+xml': '.svg',
|
|
@@ -7,34 +13,22 @@ const MIME_TO_EXTENSION = {
|
|
|
7
13
|
/**
|
|
8
14
|
* Get a url for a blob based on its BlobId
|
|
9
15
|
*/
|
|
10
|
-
export function getBlobUrl(
|
|
16
|
+
export function getBlobUrl({ serverOrigin, projectId, blobId, }) {
|
|
11
17
|
const { driveId, type, variant, name } = blobId;
|
|
12
|
-
|
|
13
|
-
baseUrl += '/';
|
|
14
|
-
}
|
|
15
|
-
return baseUrl + `${driveId}/${type}/${variant}/${name}`;
|
|
18
|
+
return `${serverOrigin}/blobs/${projectId}/${driveId}/${type}/${variant}/${name}`;
|
|
16
19
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
*
|
|
21
|
-
* @returns {Promise<string>}
|
|
22
|
-
*/
|
|
23
|
-
export function getIconUrl(baseUrl, iconId, opts) {
|
|
24
|
-
if (!baseUrl.endsWith('/')) {
|
|
25
|
-
baseUrl += '/';
|
|
26
|
-
}
|
|
27
|
-
const mimeExtension = MIME_TO_EXTENSION[opts.mimeType];
|
|
28
|
-
const pixelDensity = opts.mimeType === 'image/svg+xml' ||
|
|
20
|
+
export function getIconUrl({ serverOrigin, iconId, projectId, mimeBasedOpts, }) {
|
|
21
|
+
const mimeExtension = MIME_TO_EXTENSION[mimeBasedOpts.mimeType];
|
|
22
|
+
const pixelDensity = mimeBasedOpts.mimeType === 'image/svg+xml' ||
|
|
29
23
|
// if the pixel density is 1, we can omit the density suffix in the resulting url
|
|
30
24
|
// and assume the pixel density is 1 for applicable mime types when using the url
|
|
31
|
-
|
|
25
|
+
mimeBasedOpts.pixelDensity === 1
|
|
32
26
|
? undefined
|
|
33
|
-
:
|
|
34
|
-
return (
|
|
27
|
+
: mimeBasedOpts.pixelDensity;
|
|
28
|
+
return (`${serverOrigin}/icons/${projectId}/` +
|
|
35
29
|
constructIconPath({
|
|
36
30
|
pixelDensity,
|
|
37
|
-
size:
|
|
31
|
+
size: mimeBasedOpts.size,
|
|
38
32
|
extension: mimeExtension,
|
|
39
33
|
iconId,
|
|
40
34
|
}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@comapeo/core-react",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.0",
|
|
4
4
|
"description": "React wrapper for working with @comapeo/core",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -57,16 +57,16 @@
|
|
|
57
57
|
"types": "tsc"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"@comapeo/core": "^4.
|
|
60
|
+
"@comapeo/core": "^4.3.0",
|
|
61
61
|
"@comapeo/ipc": "^5.0.0",
|
|
62
62
|
"@comapeo/schema": "*",
|
|
63
63
|
"@tanstack/react-query": "^5",
|
|
64
64
|
"react": "^18 || ^19"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
-
"@comapeo/core": "4.
|
|
67
|
+
"@comapeo/core": "4.3.0",
|
|
68
68
|
"@comapeo/ipc": "5.0.0",
|
|
69
|
-
"@comapeo/schema": "2.
|
|
69
|
+
"@comapeo/schema": "2.1.1",
|
|
70
70
|
"@eslint/compat": "1.3.0",
|
|
71
71
|
"@eslint/js": "9.29.0",
|
|
72
72
|
"@ianvs/prettier-plugin-sort-imports": "4.4.2",
|
|
@@ -84,6 +84,7 @@
|
|
|
84
84
|
"eslint-plugin-testing-library": "7.5.3",
|
|
85
85
|
"fastify": "4.29.1",
|
|
86
86
|
"globals": "16.2.0",
|
|
87
|
+
"happy-dom": "18.0.1",
|
|
87
88
|
"husky": "9.1.7",
|
|
88
89
|
"lint-staged": "15.5.1",
|
|
89
90
|
"npm-run-all2": "7.0.2",
|