secure-scuttlebot classic
1'use strict'
2var dataurl = require('dataurl-')
3var hyperfile = require('hyperfile')
4var hypercrop = require('hypercrop')
5var hyperlightbox = require('hyperlightbox')
6var h = require('hyperscript')
7var pull = require('pull-stream')
8var getAvatar = require('ssb-avatar')
9var plugs = require('../plugs')
10var ref = require('ssb-ref')
11var visualize = require('visualize-buffer')
12var self_id = require('../keys').id
13
14//var confirm = plugs.first(exports.message_confirm = [])
15//var sbot_blobs_add = plugs.first(exports.sbot_blobs_add = [])
16//var blob_url = plugs.first(exports.blob_url = [])
17//var sbot_links = plugs.first(exports.sbot_links = [])
18//var avatar_name = plugs.first(exports.avatar_name = [])
19//
20
21function crop (d, cb) {
22 var canvas
23 var controls = h('div.row.avatar_pic__controls',
24 h('button', 'okay', {onclick: function () {
25 if (!canvas || !canvas.selection) return cb(new Error('image not ready'))
26 cb(null, canvas.selection.toDataURL())
27 }}),
28 h('button', 'cancel', {onclick: function () {
29 cb(new Error('canceled'))
30 }})
31 )
32
33 var container = h('div.column.avatar_pic',
34 // canvas will be inserted above controls once the image loads
35 controls
36 )
37
38 var img = new Image()
39 img.onload = function () {
40 canvas = hypercrop(img)
41 container.insertBefore(canvas, controls)
42 }
43 img.src = d
44
45 return container
46}
47
48exports.needs = {
49 message_confirm: 'first',
50 blob_url: 'first',
51 sbot_links: 'first',
52 avatar_name: 'first'
53}
54
55exports.gives = 'avatar_edit'
56
57exports.create = function (api) {
58 return function (id) {
59
60 var img = visualize(new Buffer(id.substring(1), 'base64'), 256)
61 img.classList.add('avatar--large')
62
63 var lb = hyperlightbox()
64 var name_input = h('input', {placeholder: 'rename'})
65 var name = api.avatar_name(id)
66 var selected = null, selected_data = null
67
68 getAvatar({links: api.sbot_links}, self_id, id, function (err, avatar) {
69 if (err) return console.error(err)
70 //don't show user has already selected an avatar.
71 if(selected) return
72 if(ref.isBlob(avatar.image))
73 img.src = api.blob_url(avatar.image)
74 })
75
76 var also_pictured = h('div.profile__alsopicturedas.wrap')
77
78 pull(
79 api.sbot_links({dest: id, rel: 'about', values: true}),
80 pull.map(function (e) {
81 return e.value.content.image
82 }),
83 pull.filter(function (e) {
84 return e && 'string' == typeof e.link
85 }),
86 pull.unique('link'),
87 pull.drain(function (image) {
88 also_pictured.appendChild(
89 h('a', {href:'#', onclick: function (ev) {
90 ev.stopPropagation()
91 ev.preventDefault()
92 selected = image
93 img.src = api.blob_url(image.link || image)
94 }},
95 h('img.avatar--thumbnail', {src: api.blob_url(image)})
96 )
97 )
98 })
99 )
100
101 return h('div.row.profile',
102 lb,
103 img,
104 h('div.column.profile__info',
105 h('strong', name),
106 name_input,
107
108 hyperfile.asDataURL(function (data) {
109 var el = crop(data, function (err, data) {
110 if(data) {
111 img.src = data
112 var _data = dataurl.parse(data)
113 var xhr = new XMLHttpRequest()
114 xhr.open('POST', '/blobs/add', true)
115 xhr.responseType = 'text'
116 xhr.onload = function () {
117 if (xhr.status < 200 || xhr.status >= 300) {
118 return alert('blob upload failed: status ' + xhr.status)
119 }
120 var hash = (xhr.responseText || '').trim()
121 selected = {
122 link: hash,
123 size: _data.data.length,
124 type: _data.mimetype,
125 width: 512,
126 height: 512
127 }
128 }
129 xhr.onerror = function () {
130 alert('blob upload network error')
131 }
132 xhr.send(_data.data)
133 }
134 lb.close()
135 })
136 lb.show(el)
137 }),
138 h('button', 'update', {onclick: function () {
139 if(name_input.value)
140 name.textContent = name_input.value
141
142 if(selected)
143 api.message_confirm({
144 type: 'about',
145 about: id,
146 name: name_input.value || undefined,
147 image: selected.link || selected
148 })
149 else if(name_input.value) //name only
150 api.message_confirm({
151 type: 'about',
152 about: id,
153 name: name_input.value || undefined,
154 })
155 else
156 //another moment of weakness
157 alert('must select a name or image')
158 }}),
159 also_pictured
160 )
161 )
162 }
163}