aboutsummaryrefslogtreecommitdiff
path: root/lib/serve.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/serve.js')
-rw-r--r--lib/serve.js95
1 files changed, 80 insertions, 15 deletions
diff --git a/lib/serve.js b/lib/serve.js
index 5836965..0a81fa1 100644
--- a/lib/serve.js
+++ b/lib/serve.js
@@ -14,6 +14,7 @@ var paginate = require('pull-paginate')
var ssbMentions = require('ssb-mentions')
var multicb = require('multicb')
var pkg = require('../package')
+var Busboy = require('busboy')
module.exports = Serve
@@ -53,18 +54,47 @@ Serve.prototype.go = function () {
var self = this
if (this.req.method === 'POST' || this.req.method === 'PUT') {
- pull(
- toPull(this.req),
- pull.collect(function (err, bufs) {
- var data
- if (!err) try {
- data = qs.parse(Buffer.concat(bufs).toString('ascii'))
- } catch(e) {
- err = e
- }
+ if (/^multipart\/form-data/.test(this.req.headers['content-type'])) {
+ var data = {}
+ var erred
+ var busboy = new Busboy({headers: this.req.headers})
+ var filesCb = multicb({pluck: 1})
+ busboy.on('finish', filesCb())
+ filesCb(function (err) {
gotData(err, data)
})
- )
+ busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
+ var done = multicb({pluck: 1, spread: true})
+ var cb = filesCb()
+ pull(
+ toPull(file),
+ u.pullLength(done()),
+ self.app.addBlob(done())
+ )
+ done(function (err, size, id) {
+ if (err) return cb(err)
+ data[fieldname] = {link: id, name: filename, type: mimetype, size: size}
+ cb()
+ })
+ })
+ busboy.on('field', function (fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype) {
+ data[fieldname] = val
+ })
+ this.req.pipe(busboy)
+ } else {
+ pull(
+ toPull(this.req),
+ pull.collect(function (err, bufs) {
+ var data
+ if (!err) try {
+ data = qs.parse(Buffer.concat(bufs).toString('ascii'))
+ } catch(e) {
+ err = e
+ }
+ gotData(err, data)
+ })
+ )
+ }
} else {
gotData(null, {})
}
@@ -768,9 +798,20 @@ Serve.prototype.composer = function (opts, cb) {
opts = opts || {}
var data = self.data
+ var blobs = u.tryDecodeJSON(data.blobs) || {}
+ if (data.upload && typeof data.upload === 'object') {
+ blobs[data.upload.link] = {
+ type: data.upload.type,
+ size: data.upload.size,
+ }
+ }
+
var done = multicb({pluck: 1, spread: true})
done()(null, h('section.composer',
- h('form', {method: 'post', action: opts.id ? '#' + opts.id : ''},
+ h('form', {method: 'post', action: opts.id ? '#' + opts.id : '',
+ enctype: 'multipart/form-data'},
+ h('input', {type: 'hidden', name: 'blobs',
+ value: JSON.stringify(blobs)}),
opts.recps ? self.app.render.privateLine(opts.recps, done()) :
opts.private ? h('div', h('input.recps-input', {name: 'recps',
value: data.recps || '', placeholder: 'recipient ids'})) : '',
@@ -784,9 +825,22 @@ Serve.prototype.composer = function (opts, cb) {
cols: 70,
placeholder: opts.placeholder || 'public message',
}, data.text || ''),
- h('div.composer-actions',
- h('input', {type: 'submit', name: 'action', value: 'raw'}), ' ',
- h('input', {type: 'submit', name: 'action', value: 'preview'})),
+ h('table.ssb-msgs',
+ h('tr.msg-row',
+ h('td.msg-left', {colspan: 2},
+ h('input', {type: 'file', name: 'upload'}), ' ',
+ h('input', {type: 'submit', name: 'action', value: 'attach'})
+ ),
+ h('td.msg-right',
+ h('input', {type: 'submit', name: 'action', value: 'raw'}), ' ',
+ h('input', {type: 'submit', name: 'action', value: 'preview'})
+ )
+ )
+ ),
+ data.upload ? [
+ h('div', h('em', 'attach:')),
+ h('pre', '[' + data.upload.name + '](' + data.upload.link + ')')
+ ] : '',
data.action === 'preview' ? preview(false, done()) :
data.action === 'raw' ? preview(true, done()) :
data.action === 'publish' ? publish(done()) : ''
@@ -806,7 +860,18 @@ Serve.prototype.composer = function (opts, cb) {
text: data.text,
}
var mentions = ssbMentions(data.text)
- if (mentions.length) content.mentions = mentions
+ if (mentions.length) {
+ content.mentions = mentions.map(function (mention) {
+ var blob = blobs[mention.link]
+ if (blob) {
+ if (!isNaN(blob.size))
+ mention.size = blob.size
+ if (blob.type && blob.type !== 'application/octet-stream')
+ mention.type = blob.type
+ }
+ return mention
+ })
+ }
if (data.recps != null) {
if (opts.recps) return cb(new Error('got recps in opts and data'))
content.recps = [myId]