sanity-plugin-graph-view 1.0.7 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,980 +0,0 @@
1
- 'use strict'
2
-
3
- var _interopRequireWildcard = require('@babel/runtime/helpers/interopRequireWildcard')
4
-
5
- var _interopRequireDefault = require('@babel/runtime/helpers/interopRequireDefault')
6
-
7
- Object.defineProperty(exports, '__esModule', {
8
- value: true,
9
- })
10
- exports.GraphView = GraphView
11
-
12
- var _toConsumableArray2 = _interopRequireDefault(
13
- require('@babel/runtime/helpers/toConsumableArray')
14
- )
15
-
16
- var _regenerator = _interopRequireDefault(require('@babel/runtime/regenerator'))
17
-
18
- var _asyncToGenerator2 = _interopRequireDefault(require('@babel/runtime/helpers/asyncToGenerator'))
19
-
20
- var _classCallCheck2 = _interopRequireDefault(require('@babel/runtime/helpers/classCallCheck'))
21
-
22
- var _createClass2 = _interopRequireDefault(require('@babel/runtime/helpers/createClass'))
23
-
24
- var _defineProperty2 = _interopRequireDefault(require('@babel/runtime/helpers/defineProperty'))
25
-
26
- var _slicedToArray2 = _interopRequireDefault(require('@babel/runtime/helpers/slicedToArray'))
27
-
28
- var _typeof2 = _interopRequireDefault(require('@babel/runtime/helpers/typeof'))
29
-
30
- var _userColor = require('@sanity/base/user-color')
31
-
32
- var _color = require('@sanity/color')
33
-
34
- var _polished = require('polished')
35
-
36
- var _deepEqual = _interopRequireDefault(require('deep-equal'))
37
-
38
- var _react = _interopRequireWildcard(require('react'))
39
-
40
- var _client = _interopRequireDefault(require('part:@sanity/base/client'))
41
-
42
- var _reactForceGraph = require('react-force-graph')
43
-
44
- var _uuid = require('uuid')
45
-
46
- var _bezierEasing = _interopRequireDefault(require('bezier-easing'))
47
-
48
- var _router = require('part:@sanity/base/router')
49
-
50
- var _hooks = require('./hooks')
51
-
52
- var _GraphTool = _interopRequireDefault(require('./GraphView.css'))
53
-
54
- function _createForOfIteratorHelper(o, allowArrayLike) {
55
- var it
56
- if (typeof Symbol === 'undefined' || o[Symbol.iterator] == null) {
57
- if (
58
- Array.isArray(o) ||
59
- (it = _unsupportedIterableToArray(o)) ||
60
- (allowArrayLike && o && typeof o.length === 'number')
61
- ) {
62
- if (it) o = it
63
- var i = 0
64
- var F = function F() {}
65
- return {
66
- s: F,
67
- n: function n() {
68
- if (i >= o.length) return {done: true}
69
- return {done: false, value: o[i++]}
70
- },
71
- e: function e(_e) {
72
- throw _e
73
- },
74
- f: F,
75
- }
76
- }
77
- throw new TypeError(
78
- 'Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.'
79
- )
80
- }
81
- var normalCompletion = true,
82
- didErr = false,
83
- err
84
- return {
85
- s: function s() {
86
- it = o[Symbol.iterator]()
87
- },
88
- n: function n() {
89
- var step = it.next()
90
- normalCompletion = step.done
91
- return step
92
- },
93
- e: function e(_e2) {
94
- didErr = true
95
- err = _e2
96
- },
97
- f: function f() {
98
- try {
99
- if (!normalCompletion && it['return'] != null) it['return']()
100
- } finally {
101
- if (didErr) throw err
102
- }
103
- },
104
- }
105
- }
106
-
107
- function _unsupportedIterableToArray(o, minLen) {
108
- if (!o) return
109
- if (typeof o === 'string') return _arrayLikeToArray(o, minLen)
110
- var n = Object.prototype.toString.call(o).slice(8, -1)
111
- if (n === 'Object' && o.constructor) n = o.constructor.name
112
- if (n === 'Map' || n === 'Set') return Array.from(o)
113
- if (n === 'Arguments' || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))
114
- return _arrayLikeToArray(o, minLen)
115
- }
116
-
117
- function _arrayLikeToArray(arr, len) {
118
- if (len == null || len > arr.length) len = arr.length
119
- for (var i = 0, arr2 = new Array(len); i < len; i++) {
120
- arr2[i] = arr[i]
121
- }
122
- return arr2
123
- }
124
-
125
- var QUERY =
126
- '\n *[\n !(_id in path("_.*")) &&\n !(_type match "system.*") &&\n !(_type match "mux.*") &&\n !(_type match "workflow.*") &&\n _type != "feedback" &&\n _type != "sanity.imageAsset"\n ]\n'
127
- var fadeEasing = (0, _bezierEasing['default'])(0, 0.9, 1, 1)
128
- var softEasing = (0, _bezierEasing['default'])(0.25, 0.1, 0.0, 1.0)
129
- var imageSize = 40
130
-
131
- function sortBy(array, f) {
132
- return array.sort(function (a, b) {
133
- var va = f(a)
134
- var vb = f(b)
135
- return va < vb ? -1 : va > vb ? 1 : 0
136
- })
137
- }
138
-
139
- function getTopDocTypes(counts) {
140
- return sortBy(Object.keys(counts), function (docType) {
141
- return counts[docType] || 0
142
- })
143
- .reverse()
144
- .slice(0, 10)
145
- }
146
-
147
- function formatDocType(docType) {
148
- return (docType.substring(0, 1).toUpperCase() + docType.substring(1))
149
- .replace(/\./g, ' ')
150
- .replace(/[A-Z]/g, ' $&')
151
- .trim()
152
- }
153
-
154
- function getDocTypeCounts(docs) {
155
- var types = {}
156
-
157
- var _iterator = _createForOfIteratorHelper(docs),
158
- _step
159
-
160
- try {
161
- for (_iterator.s(); !(_step = _iterator.n()).done; ) {
162
- var doc = _step.value
163
- types[doc._type] = (types[doc._type] || 0) + 1
164
- }
165
- } catch (err) {
166
- _iterator.e(err)
167
- } finally {
168
- _iterator.f()
169
- }
170
-
171
- return types
172
- }
173
-
174
- function truncate(s, limit) {
175
- if (s.length > limit) {
176
- s = s.substring(0, limit) + '…'
177
- }
178
-
179
- return s
180
- }
181
-
182
- function labelFor(doc) {
183
- return ''.concat(doc.title || doc.name || doc._id).trim()
184
- }
185
-
186
- function valueFor(doc, maxSize) {
187
- return 5 + 100 * (sizeOf(doc) / maxSize)
188
- }
189
-
190
- function findRefs(obj) {
191
- var dest = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []
192
-
193
- if (obj != null) {
194
- if ((0, _typeof2['default'])(obj) === 'object') {
195
- for (var _i = 0, _Object$entries = Object.entries(obj); _i < _Object$entries.length; _i++) {
196
- var _Object$entries$_i = (0, _slicedToArray2['default'])(_Object$entries[_i], 2),
197
- k = _Object$entries$_i[0],
198
- v = _Object$entries$_i[1]
199
-
200
- if (k === '_ref' && typeof v === 'string' && v.length > 0) {
201
- dest.push(stripDraftId(v))
202
- }
203
-
204
- findRefs(v, dest)
205
- }
206
- } else if (Array.isArray(obj)) {
207
- var _iterator2 = _createForOfIteratorHelper(obj),
208
- _step2
209
-
210
- try {
211
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done; ) {
212
- var _v = _step2.value
213
- findRefs(_v, dest)
214
- }
215
- } catch (err) {
216
- _iterator2.e(err)
217
- } finally {
218
- _iterator2.f()
219
- }
220
- }
221
- }
222
-
223
- return dest
224
- }
225
-
226
- function sizeOf(value) {
227
- if (value == null) {
228
- return 0
229
- }
230
-
231
- if ((0, _typeof2['default'])(value) === 'object') {
232
- return Object.entries(value).reduce(function (total, _ref) {
233
- var _ref2 = (0, _slicedToArray2['default'])(_ref, 2),
234
- k = _ref2[0],
235
- v = _ref2[1]
236
-
237
- return total + sizeOf(k) + sizeOf(v)
238
- }, 0)
239
- }
240
-
241
- if (Array.isArray(value)) {
242
- return Object.entries(value).reduce(function (total, v) {
243
- return total + sizeOf(v)
244
- }, 0)
245
- }
246
-
247
- if (typeof value === 'string') {
248
- return value.length
249
- }
250
-
251
- return 1
252
- }
253
-
254
- function loadImage(url) {
255
- return new Promise(function (resolve) {
256
- var img = new Image(imageSize, imageSize)
257
-
258
- img.onload = function () {
259
- resolve(img)
260
- }
261
-
262
- img.onerror = function (event) {
263
- console.log('Image error', event)
264
- resolve(null)
265
- }
266
-
267
- img.src = url
268
- })
269
- }
270
-
271
- function stripDraftId(id) {
272
- return id.replace(/^drafts\./, '')
273
- }
274
-
275
- function deduplicateDrafts(docs) {
276
- var deduped = {}
277
-
278
- var _iterator3 = _createForOfIteratorHelper(docs),
279
- _step3
280
-
281
- try {
282
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done; ) {
283
- var doc = _step3.value
284
-
285
- if (!/^drafts\./.test(doc._id)) {
286
- deduped[doc._id] = doc
287
- }
288
- }
289
- } catch (err) {
290
- _iterator3.e(err)
291
- } finally {
292
- _iterator3.f()
293
- }
294
-
295
- var _iterator4 = _createForOfIteratorHelper(docs),
296
- _step4
297
-
298
- try {
299
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done; ) {
300
- var _doc = _step4.value
301
-
302
- if (/^drafts\./.test(_doc._id)) {
303
- var id = stripDraftId(_doc._id)
304
- deduped[id] = Object.assign(_doc, {
305
- _id: id,
306
- })
307
- }
308
- }
309
- } catch (err) {
310
- _iterator4.e(err)
311
- } finally {
312
- _iterator4.f()
313
- }
314
-
315
- return Object.values(deduped)
316
- }
317
-
318
- var Users = /*#__PURE__*/ (function () {
319
- function Users() {
320
- ;(0, _classCallCheck2['default'])(this, Users)
321
- ;(0, _defineProperty2['default'])(this, '_users', [])
322
- }
323
-
324
- ;(0, _createClass2['default'])(Users, [
325
- {
326
- key: 'getById',
327
- value: (function () {
328
- var _getById = (0, _asyncToGenerator2['default'])(
329
- /*#__PURE__*/ _regenerator['default'].mark(function _callee(id) {
330
- var user
331
- return _regenerator['default'].wrap(
332
- function _callee$(_context) {
333
- while (1) {
334
- switch ((_context.prev = _context.next)) {
335
- case 0:
336
- user = this._users.find(function (u) {
337
- return u._id === id
338
- })
339
-
340
- if (user) {
341
- _context.next = 10
342
- break
343
- }
344
-
345
- _context.next = 4
346
- return _client['default'].users.getById(id)
347
-
348
- case 4:
349
- user = _context.sent
350
-
351
- if (/\(Robot\)$/.test(user.displayName)) {
352
- user = robotUsers[Date.now() % robotUsers.length]
353
- }
354
-
355
- this._users.push(user)
356
-
357
- _context.next = 9
358
- return loadImage(
359
- user.imageUrl ||
360
- 'https://concernedchristianmen.org/wp-content/uploads/2016/11/head-silhouette.jpg'
361
- )
362
-
363
- case 9:
364
- user.image = _context.sent
365
-
366
- case 10:
367
- return _context.abrupt('return', user)
368
-
369
- case 11:
370
- case 'end':
371
- return _context.stop()
372
- }
373
- }
374
- },
375
- _callee,
376
- this
377
- )
378
- })
379
- )
380
-
381
- function getById(_x) {
382
- return _getById.apply(this, arguments)
383
- }
384
-
385
- return getById
386
- })(),
387
- },
388
- ])
389
- return Users
390
- })()
391
-
392
- var users = new Users()
393
- var idleTimeout = 10000
394
- var robotUsers = [
395
- {
396
- displayName: 'Ole',
397
- imageUrl:
398
- 'https://cdn.sanity.io/images/ze41ydzg/production/a7e0a0a03a59cccfd06d3bcdb5df71b75401bd28-1024x1024.png?w=80&h=80&fit=crop',
399
- },
400
- {
401
- displayName: 'Jan-Tore',
402
- imageUrl:
403
- 'https://cdn.sanity.io/images/ze41ydzg/production/a79906968185c6e8a3658bcca42a79433222cc3e-1024x1024.png?w=80&h=80&fit=crop',
404
- },
405
- {
406
- displayName: 'Stein',
407
- imageUrl:
408
- 'https://cdn.sanity.io/images/ze41ydzg/production/e579ed13f214ccc1e158ed42f46a30935afeb9e0-1024x1024.png?w=80&h=80&fit=crop',
409
- },
410
- {
411
- displayName: 'Elvis',
412
- imageUrl:
413
- 'https://cdn.sanity.io/images/ze41ydzg/production/be36eb26194cb3ae3e218b1cf01d7c6c3425cf65-1024x1024.png?w=80&h=80&fit=crop',
414
- },
415
- {
416
- displayName: 'Amanda',
417
- imageUrl:
418
- 'https://cdn.sanity.io/images/ze41ydzg/production/88e1da4f85f95856c9736aa4637e2bbf48ed6773-1024x1024.png?w=80&h=80&fit=crop',
419
- },
420
- {
421
- displayName: 'Reidun',
422
- imageUrl:
423
- 'https://cdn.sanity.io/images/ze41ydzg/production/a79906968185c6e8a3658bcca42a79433222cc3e-1024x1024.png?w=80&h=80&fit=crop',
424
- },
425
- {
426
- displayName: 'Tina',
427
- imageUrl:
428
- 'https://cdn.sanity.io/images/ze41ydzg/production/6f6df5d7cc72f13988ad05ee026b567985bf1cf2-1024x1024.png?w=80&h=80&fit=crop',
429
- },
430
- ]
431
-
432
- var EditSession = function EditSession() {
433
- ;(0, _classCallCheck2['default'])(this, EditSession)
434
- ;(0, _defineProperty2['default'])(this, 'user', null)
435
- ;(0, _defineProperty2['default'])(this, 'doc', null)
436
- ;(0, _defineProperty2['default'])(this, 'lastActive', null)
437
- }
438
-
439
- var GraphData = /*#__PURE__*/ (function () {
440
- function GraphData() {
441
- var docs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []
442
- ;(0, _classCallCheck2['default'])(this, GraphData)
443
- ;(0, _defineProperty2['default'])(this, 'sessions', [])
444
- var docsById = {}
445
-
446
- var _iterator5 = _createForOfIteratorHelper(docs),
447
- _step5
448
-
449
- try {
450
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done; ) {
451
- var doc = _step5.value
452
- docsById[doc._id] = doc
453
- }
454
- } catch (err) {
455
- _iterator5.e(err)
456
- } finally {
457
- _iterator5.f()
458
- }
459
-
460
- this.data = {
461
- nodes: docs.map(function (d) {
462
- return Object.assign({
463
- id: d._id,
464
- type: 'document',
465
- doc: d,
466
- })
467
- }),
468
- links: docs
469
- .flatMap(function (doc) {
470
- return findRefs(doc).map(function (ref) {
471
- return {
472
- source: doc._id,
473
- target: ref,
474
- }
475
- })
476
- })
477
- .filter(function (link) {
478
- return docsById[link.source] && docsById[link.target]
479
- }),
480
- }
481
- }
482
-
483
- ;(0, _createClass2['default'])(GraphData, [
484
- {
485
- key: 'setEditSession',
486
- value: function setEditSession(user, docNode) {
487
- var session = this.sessions.find(function (s) {
488
- return s.user.id === user.id && s.doc._id === docNode.doc._id
489
- })
490
-
491
- if (!session) {
492
- session = new EditSession()
493
- session.id = (0, _uuid.v4)()
494
- session.user = user
495
- session.startTime = Date.now()
496
- session.doc = docNode.doc
497
- session.angle = Math.random() * 2 * Math.PI
498
- this.sessions.push(session)
499
- }
500
-
501
- session.lastActive = Date.now()
502
- },
503
- },
504
- {
505
- key: 'reapSessions',
506
- value: function reapSessions() {
507
- for (var i = 0; i < this.sessions.length; i++) {
508
- var session = this.sessions[i]
509
-
510
- if (Date.now() - session.lastActive > idleTimeout) {
511
- this.sessions = [].concat(
512
- (0, _toConsumableArray2['default'])(this.sessions.slice(0, i)),
513
- (0, _toConsumableArray2['default'])(this.sessions.slice(i + 1))
514
- )
515
- i--
516
- }
517
- }
518
- },
519
- },
520
- {
521
- key: 'clone',
522
- value: function clone() {
523
- var copy = new GraphData()
524
- Object.assign(copy, this)
525
- copy.data = {
526
- nodes: (0, _toConsumableArray2['default'])(this.data.nodes),
527
- links: (0, _toConsumableArray2['default'])(this.data.links),
528
- }
529
- return copy
530
- },
531
- },
532
- ])
533
- return GraphData
534
- })()
535
-
536
- function GraphView() {
537
- var userColorManager = (0, _userColor.useUserColorManager)()
538
-
539
- var _useState = (0, _react.useState)(0),
540
- _useState2 = (0, _slicedToArray2['default'])(_useState, 2),
541
- maxSize = _useState2[0],
542
- setMaxSize = _useState2[1]
543
-
544
- var _useState3 = (0, _react.useState)(null),
545
- _useState4 = (0, _slicedToArray2['default'])(_useState3, 2),
546
- hoverNode = _useState4[0],
547
- setHoverNode = _useState4[1]
548
-
549
- var _useState5 = (0, _react.useState)([]),
550
- _useState6 = (0, _slicedToArray2['default'])(_useState5, 2),
551
- documents = _useState6[0],
552
- setDocuments = _useState6[1]
553
-
554
- var _useState7 = (0, _react.useState)([]),
555
- _useState8 = (0, _slicedToArray2['default'])(_useState7, 2),
556
- docTypes = _useState8[0],
557
- setDocTypes = _useState8[1]
558
-
559
- var _useState9 = (0, _react.useState)(function () {
560
- return new GraphData()
561
- }),
562
- _useState10 = (0, _slicedToArray2['default'])(_useState9, 2),
563
- graph = _useState10[0],
564
- setGraph = _useState10[1]
565
-
566
- var router = (0, _router.useRouter)()
567
- var fetchCallback = (0, _react.useCallback)(function (docs) {
568
- docs = deduplicateDrafts(docs)
569
- setMaxSize(Math.max.apply(Math, (0, _toConsumableArray2['default'])(docs.map(sizeOf))))
570
- setDocuments(docs)
571
- setDocTypes(getDocTypeCounts(docs))
572
- setGraph(new GraphData(docs))
573
- }, [])
574
- var listenCallback = (0, _react.useCallback)(
575
- /*#__PURE__*/ (function () {
576
- var _ref3 = (0, _asyncToGenerator2['default'])(
577
- /*#__PURE__*/ _regenerator['default'].mark(function _callee2(update) {
578
- var doc,
579
- _docsById,
580
- _iterator6,
581
- _step6,
582
- _doc2,
583
- oldDoc,
584
- docs,
585
- idx,
586
- newGraph,
587
- graphChanged,
588
- oldRefs,
589
- newRefs,
590
- docNode,
591
- nodeIdx,
592
- user,
593
- docId,
594
- _docs,
595
- _newGraph
596
-
597
- return _regenerator['default'].wrap(function _callee2$(_context2) {
598
- while (1) {
599
- switch ((_context2.prev = _context2.next)) {
600
- case 0:
601
- console.log('Update:', update)
602
- doc = update.result
603
-
604
- if (!doc) {
605
- _context2.next = 27
606
- break
607
- }
608
-
609
- doc._id = stripDraftId(doc._id)
610
- _docsById = {}
611
- _iterator6 = _createForOfIteratorHelper(documents)
612
-
613
- try {
614
- for (_iterator6.s(); !(_step6 = _iterator6.n()).done; ) {
615
- _doc2 = _step6.value
616
- _docsById[_doc2._id] = _doc2
617
- }
618
- } catch (err) {
619
- _iterator6.e(err)
620
- } finally {
621
- _iterator6.f()
622
- }
623
-
624
- docs = (0, _toConsumableArray2['default'])(documents)
625
- idx = documents.findIndex(function (d) {
626
- return d._id === doc._id
627
- })
628
-
629
- if (idx >= 0) {
630
- oldDoc = docs[idx]
631
- docs[idx] = doc
632
- } else {
633
- docs.push(doc)
634
- }
635
-
636
- setDocuments(docs)
637
- setDocTypes(getDocTypeCounts(docs))
638
- setMaxSize(
639
- Math.max.apply(Math, (0, _toConsumableArray2['default'])(docs.map(sizeOf)))
640
- )
641
- newGraph = graph.clone()
642
- graphChanged = false
643
- oldRefs = findRefs(oldDoc || {}).filter(function (id) {
644
- return id === doc._id || _docsById[id] != null
645
- })
646
- newRefs = findRefs(doc).filter(function (id) {
647
- return id === doc._id || _docsById[id] != null
648
- })
649
-
650
- if (!(0, _deepEqual['default'])(oldRefs, newRefs)) {
651
- graphChanged = true
652
- newGraph.data.links = newGraph.data.links
653
- .filter(function (l) {
654
- return l.source.id !== doc._id
655
- })
656
- .concat(
657
- newRefs.map(function (ref) {
658
- return {
659
- source: doc._id,
660
- target: ref,
661
- }
662
- })
663
- )
664
- }
665
-
666
- nodeIdx = graph.data.nodes.findIndex(function (n) {
667
- return n.doc && n.doc._id === doc._id
668
- })
669
-
670
- if (nodeIdx >= 0) {
671
- docNode = graph.data.nodes[nodeIdx]
672
- docNode.doc = doc
673
- } else {
674
- docNode = {
675
- id: doc._id,
676
- type: 'document',
677
- doc: doc,
678
- }
679
- newGraph.data.nodes.push(docNode)
680
- graphChanged = true
681
- }
682
-
683
- if (graphChanged) {
684
- setGraph(newGraph)
685
- }
686
-
687
- _context2.next = 23
688
- return users.getById(update.identity)
689
-
690
- case 23:
691
- user = _context2.sent
692
- graph.setEditSession(user, docNode)
693
- _context2.next = 28
694
- break
695
-
696
- case 27:
697
- if (update.transition === 'disappear') {
698
- docId = stripDraftId(update.documentId)
699
- _docs = documents.filter(function (d) {
700
- return d._id !== docId
701
- })
702
- setDocuments(_docs)
703
- setDocTypes(getDocTypeCounts(_docs))
704
- setMaxSize(
705
- Math.max.apply(Math, (0, _toConsumableArray2['default'])(_docs.map(sizeOf)))
706
- )
707
- _newGraph = graph.clone()
708
- _newGraph.data.links = _newGraph.data.links.filter(function (l) {
709
- return l.source.id !== docId && l.target.id !== docId
710
- })
711
- _newGraph.data.nodes = _newGraph.data.nodes.filter(function (n) {
712
- return n.id !== docId
713
- })
714
- setGraph(_newGraph)
715
- }
716
-
717
- case 28:
718
- case 'end':
719
- return _context2.stop()
720
- }
721
- }
722
- }, _callee2)
723
- })
724
- )
725
-
726
- return function (_x2) {
727
- return _ref3.apply(this, arguments)
728
- }
729
- })(),
730
- [documents, graph]
731
- )
732
- ;(0, _hooks.useFetchDocuments)(QUERY, fetchCallback, [])
733
- ;(0, _hooks.useListen)(QUERY, {}, {}, listenCallback, [documents, graph])
734
- ;(0, _react.useEffect)(
735
- function () {
736
- var interval = setInterval(function () {
737
- graph.reapSessions()
738
- }, 1000)
739
- return function () {
740
- return clearInterval(interval)
741
- }
742
- },
743
- [graph]
744
- )
745
- return /*#__PURE__*/ _react['default'].createElement(
746
- 'div',
747
- {
748
- className: _GraphTool['default'].root,
749
- style: {
750
- background: _color.color.black.hex,
751
- },
752
- },
753
- /*#__PURE__*/ _react['default'].createElement(
754
- 'div',
755
- {
756
- className: _GraphTool['default'].legend,
757
- },
758
- getTopDocTypes(docTypes).map(function (docType) {
759
- return /*#__PURE__*/ _react['default'].createElement(
760
- 'div',
761
- {
762
- className: _GraphTool['default'].legend__row,
763
- key: docType,
764
- style: {
765
- color: getDocTypeColor(docType).fill,
766
- },
767
- },
768
- /*#__PURE__*/ _react['default'].createElement('div', {
769
- className: _GraphTool['default'].legend__badge,
770
- }),
771
- /*#__PURE__*/ _react['default'].createElement(
772
- 'div',
773
- {
774
- className: _GraphTool['default'].legend__title,
775
- },
776
- formatDocType(docType)
777
- )
778
- )
779
- })
780
- ),
781
- hoverNode &&
782
- /*#__PURE__*/ _react['default'].createElement(
783
- 'div',
784
- {
785
- className: _GraphTool['default'].hoverNode,
786
- },
787
- labelFor(hoverNode.doc)
788
- ),
789
- /*#__PURE__*/ _react['default'].createElement(_reactForceGraph.ForceGraph2D, {
790
- graphData: graph.data,
791
- nodeAutoColorBy: 'group',
792
- numDimensions: 2,
793
- enableNodeDrag: false,
794
- onNodeHover: function onNodeHover(node) {
795
- return setHoverNode(node)
796
- },
797
- onNodeClick: function onNodeClick(node) {
798
- router.navigateIntent('edit', {
799
- id: node.doc._id,
800
- documentType: node.doc._type,
801
- })
802
- },
803
- linkColor: function linkColor() {
804
- return (0, _polished.rgba)(_color.color.gray[500].hex, 0.25)
805
- },
806
- nodeLabel: function nodeLabel() {
807
- return null
808
- },
809
- nodeRelSize: 1,
810
- nodeVal: function nodeVal(node) {
811
- return valueFor(node.doc, maxSize)
812
- },
813
- onRenderFramePost: function onRenderFramePost(ctx, globalScale) {
814
- var _iterator7 = _createForOfIteratorHelper(graph.sessions),
815
- _step7
816
-
817
- try {
818
- var _loop = function _loop() {
819
- var session = _step7.value
820
- var node = graph.data.nodes.find(function (n) {
821
- return n.doc && n.doc._id === session.doc._id
822
- })
823
-
824
- if (node) {
825
- var idleFactorRange = idleTimeout
826
- ctx.save()
827
- ctx.globalAlpha = fadeEasing(
828
- 1 - Math.min(idleFactorRange, Date.now() - session.lastActive) / idleFactorRange
829
- )
830
- ctx.font = 'bold '.concat(Math.round(12 / globalScale), 'px sans-serif')
831
- var angle = session.angle
832
- var radius = Math.sqrt(valueFor(node.doc, maxSize))
833
- var image = session.user.image
834
- var userColor = userColorManager.get(session.user.displayName).tints[400].hex
835
- var distance = radius * globalScale + 40
836
- var imgW = image ? image.width : 0
837
- var imgH = image ? image.height : 0
838
- var x = node.x + (Math.sin(angle) * distance) / globalScale
839
- var y = node.y + (Math.cos(angle) * distance) / globalScale
840
- ctx.beginPath()
841
- ctx.strokeStyle = (0, _polished.rgba)(_color.color.white.hex, 1.0)
842
- ctx.lineWidth = 2 / globalScale
843
- ctx.moveTo(
844
- node.x + (Math.sin(angle) * (distance - imgW / 2)) / globalScale,
845
- node.y + (Math.cos(angle) * (distance - imgH / 2)) / globalScale
846
- )
847
- ctx.lineTo(node.x + Math.sin(angle) * radius, node.y + Math.cos(angle) * radius)
848
- ctx.stroke()
849
- ctx.beginPath()
850
- ctx.strokeStyle = (0, _polished.rgba)(_color.color.white.hex, 1.0)
851
- ctx.lineWidth = 2 / globalScale
852
- ctx.arc(node.x, node.y, radius, 0, 2 * Math.PI, false)
853
- ctx.stroke()
854
-
855
- if (image) {
856
- ctx.save()
857
- var dur = 700
858
- var f = softEasing(Math.max(0, (dur - (Date.now() - session.startTime)) / dur))
859
-
860
- if (f > 0) {
861
- ctx.beginPath()
862
- ctx.fillStyle = (0, _polished.rgba)(userColor, f)
863
- ctx.arc(x, y, (imgW / 2 + 10) / globalScale, 0, 2 * Math.PI, false)
864
- ctx.fill()
865
- }
866
-
867
- ctx.beginPath()
868
- ctx.fillStyle = (0, _polished.rgba)(_color.color.white.hex, 1.0)
869
- ctx.arc(x, y, imgW / globalScale / 2, 0, 2 * Math.PI, false)
870
- ctx.clip()
871
- ctx.drawImage(
872
- image,
873
- x - imgW / globalScale / 2,
874
- y - imgH / globalScale / 2,
875
- imgW / globalScale,
876
- imgH / globalScale
877
- )
878
- ctx.strokeStyle = _color.color.black.hex
879
- ctx.lineWidth = 6 / globalScale
880
- ctx.stroke()
881
- ctx.strokeStyle = userColor
882
- ctx.lineWidth = 4 / globalScale
883
- ctx.stroke()
884
- ctx.restore()
885
- }
886
-
887
- ctx.beginPath()
888
- ctx.strokeStyle = (0, _polished.rgba)(_color.color.black.hex, 1)
889
- ctx.lineWidth = 0.5 / globalScale
890
- ctx.arc(x, y, imgW / globalScale / 2, 0, 2 * Math.PI, false)
891
- ctx.stroke()
892
- var above = angle >= Math.PI / 2 && angle < Math.PI * 1.5
893
- var textY = above
894
- ? y - (imgH / 2 + 5) / globalScale
895
- : y + (imgH / 2 + 5) / globalScale
896
- ctx.fillStyle = (0, _polished.rgba)(_color.color.white.hex, 1.0)
897
- ctx.textAlign = 'center'
898
- ctx.textBaseline = above ? 'bottom' : 'top'
899
- ctx.fillText(session.user.displayName, x, textY)
900
- ctx.restore()
901
- }
902
- }
903
-
904
- for (_iterator7.s(); !(_step7 = _iterator7.n()).done; ) {
905
- _loop()
906
- }
907
- } catch (err) {
908
- _iterator7.e(err)
909
- } finally {
910
- _iterator7.f()
911
- }
912
- },
913
- nodeCanvasObject: function nodeCanvasObject(node, ctx, globalScale) {
914
- switch (node.type) {
915
- case 'document': {
916
- var nodeColor = getDocTypeColor(node.doc._type)
917
- var radius = Math.sqrt(valueFor(node.doc, maxSize))
918
- var fontSize = Math.min(100, 10.0 / globalScale)
919
- ctx.beginPath()
920
- ctx.fillStyle =
921
- hoverNode != null && node.doc._id === hoverNode.doc._id
922
- ? (0, _polished.rgba)(_color.color.gray[500].hex, 0.8)
923
- : nodeColor.fill
924
- ctx.strokeStyle = nodeColor.border
925
- ctx.lineWidth = 0.5
926
- ctx.arc(node.x, node.y, radius, 0, 2 * Math.PI, false)
927
- ctx.stroke()
928
- ctx.fill()
929
-
930
- if (radius * globalScale > 10) {
931
- ctx.font = ''.concat(fontSize, 'px sans-serif')
932
- var w = radius * 2 + 30 / globalScale
933
-
934
- for (var len = 50; len >= 5; len /= 1.2) {
935
- var label = truncate(labelFor(node.doc), Math.round(len))
936
- var textMetrics = ctx.measureText(label)
937
-
938
- if (textMetrics.width < w) {
939
- // ctx.fillStyle = rgba(color.white.hex, 1.0)
940
- ctx.textAlign = 'center'
941
- ctx.textBaseline = 'top'
942
- ctx.strokeStyle = (0, _polished.rgba)(_color.color.black.hex, 0.5)
943
- ctx.lineWidth = 2 / globalScale
944
- ctx.strokeText(label, node.x, node.y + radius + 5 / globalScale)
945
- ctx.fillText(label, node.x, node.y + radius + 5 / globalScale)
946
- break
947
- }
948
- }
949
- }
950
- }
951
- }
952
- },
953
- linkCanvasObject: function linkCanvasObject(link, ctx, globalScale) {
954
- ctx.beginPath()
955
- ctx.strokeStyle = (0, _polished.rgba)(_color.color.gray[500].hex, 0.125)
956
- ctx.lineWidth = 2 / globalScale
957
- ctx.moveTo(link.source.x, link.source.y)
958
- ctx.lineTo(link.target.x, link.target.y)
959
- ctx.stroke()
960
- },
961
- })
962
- )
963
- }
964
-
965
- var colorCache = {}
966
- var typeColorNum = 0
967
-
968
- function getDocTypeColor(docType) {
969
- if (colorCache[docType]) {
970
- return colorCache[docType]
971
- }
972
-
973
- var hue = _color.COLOR_HUES[typeColorNum % _color.COLOR_HUES.length]
974
- typeColorNum += 1
975
- colorCache[docType] = {
976
- fill: _color.color[hue][400].hex,
977
- border: (0, _polished.rgba)(_color.color.black.hex, 0.5),
978
- }
979
- return colorCache[docType]
980
- }