Commit bd34a8d22b29ba32048c072fecfaaa2d0fb0af0f
added external share. problem with opening external url. implements #117
andre alves garzia committed on 4/23/2018, 10:20:45 PMParent: 040b198afe9d5a0c14eae6014372adffb6c9091d
Files changed
app/page/blogShow.js | changed |
message/html/shares.js | changed |
message/html/webshares.js | added |
message/html/webshares.mcss | added |
message/index.js | changed |
message/obs/shares.js | changed |
message/obs/webshares.js | added |
translations/en.js | changed |
app/page/blogShow.js | ||
---|---|---|
@@ -11,8 +11,9 @@ | ||
11 | 11 | 'app.html.sideNav': 'first', |
12 | 12 | 'contact.html.follow': 'first', |
13 | 13 | 'message.html.channel': 'first', |
14 | 14 | 'message.html.likes': 'first', |
15 | + 'message.html.webshares': 'first', | |
15 | 16 | 'message.html.shares': 'first', |
16 | 17 | 'message.html.timeago': 'first', |
17 | 18 | 'feed.obs.thread': 'first', |
18 | 19 | 'blog.html.title': 'first', |
@@ -47,9 +48,10 @@ | ||
47 | 48 | h('h1', title), |
48 | 49 | timeago(blogMsg), |
49 | 50 | channel(blogMsg), |
50 | 51 | api.message.html.likes(blogMsg), |
51 | - api.message.html.shares(blogMsg) | |
52 | + api.message.html.shares(blogMsg), | |
53 | + api.message.html.webshares(blogMsg) | |
52 | 54 | ]), |
53 | 55 | h('div.author', [ |
54 | 56 | h('div.leftCol', api.about.html.avatar(author, 'medium')), |
55 | 57 | h('div.rightCol', [ |
message/html/shares.js | ||
---|---|---|
@@ -36,9 +36,9 @@ | ||
36 | 36 | }) |
37 | 37 | |
38 | 38 | var confirmationDialog = h('div.dialog', [ |
39 | 39 | h('div.message', [ |
40 | - h('p', strings.share.dialogLabel), | |
40 | + h('p', strings.share.shareLabel), | |
41 | 41 | ]), |
42 | 42 | h('div.form', [ |
43 | 43 | captionInput |
44 | 44 | ]), |
message/html/webshares.js | ||
---|---|---|
@@ -1,0 +1,73 @@ | ||
1 | +var { h, computed, when, Value, resolve } = require('mutant') | |
2 | +var nest = require('depnest') | |
3 | +var { clipboard } = require('electron') | |
4 | +var { shell } = require('electron') | |
5 | + | |
6 | +exports.needs = nest({ | |
7 | + 'keys.sync.id': 'first', | |
8 | + 'message.obs.webshares': 'first', | |
9 | + 'sbot.async.publish': 'first', | |
10 | + 'translations.sync.strings': 'first', | |
11 | + 'app.html.lightbox': 'first' | |
12 | +}) | |
13 | + | |
14 | +exports.gives = nest('message.html.webshares') | |
15 | + | |
16 | +exports.create = (api) => { | |
17 | + return nest('message.html.webshares', function shares(msg) { | |
18 | + var id = api.keys.sync.id() | |
19 | + var shares = api.message.obs.webshares(msg.key) | |
20 | + | |
21 | + var iShared = computed(shares, shares => shares.includes(id)) | |
22 | + var count = computed(shares, shares => shares.length ? shares.length : '') | |
23 | + var isOpen = Value(false) | |
24 | + var strings = api.translations.sync.strings() | |
25 | + var publishAndClose = (msg, action) => { | |
26 | + publishShare(msg, action) | |
27 | + isOpen.set(false) | |
28 | + } | |
29 | + var confirmationDialog = h('div.dialog', [ | |
30 | + h('div.message', [ | |
31 | + h('p', strings.share.externalShareLabel), | |
32 | + ]), | |
33 | + h('div.actions', [ | |
34 | + h('Button', { 'ev-click': () => isOpen.set(false) }, strings.userShow.action.cancel), | |
35 | + h('Button', { style: { 'margin-left': '10px', 'margin-right': '10px' }, 'ev-click': () => publishAndClose(msg, 'copy') }, strings.share.action.copy), | |
36 | + h('Button -primary', { 'ev-click': () => publishAndClose(msg, 'open') }, strings.share.action.open) | |
37 | + | |
38 | + ]) | |
39 | + ]) | |
40 | + | |
41 | + var lb = api.app.html.lightbox(confirmationDialog, isOpen) | |
42 | + | |
43 | + | |
44 | + return h('WebShares', { 'ev-click': () => isOpen.set(true) }, [ | |
45 | + h('i.fa', { className: when(iShared, 'fa-globe', 'fa-globe faint') }), | |
46 | + h('div.count', count), | |
47 | + lb | |
48 | + ]) | |
49 | + }) | |
50 | + | |
51 | + function publishShare(msg, action) { | |
52 | + var url = `http://share2.ticktack.im:8807/${msg.key}` | |
53 | + var share = { | |
54 | + type: 'share', | |
55 | + share: { link: msg.key, content: "blog", url: url } | |
56 | + } | |
57 | + if (msg.value.content.recps) { | |
58 | + share.recps = msg.value.content.recps.map(function (e) { | |
59 | + return e && typeof e !== 'string' ? e.link : e | |
60 | + }) | |
61 | + share.private = true | |
62 | + } | |
63 | + api.sbot.async.publish(share) | |
64 | + | |
65 | + if (action == "copy") { | |
66 | + console.log("copying to clipboard") | |
67 | + clipboard.writeText(url) | |
68 | + } else { | |
69 | + console.log("opening external") | |
70 | + shell.openExternal(url, err => console.log("error", err)) | |
71 | + } | |
72 | + } | |
73 | +} |
message/html/webshares.mcss | ||
---|---|---|
@@ -1,0 +1,20 @@ | ||
1 | +WebShares { | |
2 | + cursor: pointer | |
3 | + min-width: 2.5rem | |
4 | + | |
5 | + display: flex | |
6 | + align-items: center | |
7 | + | |
8 | + i { | |
9 | + margin-right: .4rem | |
10 | + } | |
11 | + i.fa-globe { | |
12 | + $colorFontPrimary | |
13 | + } | |
14 | + | |
15 | + i.faint { | |
16 | + color: #b9b9b9 | |
17 | + } | |
18 | + | |
19 | +} | |
20 | + |
message/index.js | ||
---|---|---|
@@ -6,14 +6,16 @@ | ||
6 | 6 | channel: require('./html/channel'), |
7 | 7 | compose: require('./html/compose'), |
8 | 8 | likes: require('./html/likes'), |
9 | 9 | shares: require('./html/shares'), |
10 | + webshares: require('./html/webshares'), | |
10 | 11 | subject: require('./html/subject'), |
11 | 12 | timeago: require('./html/timeago') |
12 | 13 | }, |
13 | 14 | sync: { |
14 | 15 | getParticipants: require('./sync/getParticipants') |
15 | 16 | }, |
16 | 17 | obs: { |
17 | - shares: require('./obs/shares') | |
18 | + shares: require('./obs/shares'), | |
19 | + webshares: require('./obs/webshares') | |
18 | 20 | } |
19 | 21 | } |
message/obs/shares.js | ||
---|---|---|
@@ -26,9 +26,9 @@ | ||
26 | 26 | } |
27 | 27 | |
28 | 28 | var c = msg.value.content |
29 | 29 | if (c.type !== 'share') return |
30 | - if (!c.share || !c.share.link) return | |
30 | + if (!c.share || !c.share.link || !c.share.text) return | |
31 | 31 | |
32 | 32 | activeShares.forEach((shares) => { |
33 | 33 | if (shares.id === c.share.link) { |
34 | 34 | shares.push(msg) |
@@ -56,9 +56,9 @@ | ||
56 | 56 | var shares = computed([backlinks.sync, concat([backlinks, merge])], (sync, backlinks) => { |
57 | 57 | if (sync) { |
58 | 58 | return backlinks.reduce((result, msg) => { |
59 | 59 | var c = msg.value.content |
60 | - if (c.type === 'share' && c.share && c.share.link === id) { | |
60 | + if (c.type === 'share' && c.share && c.share.text && c.share.link === id) { | |
61 | 61 | var value = result[msg.value.author] |
62 | 62 | if (!value || value[0] < msg.value.timestamp) { |
63 | 63 | result[msg.value.author] = [msg.value.timestamp, c.share.text] |
64 | 64 | } |
message/obs/webshares.js | ||
---|---|---|
@@ -1,0 +1,86 @@ | ||
1 | +var nest = require('depnest') | |
2 | +var ref = require('ssb-ref') | |
3 | +var MutantArray = require('mutant/array') | |
4 | +var concat = require('mutant/concat') | |
5 | + | |
6 | +var { computed } = require('mutant') | |
7 | + | |
8 | +exports.needs = nest({ | |
9 | + 'message.sync.unbox': 'first', | |
10 | + 'backlinks.obs.for': 'first' | |
11 | +}) | |
12 | + | |
13 | +exports.gives = nest({ | |
14 | + 'sbot.hook.publish': true, | |
15 | + 'message.obs.webshares': true | |
16 | +}) | |
17 | + | |
18 | +exports.create = function (api) { | |
19 | + var activeShares = new Set() | |
20 | + return nest({ | |
21 | + 'sbot.hook.publish': (msg) => { | |
22 | + if (!(msg && msg.value && msg.value.content)) return | |
23 | + if (typeof msg.value.content === 'string') { | |
24 | + msg = api.message.sync.unbox(msg) | |
25 | + if (!msg) return | |
26 | + } | |
27 | + | |
28 | + var c = msg.value.content | |
29 | + if (c.type !== 'share') return | |
30 | + if (!c.share || !c.share.link || !c.share.url) return | |
31 | + | |
32 | + activeShares.forEach((shares) => { | |
33 | + if (shares.id === c.share.link) { | |
34 | + shares.push(msg) | |
35 | + } | |
36 | + }) | |
37 | + }, | |
38 | + 'message.obs.webshares': (id) => { | |
39 | + if (!ref.isLink(id)) throw new Error('an id must be specified') | |
40 | + var obs = get(id) | |
41 | + obs.id = id | |
42 | + var result = computed(obs, getShares, { | |
43 | + // allow manual append for simulated realtime | |
44 | + onListen: () => activeShares.add(obs), | |
45 | + onUnlisten: () => activeShares.delete(obs) | |
46 | + }) | |
47 | + result.sync = obs.sync | |
48 | + return result | |
49 | + } | |
50 | + }) | |
51 | + | |
52 | + function get(id) { | |
53 | + var backlinks = api.backlinks.obs.for(id) | |
54 | + var merge = MutantArray() | |
55 | + | |
56 | + var shares = computed([backlinks.sync, concat([backlinks, merge])], (sync, backlinks) => { | |
57 | + if (sync) { | |
58 | + return backlinks.reduce((result, msg) => { | |
59 | + var c = msg.value.content | |
60 | + if (c.type === 'share' && c.share && c.share.url && c.share.link === id) { | |
61 | + var value = result[msg.value.author] | |
62 | + if (!value || value[0] < msg.value.timestamp) { | |
63 | + result[msg.value.author] = [msg.value.timestamp, c.share.url] | |
64 | + } | |
65 | + } | |
66 | + return result | |
67 | + }, {}) | |
68 | + } else { | |
69 | + return {} | |
70 | + } | |
71 | + }) | |
72 | + | |
73 | + shares.push = merge.push | |
74 | + shares.sync = backlinks.sync | |
75 | + return shares | |
76 | + } | |
77 | +} | |
78 | + | |
79 | +function getShares(shares) { | |
80 | + return Object.keys(shares).reduce((result, id) => { | |
81 | + if (shares[id].length >= 1) { | |
82 | + result.push(id) | |
83 | + } | |
84 | + return result | |
85 | + }, []) | |
86 | +} |
translations/en.js | ||
---|---|---|
@@ -159,11 +159,14 @@ | ||
159 | 159 | } |
160 | 160 | }, |
161 | 161 | share: { |
162 | 162 | captionPlaceholder: 'Type an optional caption here', |
163 | - dialogLabel: 'Do you to share this post with your followers?', | |
163 | + shareLabel: 'Do you to share this post with your followers?', | |
164 | + externalShareLabel: 'Do you to share this post on the Web?', | |
164 | 165 | action: { |
165 | - share: 'Share' | |
166 | + share: 'Share', | |
167 | + copy: 'Copy external URL', | |
168 | + open: 'Open external URL' | |
166 | 169 | } |
167 | 170 | }, |
168 | 171 | languages: { |
169 | 172 | en: 'English', |
Built with git-ssb-web