git ssb

16+

Dominic / patchbay



Tree: ddf533c74d989b38d8a15ce293a021f67153b2cc

Files: ddf533c74d989b38d8a15ce293a021f67153b2cc / modules_basic / compose.js

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

Built with git-ssb-web