git ssb

0+

ev / minbase



Tree: b62ecd6f843b26f37e70c7b6d65c71db35bbf922

Files: b62ecd6f843b26f37e70c7b6d65c71db35bbf922 / modules / compose.js

4282 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',
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
44 var publishBtn = h('button.compose__button', 'Preview', {onclick: publish})
45
46 var channel = h('input', {
47 placeholder: '#channel',
48 value: meta.channel ? `#${meta.channel}` : '',
49 disabled: meta.channel ? true : false,
50 title: meta.channel ? 'Reply is in same channel as original message' : '',
51 })
52
53 var ta = h('textarea', {
54 placeholder: opts.placeholder || 'Write a message',
55 style: {height: opts.shrink === false ? '200px' : ''}
56 })
57
58 accessories = h('div.row.compose__controls',
59 //hidden until you focus the textarea
60 {style: {display: opts.shrink === false ? '' : 'none'}},
61 channel,
62 api.file_input(function (file) {
63 files.push(file)
64 filesById[file.link] = file
65 var embed = file.type.indexOf('image/') === 0 ? '!' : ''
66 ta.value += embed + '['+file.name+']('+file.link+')'
67 console.log('added:', file)
68 }),
69 publishBtn)
70
71
72 if(opts.shrink !== false) {
73 var blur
74 ta.addEventListener('focus', function () {
75 clearTimeout(blur)
76 if(!ta.value) {
77 ta.style.height = '200px'
78 }
79 accessories.style.display = 'block'
80 })
81 ta.addEventListener('blur', function () {
82 //don't shrink right away, so there is time
83 //to click the publish button.
84 clearTimeout(blur)
85 blur = setTimeout(function () {
86 if(ta.value) return
87 ta.style.height = '50px'
88 //accessories.style.display = 'none'
89 }, 200)
90 })
91 }
92
93 ta.addEventListener('keydown', function (ev) {
94 if(ev.keyCode === 13 && ev.ctrlKey) publish()
95 })
96
97 var files = []
98 var filesById = {}
99
100 function publish() {
101 publishBtn.disabled = true
102 var content
103 try {
104 content = JSON.parse(ta.value)
105 } catch (err) {
106 meta.text = ta.value
107 meta.channel = (channel.value.startsWith('#') ?
108 channel.value.substr(1).trim() : channel.value.trim()) || null
109 meta.mentions = mentions(ta.value).map(function (mention) {
110 // merge markdown-detected mention with file info
111 var file = filesById[mention.link]
112 if (file) {
113 if (file.type) mention.type = file.type
114 if (file.size) mention.size = file.size
115 }
116 return mention
117 })
118 try {
119 meta = opts.prepublish(meta)
120 } catch (err) {
121 publishBtn.disabled = false
122 if (cb) cb(err)
123 else alert(err.message)
124 }
125 return api.message_confirm(meta, done)
126 }
127
128 api.message_confirm(content, done)
129
130 function done (err, msg) {
131 publishBtn.disabled = false
132 if(err) return alert(err.stack)
133 else if (msg) ta.value = ''
134
135 if (cb) cb(err, msg)
136 }
137 }
138
139
140 var composer =
141 h('div.compose',
142 h('div.column',
143 ta,
144 accessories
145 )
146 )
147
148 suggest(ta, function (name, cb) {
149 cont.para(api.suggest_mentions(name))
150 (function (err, ary) {
151 cb(null, ary.reduce(function (a, b) {
152 if(!b) return a
153 return a.concat(b)
154 }, []))
155 })
156 }, {})
157
158 return composer
159 }
160
161}
162
163
164

Built with git-ssb-web