git ssb

10+

Matt McKegg / patchwork



Tree: b0d0023156505d649f8c12faf827dd3d345a64d1

Files: b0d0023156505d649f8c12faf827dd3d345a64d1 / modules / app / link-preview.js

3002 bytesRaw
1var { h, Value, computed } = require('mutant')
2var ObserveLinkHover = require('../../lib/observe-link-hover')
3var ref = require('ssb-ref')
4
5var nest = require('depnest')
6
7exports.needs = nest({
8 'intl.sync.i18n': 'first',
9 'profile.html.preview': 'first',
10 'channel.html.preview': 'first'
11})
12
13exports.gives = nest('app.linkPreview')
14
15exports.create = function (api) {
16 var i18n = api.intl.sync.i18n
17 return nest('app.linkPreview', function (container, delay) {
18 var currentHover = ObserveLinkHover(container, (value, lastValue) => {
19 var href = value && value.getAttribute('href')
20 var oldHref = lastValue && lastValue.getAttribute('href')
21
22 var delay = 500
23 if (href && oldHref) {
24 delay = 100
25 } else if (!value) {
26 delay = 200
27 }
28
29 return delay
30 })
31 var previewElement = Value()
32
33 // hide preview on scroll
34 var hasPreview = computed(previewElement, x => !!x)
35 hasPreview(value => {
36 if (value) {
37 window.addEventListener('wheel', previewElement.cancel)
38 } else {
39 window.removeEventListener('wheel', previewElement.cancel)
40 }
41 })
42
43 currentHover(element => {
44 var href = element && element.getAttribute('href')
45 var preview = null
46
47 if (href) {
48 if (ref.isFeed(href)) {
49 preview = api.profile.html.preview(href)
50 } else if (href.includes('://')) {
51 preview = h('ProfilePreview', [
52 h('section', [
53 h('strong', [i18n('External Link'), ' ๐ŸŒ']), h('br'),
54 h('code', href)
55 ])
56 ])
57 } else if (href.startsWith('#') && href.length > 1) {
58 preview = api.channel.html.preview(href.slice(1))
59 }
60 }
61
62 if (preview) {
63 var rect = element.getBoundingClientRect()
64 var width = 510
65 var maxLeft = window.innerWidth - width
66 var maxTop = window.innerHeight - 100
67 var distanceFromRight = window.innerWidth - rect.right
68 var shouldDisplayBeside = rect.bottom > maxTop || rect.left < 50 || distanceFromRight < 50
69
70 if (shouldDisplayBeside && rect.bottom > 50) {
71 if (rect.right > maxLeft && (rect.left - width) < 0) {
72 // no room, just give up!
73 previewElement.set(null)
74 return
75 } else {
76 preview.style.top = `${Math.min(rect.top, maxTop)}px`
77 if (rect.right > maxLeft) {
78 preview.style.left = `${rect.left - width}px`
79 } else {
80 preview.style.left = `${rect.right + 5}px`
81 }
82 }
83 } else {
84 preview.style.top = `${rect.bottom + 5}px`
85 preview.style.left = `${Math.min(rect.left, maxLeft)}px`
86 }
87
88 previewElement.set(preview)
89 } else if (element !== false) {
90 previewElement.set(null)
91 }
92 })
93
94 previewElement.cancel = function () {
95 currentHover.cancel()
96 previewElement.set(null)
97 }
98
99 return previewElement
100 })
101}
102

Built with git-ssb-web