@tldraw/editor 4.6.0-next.d15997ff5a4b → 4.6.0-next.d8328a2dcc3d
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-cjs/index.d.ts +60 -18
- package/dist-cjs/index.js +5 -4
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +4 -2
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/config/{createTLUser.js → createTLCurrentUser.js} +9 -9
- package/dist-cjs/lib/config/createTLCurrentUser.js.map +7 -0
- package/dist-cjs/lib/config/createTLStore.js +23 -0
- package/dist-cjs/lib/config/createTLStore.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +111 -4
- package/dist-cjs/lib/editor/Editor.js.map +3 -3
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +1 -1
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +10 -0
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/types/clipboard-types.js.map +1 -1
- package/dist-cjs/lib/hooks/useGestureEvents.js +171 -127
- package/dist-cjs/lib/hooks/useGestureEvents.js.map +3 -3
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +60 -18
- package/dist-esm/index.mjs +9 -4
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +4 -2
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/config/{createTLUser.mjs → createTLCurrentUser.mjs} +6 -6
- package/dist-esm/lib/config/createTLCurrentUser.mjs.map +7 -0
- package/dist-esm/lib/config/createTLStore.mjs +27 -1
- package/dist-esm/lib/config/createTLStore.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +113 -4
- package/dist-esm/lib/editor/Editor.mjs.map +3 -3
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +1 -1
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +10 -0
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/hooks/useGestureEvents.mjs +171 -127
- package/dist-esm/lib/hooks/useGestureEvents.mjs.map +3 -3
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +13 -0
- package/package.json +8 -9
- package/src/index.ts +6 -1
- package/src/lib/TldrawEditor.tsx +8 -6
- package/src/lib/config/{createTLUser.ts → createTLCurrentUser.ts} +6 -6
- package/src/lib/config/createTLStore.ts +35 -1
- package/src/lib/editor/Editor.ts +140 -3
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +2 -2
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +2 -2
- package/src/lib/editor/shapes/ShapeUtil.ts +11 -0
- package/src/lib/editor/types/clipboard-types.ts +2 -1
- package/src/lib/hooks/useGestureEvents.ts +240 -168
- package/src/lib/primitives/Box.test.ts +30 -0
- package/src/lib/primitives/geometry/Geometry2d.test.ts +21 -0
- package/src/version.ts +3 -3
- package/dist-cjs/lib/config/createTLUser.js.map +0 -7
- package/dist-esm/lib/config/createTLUser.mjs.map +0 -7
|
@@ -20,9 +20,11 @@ var createTLStore_exports = {};
|
|
|
20
20
|
__export(createTLStore_exports, {
|
|
21
21
|
createTLSchemaFromUtils: () => createTLSchemaFromUtils,
|
|
22
22
|
createTLStore: () => createTLStore,
|
|
23
|
+
defaultUserStore: () => defaultUserStore,
|
|
23
24
|
inlineBase64AssetStore: () => inlineBase64AssetStore
|
|
24
25
|
});
|
|
25
26
|
module.exports = __toCommonJS(createTLStore_exports);
|
|
27
|
+
var import_state = require("@tldraw/state");
|
|
26
28
|
var import_store = require("@tldraw/store");
|
|
27
29
|
var import_tlschema = require("@tldraw/tlschema");
|
|
28
30
|
var import_utils = require("@tldraw/utils");
|
|
@@ -30,7 +32,20 @@ var import_Editor = require("../editor/Editor");
|
|
|
30
32
|
var import_defaultBindings = require("./defaultBindings");
|
|
31
33
|
var import_defaultShapes = require("./defaultShapes");
|
|
32
34
|
var import_TLEditorSnapshot = require("./TLEditorSnapshot");
|
|
35
|
+
var import_TLUserPreferences = require("./TLUserPreferences");
|
|
33
36
|
const defaultAssetResolve = (asset) => asset.props.src;
|
|
37
|
+
const _defaultCurrentUser = (0, import_state.computed)("defaultCurrentUser", () => {
|
|
38
|
+
const prefs = (0, import_TLUserPreferences.getUserPreferences)();
|
|
39
|
+
if (!prefs.id) return null;
|
|
40
|
+
return import_tlschema.UserRecordType.create({
|
|
41
|
+
id: (0, import_tlschema.createUserId)(prefs.id),
|
|
42
|
+
name: prefs.name ?? "",
|
|
43
|
+
color: prefs.color ?? import_TLUserPreferences.defaultUserPreferences.color
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
const defaultUserStore = {
|
|
47
|
+
currentUser: _defaultCurrentUser
|
|
48
|
+
};
|
|
34
49
|
const inlineBase64AssetStore = {
|
|
35
50
|
upload: async (_, file) => {
|
|
36
51
|
return { src: await import_utils.FileHelpers.blobToDataUrl(file) };
|
|
@@ -50,6 +65,7 @@ function createTLStore({
|
|
|
50
65
|
defaultName = "",
|
|
51
66
|
id,
|
|
52
67
|
assets = inlineBase64AssetStore,
|
|
68
|
+
users = defaultUserStore,
|
|
53
69
|
onMount,
|
|
54
70
|
collaboration,
|
|
55
71
|
...rest
|
|
@@ -66,6 +82,13 @@ function createTLStore({
|
|
|
66
82
|
resolve: assets.resolve ?? defaultAssetResolve,
|
|
67
83
|
remove: assets.remove ?? (() => Promise.resolve())
|
|
68
84
|
},
|
|
85
|
+
users: {
|
|
86
|
+
currentUser: users.currentUser,
|
|
87
|
+
resolve: users.resolve ?? (0, import_tlschema.createCachedUserResolve)((userId) => {
|
|
88
|
+
const current = users.currentUser.get();
|
|
89
|
+
return current && current.id === (0, import_tlschema.createUserId)(userId) ? current : null;
|
|
90
|
+
})
|
|
91
|
+
},
|
|
69
92
|
onMount: (editor) => {
|
|
70
93
|
(0, import_utils.assert)(editor instanceof import_Editor.Editor);
|
|
71
94
|
onMount?.(editor);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/config/createTLStore.ts"],
|
|
4
|
-
"sourcesContent": ["import { Signal } from '@tldraw/state'\nimport { HistoryEntry, MigrationSequence, SerializedStore, Store, StoreSchema } from '@tldraw/store'\nimport {\n\tCustomRecordInfo,\n\tSchemaPropsInfo,\n\tTLAssetStore,\n\tTLRecord,\n\tTLStore,\n\tTLStoreProps,\n\tTLStoreSnapshot,\n\tcreateTLSchema,\n} from '@tldraw/tlschema'\nimport { FileHelpers, assert } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { TLAnyBindingUtilConstructor, checkBindings } from './defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from './defaultShapes'\nimport { TLEditorSnapshot, loadSnapshot } from './TLEditorSnapshot'\n\n/** @public */\nexport interface TLStoreBaseOptions {\n\t/** The initial data for the store. */\n\tinitialData?: SerializedStore<TLRecord>\n\n\t/** A snapshot of initial data to migrate and load into the store. */\n\tsnapshot?: Partial<TLEditorSnapshot> | TLStoreSnapshot\n\n\t/** The default name for the store. */\n\tdefaultName?: string\n\n\t/** How should this store upload & resolve assets? */\n\tassets?: TLAssetStore\n\n\t/** Called when the store is connected to an {@link @tldraw/editor#Editor}. */\n\tonMount?(editor: Editor): void | (() => void)\n}\n\n/** @public */\nexport type TLStoreSchemaOptions =\n\t| {\n\t\t\tschema?: StoreSchema<TLRecord, TLStoreProps>\n\t }\n\t| {\n\t\t\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\t\t\tmigrations?: readonly MigrationSequence[]\n\t\t\tbindingUtils?: readonly TLAnyBindingUtilConstructor[]\n\t\t\trecords?: Record<string, CustomRecordInfo>\n\t }\n\n/** @public */\nexport type TLStoreOptions = TLStoreBaseOptions & {\n\tid?: string\n\t/** Collaboration options for the store. */\n\tcollaboration?: {\n\t\tstatus: Signal<'online' | 'offline'> | null\n\t\tmode?: Signal<'readonly' | 'readwrite'> | null\n\t}\n} & TLStoreSchemaOptions\n\n/** @public */\nexport type TLStoreEventInfo = HistoryEntry<TLRecord>\n\nconst defaultAssetResolve: NonNullable<TLAssetStore['resolve']> = (asset) => asset.props.src\n\n/** @public */\nexport const inlineBase64AssetStore: TLAssetStore = {\n\tupload: async (_, file) => {\n\t\treturn { src: await FileHelpers.blobToDataUrl(file) }\n\t},\n}\n\n/**\n * A helper for creating a TLStore schema from either an object with shapeUtils, bindingUtils, and\n * migrations, or a schema.\n *\n * @param opts - Options for creating the schema.\n *\n * @public\n */\nexport function createTLSchemaFromUtils(\n\topts: TLStoreSchemaOptions\n): StoreSchema<TLRecord, TLStoreProps> {\n\tif ('schema' in opts && opts.schema) return opts.schema\n\n\treturn createTLSchema({\n\t\tshapes:\n\t\t\t'shapeUtils' in opts && opts.shapeUtils\n\t\t\t\t? utilsToMap(checkShapesAndAddCore(opts.shapeUtils))\n\t\t\t\t: undefined,\n\t\tbindings:\n\t\t\t'bindingUtils' in opts && opts.bindingUtils\n\t\t\t\t? utilsToMap(checkBindings(opts.bindingUtils))\n\t\t\t\t: undefined,\n\t\trecords: 'records' in opts ? opts.records : undefined,\n\t\tmigrations: 'migrations' in opts ? opts.migrations : undefined,\n\t})\n}\n\n/**\n * A helper for creating a TLStore.\n *\n * @param opts - Options for creating the store.\n *\n * @public\n */\nexport function createTLStore({\n\tinitialData,\n\tdefaultName = '',\n\tid,\n\tassets = inlineBase64AssetStore,\n\tonMount,\n\tcollaboration,\n\t...rest\n}: TLStoreOptions = {}): TLStore {\n\tconst schema = createTLSchemaFromUtils(rest)\n\n\tconst store = new Store({\n\t\tid,\n\t\tschema,\n\t\tinitialData,\n\t\tprops: {\n\t\t\tdefaultName,\n\t\t\tassets: {\n\t\t\t\tupload: assets.upload,\n\t\t\t\tresolve: assets.resolve ?? defaultAssetResolve,\n\t\t\t\tremove: assets.remove ?? (() => Promise.resolve()),\n\t\t\t},\n\t\t\tonMount: (editor) => {\n\t\t\t\tassert(editor instanceof Editor)\n\t\t\t\tonMount?.(editor)\n\t\t\t},\n\t\t\tcollaboration,\n\t\t},\n\t})\n\n\tif (rest.snapshot) {\n\t\tif (initialData) throw new Error('Cannot provide both initialData and snapshot')\n\t\tloadSnapshot(store, rest.snapshot, { forceOverwriteSessionState: true })\n\t}\n\n\treturn store\n}\n\nfunction utilsToMap<T extends SchemaPropsInfo & { type: string }>(utils: T[]) {\n\treturn Object.fromEntries(\n\t\tutils.map((s): [string, SchemaPropsInfo] => [\n\t\t\ts.type,\n\t\t\t{\n\t\t\t\tprops: s.props,\n\t\t\t\tmigrations: s.migrations,\n\t\t\t},\n\t\t])\n\t)\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import { Signal, computed } from '@tldraw/state'\nimport { HistoryEntry, MigrationSequence, SerializedStore, Store, StoreSchema } from '@tldraw/store'\nimport {\n\tCustomRecordInfo,\n\tSchemaPropsInfo,\n\tTLAssetStore,\n\tTLRecord,\n\tTLStore,\n\tTLStoreProps,\n\tTLStoreSnapshot,\n\tTLUser,\n\tTLUserStore,\n\tUserRecordType,\n\tcreateCachedUserResolve,\n\tcreateTLSchema,\n\tcreateUserId,\n} from '@tldraw/tlschema'\nimport { FileHelpers, assert } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { TLAnyBindingUtilConstructor, checkBindings } from './defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from './defaultShapes'\nimport { TLEditorSnapshot, loadSnapshot } from './TLEditorSnapshot'\nimport { defaultUserPreferences, getUserPreferences } from './TLUserPreferences'\n\n/** @public */\nexport interface TLStoreBaseOptions {\n\t/** The initial data for the store. */\n\tinitialData?: SerializedStore<TLRecord>\n\n\t/** A snapshot of initial data to migrate and load into the store. */\n\tsnapshot?: Partial<TLEditorSnapshot> | TLStoreSnapshot\n\n\t/** The default name for the store. */\n\tdefaultName?: string\n\n\t/** How should this store upload & resolve assets? */\n\tassets?: TLAssetStore\n\n\t/** How should this store resolve users for attribution? */\n\tusers?: TLUserStore\n\n\t/** Called when the store is connected to an {@link @tldraw/editor#Editor}. */\n\tonMount?(editor: Editor): void | (() => void)\n}\n\n/** @public */\nexport type TLStoreSchemaOptions =\n\t| {\n\t\t\tschema?: StoreSchema<TLRecord, TLStoreProps>\n\t }\n\t| {\n\t\t\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\t\t\tmigrations?: readonly MigrationSequence[]\n\t\t\tbindingUtils?: readonly TLAnyBindingUtilConstructor[]\n\t\t\trecords?: Record<string, CustomRecordInfo>\n\t }\n\n/** @public */\nexport type TLStoreOptions = TLStoreBaseOptions & {\n\tid?: string\n\t/** Collaboration options for the store. */\n\tcollaboration?: {\n\t\tstatus: Signal<'online' | 'offline'> | null\n\t\tmode?: Signal<'readonly' | 'readwrite'> | null\n\t}\n} & TLStoreSchemaOptions\n\n/** @public */\nexport type TLStoreEventInfo = HistoryEntry<TLRecord>\n\nconst defaultAssetResolve: NonNullable<TLAssetStore['resolve']> = (asset) => asset.props.src\n\nconst _defaultCurrentUser: Signal<TLUser | null> = computed('defaultCurrentUser', () => {\n\tconst prefs = getUserPreferences()\n\tif (!prefs.id) return null\n\treturn UserRecordType.create({\n\t\tid: createUserId(prefs.id),\n\t\tname: prefs.name ?? '',\n\t\tcolor: prefs.color ?? defaultUserPreferences.color,\n\t})\n})\n\n/** @public */\nexport const defaultUserStore: TLUserStore = {\n\tcurrentUser: _defaultCurrentUser,\n}\n\n/** @public */\nexport const inlineBase64AssetStore: TLAssetStore = {\n\tupload: async (_, file) => {\n\t\treturn { src: await FileHelpers.blobToDataUrl(file) }\n\t},\n}\n\n/**\n * A helper for creating a TLStore schema from either an object with shapeUtils, bindingUtils, and\n * migrations, or a schema.\n *\n * @param opts - Options for creating the schema.\n *\n * @public\n */\nexport function createTLSchemaFromUtils(\n\topts: TLStoreSchemaOptions\n): StoreSchema<TLRecord, TLStoreProps> {\n\tif ('schema' in opts && opts.schema) return opts.schema\n\n\treturn createTLSchema({\n\t\tshapes:\n\t\t\t'shapeUtils' in opts && opts.shapeUtils\n\t\t\t\t? utilsToMap(checkShapesAndAddCore(opts.shapeUtils))\n\t\t\t\t: undefined,\n\t\tbindings:\n\t\t\t'bindingUtils' in opts && opts.bindingUtils\n\t\t\t\t? utilsToMap(checkBindings(opts.bindingUtils))\n\t\t\t\t: undefined,\n\t\trecords: 'records' in opts ? opts.records : undefined,\n\t\tmigrations: 'migrations' in opts ? opts.migrations : undefined,\n\t})\n}\n\n/**\n * A helper for creating a TLStore.\n *\n * @param opts - Options for creating the store.\n *\n * @public\n */\nexport function createTLStore({\n\tinitialData,\n\tdefaultName = '',\n\tid,\n\tassets = inlineBase64AssetStore,\n\tusers = defaultUserStore,\n\tonMount,\n\tcollaboration,\n\t...rest\n}: TLStoreOptions = {}): TLStore {\n\tconst schema = createTLSchemaFromUtils(rest)\n\n\tconst store = new Store({\n\t\tid,\n\t\tschema,\n\t\tinitialData,\n\t\tprops: {\n\t\t\tdefaultName,\n\t\t\tassets: {\n\t\t\t\tupload: assets.upload,\n\t\t\t\tresolve: assets.resolve ?? defaultAssetResolve,\n\t\t\t\tremove: assets.remove ?? (() => Promise.resolve()),\n\t\t\t},\n\t\t\tusers: {\n\t\t\t\tcurrentUser: users.currentUser,\n\t\t\t\tresolve:\n\t\t\t\t\tusers.resolve ??\n\t\t\t\t\tcreateCachedUserResolve((userId) => {\n\t\t\t\t\t\tconst current = users.currentUser.get()\n\t\t\t\t\t\treturn current && current.id === createUserId(userId) ? current : null\n\t\t\t\t\t}),\n\t\t\t},\n\t\t\tonMount: (editor) => {\n\t\t\t\tassert(editor instanceof Editor)\n\t\t\t\tonMount?.(editor)\n\t\t\t},\n\t\t\tcollaboration,\n\t\t},\n\t})\n\n\tif (rest.snapshot) {\n\t\tif (initialData) throw new Error('Cannot provide both initialData and snapshot')\n\t\tloadSnapshot(store, rest.snapshot, { forceOverwriteSessionState: true })\n\t}\n\n\treturn store\n}\n\nfunction utilsToMap<T extends SchemaPropsInfo & { type: string }>(utils: T[]) {\n\treturn Object.fromEntries(\n\t\tutils.map((s): [string, SchemaPropsInfo] => [\n\t\t\ts.type,\n\t\t\t{\n\t\t\t\tprops: s.props,\n\t\t\t\tmigrations: s.migrations,\n\t\t\t},\n\t\t])\n\t)\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAiC;AACjC,mBAAqF;AACrF,sBAcO;AACP,mBAAoC;AACpC,oBAAuB;AACvB,6BAA2D;AAC3D,2BAAiE;AACjE,8BAA+C;AAC/C,+BAA2D;AAgD3D,MAAM,sBAA4D,CAAC,UAAU,MAAM,MAAM;AAEzF,MAAM,0BAA6C,uBAAS,sBAAsB,MAAM;AACvF,QAAM,YAAQ,6CAAmB;AACjC,MAAI,CAAC,MAAM,GAAI,QAAO;AACtB,SAAO,+BAAe,OAAO;AAAA,IAC5B,QAAI,8BAAa,MAAM,EAAE;AAAA,IACzB,MAAM,MAAM,QAAQ;AAAA,IACpB,OAAO,MAAM,SAAS,gDAAuB;AAAA,EAC9C,CAAC;AACF,CAAC;AAGM,MAAM,mBAAgC;AAAA,EAC5C,aAAa;AACd;AAGO,MAAM,yBAAuC;AAAA,EACnD,QAAQ,OAAO,GAAG,SAAS;AAC1B,WAAO,EAAE,KAAK,MAAM,yBAAY,cAAc,IAAI,EAAE;AAAA,EACrD;AACD;AAUO,SAAS,wBACf,MACsC;AACtC,MAAI,YAAY,QAAQ,KAAK,OAAQ,QAAO,KAAK;AAEjD,aAAO,gCAAe;AAAA,IACrB,QACC,gBAAgB,QAAQ,KAAK,aAC1B,eAAW,4CAAsB,KAAK,UAAU,CAAC,IACjD;AAAA,IACJ,UACC,kBAAkB,QAAQ,KAAK,eAC5B,eAAW,sCAAc,KAAK,YAAY,CAAC,IAC3C;AAAA,IACJ,SAAS,aAAa,OAAO,KAAK,UAAU;AAAA,IAC5C,YAAY,gBAAgB,OAAO,KAAK,aAAa;AAAA,EACtD,CAAC;AACF;AASO,SAAS,cAAc;AAAA,EAC7B;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA,SAAS;AAAA,EACT,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA,GAAG;AACJ,IAAoB,CAAC,GAAY;AAChC,QAAM,SAAS,wBAAwB,IAAI;AAE3C,QAAM,QAAQ,IAAI,mBAAM;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACP,QAAQ,OAAO;AAAA,QACf,SAAS,OAAO,WAAW;AAAA,QAC3B,QAAQ,OAAO,WAAW,MAAM,QAAQ,QAAQ;AAAA,MACjD;AAAA,MACA,OAAO;AAAA,QACN,aAAa,MAAM;AAAA,QACnB,SACC,MAAM,eACN,yCAAwB,CAAC,WAAW;AACnC,gBAAM,UAAU,MAAM,YAAY,IAAI;AACtC,iBAAO,WAAW,QAAQ,WAAO,8BAAa,MAAM,IAAI,UAAU;AAAA,QACnE,CAAC;AAAA,MACH;AAAA,MACA,SAAS,CAAC,WAAW;AACpB,iCAAO,kBAAkB,oBAAM;AAC/B,kBAAU,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,IACD;AAAA,EACD,CAAC;AAED,MAAI,KAAK,UAAU;AAClB,QAAI,YAAa,OAAM,IAAI,MAAM,8CAA8C;AAC/E,8CAAa,OAAO,KAAK,UAAU,EAAE,4BAA4B,KAAK,CAAC;AAAA,EACxE;AAEA,SAAO;AACR;AAEA,SAAS,WAAyD,OAAY;AAC7E,SAAO,OAAO;AAAA,IACb,MAAM,IAAI,CAAC,MAAiC;AAAA,MAC3C,EAAE;AAAA,MACF;AAAA,QACC,OAAO,EAAE;AAAA,QACT,YAAY,EAAE;AAAA,MACf;AAAA,IACD,CAAC;AAAA,EACF;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -44,7 +44,7 @@ var import_store = require("@tldraw/store");
|
|
|
44
44
|
var import_tlschema = require("@tldraw/tlschema");
|
|
45
45
|
var import_utils = require("@tldraw/utils");
|
|
46
46
|
var import_eventemitter3 = __toESM(require("eventemitter3"), 1);
|
|
47
|
-
var
|
|
47
|
+
var import_createTLCurrentUser = require("../config/createTLCurrentUser");
|
|
48
48
|
var import_defaultBindings = require("../config/defaultBindings");
|
|
49
49
|
var import_defaultShapes = require("../config/defaultShapes");
|
|
50
50
|
var import_TLEditorSnapshot = require("../config/TLEditorSnapshot");
|
|
@@ -132,13 +132,17 @@ class Editor extends import_eventemitter3.default {
|
|
|
132
132
|
...options?.camera
|
|
133
133
|
});
|
|
134
134
|
this._textOptions = (0, import_state.atom)("text options", options?.text ?? null);
|
|
135
|
-
this.user = new import_UserPreferencesManager.UserPreferencesManager(user ?? (0,
|
|
135
|
+
this.user = new import_UserPreferencesManager.UserPreferencesManager(user ?? (0, import_createTLCurrentUser.createTLCurrentUser)(), inferDarkMode ?? false);
|
|
136
136
|
this.disposables.add(() => this.user.dispose());
|
|
137
137
|
this.getContainer = getContainer;
|
|
138
138
|
this.textMeasure = new import_TextManager.TextManager(this);
|
|
139
139
|
this.disposables.add(() => this.textMeasure.dispose());
|
|
140
140
|
this.fonts = new import_FontManager.FontManager(this, fontAssetUrls);
|
|
141
141
|
this._tickManager = new import_TickManager.TickManager(this);
|
|
142
|
+
this.disposables.add(() => {
|
|
143
|
+
this.off("tick", this._decayCameraStateTimeout);
|
|
144
|
+
this._setCameraState("idle");
|
|
145
|
+
});
|
|
142
146
|
this.inputs = new import_InputsManager.InputsManager(this);
|
|
143
147
|
class NewRoot extends import_RootState.RootState {
|
|
144
148
|
static initial = initialState ?? "";
|
|
@@ -515,6 +519,14 @@ class Editor extends import_eventemitter3.default {
|
|
|
515
519
|
})
|
|
516
520
|
);
|
|
517
521
|
}
|
|
522
|
+
this.disposables.add(
|
|
523
|
+
(0, import_state.react)("sync current user record", () => {
|
|
524
|
+
const user2 = this.store.props.users.currentUser.get();
|
|
525
|
+
if (user2) {
|
|
526
|
+
this._ensureUserRecord(user2);
|
|
527
|
+
}
|
|
528
|
+
})
|
|
529
|
+
);
|
|
518
530
|
}
|
|
519
531
|
_getShapeVisibility;
|
|
520
532
|
getIsShapeHiddenCache() {
|
|
@@ -2821,6 +2833,76 @@ class Editor extends import_eventemitter3.default {
|
|
|
2821
2833
|
const currentPageId = this.getCurrentPageId();
|
|
2822
2834
|
return this.getCollaborators().filter((c) => c.currentPageId === currentPageId);
|
|
2823
2835
|
}
|
|
2836
|
+
// Attribution
|
|
2837
|
+
/**
|
|
2838
|
+
* Get the current user's ID for attribution purposes.
|
|
2839
|
+
* Also ensures a `user:` record exists in the store for the current user.
|
|
2840
|
+
* Returns `null` when the user store has no current user.
|
|
2841
|
+
*
|
|
2842
|
+
* @public
|
|
2843
|
+
*/
|
|
2844
|
+
getAttributionUserId() {
|
|
2845
|
+
const user = this.store.props.users.currentUser.get();
|
|
2846
|
+
if (!user) return null;
|
|
2847
|
+
this._ensureUserRecord(user);
|
|
2848
|
+
return import_tlschema.UserRecordType.parseId(user.id);
|
|
2849
|
+
}
|
|
2850
|
+
/**
|
|
2851
|
+
* Ensure a user record exists in the store for the given user,
|
|
2852
|
+
* updating it if the data has changed.
|
|
2853
|
+
*
|
|
2854
|
+
* @internal
|
|
2855
|
+
*/
|
|
2856
|
+
_ensureUserRecord(user) {
|
|
2857
|
+
const existing = this.store.get(user.id);
|
|
2858
|
+
if (existing && existing.name === user.name && existing.color === user.color && existing.imageUrl === user.imageUrl && existing.meta === user.meta) {
|
|
2859
|
+
return;
|
|
2860
|
+
}
|
|
2861
|
+
this.run(
|
|
2862
|
+
() => {
|
|
2863
|
+
this.store.put([user]);
|
|
2864
|
+
},
|
|
2865
|
+
{ history: "ignore" }
|
|
2866
|
+
);
|
|
2867
|
+
}
|
|
2868
|
+
/**
|
|
2869
|
+
* Resolve a display name for a user ID. Asks the
|
|
2870
|
+
* {@link @tldraw/tlschema#TLUserStore} first (the app's source of truth),
|
|
2871
|
+
* falling back to the `user:` record in the store.
|
|
2872
|
+
*
|
|
2873
|
+
* @public
|
|
2874
|
+
*/
|
|
2875
|
+
getAttributionDisplayName(userId) {
|
|
2876
|
+
if (!userId) return null;
|
|
2877
|
+
return this.store.props.users.resolve(userId).get()?.name ?? this.store.get((0, import_tlschema.createUserId)(userId))?.name ?? null;
|
|
2878
|
+
}
|
|
2879
|
+
/**
|
|
2880
|
+
* Resolve a user record by ID. Asks the
|
|
2881
|
+
* {@link @tldraw/tlschema#TLUserStore} first (the app's source of truth),
|
|
2882
|
+
* falling back to the `user:` record in the store.
|
|
2883
|
+
*
|
|
2884
|
+
* @public
|
|
2885
|
+
*/
|
|
2886
|
+
getAttributionUser(userId) {
|
|
2887
|
+
if (!userId) return null;
|
|
2888
|
+
return this.store.props.users.resolve(userId).get() ?? this.store.get((0, import_tlschema.createUserId)(userId)) ?? null;
|
|
2889
|
+
}
|
|
2890
|
+
/**
|
|
2891
|
+
* Collect user IDs referenced by a set of shapes via shape-specific props
|
|
2892
|
+
* (e.g. `textFirstEditedBy` on notes).
|
|
2893
|
+
*
|
|
2894
|
+
* @internal
|
|
2895
|
+
*/
|
|
2896
|
+
_getReferencedUserIds(shapes) {
|
|
2897
|
+
const userIds = /* @__PURE__ */ new Set();
|
|
2898
|
+
for (const shape of shapes) {
|
|
2899
|
+
const util = this.getShapeUtil(shape);
|
|
2900
|
+
for (const id of util.getReferencedUserIds(shape)) {
|
|
2901
|
+
userIds.add(id);
|
|
2902
|
+
}
|
|
2903
|
+
}
|
|
2904
|
+
return userIds;
|
|
2905
|
+
}
|
|
2824
2906
|
// Following
|
|
2825
2907
|
// When we are 'locked on' to a user, our camera is derived from their camera.
|
|
2826
2908
|
_isLockedOnFollowingUser = (0, import_state.atom)("isLockedOnFollowingUser", false);
|
|
@@ -6534,12 +6616,22 @@ class Editor extends import_eventemitter3.default {
|
|
|
6534
6616
|
if (!asset) continue;
|
|
6535
6617
|
assets.push(asset);
|
|
6536
6618
|
}
|
|
6619
|
+
const users = [];
|
|
6620
|
+
const seenUserIds = /* @__PURE__ */ new Set();
|
|
6621
|
+
for (const userId of this._getReferencedUserIds(shapes2)) {
|
|
6622
|
+
const recordId = (0, import_tlschema.createUserId)(userId);
|
|
6623
|
+
if (seenUserIds.has(recordId)) continue;
|
|
6624
|
+
seenUserIds.add(recordId);
|
|
6625
|
+
const user = this.store.get(recordId);
|
|
6626
|
+
if (user) users.push(user);
|
|
6627
|
+
}
|
|
6537
6628
|
return {
|
|
6538
6629
|
schema: this.store.schema.serialize(),
|
|
6539
6630
|
shapes: shapes2,
|
|
6540
6631
|
rootShapeIds,
|
|
6541
6632
|
bindings,
|
|
6542
|
-
assets
|
|
6633
|
+
assets,
|
|
6634
|
+
users
|
|
6543
6635
|
};
|
|
6544
6636
|
});
|
|
6545
6637
|
}
|
|
@@ -6589,13 +6681,15 @@ class Editor extends import_eventemitter3.default {
|
|
|
6589
6681
|
const assets = [];
|
|
6590
6682
|
const shapes = [];
|
|
6591
6683
|
const bindings = [];
|
|
6684
|
+
const users = [];
|
|
6592
6685
|
const store = {
|
|
6593
6686
|
store: {
|
|
6594
6687
|
...Object.fromEntries(content.assets.map((asset) => [asset.id, asset])),
|
|
6595
6688
|
...Object.fromEntries(content.shapes.map((shape) => [shape.id, shape])),
|
|
6596
6689
|
...Object.fromEntries(
|
|
6597
6690
|
content.bindings?.map((bindings2) => [bindings2.id, bindings2]) ?? []
|
|
6598
|
-
)
|
|
6691
|
+
),
|
|
6692
|
+
...Object.fromEntries(content.users?.map((user) => [user.id, user]) ?? [])
|
|
6599
6693
|
},
|
|
6600
6694
|
schema: content.schema
|
|
6601
6695
|
};
|
|
@@ -6617,6 +6711,19 @@ class Editor extends import_eventemitter3.default {
|
|
|
6617
6711
|
bindings.push(record);
|
|
6618
6712
|
break;
|
|
6619
6713
|
}
|
|
6714
|
+
case "user": {
|
|
6715
|
+
users.push(record);
|
|
6716
|
+
break;
|
|
6717
|
+
}
|
|
6718
|
+
}
|
|
6719
|
+
}
|
|
6720
|
+
if (users.length > 0) {
|
|
6721
|
+
const existingUserIds = new Set(
|
|
6722
|
+
this.store.allRecords().filter((r) => r.typeName === "user").map((r) => r.id)
|
|
6723
|
+
);
|
|
6724
|
+
const usersToCreate = users.filter((u) => !existingUserIds.has(u.id));
|
|
6725
|
+
if (usersToCreate.length > 0) {
|
|
6726
|
+
this.store.put(usersToCreate);
|
|
6620
6727
|
}
|
|
6621
6728
|
}
|
|
6622
6729
|
const shapeIdMap = new Map(
|