git ssb

16+

Dominic / patchbay



Tree: 40ad2f6bbef55f050717028457e776f6ce878ec9

Files: 40ad2f6bbef55f050717028457e776f6ce878ec9 / modules / compose.js

4000 bytesRaw
1'use strict'
2var h = require('hyperscript')
3var u = require('../util')
4var suggest = require('suggest-box')
5var cont = require('cont')
6var mentions = require('ssb-mentions')
7var lightbox = require('hyperlightbox')
8
9var plugs = require('../plugs')
10
11//var suggest = plugs.map(exports.suggest = [])
12var publish = plugs.first(exports.sbot_publish = [])
13var message_content = plugs.first(exports.message_content = [])
14var message_confirm = plugs.first(exports.message_confirm = [])
15var file_input = plugs.first(exports.file_input = [])
16
17exports.suggest = []
18
19function id (e) { return e }
20
21/*
22 opts can take
23
24 placeholder: string. placeholder text, defaults to "Write a message"
25 prepublish: function. called before publishing a message.
26 shrink: boolean. set to false, to make composer not shrink (or hide controls) when unfocused.
27*/
28
29exports.message_compose = function (meta, opts, cb) {
30 if('function' === typeof cb) {
31 if('function' === typeof opts)
32 opts = {prepublish: opts}
33 }
34
35 if(!opts) opts = {}
36 opts.prepublish = opts.prepublish || id
37
38 var accessories
39 meta = meta || {}
40 if(!meta.type) throw new Error('message must have type')
41 var ta = h('textarea', {
42 placeholder: opts.placeholder || 'Write a message',
43 style: {height: opts.shrink === false ? '200px' : ''}
44 })
45
46 if(opts.shrink !== false) {
47 var blur
48 ta.addEventListener('focus', function () {
49 clearTimeout(blur)
50 if(!ta.value) {
51 ta.style.height = '200px'
52 }
53 accessories.style.display = 'block'
54 })
55 ta.addEventListener('blur', function () {
56 //don't shrink right away, so there is time
57 //to click the publish button.
58 clearTimeout(blur)
59 blur = setTimeout(function () {
60 if(ta.value) return
61 ta.style.height = '50px'
62 accessories.style.display = 'none'
63 }, 200)
64 })
65 }
66
67 ta.addEventListener('keydown', function (ev) {
68 if(ev.keyCode === 13 && ev.ctrlKey) publish()
69 })
70
71 var files = []
72 var filesById = {}
73
74 function publish() {
75 publishBtn.disabled = true
76 var content
77 try {
78 content = JSON.parse(ta.value)
79 } catch (err) {
80 meta.text = ta.value
81 meta.mentions = mentions(ta.value).map(function (mention) {
82 // merge markdown-detected mention with file info
83 var file = filesById[mention.link]
84 if (file) {
85 if (file.type) mention.type = file.type
86 if (file.size) mention.size = file.size
87 }
88 return mention
89 })
90 try {
91 meta = opts.prepublish(meta)
92 } catch (err) {
93 publishBtn.disabled = false
94 if (cb) cb(err)
95 else alert(err.message)
96 }
97 return message_confirm(meta, done)
98 }
99 message_confirm(content, done)
100
101 function done (err, msg) {
102 publishBtn.disabled = false
103 if(err) return alert(err.stack)
104 else if (msg) ta.value = ''
105
106 if (cb) cb(err, msg)
107 }
108 }
109
110
111 var publishBtn = h('button', 'Publish', {onclick: publish})
112 var composer =
113 h('div.compose', h('div.column', ta,
114 accessories = h('div.row.compose__controls',
115 //hidden until you focus the textarea
116 {style: {display: opts.shrink === false ? '' : 'none'}},
117 file_input(function (file) {
118 files.push(file)
119 filesById[file.link] = file
120
121 var embed = file.type.indexOf('image/') === 0 ? '!' : ''
122 ta.value += embed + '['+file.name+']('+file.link+')'
123 console.log('added:', file)
124 }),
125 publishBtn)
126 )
127 )
128
129 suggest(ta, function (word, cb) {
130 cont.para(exports.suggest.map(function (fn) {
131 return function (cb) { fn(word, cb) }
132 }))
133 (function (err, results) {
134 if(err) console.error(err)
135 results = results.reduce(function (ary, item) {
136 return ary.concat(item)
137 }, []).sort(function (a, b) {
138 return b.rank - a.rank
139 }).filter(Boolean)
140
141 cb(null, results)
142 })
143 }, {})
144
145 return composer
146
147}
148
149
150
151

Built with git-ssb-web