@raster-app/react 0.1.0-canary-623b3d3 → 0.1.0-canary-58c063f
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/picker-parts.d.ts +10 -1
- package/dist/picker-parts.js +58 -5
- package/dist/picker-parts.js.map +1 -1
- package/dist/raster-picker.js +13 -11
- package/dist/raster-picker.js.map +1 -1
- package/dist/styles.css +28 -15
- package/dist/use-asset-search.js +3 -1
- package/dist/use-asset-search.js.map +1 -1
- package/package.json +4 -3
package/dist/picker-parts.d.ts
CHANGED
|
@@ -14,6 +14,15 @@ export declare function Empty({ glyph, title, text, children, }: {
|
|
|
14
14
|
text: string;
|
|
15
15
|
children?: ReactNode;
|
|
16
16
|
}): import("react").JSX.Element;
|
|
17
|
+
/** Raster's columns for a grid this wide: its window holds a 266px sidebar and 30px padding too. */
|
|
18
|
+
export declare function gridColumns(width: number): number;
|
|
19
|
+
/**
|
|
20
|
+
* Tiles in Raster's grid, a row at a time as the Raster app draws them: only the rows in view,
|
|
21
|
+
* and five either side, are mounted, however many have loaded.
|
|
22
|
+
*/
|
|
23
|
+
export declare function TileGrid({ children }: {
|
|
24
|
+
children: ReactNode;
|
|
25
|
+
}): import("react").JSX.Element;
|
|
17
26
|
/**
|
|
18
27
|
* Raster's grid tile: the picture over its blurred fill, or a checkerboard where it has alpha,
|
|
19
28
|
* with a pill for a badge on the left and one for an action on the right.
|
|
@@ -32,7 +41,7 @@ export declare function Tile({ asset, onOpen, selected, badge, action, }: {
|
|
|
32
41
|
*/
|
|
33
42
|
export declare function Detail({ item, busy, onPick, }: {
|
|
34
43
|
item: Asset | SearchHit | AssetVariant;
|
|
35
|
-
/** While the asset is read in full for the host. */
|
|
44
|
+
/** While the asset is read in full for the host, or a promote has yet to land. */
|
|
36
45
|
busy: boolean;
|
|
37
46
|
onPick?: () => void;
|
|
38
47
|
}): import("react").JSX.Element;
|
package/dist/picker-parts.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
3
|
+
import { Children, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
3
4
|
import { formatDateLong, formatFileSize, formatRelativeTime, getBlurhashPlaceholder, getPreviewUrl, getThumbUrl, isReady, toUserMessage, } from '@raster-app/sdk';
|
|
4
5
|
import { useRasterClient } from './context.js';
|
|
5
6
|
import { Icon } from './icons.js';
|
|
@@ -20,6 +21,54 @@ export function ErrorCard({ error, onError }) {
|
|
|
20
21
|
export function Empty({ glyph, title, text, children, }) {
|
|
21
22
|
return (_jsxs("div", { className: "rs-empty", children: [_jsx("div", { className: "rs-empty-glyph", children: glyph === 'grid' ? _jsx(Icon, { shape: "grid" }) : glyph }), _jsx("h2", { className: "rs-heading", children: title }), _jsx("p", { className: "rs-muted rs-small", children: text }), children] }));
|
|
22
23
|
}
|
|
24
|
+
/** Raster's tile height (`.rs-asset-thumb`) and the gap between its rows. */
|
|
25
|
+
const ROW_HEIGHT = 210 + 30;
|
|
26
|
+
/** The Raster app's columns from its window's width (`calculateGridColumns`). */
|
|
27
|
+
const BREAKPOINTS = [
|
|
28
|
+
[2180, 7],
|
|
29
|
+
[1920, 6],
|
|
30
|
+
[1536, 5],
|
|
31
|
+
[1280, 4],
|
|
32
|
+
[1024, 3],
|
|
33
|
+
[768, 2],
|
|
34
|
+
];
|
|
35
|
+
/** Raster's columns for a grid this wide: its window holds a 266px sidebar and 30px padding too. */
|
|
36
|
+
export function gridColumns(width) {
|
|
37
|
+
const viewport = width + 266 + 2 * 30;
|
|
38
|
+
return BREAKPOINTS.find(([min]) => viewport >= min)?.[1] ?? 1;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Tiles in Raster's grid, a row at a time as the Raster app draws them: only the rows in view,
|
|
42
|
+
* and five either side, are mounted, however many have loaded.
|
|
43
|
+
*/
|
|
44
|
+
export function TileGrid({ children }) {
|
|
45
|
+
const tiles = Children.toArray(children);
|
|
46
|
+
const grid = useRef(null);
|
|
47
|
+
const [width, setWidth] = useState(0);
|
|
48
|
+
useLayoutEffect(() => {
|
|
49
|
+
const node = grid.current;
|
|
50
|
+
if (node === null)
|
|
51
|
+
return;
|
|
52
|
+
setWidth(node.clientWidth);
|
|
53
|
+
if (typeof ResizeObserver === 'undefined')
|
|
54
|
+
return;
|
|
55
|
+
const observer = new ResizeObserver(() => setWidth(node.clientWidth));
|
|
56
|
+
observer.observe(node);
|
|
57
|
+
return () => observer.disconnect();
|
|
58
|
+
}, []);
|
|
59
|
+
const columns = gridColumns(width);
|
|
60
|
+
const rows = useVirtualizer({
|
|
61
|
+
count: Math.ceil(tiles.length / columns),
|
|
62
|
+
getScrollElement: () => grid.current?.closest('.rs-content') ?? null,
|
|
63
|
+
estimateSize: () => ROW_HEIGHT,
|
|
64
|
+
overscan: 5,
|
|
65
|
+
scrollMargin: grid.current?.offsetTop ?? 0,
|
|
66
|
+
});
|
|
67
|
+
return (_jsx("div", { ref: grid, className: "rs-tile-grid", style: { height: rows.getTotalSize() }, children: rows.getVirtualItems().map((row) => (_jsx("div", { className: "rs-grid", style: {
|
|
68
|
+
top: row.start - rows.options.scrollMargin,
|
|
69
|
+
gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
|
|
70
|
+
}, children: tiles.slice(row.index * columns, (row.index + 1) * columns) }, row.key))) }));
|
|
71
|
+
}
|
|
23
72
|
/**
|
|
24
73
|
* Raster's grid tile: the picture over its blurred fill, or a checkerboard where it has alpha,
|
|
25
74
|
* with a pill for a badge on the left and one for an action on the right.
|
|
@@ -28,7 +77,7 @@ export function Tile({ asset, onOpen, selected, badge, action, }) {
|
|
|
28
77
|
const [loaded, setLoaded] = useState(false);
|
|
29
78
|
const ready = isReady(asset);
|
|
30
79
|
const thumb = getThumbUrl(asset);
|
|
31
|
-
const fill =
|
|
80
|
+
const fill = 'blurhash' in asset ? getBlurhashPlaceholder(asset) : null;
|
|
32
81
|
const transparent = 'contentType' in asset && /png|svg|webp|gif/.test(asset.contentType ?? '');
|
|
33
82
|
const size = 'size' in asset ? formatFileSize(asset.size) : '';
|
|
34
83
|
const updated = 'updated' in asset ? formatRelativeTime(asset.updated) : '';
|
|
@@ -56,7 +105,7 @@ export function Detail({ item, busy, onPick, }) {
|
|
|
56
105
|
}
|
|
57
106
|
/** A file on its way into Raster, as the grid shows it until Raster has processed it. */
|
|
58
107
|
export function PendingTile({ name, preview, status, }) {
|
|
59
|
-
return (_jsx("div", { className: "rs-tile", children: _jsxs("div", { className: "rs-asset-thumb", "data-loaded": true, "aria-busy": "true", children: [_jsx("
|
|
108
|
+
return (_jsx("div", { className: "rs-tile", children: _jsxs("div", { className: "rs-asset-thumb", "data-loaded": true, "aria-busy": "true", children: [_jsx("div", { className: "rs-thumb-preview", children: _jsx("img", { src: preview, alt: "" }) }), _jsxs("div", { className: "rs-thumb-meta", children: [_jsx("span", { className: "rs-thumb-title", children: name }), _jsxs("span", { className: "rs-thumb-subtitle", children: [_jsx("span", { className: "rs-spinner" }), status] })] })] }) }));
|
|
60
109
|
}
|
|
61
110
|
/** A control that opens the file chooser, drawn as whatever `className` makes it. */
|
|
62
111
|
export function FilePicker({ className, disabled, focusable = true, onFile, children, }) {
|
|
@@ -100,8 +149,12 @@ export function OrganizationSwitcher({ organizations, current, onIntent, onSelec
|
|
|
100
149
|
return;
|
|
101
150
|
const close = (event) => {
|
|
102
151
|
const outside = event.target instanceof Node && !root.current?.contains(event.target);
|
|
103
|
-
if (event instanceof KeyboardEvent ? event.key
|
|
104
|
-
|
|
152
|
+
if (event instanceof KeyboardEvent ? event.key !== 'Escape' : !outside)
|
|
153
|
+
return;
|
|
154
|
+
// Stopped here, so a host dialog that closes on Escape stays open.
|
|
155
|
+
if (event instanceof KeyboardEvent)
|
|
156
|
+
event.stopPropagation();
|
|
157
|
+
setOpen(false);
|
|
105
158
|
};
|
|
106
159
|
document.addEventListener('mousedown', close);
|
|
107
160
|
document.addEventListener('keydown', close);
|
package/dist/picker-parts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"picker-parts.js","sourceRoot":"","sources":["../src/picker-parts.tsx"],"names":[],"mappings":"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","sourcesContent":["import { type ReactNode, useEffect, useRef, useState } from 'react'\n\nimport {\n\ttype Asset,\n\ttype AssetVariant,\n\ttype Organization,\n\ttype RasterApiError,\n\ttype SearchHit,\n\tformatDateLong,\n\tformatFileSize,\n\tformatRelativeTime,\n\tgetBlurhashPlaceholder,\n\tgetPreviewUrl,\n\tgetThumbUrl,\n\tisReady,\n\ttoUserMessage,\n} from '@raster-app/sdk'\n\nimport { useRasterClient } from './context.js'\nimport { Icon } from './icons.js'\nimport type { PromoteState } from './use-promote-variant.js'\nimport type { UploadState } from './use-asset-upload.js'\n\nexport type ReportError = ((error: RasterApiError) => void) | undefined\n\nexport function Brand() {\n\treturn (\n\t\t<div className=\"rs-brand\">\n\t\t\t<Icon shape=\"raster\" solid width={18} />\n\t\t\tRaster\n\t\t</div>\n\t)\n}\n\n// Strict Mode runs an effect twice in development; the host hears of each error once.\nconst reported = new WeakSet<RasterApiError>()\n\nexport function ErrorCard({ error, onError }: { error: RasterApiError; onError: ReportError }) {\n\tuseEffect(() => {\n\t\tif (reported.has(error)) return\n\t\treported.add(error)\n\t\tonError?.(error)\n\t}, [error, onError])\n\treturn (\n\t\t<p role=\"alert\" className=\"rs-card\">\n\t\t\t{toUserMessage(error)}\n\t\t</p>\n\t)\n}\n\nexport function Empty({\n\tglyph,\n\ttitle,\n\ttext,\n\tchildren,\n}: {\n\tglyph: 'grid' | '∅'\n\ttitle: string\n\ttext: string\n\tchildren?: ReactNode\n}) {\n\treturn (\n\t\t<div className=\"rs-empty\">\n\t\t\t<div className=\"rs-empty-glyph\">{glyph === 'grid' ? <Icon shape=\"grid\" /> : glyph}</div>\n\t\t\t<h2 className=\"rs-heading\">{title}</h2>\n\t\t\t<p className=\"rs-muted rs-small\">{text}</p>\n\t\t\t{children}\n\t\t</div>\n\t)\n}\n\n/**\n * Raster's grid tile: the picture over its blurred fill, or a checkerboard where it has alpha,\n * with a pill for a badge on the left and one for an action on the right.\n */\nexport function Tile({\n\tasset,\n\tonOpen,\n\tselected,\n\tbadge,\n\taction,\n}: {\n\tasset: Asset | SearchHit | AssetVariant\n\tonOpen: () => void\n\t/** Whether this is the version shown large, among an asset's versions. */\n\tselected?: boolean\n\tbadge?: ReactNode\n\taction?: ReactNode\n}) {\n\tconst [loaded, setLoaded] = useState(false)\n\tconst ready = isReady(asset)\n\tconst thumb = getThumbUrl(asset)\n\tconst fill = ('blurhash' in asset ? getBlurhashPlaceholder(asset) : null) ?? thumb\n\tconst transparent = 'contentType' in asset && /png|svg|webp|gif/.test(asset.contentType ?? '')\n\tconst size = 'size' in asset ? formatFileSize(asset.size) : ''\n\tconst updated = 'updated' in asset ? formatRelativeTime(asset.updated) : ''\n\n\treturn (\n\t\t<div className=\"rs-tile\">\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName=\"rs-asset-thumb\"\n\t\t\t\tdata-loaded={loaded || undefined}\n\t\t\t\tdisabled={!ready}\n\t\t\t\taria-pressed={selected}\n\t\t\t\ttitle={\n\t\t\t\t\t'created' in asset && asset.created\n\t\t\t\t\t\t? `Created ${formatDateLong(asset.created)}`\n\t\t\t\t\t\t: undefined\n\t\t\t\t}\n\t\t\t\tonClick={onOpen}\n\t\t\t>\n\t\t\t\t{transparent ? (\n\t\t\t\t\t<div className=\"rs-transparent\" />\n\t\t\t\t) : (\n\t\t\t\t\tfill && <img className=\"rs-thumb-blur\" src={fill} alt=\"\" />\n\t\t\t\t)}\n\t\t\t\t<div className=\"rs-thumb-preview\">\n\t\t\t\t\t{thumb && (\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tkey={thumb}\n\t\t\t\t\t\t\tsrc={thumb}\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\tloading=\"lazy\"\n\t\t\t\t\t\t\tdecoding=\"async\"\n\t\t\t\t\t\t\tonLoad={() => setLoaded(true)}\n\t\t\t\t\t\t\tonError={() => setLoaded(true)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t<div className=\"rs-thumb-meta\">\n\t\t\t\t\t<span className=\"rs-thumb-title\">{asset.name}</span>\n\t\t\t\t\t<span className=\"rs-thumb-subtitle\">\n\t\t\t\t\t\t{!ready && <span>Not ready</span>}\n\t\t\t\t\t\t{ready && size && <span>{size}</span>}\n\t\t\t\t\t\t{ready && updated && <span>{updated}</span>}\n\t\t\t\t\t\t{ready && !size && !updated && asset.width && asset.height && (\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t{asset.width} × {asset.height}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t</button>\n\t\t\t{badge}\n\t\t\t{action}\n\t\t</div>\n\t)\n}\n\n/**\n * An opened asset or variant: the image large, its facts, and what the host can do with it.\n * Raster opens through the host, which reaches the browser from a Figma plugin too.\n */\nexport function Detail({\n\titem,\n\tbusy,\n\tonPick,\n}: {\n\titem: Asset | SearchHit | AssetVariant\n\t/** While the asset is read in full for the host. */\n\tbusy: boolean\n\tonPick?: () => void\n}) {\n\tconst { host } = useRasterClient()\n\tconst image = getPreviewUrl(item)\n\tconst appUrl = item.appUrl\n\tconst facts = [\n\t\titem.width && item.height ? `${item.width} × ${item.height}` : '',\n\t\t'size' in item ? formatFileSize(item.size) : '',\n\t\t'created' in item && item.created ? `Created ${formatDateLong(item.created)}` : '',\n\t].filter((fact) => fact !== '')\n\n\treturn (\n\t\t<div className=\"rs-detail\">\n\t\t\t<div className=\"rs-detail-image\">{image && <img key={image} src={image} alt=\"\" />}</div>\n\t\t\t<div className=\"rs-detail-info\">\n\t\t\t\t<h2 className=\"rs-heading\">{item.name}</h2>\n\t\t\t\t{facts.length > 0 && <p className=\"rs-muted rs-small\">{facts.join(' · ')}</p>}\n\t\t\t\t{onPick && (\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"rs-button rs-button-primary\"\n\t\t\t\t\t\tdisabled={!isReady(item) || busy}\n\t\t\t\t\t\tonClick={onPick}\n\t\t\t\t\t>\n\t\t\t\t\t\tPick asset\n\t\t\t\t\t</button>\n\t\t\t\t)}\n\t\t\t\t{appUrl && (\n\t\t\t\t\t<a\n\t\t\t\t\t\tclassName=\"rs-button rs-button-secondary\"\n\t\t\t\t\t\thref={appUrl}\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\t\thost.openExternal(appUrl)\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon shape=\"link\" width={12.25} />\n\t\t\t\t\t\tOpen in Raster\n\t\t\t\t\t</a>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\n/** A file on its way into Raster, as the grid shows it until Raster has processed it. */\nexport function PendingTile({\n\tname,\n\tpreview,\n\tstatus,\n}: {\n\tname: string\n\tpreview: string\n\tstatus: string\n}) {\n\treturn (\n\t\t<div className=\"rs-tile\">\n\t\t\t<div className=\"rs-asset-thumb\" data-loaded aria-busy=\"true\">\n\t\t\t\t<img className=\"rs-thumb-blur\" src={preview} alt=\"\" />\n\t\t\t\t<div className=\"rs-thumb-preview\">\n\t\t\t\t\t<img src={preview} alt=\"\" />\n\t\t\t\t</div>\n\t\t\t\t<div className=\"rs-thumb-meta\">\n\t\t\t\t\t<span className=\"rs-thumb-title\">{name}</span>\n\t\t\t\t\t<span className=\"rs-thumb-subtitle\">\n\t\t\t\t\t\t<span className=\"rs-spinner\" />\n\t\t\t\t\t\t{status}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\n/** A control that opens the file chooser, drawn as whatever `className` makes it. */\nexport function FilePicker({\n\tclassName,\n\tdisabled,\n\tfocusable = true,\n\tonFile,\n\tchildren,\n}: {\n\tclassName: string\n\tdisabled: boolean\n\tfocusable?: boolean\n\tonFile: (file: File) => void\n\tchildren: ReactNode\n}) {\n\treturn (\n\t\t<label className={className}>\n\t\t\t{children}\n\t\t\t<input\n\t\t\t\tclassName=\"rs-visually-hidden\"\n\t\t\t\ttype=\"file\"\n\t\t\t\tdisabled={disabled}\n\t\t\t\ttabIndex={focusable ? 0 : -1}\n\t\t\t\tonChange={(event) => {\n\t\t\t\t\tconst file = event.target.files?.[0]\n\t\t\t\t\t// Cleared, so picking the same file again uploads it again.\n\t\t\t\t\tevent.target.value = ''\n\t\t\t\t\tif (file) onFile(file)\n\t\t\t\t}}\n\t\t\t/>\n\t\t</label>\n\t)\n}\n\nconst UPLOADS = {\n\tuploading: 'Uploading',\n\tprocessing: 'Processing',\n\tdone: 'Uploaded',\n\t'timed-out': 'Still processing',\n} as const\nconst PROMOTES = {\n\tpromoting: 'Setting as default',\n\tdone: 'Default set',\n\t'timed-out': 'Still setting as default',\n} as const\n\n/** Where an upload and a promote stand, beside the header; each failure shows as an error. */\nexport function Progress({ upload, promote }: { upload: UploadState; promote: PromoteState }) {\n\treturn (\n\t\t<>\n\t\t\t{upload.status !== 'idle' && upload.status !== 'error' && (\n\t\t\t\t<Status status={upload.status} text={UPLOADS[upload.status]} />\n\t\t\t)}\n\t\t\t{promote.status !== 'idle' && promote.status !== 'error' && (\n\t\t\t\t<Status status={promote.status} text={PROMOTES[promote.status]} />\n\t\t\t)}\n\t\t</>\n\t)\n}\n\nfunction Status({ status, text }: { status: string; text: string }) {\n\tlet glyph = <span className=\"rs-spinner\" />\n\tif (status === 'done') glyph = <Icon shape=\"check\" />\n\tif (status === 'timed-out') glyph = <Icon shape=\"info-circle\" />\n\treturn (\n\t\t<span className=\"rs-status\" data-status={status}>\n\t\t\t{glyph}\n\t\t\t{text}\n\t\t</span>\n\t)\n}\n\n/** Raster's organization switcher: the current organization, over a menu of every one. */\nexport function OrganizationSwitcher({\n\torganizations,\n\tcurrent,\n\tonIntent,\n\tonSelect,\n}: {\n\torganizations: Array<Organization>\n\tcurrent: Organization | undefined\n\tonIntent: (organization: Organization) => void\n\tonSelect: (organizationId: string) => void\n}) {\n\tconst [open, setOpen] = useState(false)\n\tconst root = useRef<HTMLDivElement>(null)\n\n\tuseEffect(() => {\n\t\tif (!open) return\n\t\tconst close = (event: MouseEvent | KeyboardEvent) => {\n\t\t\tconst outside = event.target instanceof Node && !root.current?.contains(event.target)\n\t\t\tif (event instanceof KeyboardEvent ? event.key === 'Escape' : outside) setOpen(false)\n\t\t}\n\t\tdocument.addEventListener('mousedown', close)\n\t\tdocument.addEventListener('keydown', close)\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('mousedown', close)\n\t\t\tdocument.removeEventListener('keydown', close)\n\t\t}\n\t}, [open])\n\n\treturn (\n\t\t<div className=\"rs-org\" ref={root}>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName=\"rs-sidebar-item rs-org-trigger\"\n\t\t\t\taria-expanded={open}\n\t\t\t\tonClick={() => setOpen(!open)}\n\t\t\t>\n\t\t\t\t<Avatar name={current?.name ?? current?.id ?? ''} />\n\t\t\t\t<span className=\"rs-library-name\">{current?.name ?? current?.id}</span>\n\t\t\t\t<Icon shape=\"chevron-up-down\" />\n\t\t\t</button>\n\t\t\t{open && (\n\t\t\t\t<div className=\"rs-menu\">\n\t\t\t\t\t<div className=\"rs-menu-heading\">Organizations</div>\n\t\t\t\t\t{organizations.map((organization) => (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tkey={organization.id}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\torganization.id === current?.id ? 'rs-sidebar-item is-active' : 'rs-sidebar-item'\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tonMouseEnter={() => onIntent(organization)}\n\t\t\t\t\t\t\tonFocus={() => onIntent(organization)}\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tsetOpen(false)\n\t\t\t\t\t\t\t\tonSelect(organization.id)\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Avatar name={organization.name ?? organization.id} />\n\t\t\t\t\t\t\t<span className=\"rs-library-name\">{organization.name ?? organization.id}</span>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n\n/** Raster's letter avatar, on a gradient hued from the name as the app hues it. */\nfunction Avatar({ name }: { name: string }) {\n\tif (name === '') return null\n\tlet hex = ''\n\tfor (let index = 0; index < Math.min(name.length, 10); index++) {\n\t\thex += `000${name.charCodeAt(index).toString(16)}`.slice(-4)\n\t}\n\tconst hue = Number.parseInt(hex, 16) % 360\n\treturn (\n\t\t<span\n\t\t\tclassName=\"rs-avatar\"\n\t\t\tstyle={{\n\t\t\t\tbackgroundImage: `linear-gradient(45deg, hsl(${hue}, 70%, 50%), hsl(${(hue + 60) % 360}, 70%, 50%))`,\n\t\t\t}}\n\t\t>\n\t\t\t{name.charAt(0).toUpperCase()}\n\t\t</span>\n\t)\n}\n\n/**\n * The spinner at the end of the grid, which asks for the next page once it is within two rows\n * of view. Keyed by the item count, so it looks again after each page lands.\n */\nexport function Sentinel({ onVisible }: { onVisible: () => void }) {\n\tconst spinner = useRef<HTMLSpanElement>(null)\n\n\tuseEffect(() => {\n\t\tconst node = spinner.current\n\t\tif (node === null || typeof IntersectionObserver === 'undefined') return\n\t\tconst observer = new IntersectionObserver(\n\t\t\t(entries) => {\n\t\t\t\tif (entries.some((entry) => entry.isIntersecting)) onVisible()\n\t\t\t},\n\t\t\t{ root: node.closest('.rs-content'), rootMargin: '0px 0px 360px 0px' }\n\t\t)\n\t\tobserver.observe(node)\n\t\treturn () => observer.disconnect()\n\t}, [onVisible])\n\n\treturn <span ref={spinner} className=\"rs-spinner\" />\n}\n"]}
|
|
1
|
+
{"version":3,"file":"picker-parts.js","sourceRoot":"","sources":["../src/picker-parts.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useVirtualizer } from '@tanstack/react-virtual'\nimport { Children, type ReactNode, useEffect, useLayoutEffect, useRef, useState } from 'react'\n\nimport {\n\ttype Asset,\n\ttype AssetVariant,\n\ttype Organization,\n\ttype RasterApiError,\n\ttype SearchHit,\n\tformatDateLong,\n\tformatFileSize,\n\tformatRelativeTime,\n\tgetBlurhashPlaceholder,\n\tgetPreviewUrl,\n\tgetThumbUrl,\n\tisReady,\n\ttoUserMessage,\n} from '@raster-app/sdk'\n\nimport { useRasterClient } from './context.js'\nimport { Icon } from './icons.js'\nimport type { PromoteState } from './use-promote-variant.js'\nimport type { UploadState } from './use-asset-upload.js'\n\nexport type ReportError = ((error: RasterApiError) => void) | undefined\n\nexport function Brand() {\n\treturn (\n\t\t<div className=\"rs-brand\">\n\t\t\t<Icon shape=\"raster\" solid width={18} />\n\t\t\tRaster\n\t\t</div>\n\t)\n}\n\n// Strict Mode runs an effect twice in development; the host hears of each error once.\nconst reported = new WeakSet<RasterApiError>()\n\nexport function ErrorCard({ error, onError }: { error: RasterApiError; onError: ReportError }) {\n\tuseEffect(() => {\n\t\tif (reported.has(error)) return\n\t\treported.add(error)\n\t\tonError?.(error)\n\t}, [error, onError])\n\treturn (\n\t\t<p role=\"alert\" className=\"rs-card\">\n\t\t\t{toUserMessage(error)}\n\t\t</p>\n\t)\n}\n\nexport function Empty({\n\tglyph,\n\ttitle,\n\ttext,\n\tchildren,\n}: {\n\tglyph: 'grid' | '∅'\n\ttitle: string\n\ttext: string\n\tchildren?: ReactNode\n}) {\n\treturn (\n\t\t<div className=\"rs-empty\">\n\t\t\t<div className=\"rs-empty-glyph\">{glyph === 'grid' ? <Icon shape=\"grid\" /> : glyph}</div>\n\t\t\t<h2 className=\"rs-heading\">{title}</h2>\n\t\t\t<p className=\"rs-muted rs-small\">{text}</p>\n\t\t\t{children}\n\t\t</div>\n\t)\n}\n\n/** Raster's tile height (`.rs-asset-thumb`) and the gap between its rows. */\nconst ROW_HEIGHT = 210 + 30\n\n/** The Raster app's columns from its window's width (`calculateGridColumns`). */\nconst BREAKPOINTS: Array<[number, number]> = [\n\t[2180, 7],\n\t[1920, 6],\n\t[1536, 5],\n\t[1280, 4],\n\t[1024, 3],\n\t[768, 2],\n]\n\n/** Raster's columns for a grid this wide: its window holds a 266px sidebar and 30px padding too. */\nexport function gridColumns(width: number): number {\n\tconst viewport = width + 266 + 2 * 30\n\treturn BREAKPOINTS.find(([min]) => viewport >= min)?.[1] ?? 1\n}\n\n/**\n * Tiles in Raster's grid, a row at a time as the Raster app draws them: only the rows in view,\n * and five either side, are mounted, however many have loaded.\n */\nexport function TileGrid({ children }: { children: ReactNode }) {\n\tconst tiles = Children.toArray(children)\n\tconst grid = useRef<HTMLDivElement>(null)\n\tconst [width, setWidth] = useState(0)\n\n\tuseLayoutEffect(() => {\n\t\tconst node = grid.current\n\t\tif (node === null) return\n\t\tsetWidth(node.clientWidth)\n\t\tif (typeof ResizeObserver === 'undefined') return\n\t\tconst observer = new ResizeObserver(() => setWidth(node.clientWidth))\n\t\tobserver.observe(node)\n\t\treturn () => observer.disconnect()\n\t}, [])\n\n\tconst columns = gridColumns(width)\n\tconst rows = useVirtualizer({\n\t\tcount: Math.ceil(tiles.length / columns),\n\t\tgetScrollElement: () => grid.current?.closest('.rs-content') ?? null,\n\t\testimateSize: () => ROW_HEIGHT,\n\t\toverscan: 5,\n\t\tscrollMargin: grid.current?.offsetTop ?? 0,\n\t})\n\n\treturn (\n\t\t<div ref={grid} className=\"rs-tile-grid\" style={{ height: rows.getTotalSize() }}>\n\t\t\t{rows.getVirtualItems().map((row) => (\n\t\t\t\t<div\n\t\t\t\t\tkey={row.key}\n\t\t\t\t\tclassName=\"rs-grid\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\ttop: row.start - rows.options.scrollMargin,\n\t\t\t\t\t\tgridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{tiles.slice(row.index * columns, (row.index + 1) * columns)}\n\t\t\t\t</div>\n\t\t\t))}\n\t\t</div>\n\t)\n}\n\n/**\n * Raster's grid tile: the picture over its blurred fill, or a checkerboard where it has alpha,\n * with a pill for a badge on the left and one for an action on the right.\n */\nexport function Tile({\n\tasset,\n\tonOpen,\n\tselected,\n\tbadge,\n\taction,\n}: {\n\tasset: Asset | SearchHit | AssetVariant\n\tonOpen: () => void\n\t/** Whether this is the version shown large, among an asset's versions. */\n\tselected?: boolean\n\tbadge?: ReactNode\n\taction?: ReactNode\n}) {\n\tconst [loaded, setLoaded] = useState(false)\n\tconst ready = isReady(asset)\n\tconst thumb = getThumbUrl(asset)\n\tconst fill = 'blurhash' in asset ? getBlurhashPlaceholder(asset) : null\n\tconst transparent = 'contentType' in asset && /png|svg|webp|gif/.test(asset.contentType ?? '')\n\tconst size = 'size' in asset ? formatFileSize(asset.size) : ''\n\tconst updated = 'updated' in asset ? formatRelativeTime(asset.updated) : ''\n\n\treturn (\n\t\t<div className=\"rs-tile\">\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName=\"rs-asset-thumb\"\n\t\t\t\tdata-loaded={loaded || undefined}\n\t\t\t\tdisabled={!ready}\n\t\t\t\taria-pressed={selected}\n\t\t\t\ttitle={\n\t\t\t\t\t'created' in asset && asset.created\n\t\t\t\t\t\t? `Created ${formatDateLong(asset.created)}`\n\t\t\t\t\t\t: undefined\n\t\t\t\t}\n\t\t\t\tonClick={onOpen}\n\t\t\t>\n\t\t\t\t{transparent ? (\n\t\t\t\t\t<div className=\"rs-transparent\" />\n\t\t\t\t) : (\n\t\t\t\t\tfill && <img className=\"rs-thumb-blur\" src={fill} alt=\"\" />\n\t\t\t\t)}\n\t\t\t\t<div className=\"rs-thumb-preview\">\n\t\t\t\t\t{thumb && (\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tkey={thumb}\n\t\t\t\t\t\t\tsrc={thumb}\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\tloading=\"lazy\"\n\t\t\t\t\t\t\tdecoding=\"async\"\n\t\t\t\t\t\t\tonLoad={() => setLoaded(true)}\n\t\t\t\t\t\t\tonError={() => setLoaded(true)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t<div className=\"rs-thumb-meta\">\n\t\t\t\t\t<span className=\"rs-thumb-title\">{asset.name}</span>\n\t\t\t\t\t<span className=\"rs-thumb-subtitle\">\n\t\t\t\t\t\t{!ready && <span>Not ready</span>}\n\t\t\t\t\t\t{ready && size && <span>{size}</span>}\n\t\t\t\t\t\t{ready && updated && <span>{updated}</span>}\n\t\t\t\t\t\t{ready && !size && !updated && asset.width && asset.height && (\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t{asset.width} × {asset.height}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t</button>\n\t\t\t{badge}\n\t\t\t{action}\n\t\t</div>\n\t)\n}\n\n/**\n * An opened asset or variant: the image large, its facts, and what the host can do with it.\n * Raster opens through the host, which reaches the browser from a Figma plugin too.\n */\nexport function Detail({\n\titem,\n\tbusy,\n\tonPick,\n}: {\n\titem: Asset | SearchHit | AssetVariant\n\t/** While the asset is read in full for the host, or a promote has yet to land. */\n\tbusy: boolean\n\tonPick?: () => void\n}) {\n\tconst { host } = useRasterClient()\n\tconst image = getPreviewUrl(item)\n\tconst appUrl = item.appUrl\n\tconst facts = [\n\t\titem.width && item.height ? `${item.width} × ${item.height}` : '',\n\t\t'size' in item ? formatFileSize(item.size) : '',\n\t\t'created' in item && item.created ? `Created ${formatDateLong(item.created)}` : '',\n\t].filter((fact) => fact !== '')\n\n\treturn (\n\t\t<div className=\"rs-detail\">\n\t\t\t<div className=\"rs-detail-image\">{image && <img key={image} src={image} alt=\"\" />}</div>\n\t\t\t<div className=\"rs-detail-info\">\n\t\t\t\t<h2 className=\"rs-heading\">{item.name}</h2>\n\t\t\t\t{facts.length > 0 && <p className=\"rs-muted rs-small\">{facts.join(' · ')}</p>}\n\t\t\t\t{onPick && (\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"rs-button rs-button-primary\"\n\t\t\t\t\t\tdisabled={!isReady(item) || busy}\n\t\t\t\t\t\tonClick={onPick}\n\t\t\t\t\t>\n\t\t\t\t\t\tPick asset\n\t\t\t\t\t</button>\n\t\t\t\t)}\n\t\t\t\t{appUrl && (\n\t\t\t\t\t<a\n\t\t\t\t\t\tclassName=\"rs-button rs-button-secondary\"\n\t\t\t\t\t\thref={appUrl}\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\t\thost.openExternal(appUrl)\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon shape=\"link\" width={12.25} />\n\t\t\t\t\t\tOpen in Raster\n\t\t\t\t\t</a>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\n/** A file on its way into Raster, as the grid shows it until Raster has processed it. */\nexport function PendingTile({\n\tname,\n\tpreview,\n\tstatus,\n}: {\n\tname: string\n\tpreview: string\n\tstatus: string\n}) {\n\treturn (\n\t\t<div className=\"rs-tile\">\n\t\t\t<div className=\"rs-asset-thumb\" data-loaded aria-busy=\"true\">\n\t\t\t\t<div className=\"rs-thumb-preview\">\n\t\t\t\t\t<img src={preview} alt=\"\" />\n\t\t\t\t</div>\n\t\t\t\t<div className=\"rs-thumb-meta\">\n\t\t\t\t\t<span className=\"rs-thumb-title\">{name}</span>\n\t\t\t\t\t<span className=\"rs-thumb-subtitle\">\n\t\t\t\t\t\t<span className=\"rs-spinner\" />\n\t\t\t\t\t\t{status}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\n/** A control that opens the file chooser, drawn as whatever `className` makes it. */\nexport function FilePicker({\n\tclassName,\n\tdisabled,\n\tfocusable = true,\n\tonFile,\n\tchildren,\n}: {\n\tclassName: string\n\tdisabled: boolean\n\tfocusable?: boolean\n\tonFile: (file: File) => void\n\tchildren: ReactNode\n}) {\n\treturn (\n\t\t<label className={className}>\n\t\t\t{children}\n\t\t\t<input\n\t\t\t\tclassName=\"rs-visually-hidden\"\n\t\t\t\ttype=\"file\"\n\t\t\t\tdisabled={disabled}\n\t\t\t\ttabIndex={focusable ? 0 : -1}\n\t\t\t\tonChange={(event) => {\n\t\t\t\t\tconst file = event.target.files?.[0]\n\t\t\t\t\t// Cleared, so picking the same file again uploads it again.\n\t\t\t\t\tevent.target.value = ''\n\t\t\t\t\tif (file) onFile(file)\n\t\t\t\t}}\n\t\t\t/>\n\t\t</label>\n\t)\n}\n\nconst UPLOADS = {\n\tuploading: 'Uploading',\n\tprocessing: 'Processing',\n\tdone: 'Uploaded',\n\t'timed-out': 'Still processing',\n} as const\nconst PROMOTES = {\n\tpromoting: 'Setting as default',\n\tdone: 'Default set',\n\t'timed-out': 'Still setting as default',\n} as const\n\n/** Where an upload and a promote stand, beside the header; each failure shows as an error. */\nexport function Progress({ upload, promote }: { upload: UploadState; promote: PromoteState }) {\n\treturn (\n\t\t<>\n\t\t\t{upload.status !== 'idle' && upload.status !== 'error' && (\n\t\t\t\t<Status status={upload.status} text={UPLOADS[upload.status]} />\n\t\t\t)}\n\t\t\t{promote.status !== 'idle' && promote.status !== 'error' && (\n\t\t\t\t<Status status={promote.status} text={PROMOTES[promote.status]} />\n\t\t\t)}\n\t\t</>\n\t)\n}\n\nfunction Status({ status, text }: { status: string; text: string }) {\n\tlet glyph = <span className=\"rs-spinner\" />\n\tif (status === 'done') glyph = <Icon shape=\"check\" />\n\tif (status === 'timed-out') glyph = <Icon shape=\"info-circle\" />\n\treturn (\n\t\t<span className=\"rs-status\" data-status={status}>\n\t\t\t{glyph}\n\t\t\t{text}\n\t\t</span>\n\t)\n}\n\n/** Raster's organization switcher: the current organization, over a menu of every one. */\nexport function OrganizationSwitcher({\n\torganizations,\n\tcurrent,\n\tonIntent,\n\tonSelect,\n}: {\n\torganizations: Array<Organization>\n\tcurrent: Organization | undefined\n\tonIntent: (organization: Organization) => void\n\tonSelect: (organizationId: string) => void\n}) {\n\tconst [open, setOpen] = useState(false)\n\tconst root = useRef<HTMLDivElement>(null)\n\n\tuseEffect(() => {\n\t\tif (!open) return\n\t\tconst close = (event: MouseEvent | KeyboardEvent) => {\n\t\t\tconst outside = event.target instanceof Node && !root.current?.contains(event.target)\n\t\t\tif (event instanceof KeyboardEvent ? event.key !== 'Escape' : !outside) return\n\t\t\t// Stopped here, so a host dialog that closes on Escape stays open.\n\t\t\tif (event instanceof KeyboardEvent) event.stopPropagation()\n\t\t\tsetOpen(false)\n\t\t}\n\t\tdocument.addEventListener('mousedown', close)\n\t\tdocument.addEventListener('keydown', close)\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('mousedown', close)\n\t\t\tdocument.removeEventListener('keydown', close)\n\t\t}\n\t}, [open])\n\n\treturn (\n\t\t<div className=\"rs-org\" ref={root}>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName=\"rs-sidebar-item rs-org-trigger\"\n\t\t\t\taria-expanded={open}\n\t\t\t\tonClick={() => setOpen(!open)}\n\t\t\t>\n\t\t\t\t<Avatar name={current?.name ?? current?.id ?? ''} />\n\t\t\t\t<span className=\"rs-library-name\">{current?.name ?? current?.id}</span>\n\t\t\t\t<Icon shape=\"chevron-up-down\" />\n\t\t\t</button>\n\t\t\t{open && (\n\t\t\t\t<div className=\"rs-menu\">\n\t\t\t\t\t<div className=\"rs-menu-heading\">Organizations</div>\n\t\t\t\t\t{organizations.map((organization) => (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tkey={organization.id}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\torganization.id === current?.id ? 'rs-sidebar-item is-active' : 'rs-sidebar-item'\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tonMouseEnter={() => onIntent(organization)}\n\t\t\t\t\t\t\tonFocus={() => onIntent(organization)}\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tsetOpen(false)\n\t\t\t\t\t\t\t\tonSelect(organization.id)\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Avatar name={organization.name ?? organization.id} />\n\t\t\t\t\t\t\t<span className=\"rs-library-name\">{organization.name ?? organization.id}</span>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n\n/** Raster's letter avatar, on a gradient hued from the name as the app hues it. */\nfunction Avatar({ name }: { name: string }) {\n\tif (name === '') return null\n\tlet hex = ''\n\tfor (let index = 0; index < Math.min(name.length, 10); index++) {\n\t\thex += `000${name.charCodeAt(index).toString(16)}`.slice(-4)\n\t}\n\tconst hue = Number.parseInt(hex, 16) % 360\n\treturn (\n\t\t<span\n\t\t\tclassName=\"rs-avatar\"\n\t\t\tstyle={{\n\t\t\t\tbackgroundImage: `linear-gradient(45deg, hsl(${hue}, 70%, 50%), hsl(${(hue + 60) % 360}, 70%, 50%))`,\n\t\t\t}}\n\t\t>\n\t\t\t{name.charAt(0).toUpperCase()}\n\t\t</span>\n\t)\n}\n\n/**\n * The spinner at the end of the grid, which asks for the next page once it is within two rows\n * of view. Keyed by the item count, so it looks again after each page lands.\n */\nexport function Sentinel({ onVisible }: { onVisible: () => void }) {\n\tconst spinner = useRef<HTMLSpanElement>(null)\n\n\tuseEffect(() => {\n\t\tconst node = spinner.current\n\t\tif (node === null || typeof IntersectionObserver === 'undefined') return\n\t\tconst observer = new IntersectionObserver(\n\t\t\t(entries) => {\n\t\t\t\tif (entries.some((entry) => entry.isIntersecting)) onVisible()\n\t\t\t},\n\t\t\t{ root: node.closest('.rs-content'), rootMargin: '0px 0px 360px 0px' }\n\t\t)\n\t\tobserver.observe(node)\n\t\treturn () => observer.disconnect()\n\t}, [onVisible])\n\n\treturn <span ref={spinner} className=\"rs-spinner\" />\n}\n"]}
|
package/dist/raster-picker.js
CHANGED
|
@@ -4,7 +4,7 @@ import { useRef, useState } from 'react';
|
|
|
4
4
|
import { isReady, } from '@raster-app/sdk';
|
|
5
5
|
import { useRasterClient } from './context.js';
|
|
6
6
|
import { Icon } from './icons.js';
|
|
7
|
-
import { Brand, Detail, Empty, ErrorCard, FilePicker, OrganizationSwitcher, PendingTile, Progress, Sentinel, Tile, } from './picker-parts.js';
|
|
7
|
+
import { Brand, Detail, Empty, ErrorCard, FilePicker, OrganizationSwitcher, PendingTile, Progress, Sentinel, Tile, TileGrid, } from './picker-parts.js';
|
|
8
8
|
import { SignIn } from './picker-sign-in.js';
|
|
9
9
|
import { useAssetSearch } from './use-asset-search.js';
|
|
10
10
|
import { useAssetUpload } from './use-asset-upload.js';
|
|
@@ -69,6 +69,8 @@ function Browser({ onPick, onError, }) {
|
|
|
69
69
|
const shown = search.active ? search : library === null ? null : assets;
|
|
70
70
|
const items = search.active ? search.hits : assets.assets;
|
|
71
71
|
const hit = search.active ? (search.hits?.find((entry) => entry.id === focusId) ?? null) : null;
|
|
72
|
+
// Until a promote lands, the cached asset is still the previous default.
|
|
73
|
+
const busy = read.isPending || promote.state.status === 'promoting';
|
|
72
74
|
/** Hand the host the whole asset: a search hit or a variant carries less, so it is read first. */
|
|
73
75
|
function pick(item) {
|
|
74
76
|
if (organizationId === null || onPick === undefined)
|
|
@@ -86,14 +88,14 @@ function Browser({ onPick, onError, }) {
|
|
|
86
88
|
}
|
|
87
89
|
/** Upload one file into the open library, or as a variant of `parentId`. */
|
|
88
90
|
async function send(file, parentId) {
|
|
89
|
-
|
|
91
|
+
// A second upload would cancel the one in flight.
|
|
92
|
+
if (organizationId === null || library === null || !writable || pending !== null)
|
|
90
93
|
return;
|
|
91
94
|
const preview = URL.createObjectURL(file);
|
|
92
95
|
setPending({ name: file.name, preview, parentId });
|
|
93
96
|
await upload.upload({ organizationId, libraryId: library.id, parentId, source: file });
|
|
94
97
|
URL.revokeObjectURL(preview);
|
|
95
|
-
|
|
96
|
-
setPending((current) => (current?.preview === preview ? null : current));
|
|
98
|
+
setPending(null);
|
|
97
99
|
}
|
|
98
100
|
/** The first press asks to confirm; the second promotes. */
|
|
99
101
|
function setDefault(variant) {
|
|
@@ -124,23 +126,23 @@ function Browser({ onPick, onError, }) {
|
|
|
124
126
|
if (versions) {
|
|
125
127
|
const focused = [opened, ...variants].find((entry) => entry.id === focusId) ?? opened;
|
|
126
128
|
heading = (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "rs-crumb", onClick: () => navigation.openAsset(null), children: library?.name }), _jsx("span", { className: "rs-muted", children: "/" }), _jsx("h1", { className: "rs-heading", children: opened.name }), _jsxs("span", { className: "rs-sidebar-count is-active", children: [variants.length + 1, " versions"] })] }));
|
|
127
|
-
content = (_jsxs(_Fragment, { children: [_jsx(Detail, { item: focused, busy:
|
|
129
|
+
content = (_jsxs(_Fragment, { children: [_jsx(Detail, { item: focused, busy: busy, onPick: onPick && (() => pick(focused)) }), _jsxs(TileGrid, { children: [_jsx(Tile, { asset: opened, selected: focused.id === opened.id, onOpen: () => setFocus({ scope, id: opened.id }), badge: _jsxs("span", { className: "rs-pill rs-tile-badge", children: [_jsx(Icon, { shape: "star", solid: true, width: 10.5 }), "Default"] }) }), variants.map((variant) => (_jsx(Tile, { asset: variant, selected: focused.id === variant.id, onOpen: () => setFocus({ scope, id: variant.id }), action: writable &&
|
|
128
130
|
isReady(variant) && (_jsxs("button", { type: "button", className: confirming === variant.id
|
|
129
131
|
? 'rs-pill rs-tile-action is-confirming'
|
|
130
132
|
: 'rs-pill rs-tile-action', disabled: promote.state.status === 'promoting', onClick: () => setDefault(variant), children: [_jsx(Icon, { shape: "star", width: 10.5 }), confirming === variant.id ? 'Confirm' : 'Set as default'] })) }, variant.id))), pendingTile] })] }));
|
|
131
133
|
}
|
|
132
134
|
else if (hit) {
|
|
133
135
|
heading = (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "rs-crumb", onClick: () => setFocus(null), children: "Search" }), _jsx("span", { className: "rs-muted", children: "/" }), _jsx("h1", { className: "rs-heading", children: hit.name })] }));
|
|
134
|
-
content = _jsx(Detail, { item: hit, busy:
|
|
136
|
+
content = _jsx(Detail, { item: hit, busy: busy, onPick: onPick && (() => pick(hit)) });
|
|
135
137
|
}
|
|
136
138
|
else if (shown === null ? organizations.isLoading || libraries.isLoading : items === null) {
|
|
137
139
|
content = shown?.error ? null : (_jsx("div", { className: "rs-center", children: _jsx("span", { className: "rs-spinner" }) }));
|
|
138
140
|
}
|
|
139
141
|
else if (shown !== null && items?.length === 0 && !pendingTile) {
|
|
140
|
-
content = search.active ? (_jsx(Empty, { glyph: "\u2205", title: "No results", text: `Nothing matches “${search.query}”.` })) : (_jsx(Empty, { glyph: "\u2205", title: "No assets", text: "This library is empty.", children: writable && library !== null && (_jsx(FilePicker, { className: "rs-button rs-button-primary rs-button-sm", disabled:
|
|
142
|
+
content = search.active ? (_jsx(Empty, { glyph: "\u2205", title: "No results", text: `Nothing matches “${search.query}”.` })) : (_jsx(Empty, { glyph: "\u2205", title: "No assets", text: "This library is empty.", children: writable && library !== null && (_jsx(FilePicker, { className: "rs-button rs-button-primary rs-button-sm", disabled: pending !== null, onFile: (file) => void send(file, null), children: "Upload files" })) }));
|
|
141
143
|
}
|
|
142
144
|
else if (shown !== null && items) {
|
|
143
|
-
content = (_jsxs(_Fragment, { children: [_jsxs(
|
|
145
|
+
content = (_jsxs(_Fragment, { children: [_jsxs(TileGrid, { children: [pendingTile, search.active
|
|
144
146
|
? search.hits?.map((entry) => (_jsx(Tile, { asset: entry, onOpen: () => setFocus({ scope, id: entry.id }) }, entry.id)))
|
|
145
147
|
: assets.assets?.map((asset) => {
|
|
146
148
|
const count = asset.variants?.filter(Boolean).length ?? 0;
|
|
@@ -160,12 +162,12 @@ function Browser({ onPick, onError, }) {
|
|
|
160
162
|
};
|
|
161
163
|
return (_jsxs("div", { className: open ? 'rs-library is-expanded' : 'rs-library', children: [_jsxs("button", { type: "button", className: "rs-sidebar-item rs-library-row", disabled: entry.access === null, onMouseEnter: warm, onFocus: warm, onClick: () => navigation.openLibrary(entry), children: [_jsx(Icon, { shape: "grid" }), _jsx("span", { className: "rs-library-name", children: entry.name }), _jsx("span", { className: open ? 'rs-sidebar-count is-active' : 'rs-sidebar-count', children: COUNT.format(entry.assetsCount ?? 0) })] }), _jsx("div", { className: open ? 'rs-library-menu is-expanded' : 'rs-library-menu', "aria-hidden": !open, children: _jsxs("div", { children: [_jsxs("button", { type: "button", tabIndex: open ? 0 : -1, className: open && !search.active && opened === null
|
|
162
164
|
? 'rs-sidebar-item is-active'
|
|
163
|
-
: 'rs-sidebar-item', onClick: toGrid, children: [_jsx(Icon, { shape: "circle" }), "All Assets"] }), _jsxs(FilePicker, { className: "rs-sidebar-item", disabled: !open || entry.access !== 'write', focusable: open, onFile: (file) => {
|
|
165
|
+
: 'rs-sidebar-item', onClick: toGrid, children: [_jsx(Icon, { shape: "circle" }), "All Assets"] }), _jsxs(FilePicker, { className: "rs-sidebar-item", disabled: !open || entry.access !== 'write' || pending !== null, focusable: open, onFile: (file) => {
|
|
164
166
|
toGrid();
|
|
165
167
|
void send(file, null);
|
|
166
168
|
}, children: [_jsx(Icon, { shape: "upload" }), "Upload"] })] }) })] }, entry.id));
|
|
167
169
|
})] }), _jsxs("div", { className: "rs-sidebar-footer", children: [_jsx("span", { className: "rs-sidebar-item rs-muted", children: session.isSignedIn ? (session.userName ?? 'Signed in') : 'API key' }), _jsx("button", { type: "button", className: "rs-sidebar-item", onClick: () => void session.signOut(), children: "Sign out" })] })] }), _jsxs("section", { className: "rs-main", "aria-label": "Assets", onDragEnter: (event) => {
|
|
168
|
-
if (!dropTarget || !event.dataTransfer.types.includes('Files'))
|
|
170
|
+
if (!dropTarget || pending !== null || !event.dataTransfer.types.includes('Files'))
|
|
169
171
|
return;
|
|
170
172
|
dragDepth.current += 1;
|
|
171
173
|
setDragging(true);
|
|
@@ -183,6 +185,6 @@ function Browser({ onPick, onError, }) {
|
|
|
183
185
|
const file = event.dataTransfer.files[0];
|
|
184
186
|
if (file && dropTarget)
|
|
185
187
|
void send(file, versions ? opened.id : null);
|
|
186
|
-
}, children: [_jsxs("header", { className: "rs-header", children: [heading, _jsx("span", { className: "rs-muted rs-small", children: status }), _jsx(Progress, { upload: upload.state, promote: promote.state }), _jsxs("div", { className: "rs-search", children: [_jsx(Icon, { shape: "search", width: 12.25 }), _jsx("input", { ref: searchInput, className: "rs-input", "aria-label": "Search Raster", placeholder: library === null ? 'Search every library…' : `Search ${library.name}…`, value: query, onChange: (event) => navigation.setQuery(event.target.value) }), query !== '' && (_jsx("button", { type: "button", className: "rs-icon-button", "aria-label": "Clear search", onClick: () => navigation.setQuery(''), children: _jsx(Icon, { shape: "x", width: 10.5 }) }))] }), versions && writable && (_jsxs(FilePicker, { className: "rs-button rs-button-sm", disabled:
|
|
188
|
+
}, children: [_jsxs("header", { className: "rs-header", children: [heading, _jsx("span", { className: "rs-muted rs-small", children: status }), _jsx(Progress, { upload: upload.state, promote: promote.state }), _jsxs("div", { className: "rs-search", children: [_jsx(Icon, { shape: "search", width: 12.25 }), _jsx("input", { ref: searchInput, className: "rs-input", "aria-label": "Search Raster", placeholder: library === null ? 'Search every library…' : `Search ${library.name}…`, value: query, onChange: (event) => navigation.setQuery(event.target.value) }), query !== '' && (_jsx("button", { type: "button", className: "rs-icon-button", "aria-label": "Clear search", onClick: () => navigation.setQuery(''), children: _jsx(Icon, { shape: "x", width: 10.5 }) }))] }), versions && writable && (_jsxs(FilePicker, { className: "rs-button rs-button-sm", disabled: pending !== null, onFile: (file) => void send(file, opened.id), children: [_jsx(Icon, { shape: "upload", width: 12.25 }), "Upload variant"] })), _jsx("button", { type: "button", className: "rs-button rs-button-sm", onClick: navigation.refresh, children: "Refresh" })] }), _jsxs("div", { className: "rs-content", children: [organizations.error && _jsx(ErrorCard, { error: organizations.error, onError: onError }), libraries.error && _jsx(ErrorCard, { error: libraries.error, onError: onError }), shown?.error && _jsx(ErrorCard, { error: shown.error, onError: onError }), read.error && _jsx(ErrorCard, { error: read.error, onError: onError }), upload.state.status === 'error' && (_jsx(ErrorCard, { error: upload.state.error, onError: onError })), promote.state.status === 'error' && (_jsx(ErrorCard, { error: promote.state.error, onError: onError })), content] }), _jsx("div", { className: dragging ? 'rs-drop is-active' : 'rs-drop' })] })] }));
|
|
187
189
|
}
|
|
188
190
|
//# sourceMappingURL=raster-picker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raster-picker.js","sourceRoot":"","sources":["../src/raster-picker.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMutation } from '@tanstack/react-query'\nimport { type ReactNode, useRef, useState } from 'react'\n\nimport {\n\ttype Asset,\n\ttype AssetVariant,\n\ttype RasterApiError,\n\ttype SearchHit,\n\tisReady,\n} from '@raster-app/sdk'\n\nimport { useRasterClient } from './context.js'\nimport { Icon } from './icons.js'\nimport {\n\tBrand,\n\tDetail,\n\tEmpty,\n\tErrorCard,\n\tFilePicker,\n\tOrganizationSwitcher,\n\tPendingTile,\n\tProgress,\n\ttype ReportError,\n\tSentinel,\n\tTile,\n} from './picker-parts.js'\nimport { SignIn } from './picker-sign-in.js'\nimport { useAssetSearch } from './use-asset-search.js'\nimport { useAssetUpload } from './use-asset-upload.js'\nimport { useAssets, usePrefetchAssets } from './use-assets.js'\nimport { useLibraries, usePrefetchLibraries } from './use-libraries.js'\nimport { useRasterNavigation } from './use-navigation.js'\nimport { useOrganizations } from './use-organizations.js'\nimport { usePromoteVariant } from './use-promote-variant.js'\nimport { useSession } from './use-session.js'\n\nexport type RasterPickerProps = {\n\t/**\n\t * The picked asset, whole whether it came from a library, a search or an asset's versions, and\n\t * its organization. `getFullSizeUrl(asset)` is the image. Without it, the picker only browses,\n\t * with no Pick asset button.\n\t */\n\tonPick?: (asset: Asset, organizationId: string) => void\n\t/** Binds the device sign-in to this organization; any other grant fails. */\n\torganizationId?: string\n\t/** The consent the device sign-in asks for: `org` when `organizationId` is set, else `user`. */\n\tscope?: 'user' | 'org'\n\t/** Each failure the picker shows, once, for the host to log. */\n\tonError?: (error: RasterApiError) => void\n\t/** Follows the system's color scheme when unset. */\n\ttheme?: 'light' | 'dark'\n}\n\nconst COUNT = new Intl.NumberFormat('en-US', { notation: 'compact' })\n\n/** A file on its way in, which the grid shows until Raster has processed it. */\ntype Pending = { name: string; preview: string; parentId: string | null }\n\n/**\n * Raster's asset picker, drawn as Raster draws it (`@raster-app/react/styles.css`): sign-in, the\n * organization's libraries, search and uploads. A tile opens its asset large, to pick or open in\n * Raster, over its versions with the default to set. It fills its container, inside a\n * `RasterProvider`.\n */\nexport function RasterPicker({ onPick, organizationId, scope, onError, theme }: RasterPickerProps) {\n\tconst { credentials, isConfigured } = useSession()\n\n\tlet body = (\n\t\t<div className=\"rs-center\">\n\t\t\t<span className=\"rs-spinner\" />\n\t\t</div>\n\t)\n\tif (credentials !== undefined && !isConfigured) {\n\t\tbody = (\n\t\t\t<SignIn\n\t\t\t\torganizationId={organizationId}\n\t\t\t\tscope={scope ?? (organizationId === undefined ? 'user' : 'org')}\n\t\t\t\tonError={onError}\n\t\t\t/>\n\t\t)\n\t} else if (isConfigured) {\n\t\tbody = <Browser onPick={onPick} onError={onError} />\n\t}\n\treturn (\n\t\t<div className=\"rs rs-picker\" data-theme={theme}>\n\t\t\t{body}\n\t\t</div>\n\t)\n}\n\nfunction Browser({\n\tonPick,\n\tonError,\n}: {\n\tonPick: RasterPickerProps['onPick']\n\tonError: ReportError\n}) {\n\tconst client = useRasterClient()\n\tconst session = useSession()\n\tconst organizations = useOrganizations()\n\tconst navigation = useRasterNavigation({ organizations: organizations.data ?? null })\n\tconst { organizationId, library, query } = navigation\n\tconst organization = organizations.data?.find((entry) => entry.id === organizationId)\n\tconst libraries = useLibraries({ organizationId, organizationName: organization?.name ?? null })\n\tconst assets = useAssets({ organizationId, libraryId: library?.id ?? null })\n\tconst search = useAssetSearch(\n\t\torganizationId === null ? null : { organizationId, libraryId: library?.id ?? null },\n\t\tquery\n\t)\n\tconst upload = useAssetUpload()\n\tconst promote = usePromoteVariant()\n\tconst read = useMutation<Asset, RasterApiError, Parameters<typeof client.assets.get>[0]>({\n\t\tmutationFn: (options) => client.assets.get(options),\n\t})\n\tconst prefetchAssets = usePrefetchAssets()\n\tconst prefetchLibraries = usePrefetchLibraries()\n\tconst searchInput = useRef<HTMLInputElement>(null)\n\tconst [pending, setPending] = useState<Pending | null>(null)\n\tconst [confirming, setConfirming] = useState<string | null>(null)\n\tconst [dragging, setDragging] = useState(false)\n\tconst dragDepth = useRef(0)\n\t// The version shown large, or the search hit opened, for the scope it was chosen in.\n\tconst [focus, setFocus] = useState<{ scope: string; id: string } | null>(null)\n\tconst scope = [organizationId, library?.id, navigation.asset?.id, query].join('/')\n\tconst focusId = focus?.scope === scope ? focus.id : null\n\n\tconst access = libraries.data?.find((entry) => entry.id === library?.id)?.access ?? null\n\tconst writable = access === 'write'\n\t// The asset as the list last read it, which refetches after an upload or a promote.\n\tconst opened =\n\t\tnavigation.asset === null\n\t\t\t? null\n\t\t\t: (assets.assets?.find((entry) => entry.id === navigation.asset?.id) ?? navigation.asset)\n\tconst versions = !search.active && opened !== null\n\tconst variants = (opened?.variants ?? []).filter(\n\t\t(variant): variant is AssetVariant => variant !== null\n\t)\n\tconst shown = search.active ? search : library === null ? null : assets\n\tconst items = search.active ? search.hits : assets.assets\n\tconst hit = search.active ? (search.hits?.find((entry) => entry.id === focusId) ?? null) : null\n\n\t/** Hand the host the whole asset: a search hit or a variant carries less, so it is read first. */\n\tfunction pick(item: Asset | SearchHit | AssetVariant) {\n\t\tif (organizationId === null || onPick === undefined) return\n\t\tconst loaded = assets.assets?.find((entry) => entry.id === item.id)\n\t\tif (loaded) {\n\t\t\tonPick(loaded, organizationId)\n\t\t\treturn\n\t\t}\n\t\t// A variant lives in its original's library, which is the open one.\n\t\tconst libraryId = ('libraryId' in item ? item.libraryId : null) ?? library?.id\n\t\tif (!libraryId) return\n\t\tread.mutate(\n\t\t\t{ organizationId, libraryId, assetId: item.id },\n\t\t\t{ onSuccess: (asset) => onPick(asset, organizationId) }\n\t\t)\n\t}\n\n\t/** Upload one file into the open library, or as a variant of `parentId`. */\n\tasync function send(file: File, parentId: string | null) {\n\t\tif (organizationId === null || library === null || !writable) return\n\t\tconst preview = URL.createObjectURL(file)\n\t\tsetPending({ name: file.name, preview, parentId })\n\t\tawait upload.upload({ organizationId, libraryId: library.id, parentId, source: file })\n\t\tURL.revokeObjectURL(preview)\n\t\t// A later upload may have taken the placeholder over by now.\n\t\tsetPending((current) => (current?.preview === preview ? null : current))\n\t}\n\n\t/** The first press asks to confirm; the second promotes. */\n\tfunction setDefault(variant: AssetVariant) {\n\t\tif (confirming !== variant.id) {\n\t\t\tsetConfirming(variant.id)\n\t\t\treturn\n\t\t}\n\t\tsetConfirming(null)\n\t\tif (organizationId === null || library === null || opened === null) return\n\t\tvoid promote.promote({\n\t\t\torganizationId,\n\t\t\tlibraryId: library.id,\n\t\t\tassetId: opened.id,\n\t\t\tvariantId: variant.id,\n\t\t})\n\t}\n\n\tconst pendingTile = pending !== null &&\n\t\t!search.active &&\n\t\tpending.parentId === (opened?.id ?? null) && (\n\t\t\t<PendingTile\n\t\t\t\tname={pending.name}\n\t\t\t\tpreview={pending.preview}\n\t\t\t\tstatus={upload.state.status === 'uploading' ? 'Uploading' : 'Processing'}\n\t\t\t/>\n\t\t)\n\n\tlet status = ''\n\tif (search.active) status = search.isSearching ? 'Searching' : `${search.found} found`\n\telse if (library !== null && !versions) status = `${assets.assets?.length ?? 0} loaded`\n\n\tlet heading: ReactNode = (\n\t\t<>\n\t\t\t<h1 className=\"rs-heading\">{search.active ? 'Search' : (library?.name ?? 'Libraries')}</h1>\n\t\t\t{!search.active && library !== null && (\n\t\t\t\t<span className=\"rs-sidebar-count is-active\">{access ?? 'no access'}</span>\n\t\t\t)}\n\t\t</>\n\t)\n\tlet content: ReactNode = (\n\t\t<Empty glyph=\"grid\" title=\"Choose a library\" text=\"Or search every library.\" />\n\t)\n\tif (versions) {\n\t\tconst focused = [opened, ...variants].find((entry) => entry.id === focusId) ?? opened\n\t\theading = (\n\t\t\t<>\n\t\t\t\t<button type=\"button\" className=\"rs-crumb\" onClick={() => navigation.openAsset(null)}>\n\t\t\t\t\t{library?.name}\n\t\t\t\t</button>\n\t\t\t\t<span className=\"rs-muted\">/</span>\n\t\t\t\t<h1 className=\"rs-heading\">{opened.name}</h1>\n\t\t\t\t<span className=\"rs-sidebar-count is-active\">{variants.length + 1} versions</span>\n\t\t\t</>\n\t\t)\n\t\tcontent = (\n\t\t\t<>\n\t\t\t\t<Detail item={focused} busy={read.isPending} onPick={onPick && (() => pick(focused))} />\n\t\t\t\t<div className=\"rs-grid\">\n\t\t\t\t\t<Tile\n\t\t\t\t\t\tasset={opened}\n\t\t\t\t\t\tselected={focused.id === opened.id}\n\t\t\t\t\t\tonOpen={() => setFocus({ scope, id: opened.id })}\n\t\t\t\t\t\tbadge={\n\t\t\t\t\t\t\t<span className=\"rs-pill rs-tile-badge\">\n\t\t\t\t\t\t\t\t<Icon shape=\"star\" solid width={10.5} />\n\t\t\t\t\t\t\t\tDefault\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t\t{variants.map((variant) => (\n\t\t\t\t\t\t<Tile\n\t\t\t\t\t\t\tkey={variant.id}\n\t\t\t\t\t\t\tasset={variant}\n\t\t\t\t\t\t\tselected={focused.id === variant.id}\n\t\t\t\t\t\t\tonOpen={() => setFocus({ scope, id: variant.id })}\n\t\t\t\t\t\t\taction={\n\t\t\t\t\t\t\t\twritable &&\n\t\t\t\t\t\t\t\tisReady(variant) && (\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\t\t\tconfirming === variant.id\n\t\t\t\t\t\t\t\t\t\t\t\t? 'rs-pill rs-tile-action is-confirming'\n\t\t\t\t\t\t\t\t\t\t\t\t: 'rs-pill rs-tile-action'\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tdisabled={promote.state.status === 'promoting'}\n\t\t\t\t\t\t\t\t\t\tonClick={() => setDefault(variant)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<Icon shape=\"star\" width={10.5} />\n\t\t\t\t\t\t\t\t\t\t{confirming === variant.id ? 'Confirm' : 'Set as default'}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t\t{pendingTile}\n\t\t\t\t</div>\n\t\t\t</>\n\t\t)\n\t} else if (hit) {\n\t\theading = (\n\t\t\t<>\n\t\t\t\t<button type=\"button\" className=\"rs-crumb\" onClick={() => setFocus(null)}>\n\t\t\t\t\tSearch\n\t\t\t\t</button>\n\t\t\t\t<span className=\"rs-muted\">/</span>\n\t\t\t\t<h1 className=\"rs-heading\">{hit.name}</h1>\n\t\t\t</>\n\t\t)\n\t\tcontent = <Detail item={hit} busy={read.isPending} onPick={onPick && (() => pick(hit))} />\n\t} else if (shown === null ? organizations.isLoading || libraries.isLoading : items === null) {\n\t\tcontent = shown?.error ? null : (\n\t\t\t<div className=\"rs-center\">\n\t\t\t\t<span className=\"rs-spinner\" />\n\t\t\t</div>\n\t\t)\n\t} else if (shown !== null && items?.length === 0 && !pendingTile) {\n\t\tcontent = search.active ? (\n\t\t\t<Empty glyph=\"∅\" title=\"No results\" text={`Nothing matches “${search.query}”.`} />\n\t\t) : (\n\t\t\t<Empty glyph=\"∅\" title=\"No assets\" text=\"This library is empty.\">\n\t\t\t\t{writable && library !== null && (\n\t\t\t\t\t<FilePicker\n\t\t\t\t\t\tclassName=\"rs-button rs-button-primary rs-button-sm\"\n\t\t\t\t\t\tdisabled={false}\n\t\t\t\t\t\tonFile={(file) => void send(file, null)}\n\t\t\t\t\t>\n\t\t\t\t\t\tUpload files\n\t\t\t\t\t</FilePicker>\n\t\t\t\t)}\n\t\t\t</Empty>\n\t\t)\n\t} else if (shown !== null && items) {\n\t\tcontent = (\n\t\t\t<>\n\t\t\t\t<div className=\"rs-grid\">\n\t\t\t\t\t{pendingTile}\n\t\t\t\t\t{search.active\n\t\t\t\t\t\t? search.hits?.map((entry) => (\n\t\t\t\t\t\t\t\t<Tile\n\t\t\t\t\t\t\t\t\tkey={entry.id}\n\t\t\t\t\t\t\t\t\tasset={entry}\n\t\t\t\t\t\t\t\t\tonOpen={() => setFocus({ scope, id: entry.id })}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t))\n\t\t\t\t\t\t: assets.assets?.map((asset) => {\n\t\t\t\t\t\t\t\tconst count = asset.variants?.filter(Boolean).length ?? 0\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<Tile\n\t\t\t\t\t\t\t\t\t\tkey={asset.id}\n\t\t\t\t\t\t\t\t\t\tasset={asset}\n\t\t\t\t\t\t\t\t\t\tonOpen={() => {\n\t\t\t\t\t\t\t\t\t\t\tsetConfirming(null)\n\t\t\t\t\t\t\t\t\t\t\tnavigation.openAsset(asset)\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tbadge={\n\t\t\t\t\t\t\t\t\t\t\tcount > 0 && (\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"rs-pill rs-tile-badge\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Icon shape=\"layers\" width={10.5} />\n\t\t\t\t\t\t\t\t\t\t\t\t\t{count + 1} versions\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t\t{shown.hasMore && (\n\t\t\t\t\t<div className=\"rs-center\">\n\t\t\t\t\t\t<Sentinel key={items.length} onVisible={shown.loadMore} />\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</>\n\t\t)\n\t}\n\n\tconst dropTarget = writable && library !== null && !search.active\n\n\treturn (\n\t\t<>\n\t\t\t<aside className=\"rs-sidebar\">\n\t\t\t\t<Brand />\n\t\t\t\t<OrganizationSwitcher\n\t\t\t\t\torganizations={organizations.data ?? []}\n\t\t\t\t\tcurrent={organization}\n\t\t\t\t\tonIntent={(entry) =>\n\t\t\t\t\t\tentry.id !== organizationId && prefetchLibraries(entry.id, entry.name)\n\t\t\t\t\t}\n\t\t\t\t\tonSelect={navigation.selectOrganization}\n\t\t\t\t/>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName={search.active ? 'rs-sidebar-item is-active' : 'rs-sidebar-item'}\n\t\t\t\t\tonClick={() => searchInput.current?.focus()}\n\t\t\t\t>\n\t\t\t\t\t<Icon shape=\"search\" />\n\t\t\t\t\tSearch\n\t\t\t\t</button>\n\t\t\t\t<nav className=\"rs-scroll\">\n\t\t\t\t\t<h2 className=\"rs-sidebar-heading\">Libraries</h2>\n\t\t\t\t\t{libraries.data?.map((entry) => {\n\t\t\t\t\t\tconst open = entry.id === library?.id\n\t\t\t\t\t\tconst warm = () => organizationId !== null && prefetchAssets(organizationId, entry.id)\n\t\t\t\t\t\tconst toGrid = () => {\n\t\t\t\t\t\t\tnavigation.setQuery('')\n\t\t\t\t\t\t\tnavigation.openAsset(null)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div key={entry.id} className={open ? 'rs-library is-expanded' : 'rs-library'}>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"rs-sidebar-item rs-library-row\"\n\t\t\t\t\t\t\t\t\tdisabled={entry.access === null}\n\t\t\t\t\t\t\t\t\tonMouseEnter={warm}\n\t\t\t\t\t\t\t\t\tonFocus={warm}\n\t\t\t\t\t\t\t\t\tonClick={() => navigation.openLibrary(entry)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Icon shape=\"grid\" />\n\t\t\t\t\t\t\t\t\t<span className=\"rs-library-name\">{entry.name}</span>\n\t\t\t\t\t\t\t\t\t<span className={open ? 'rs-sidebar-count is-active' : 'rs-sidebar-count'}>\n\t\t\t\t\t\t\t\t\t\t{COUNT.format(entry.assetsCount ?? 0)}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tclassName={open ? 'rs-library-menu is-expanded' : 'rs-library-menu'}\n\t\t\t\t\t\t\t\t\taria-hidden={!open}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\ttabIndex={open ? 0 : -1}\n\t\t\t\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\t\t\t\topen && !search.active && opened === null\n\t\t\t\t\t\t\t\t\t\t\t\t\t? 'rs-sidebar-item is-active'\n\t\t\t\t\t\t\t\t\t\t\t\t\t: 'rs-sidebar-item'\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tonClick={toGrid}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<Icon shape=\"circle\" />\n\t\t\t\t\t\t\t\t\t\t\tAll Assets\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t<FilePicker\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"rs-sidebar-item\"\n\t\t\t\t\t\t\t\t\t\t\tdisabled={!open || entry.access !== 'write'}\n\t\t\t\t\t\t\t\t\t\t\tfocusable={open}\n\t\t\t\t\t\t\t\t\t\t\tonFile={(file) => {\n\t\t\t\t\t\t\t\t\t\t\t\ttoGrid()\n\t\t\t\t\t\t\t\t\t\t\t\tvoid send(file, null)\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<Icon shape=\"upload\" />\n\t\t\t\t\t\t\t\t\t\t\tUpload\n\t\t\t\t\t\t\t\t\t\t</FilePicker>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)\n\t\t\t\t\t})}\n\t\t\t\t</nav>\n\t\t\t\t<div className=\"rs-sidebar-footer\">\n\t\t\t\t\t<span className=\"rs-sidebar-item rs-muted\">\n\t\t\t\t\t\t{session.isSignedIn ? (session.userName ?? 'Signed in') : 'API key'}\n\t\t\t\t\t</span>\n\t\t\t\t\t<button type=\"button\" className=\"rs-sidebar-item\" onClick={() => void session.signOut()}>\n\t\t\t\t\t\tSign out\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</aside>\n\t\t\t<section\n\t\t\t\tclassName=\"rs-main\"\n\t\t\t\taria-label=\"Assets\"\n\t\t\t\tonDragEnter={(event) => {\n\t\t\t\t\tif (!dropTarget || !event.dataTransfer.types.includes('Files')) return\n\t\t\t\t\tdragDepth.current += 1\n\t\t\t\t\tsetDragging(true)\n\t\t\t\t}}\n\t\t\t\tonDragOver={(event) => {\n\t\t\t\t\tif (dropTarget) event.preventDefault()\n\t\t\t\t}}\n\t\t\t\tonDragLeave={() => {\n\t\t\t\t\tdragDepth.current = Math.max(0, dragDepth.current - 1)\n\t\t\t\t\tif (dragDepth.current === 0) setDragging(false)\n\t\t\t\t}}\n\t\t\t\tonDrop={(event) => {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tdragDepth.current = 0\n\t\t\t\t\tsetDragging(false)\n\t\t\t\t\tconst file = event.dataTransfer.files[0]\n\t\t\t\t\tif (file && dropTarget) void send(file, versions ? opened.id : null)\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<header className=\"rs-header\">\n\t\t\t\t\t{heading}\n\t\t\t\t\t<span className=\"rs-muted rs-small\">{status}</span>\n\t\t\t\t\t<Progress upload={upload.state} promote={promote.state} />\n\t\t\t\t\t<div className=\"rs-search\">\n\t\t\t\t\t\t<Icon shape=\"search\" width={12.25} />\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tref={searchInput}\n\t\t\t\t\t\t\tclassName=\"rs-input\"\n\t\t\t\t\t\t\taria-label=\"Search Raster\"\n\t\t\t\t\t\t\tplaceholder={library === null ? 'Search every library…' : `Search ${library.name}…`}\n\t\t\t\t\t\t\tvalue={query}\n\t\t\t\t\t\t\tonChange={(event) => navigation.setQuery(event.target.value)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{query !== '' && (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"rs-icon-button\"\n\t\t\t\t\t\t\t\taria-label=\"Clear search\"\n\t\t\t\t\t\t\t\tonClick={() => navigation.setQuery('')}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon shape=\"x\" width={10.5} />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t\t{versions && writable && (\n\t\t\t\t\t\t<FilePicker\n\t\t\t\t\t\t\tclassName=\"rs-button rs-button-sm\"\n\t\t\t\t\t\t\tdisabled={false}\n\t\t\t\t\t\t\tonFile={(file) => void send(file, opened.id)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Icon shape=\"upload\" width={12.25} />\n\t\t\t\t\t\t\tUpload variant\n\t\t\t\t\t\t</FilePicker>\n\t\t\t\t\t)}\n\t\t\t\t\t<button type=\"button\" className=\"rs-button rs-button-sm\" onClick={navigation.refresh}>\n\t\t\t\t\t\tRefresh\n\t\t\t\t\t</button>\n\t\t\t\t</header>\n\t\t\t\t<div className=\"rs-content rs-scroll\">\n\t\t\t\t\t{organizations.error && <ErrorCard error={organizations.error} onError={onError} />}\n\t\t\t\t\t{libraries.error && <ErrorCard error={libraries.error} onError={onError} />}\n\t\t\t\t\t{shown?.error && <ErrorCard error={shown.error} onError={onError} />}\n\t\t\t\t\t{read.error && <ErrorCard error={read.error} onError={onError} />}\n\t\t\t\t\t{upload.state.status === 'error' && (\n\t\t\t\t\t\t<ErrorCard error={upload.state.error} onError={onError} />\n\t\t\t\t\t)}\n\t\t\t\t\t{promote.state.status === 'error' && (\n\t\t\t\t\t\t<ErrorCard error={promote.state.error} onError={onError} />\n\t\t\t\t\t)}\n\t\t\t\t\t{content}\n\t\t\t\t</div>\n\t\t\t\t<div className={dragging ? 'rs-drop is-active' : 'rs-drop'} />\n\t\t\t</section>\n\t\t</>\n\t)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"raster-picker.js","sourceRoot":"","sources":["../src/raster-picker.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMutation } from '@tanstack/react-query'\nimport { type ReactNode, useRef, useState } from 'react'\n\nimport {\n\ttype Asset,\n\ttype AssetVariant,\n\ttype RasterApiError,\n\ttype SearchHit,\n\tisReady,\n} from '@raster-app/sdk'\n\nimport { useRasterClient } from './context.js'\nimport { Icon } from './icons.js'\nimport {\n\tBrand,\n\tDetail,\n\tEmpty,\n\tErrorCard,\n\tFilePicker,\n\tOrganizationSwitcher,\n\tPendingTile,\n\tProgress,\n\ttype ReportError,\n\tSentinel,\n\tTile,\n\tTileGrid,\n} from './picker-parts.js'\nimport { SignIn } from './picker-sign-in.js'\nimport { useAssetSearch } from './use-asset-search.js'\nimport { useAssetUpload } from './use-asset-upload.js'\nimport { useAssets, usePrefetchAssets } from './use-assets.js'\nimport { useLibraries, usePrefetchLibraries } from './use-libraries.js'\nimport { useRasterNavigation } from './use-navigation.js'\nimport { useOrganizations } from './use-organizations.js'\nimport { usePromoteVariant } from './use-promote-variant.js'\nimport { useSession } from './use-session.js'\n\nexport type RasterPickerProps = {\n\t/**\n\t * The picked asset, whole whether it came from a library, a search or an asset's versions, and\n\t * its organization. `getFullSizeUrl(asset)` is the image. Without it, the picker only browses,\n\t * with no Pick asset button.\n\t */\n\tonPick?: (asset: Asset, organizationId: string) => void\n\t/** Binds the device sign-in to this organization; any other grant fails. */\n\torganizationId?: string\n\t/** The consent the device sign-in asks for: `org` when `organizationId` is set, else `user`. */\n\tscope?: 'user' | 'org'\n\t/** Each failure the picker shows, once, for the host to log. */\n\tonError?: (error: RasterApiError) => void\n\t/** Follows the system's color scheme when unset. */\n\ttheme?: 'light' | 'dark'\n}\n\nconst COUNT = new Intl.NumberFormat('en-US', { notation: 'compact' })\n\n/** A file on its way in, which the grid shows until Raster has processed it. */\ntype Pending = { name: string; preview: string; parentId: string | null }\n\n/**\n * Raster's asset picker, drawn as Raster draws it (`@raster-app/react/styles.css`): sign-in, the\n * organization's libraries, search and uploads. A tile opens its asset large, to pick or open in\n * Raster, over its versions with the default to set. It fills its container, inside a\n * `RasterProvider`.\n */\nexport function RasterPicker({ onPick, organizationId, scope, onError, theme }: RasterPickerProps) {\n\tconst { credentials, isConfigured } = useSession()\n\n\tlet body = (\n\t\t<div className=\"rs-center\">\n\t\t\t<span className=\"rs-spinner\" />\n\t\t</div>\n\t)\n\tif (credentials !== undefined && !isConfigured) {\n\t\tbody = (\n\t\t\t<SignIn\n\t\t\t\torganizationId={organizationId}\n\t\t\t\tscope={scope ?? (organizationId === undefined ? 'user' : 'org')}\n\t\t\t\tonError={onError}\n\t\t\t/>\n\t\t)\n\t} else if (isConfigured) {\n\t\tbody = <Browser onPick={onPick} onError={onError} />\n\t}\n\treturn (\n\t\t<div className=\"rs rs-picker\" data-theme={theme}>\n\t\t\t{body}\n\t\t</div>\n\t)\n}\n\nfunction Browser({\n\tonPick,\n\tonError,\n}: {\n\tonPick: RasterPickerProps['onPick']\n\tonError: ReportError\n}) {\n\tconst client = useRasterClient()\n\tconst session = useSession()\n\tconst organizations = useOrganizations()\n\tconst navigation = useRasterNavigation({ organizations: organizations.data ?? null })\n\tconst { organizationId, library, query } = navigation\n\tconst organization = organizations.data?.find((entry) => entry.id === organizationId)\n\tconst libraries = useLibraries({ organizationId, organizationName: organization?.name ?? null })\n\tconst assets = useAssets({ organizationId, libraryId: library?.id ?? null })\n\tconst search = useAssetSearch(\n\t\torganizationId === null ? null : { organizationId, libraryId: library?.id ?? null },\n\t\tquery\n\t)\n\tconst upload = useAssetUpload()\n\tconst promote = usePromoteVariant()\n\tconst read = useMutation<Asset, RasterApiError, Parameters<typeof client.assets.get>[0]>({\n\t\tmutationFn: (options) => client.assets.get(options),\n\t})\n\tconst prefetchAssets = usePrefetchAssets()\n\tconst prefetchLibraries = usePrefetchLibraries()\n\tconst searchInput = useRef<HTMLInputElement>(null)\n\tconst [pending, setPending] = useState<Pending | null>(null)\n\tconst [confirming, setConfirming] = useState<string | null>(null)\n\tconst [dragging, setDragging] = useState(false)\n\tconst dragDepth = useRef(0)\n\t// The version shown large, or the search hit opened, for the scope it was chosen in.\n\tconst [focus, setFocus] = useState<{ scope: string; id: string } | null>(null)\n\tconst scope = [organizationId, library?.id, navigation.asset?.id, query].join('/')\n\tconst focusId = focus?.scope === scope ? focus.id : null\n\n\tconst access = libraries.data?.find((entry) => entry.id === library?.id)?.access ?? null\n\tconst writable = access === 'write'\n\t// The asset as the list last read it, which refetches after an upload or a promote.\n\tconst opened =\n\t\tnavigation.asset === null\n\t\t\t? null\n\t\t\t: (assets.assets?.find((entry) => entry.id === navigation.asset?.id) ?? navigation.asset)\n\tconst versions = !search.active && opened !== null\n\tconst variants = (opened?.variants ?? []).filter(\n\t\t(variant): variant is AssetVariant => variant !== null\n\t)\n\tconst shown = search.active ? search : library === null ? null : assets\n\tconst items = search.active ? search.hits : assets.assets\n\tconst hit = search.active ? (search.hits?.find((entry) => entry.id === focusId) ?? null) : null\n\t// Until a promote lands, the cached asset is still the previous default.\n\tconst busy = read.isPending || promote.state.status === 'promoting'\n\n\t/** Hand the host the whole asset: a search hit or a variant carries less, so it is read first. */\n\tfunction pick(item: Asset | SearchHit | AssetVariant) {\n\t\tif (organizationId === null || onPick === undefined) return\n\t\tconst loaded = assets.assets?.find((entry) => entry.id === item.id)\n\t\tif (loaded) {\n\t\t\tonPick(loaded, organizationId)\n\t\t\treturn\n\t\t}\n\t\t// A variant lives in its original's library, which is the open one.\n\t\tconst libraryId = ('libraryId' in item ? item.libraryId : null) ?? library?.id\n\t\tif (!libraryId) return\n\t\tread.mutate(\n\t\t\t{ organizationId, libraryId, assetId: item.id },\n\t\t\t{ onSuccess: (asset) => onPick(asset, organizationId) }\n\t\t)\n\t}\n\n\t/** Upload one file into the open library, or as a variant of `parentId`. */\n\tasync function send(file: File, parentId: string | null) {\n\t\t// A second upload would cancel the one in flight.\n\t\tif (organizationId === null || library === null || !writable || pending !== null) return\n\t\tconst preview = URL.createObjectURL(file)\n\t\tsetPending({ name: file.name, preview, parentId })\n\t\tawait upload.upload({ organizationId, libraryId: library.id, parentId, source: file })\n\t\tURL.revokeObjectURL(preview)\n\t\tsetPending(null)\n\t}\n\n\t/** The first press asks to confirm; the second promotes. */\n\tfunction setDefault(variant: AssetVariant) {\n\t\tif (confirming !== variant.id) {\n\t\t\tsetConfirming(variant.id)\n\t\t\treturn\n\t\t}\n\t\tsetConfirming(null)\n\t\tif (organizationId === null || library === null || opened === null) return\n\t\tvoid promote.promote({\n\t\t\torganizationId,\n\t\t\tlibraryId: library.id,\n\t\t\tassetId: opened.id,\n\t\t\tvariantId: variant.id,\n\t\t})\n\t}\n\n\tconst pendingTile = pending !== null &&\n\t\t!search.active &&\n\t\tpending.parentId === (opened?.id ?? null) && (\n\t\t\t<PendingTile\n\t\t\t\tname={pending.name}\n\t\t\t\tpreview={pending.preview}\n\t\t\t\tstatus={upload.state.status === 'uploading' ? 'Uploading' : 'Processing'}\n\t\t\t/>\n\t\t)\n\n\tlet status = ''\n\tif (search.active) status = search.isSearching ? 'Searching' : `${search.found} found`\n\telse if (library !== null && !versions) status = `${assets.assets?.length ?? 0} loaded`\n\n\tlet heading: ReactNode = (\n\t\t<>\n\t\t\t<h1 className=\"rs-heading\">{search.active ? 'Search' : (library?.name ?? 'Libraries')}</h1>\n\t\t\t{!search.active && library !== null && (\n\t\t\t\t<span className=\"rs-sidebar-count is-active\">{access ?? 'no access'}</span>\n\t\t\t)}\n\t\t</>\n\t)\n\tlet content: ReactNode = (\n\t\t<Empty glyph=\"grid\" title=\"Choose a library\" text=\"Or search every library.\" />\n\t)\n\tif (versions) {\n\t\tconst focused = [opened, ...variants].find((entry) => entry.id === focusId) ?? opened\n\t\theading = (\n\t\t\t<>\n\t\t\t\t<button type=\"button\" className=\"rs-crumb\" onClick={() => navigation.openAsset(null)}>\n\t\t\t\t\t{library?.name}\n\t\t\t\t</button>\n\t\t\t\t<span className=\"rs-muted\">/</span>\n\t\t\t\t<h1 className=\"rs-heading\">{opened.name}</h1>\n\t\t\t\t<span className=\"rs-sidebar-count is-active\">{variants.length + 1} versions</span>\n\t\t\t</>\n\t\t)\n\t\tcontent = (\n\t\t\t<>\n\t\t\t\t<Detail item={focused} busy={busy} onPick={onPick && (() => pick(focused))} />\n\t\t\t\t<TileGrid>\n\t\t\t\t\t<Tile\n\t\t\t\t\t\tasset={opened}\n\t\t\t\t\t\tselected={focused.id === opened.id}\n\t\t\t\t\t\tonOpen={() => setFocus({ scope, id: opened.id })}\n\t\t\t\t\t\tbadge={\n\t\t\t\t\t\t\t<span className=\"rs-pill rs-tile-badge\">\n\t\t\t\t\t\t\t\t<Icon shape=\"star\" solid width={10.5} />\n\t\t\t\t\t\t\t\tDefault\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t\t{variants.map((variant) => (\n\t\t\t\t\t\t<Tile\n\t\t\t\t\t\t\tkey={variant.id}\n\t\t\t\t\t\t\tasset={variant}\n\t\t\t\t\t\t\tselected={focused.id === variant.id}\n\t\t\t\t\t\t\tonOpen={() => setFocus({ scope, id: variant.id })}\n\t\t\t\t\t\t\taction={\n\t\t\t\t\t\t\t\twritable &&\n\t\t\t\t\t\t\t\tisReady(variant) && (\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\t\t\tconfirming === variant.id\n\t\t\t\t\t\t\t\t\t\t\t\t? 'rs-pill rs-tile-action is-confirming'\n\t\t\t\t\t\t\t\t\t\t\t\t: 'rs-pill rs-tile-action'\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tdisabled={promote.state.status === 'promoting'}\n\t\t\t\t\t\t\t\t\t\tonClick={() => setDefault(variant)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<Icon shape=\"star\" width={10.5} />\n\t\t\t\t\t\t\t\t\t\t{confirming === variant.id ? 'Confirm' : 'Set as default'}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t\t{pendingTile}\n\t\t\t\t</TileGrid>\n\t\t\t</>\n\t\t)\n\t} else if (hit) {\n\t\theading = (\n\t\t\t<>\n\t\t\t\t<button type=\"button\" className=\"rs-crumb\" onClick={() => setFocus(null)}>\n\t\t\t\t\tSearch\n\t\t\t\t</button>\n\t\t\t\t<span className=\"rs-muted\">/</span>\n\t\t\t\t<h1 className=\"rs-heading\">{hit.name}</h1>\n\t\t\t</>\n\t\t)\n\t\tcontent = <Detail item={hit} busy={busy} onPick={onPick && (() => pick(hit))} />\n\t} else if (shown === null ? organizations.isLoading || libraries.isLoading : items === null) {\n\t\tcontent = shown?.error ? null : (\n\t\t\t<div className=\"rs-center\">\n\t\t\t\t<span className=\"rs-spinner\" />\n\t\t\t</div>\n\t\t)\n\t} else if (shown !== null && items?.length === 0 && !pendingTile) {\n\t\tcontent = search.active ? (\n\t\t\t<Empty glyph=\"∅\" title=\"No results\" text={`Nothing matches “${search.query}”.`} />\n\t\t) : (\n\t\t\t<Empty glyph=\"∅\" title=\"No assets\" text=\"This library is empty.\">\n\t\t\t\t{writable && library !== null && (\n\t\t\t\t\t<FilePicker\n\t\t\t\t\t\tclassName=\"rs-button rs-button-primary rs-button-sm\"\n\t\t\t\t\t\tdisabled={pending !== null}\n\t\t\t\t\t\tonFile={(file) => void send(file, null)}\n\t\t\t\t\t>\n\t\t\t\t\t\tUpload files\n\t\t\t\t\t</FilePicker>\n\t\t\t\t)}\n\t\t\t</Empty>\n\t\t)\n\t} else if (shown !== null && items) {\n\t\tcontent = (\n\t\t\t<>\n\t\t\t\t<TileGrid>\n\t\t\t\t\t{pendingTile}\n\t\t\t\t\t{search.active\n\t\t\t\t\t\t? search.hits?.map((entry) => (\n\t\t\t\t\t\t\t\t<Tile\n\t\t\t\t\t\t\t\t\tkey={entry.id}\n\t\t\t\t\t\t\t\t\tasset={entry}\n\t\t\t\t\t\t\t\t\tonOpen={() => setFocus({ scope, id: entry.id })}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t))\n\t\t\t\t\t\t: assets.assets?.map((asset) => {\n\t\t\t\t\t\t\t\tconst count = asset.variants?.filter(Boolean).length ?? 0\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<Tile\n\t\t\t\t\t\t\t\t\t\tkey={asset.id}\n\t\t\t\t\t\t\t\t\t\tasset={asset}\n\t\t\t\t\t\t\t\t\t\tonOpen={() => {\n\t\t\t\t\t\t\t\t\t\t\tsetConfirming(null)\n\t\t\t\t\t\t\t\t\t\t\tnavigation.openAsset(asset)\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tbadge={\n\t\t\t\t\t\t\t\t\t\t\tcount > 0 && (\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"rs-pill rs-tile-badge\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Icon shape=\"layers\" width={10.5} />\n\t\t\t\t\t\t\t\t\t\t\t\t\t{count + 1} versions\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t})}\n\t\t\t\t</TileGrid>\n\t\t\t\t{shown.hasMore && (\n\t\t\t\t\t<div className=\"rs-center\">\n\t\t\t\t\t\t<Sentinel key={items.length} onVisible={shown.loadMore} />\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</>\n\t\t)\n\t}\n\n\tconst dropTarget = writable && library !== null && !search.active\n\n\treturn (\n\t\t<>\n\t\t\t<aside className=\"rs-sidebar\">\n\t\t\t\t<Brand />\n\t\t\t\t<OrganizationSwitcher\n\t\t\t\t\torganizations={organizations.data ?? []}\n\t\t\t\t\tcurrent={organization}\n\t\t\t\t\tonIntent={(entry) =>\n\t\t\t\t\t\tentry.id !== organizationId && prefetchLibraries(entry.id, entry.name)\n\t\t\t\t\t}\n\t\t\t\t\tonSelect={navigation.selectOrganization}\n\t\t\t\t/>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName={search.active ? 'rs-sidebar-item is-active' : 'rs-sidebar-item'}\n\t\t\t\t\tonClick={() => searchInput.current?.focus()}\n\t\t\t\t>\n\t\t\t\t\t<Icon shape=\"search\" />\n\t\t\t\t\tSearch\n\t\t\t\t</button>\n\t\t\t\t<nav className=\"rs-scroll\">\n\t\t\t\t\t<h2 className=\"rs-sidebar-heading\">Libraries</h2>\n\t\t\t\t\t{libraries.data?.map((entry) => {\n\t\t\t\t\t\tconst open = entry.id === library?.id\n\t\t\t\t\t\tconst warm = () => organizationId !== null && prefetchAssets(organizationId, entry.id)\n\t\t\t\t\t\tconst toGrid = () => {\n\t\t\t\t\t\t\tnavigation.setQuery('')\n\t\t\t\t\t\t\tnavigation.openAsset(null)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div key={entry.id} className={open ? 'rs-library is-expanded' : 'rs-library'}>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"rs-sidebar-item rs-library-row\"\n\t\t\t\t\t\t\t\t\tdisabled={entry.access === null}\n\t\t\t\t\t\t\t\t\tonMouseEnter={warm}\n\t\t\t\t\t\t\t\t\tonFocus={warm}\n\t\t\t\t\t\t\t\t\tonClick={() => navigation.openLibrary(entry)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Icon shape=\"grid\" />\n\t\t\t\t\t\t\t\t\t<span className=\"rs-library-name\">{entry.name}</span>\n\t\t\t\t\t\t\t\t\t<span className={open ? 'rs-sidebar-count is-active' : 'rs-sidebar-count'}>\n\t\t\t\t\t\t\t\t\t\t{COUNT.format(entry.assetsCount ?? 0)}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tclassName={open ? 'rs-library-menu is-expanded' : 'rs-library-menu'}\n\t\t\t\t\t\t\t\t\taria-hidden={!open}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\ttabIndex={open ? 0 : -1}\n\t\t\t\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\t\t\t\topen && !search.active && opened === null\n\t\t\t\t\t\t\t\t\t\t\t\t\t? 'rs-sidebar-item is-active'\n\t\t\t\t\t\t\t\t\t\t\t\t\t: 'rs-sidebar-item'\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tonClick={toGrid}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<Icon shape=\"circle\" />\n\t\t\t\t\t\t\t\t\t\t\tAll Assets\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t<FilePicker\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"rs-sidebar-item\"\n\t\t\t\t\t\t\t\t\t\t\tdisabled={!open || entry.access !== 'write' || pending !== null}\n\t\t\t\t\t\t\t\t\t\t\tfocusable={open}\n\t\t\t\t\t\t\t\t\t\t\tonFile={(file) => {\n\t\t\t\t\t\t\t\t\t\t\t\ttoGrid()\n\t\t\t\t\t\t\t\t\t\t\t\tvoid send(file, null)\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<Icon shape=\"upload\" />\n\t\t\t\t\t\t\t\t\t\t\tUpload\n\t\t\t\t\t\t\t\t\t\t</FilePicker>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)\n\t\t\t\t\t})}\n\t\t\t\t</nav>\n\t\t\t\t<div className=\"rs-sidebar-footer\">\n\t\t\t\t\t<span className=\"rs-sidebar-item rs-muted\">\n\t\t\t\t\t\t{session.isSignedIn ? (session.userName ?? 'Signed in') : 'API key'}\n\t\t\t\t\t</span>\n\t\t\t\t\t<button type=\"button\" className=\"rs-sidebar-item\" onClick={() => void session.signOut()}>\n\t\t\t\t\t\tSign out\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</aside>\n\t\t\t<section\n\t\t\t\tclassName=\"rs-main\"\n\t\t\t\taria-label=\"Assets\"\n\t\t\t\tonDragEnter={(event) => {\n\t\t\t\t\tif (!dropTarget || pending !== null || !event.dataTransfer.types.includes('Files')) return\n\t\t\t\t\tdragDepth.current += 1\n\t\t\t\t\tsetDragging(true)\n\t\t\t\t}}\n\t\t\t\tonDragOver={(event) => {\n\t\t\t\t\tif (dropTarget) event.preventDefault()\n\t\t\t\t}}\n\t\t\t\tonDragLeave={() => {\n\t\t\t\t\tdragDepth.current = Math.max(0, dragDepth.current - 1)\n\t\t\t\t\tif (dragDepth.current === 0) setDragging(false)\n\t\t\t\t}}\n\t\t\t\tonDrop={(event) => {\n\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\tdragDepth.current = 0\n\t\t\t\t\tsetDragging(false)\n\t\t\t\t\tconst file = event.dataTransfer.files[0]\n\t\t\t\t\tif (file && dropTarget) void send(file, versions ? opened.id : null)\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<header className=\"rs-header\">\n\t\t\t\t\t{heading}\n\t\t\t\t\t<span className=\"rs-muted rs-small\">{status}</span>\n\t\t\t\t\t<Progress upload={upload.state} promote={promote.state} />\n\t\t\t\t\t<div className=\"rs-search\">\n\t\t\t\t\t\t<Icon shape=\"search\" width={12.25} />\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tref={searchInput}\n\t\t\t\t\t\t\tclassName=\"rs-input\"\n\t\t\t\t\t\t\taria-label=\"Search Raster\"\n\t\t\t\t\t\t\tplaceholder={library === null ? 'Search every library…' : `Search ${library.name}…`}\n\t\t\t\t\t\t\tvalue={query}\n\t\t\t\t\t\t\tonChange={(event) => navigation.setQuery(event.target.value)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{query !== '' && (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"rs-icon-button\"\n\t\t\t\t\t\t\t\taria-label=\"Clear search\"\n\t\t\t\t\t\t\t\tonClick={() => navigation.setQuery('')}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon shape=\"x\" width={10.5} />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t\t{versions && writable && (\n\t\t\t\t\t\t<FilePicker\n\t\t\t\t\t\t\tclassName=\"rs-button rs-button-sm\"\n\t\t\t\t\t\t\tdisabled={pending !== null}\n\t\t\t\t\t\t\tonFile={(file) => void send(file, opened.id)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Icon shape=\"upload\" width={12.25} />\n\t\t\t\t\t\t\tUpload variant\n\t\t\t\t\t\t</FilePicker>\n\t\t\t\t\t)}\n\t\t\t\t\t<button type=\"button\" className=\"rs-button rs-button-sm\" onClick={navigation.refresh}>\n\t\t\t\t\t\tRefresh\n\t\t\t\t\t</button>\n\t\t\t\t</header>\n\t\t\t\t<div className=\"rs-content\">\n\t\t\t\t\t{organizations.error && <ErrorCard error={organizations.error} onError={onError} />}\n\t\t\t\t\t{libraries.error && <ErrorCard error={libraries.error} onError={onError} />}\n\t\t\t\t\t{shown?.error && <ErrorCard error={shown.error} onError={onError} />}\n\t\t\t\t\t{read.error && <ErrorCard error={read.error} onError={onError} />}\n\t\t\t\t\t{upload.state.status === 'error' && (\n\t\t\t\t\t\t<ErrorCard error={upload.state.error} onError={onError} />\n\t\t\t\t\t)}\n\t\t\t\t\t{promote.state.status === 'error' && (\n\t\t\t\t\t\t<ErrorCard error={promote.state.error} onError={onError} />\n\t\t\t\t\t)}\n\t\t\t\t\t{content}\n\t\t\t\t</div>\n\t\t\t\t<div className={dragging ? 'rs-drop is-active' : 'rs-drop'} />\n\t\t\t</section>\n\t\t</>\n\t)\n}\n"]}
|
package/dist/styles.css
CHANGED
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
.rs-picker > .rs-sidebar {
|
|
105
|
-
width:
|
|
105
|
+
width: 266px;
|
|
106
106
|
flex-shrink: 0;
|
|
107
107
|
}
|
|
108
108
|
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
flex-shrink: 0;
|
|
120
120
|
align-items: center;
|
|
121
121
|
gap: 10.5px;
|
|
122
|
-
padding: 10.5px 10.5px 0
|
|
122
|
+
padding: 10.5px 10.5px 0 30px;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
/* The title and search give way first, so no button's label is cut. */
|
|
@@ -127,10 +127,16 @@
|
|
|
127
127
|
flex-shrink: 0;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
/*
|
|
131
|
+
* Positioned, so a grid's `offsetTop` counts from the top of the scroll. Its scrollbar is the
|
|
132
|
+
* system's, as Raster's grid has, so it takes none of the grid's width.
|
|
133
|
+
*/
|
|
130
134
|
.rs-content {
|
|
135
|
+
position: relative;
|
|
131
136
|
flex: 1;
|
|
132
137
|
min-height: 0;
|
|
133
|
-
|
|
138
|
+
overflow-y: auto;
|
|
139
|
+
padding: 30px;
|
|
134
140
|
}
|
|
135
141
|
|
|
136
142
|
.rs-content > * + * {
|
|
@@ -622,10 +628,20 @@
|
|
|
622
628
|
|
|
623
629
|
/* ---- asset tiles ---- */
|
|
624
630
|
|
|
631
|
+
/* A row of tiles, with its columns from `gridColumns`, placed where the scroll puts it. */
|
|
625
632
|
.rs-grid {
|
|
626
633
|
display: grid;
|
|
627
|
-
|
|
628
|
-
|
|
634
|
+
gap: 30px;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
.rs-tile-grid {
|
|
638
|
+
position: relative;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
.rs-tile-grid > .rs-grid {
|
|
642
|
+
position: absolute;
|
|
643
|
+
right: 0;
|
|
644
|
+
left: 0;
|
|
629
645
|
}
|
|
630
646
|
|
|
631
647
|
.rs-asset-thumb {
|
|
@@ -635,7 +651,7 @@
|
|
|
635
651
|
flex-direction: column;
|
|
636
652
|
justify-content: space-between;
|
|
637
653
|
width: 100%;
|
|
638
|
-
height:
|
|
654
|
+
height: 210px;
|
|
639
655
|
overflow: hidden;
|
|
640
656
|
padding: 0;
|
|
641
657
|
border: 0;
|
|
@@ -667,16 +683,15 @@
|
|
|
667
683
|
opacity: 0.6;
|
|
668
684
|
}
|
|
669
685
|
|
|
686
|
+
/* The blurhash is blurred already, so it is stretched over the tile with no filter to composite. */
|
|
670
687
|
.rs-thumb-blur {
|
|
671
688
|
position: absolute;
|
|
672
|
-
inset:
|
|
689
|
+
inset: 0;
|
|
673
690
|
z-index: 10;
|
|
674
|
-
width:
|
|
675
|
-
height:
|
|
691
|
+
width: 100%;
|
|
692
|
+
height: 100%;
|
|
676
693
|
object-fit: cover;
|
|
677
|
-
filter: blur(40px);
|
|
678
694
|
opacity: 0.75;
|
|
679
|
-
transform: translateZ(0);
|
|
680
695
|
}
|
|
681
696
|
|
|
682
697
|
.rs-thumb-preview {
|
|
@@ -706,11 +721,9 @@
|
|
|
706
721
|
flex-direction: column;
|
|
707
722
|
justify-content: center;
|
|
708
723
|
flex-shrink: 0;
|
|
709
|
-
height:
|
|
724
|
+
height: 54px;
|
|
710
725
|
padding: 7px 10.5px;
|
|
711
726
|
background: var(--rs-thumb-meta);
|
|
712
|
-
-webkit-backdrop-filter: blur(12px);
|
|
713
|
-
backdrop-filter: blur(12px);
|
|
714
727
|
}
|
|
715
728
|
|
|
716
729
|
.rs-thumb-title {
|
|
@@ -800,7 +813,7 @@
|
|
|
800
813
|
/* The transparency checkerboard, behind a format that carries alpha. */
|
|
801
814
|
.rs-transparent {
|
|
802
815
|
position: absolute;
|
|
803
|
-
inset: 0 0
|
|
816
|
+
inset: 0 0 54px 0;
|
|
804
817
|
z-index: 10;
|
|
805
818
|
background-color: var(--rs-thumb-bg);
|
|
806
819
|
}
|
package/dist/use-asset-search.js
CHANGED
|
@@ -65,9 +65,11 @@ export function useAssetSearch(scope, rawQuery) {
|
|
|
65
65
|
void fetchNextPage({ cancelRefetch: false });
|
|
66
66
|
}, [hasMore, fetchNextPage]);
|
|
67
67
|
useEffect(() => {
|
|
68
|
+
if (query === debouncedQuery)
|
|
69
|
+
return;
|
|
68
70
|
const timer = setTimeout(() => setDebouncedQuery(query), SEARCH_DEBOUNCE_MS);
|
|
69
71
|
return () => clearTimeout(timer);
|
|
70
|
-
}, [query]);
|
|
72
|
+
}, [query, debouncedQuery]);
|
|
71
73
|
return {
|
|
72
74
|
active,
|
|
73
75
|
query,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-asset-search.js","sourceRoot":"","sources":["../src/use-asset-search.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"use-asset-search.js","sourceRoot":"","sources":["../src/use-asset-search.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype InfiniteData,\n\ttype QueryKey,\n\tskipToken,\n\tuseInfiniteQuery,\n} from '@tanstack/react-query'\nimport { useCallback, useEffect, useState } from 'react'\n\nimport {\n\ttype RasterApiError,\n\tSEARCH_PAGE_SIZE,\n\ttype SearchHit,\n\ttype SearchResult,\n} from '@raster-app/sdk'\n\nimport { useRasterClient } from './context.js'\nimport { rasterKeys } from './query-keys.js'\nimport { useCredentialIdentity } from './use-session.js'\n\n/** How long typing must pause before a query is sent, so a word costs one request. */\nconst SEARCH_DEBOUNCE_MS = 300\n\n/** Where a search looks: one organization, optionally narrowed to one of its libraries. */\nexport type SearchScope = {\n\torganizationId: string\n\t/** Null searches every library in the organization. */\n\tlibraryId: string | null\n}\n\nexport type AssetSearch = {\n\t/** Whether there is a query to show results for — views swap to results on this. */\n\tactive: boolean\n\t/** The trimmed query the results are (or will be) for. */\n\tquery: string\n\t/** Null until the first page has landed. */\n\thits: Array<SearchHit> | null\n\t/** Total matches in scope, from the index — not just those loaded so far. */\n\tfound: number\n\tisSearching: boolean\n\thasMore: boolean\n\t/** Fetch the next page. A no-op while one is already in flight, at the end, or after a failure. */\n\tloadMore: () => void\n\terror: RasterApiError | null\n}\n\ntype Results = Pick<SearchResult, 'hits' | 'found'>\n\nfunction toResults(data: InfiniteData<SearchResult>): Results {\n\treturn {\n\t\t// The index can shift between pages; a hit already shown is not shown twice.\n\t\thits: Array.from(\n\t\t\tnew Map(data.pages.flatMap((page) => page.hits).map((hit) => [hit.id, hit])).values()\n\t\t),\n\t\tfound: data.pages[data.pages.length - 1]?.found ?? 0,\n\t}\n}\n\n/**\n * Full-text search over Raster, as a header search box drives it. The previous results stay\n * on screen while the next query runs, since a grid that blanks on every keystroke makes\n * typing feel destructive. A null scope switches the search off.\n */\nexport function useAssetSearch(scope: SearchScope | null, rawQuery: string): AssetSearch {\n\tconst client = useRasterClient()\n\n\tconst identity = useCredentialIdentity()\n\n\tconst [debouncedQuery, setDebouncedQuery] = useState('')\n\n\tconst query = rawQuery.trim()\n\tconst active = scope !== null && query !== ''\n\n\tconst { data, error, isFetching, isError, hasNextPage, fetchNextPage } = useInfiniteQuery<\n\t\tSearchResult,\n\t\tRasterApiError,\n\t\tResults,\n\t\tQueryKey,\n\t\tnumber\n\t>({\n\t\tqueryKey: [\n\t\t\t...rasterKeys.search(identity, scope?.organizationId ?? null),\n\t\t\tscope?.libraryId ?? null,\n\t\t\tdebouncedQuery,\n\t\t],\n\t\tqueryFn:\n\t\t\tscope === null\n\t\t\t\t? skipToken\n\t\t\t\t: ({ pageParam, signal }) =>\n\t\t\t\t\t\tclient.search({\n\t\t\t\t\t\t\torganizationId: scope.organizationId,\n\t\t\t\t\t\t\tlibraryIds: scope.libraryId === null ? undefined : [scope.libraryId],\n\t\t\t\t\t\t\tquery: debouncedQuery,\n\t\t\t\t\t\t\tpage: pageParam,\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t}),\n\t\tinitialPageParam: 1,\n\t\tgetNextPageParam: (lastPage, pages) =>\n\t\t\tlastPage.hits.length === SEARCH_PAGE_SIZE && pages.length * SEARCH_PAGE_SIZE < lastPage.found\n\t\t\t\t? pages.length + 1\n\t\t\t\t: undefined,\n\t\tselect: toResults,\n\t\t// `keepPreviousData` within one sign-in's search of one organization. The observer holds\n\t\t// the last account's results after their cache is dropped, and a hit names its library but\n\t\t// not its organization, so one shown under another organization would be acted on there.\n\t\tplaceholderData: (previous, previousQuery) => {\n\t\t\tconst [, signIn, , organizationId] = previousQuery?.queryKey ?? []\n\t\t\treturn signIn === identity && organizationId === scope?.organizationId ? previous : undefined\n\t\t},\n\t\t// A blank `q` returns recent assets rather than matches.\n\t\tenabled: identity !== null && active && debouncedQuery !== '',\n\t})\n\n\tconst shown = active ? data : undefined\n\t// Up from the keystroke rather than from when the request goes out, so the spinner confirms\n\t// the typing was noticed.\n\tconst isSearching = active && (query !== debouncedQuery || isFetching)\n\t// A failure also stops paging, rather than let an observer retry it on every scroll.\n\tconst hasMore = active && hasNextPage && !isError\n\n\tconst loadMore = useCallback(() => {\n\t\tif (hasMore) void fetchNextPage({ cancelRefetch: false })\n\t}, [hasMore, fetchNextPage])\n\n\tuseEffect(() => {\n\t\tif (query === debouncedQuery) return\n\t\tconst timer = setTimeout(() => setDebouncedQuery(query), SEARCH_DEBOUNCE_MS)\n\t\treturn () => clearTimeout(timer)\n\t}, [query, debouncedQuery])\n\n\treturn {\n\t\tactive,\n\t\tquery,\n\t\thits: shown?.hits ?? null,\n\t\tfound: shown?.found ?? 0,\n\t\tisSearching,\n\t\thasMore,\n\t\tloadMore,\n\t\terror: active ? error : null,\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raster-app/react",
|
|
3
|
-
"version": "0.1.0-canary-
|
|
3
|
+
"version": "0.1.0-canary-58c063f",
|
|
4
4
|
"description": "React provider and hooks for the Raster SDK: session, organizations, libraries, assets, search and uploads.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://raster.app/docs/api/sdk",
|
|
@@ -40,8 +40,9 @@
|
|
|
40
40
|
"test": "bun test"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@raster-app/sdk": "0.1.0-canary-
|
|
44
|
-
"@tanstack/react-query": "^5.103.1"
|
|
43
|
+
"@raster-app/sdk": "0.1.0-canary-58c063f",
|
|
44
|
+
"@tanstack/react-query": "^5.103.1",
|
|
45
|
+
"@tanstack/react-virtual": "^3.14.13"
|
|
45
46
|
},
|
|
46
47
|
"peerDependencies": {
|
|
47
48
|
"react": "^18 || ^19"
|