git ssb

1+

ev / minbay



Tree: afe7de9580840925af61711b5ab0d6c57d1131a4

Files: afe7de9580840925af61711b5ab0d6c57d1131a4 / modules / compose.js

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

Built with git-ssb-web