git ssb

16+

Dominic / patchbay



Tree: b5cf9912e3e6845bf8f4aeeebea6559069eeb23d

Files: b5cf9912e3e6845bf8f4aeeebea6559069eeb23d / modules_basic / avatar / edit.js

4964 bytesRaw
1'use strict'
2const fs = require('fs')
3const dataurl = require('dataurl-')
4const hyperfile = require('hyperfile')
5const hypercrop = require('hypercrop')
6const hyperlightbox = require('hyperlightbox')
7const h = require('../../h')
8const {
9 Value, Array: MutantArray, Dict: MutantObject,
10 map, computed, when, dictToCollection
11} = require('@mmckegg/mutant')
12const pull = require('pull-stream')
13const getAvatar = require('ssb-avatar')
14const ref = require('ssb-ref')
15const visualize = require('visualize-buffer')
16const self_id = require('../../keys').id
17
18function crop (d, cb) {
19 var canvas = hypercrop(h('img', {src: d}))
20
21 return h('div.column.avatar_pic', [
22 canvas,
23 //canvas.selection,
24 h('div.row.avatar_pic__controls', [
25 h('button', {'ev-click': () => cb(null, canvas.selection.toDataURL()) }, 'okay'),
26 h('button', {'ev-click': () => cb(new Error('canceled')) }, 'cancel')
27 ])
28 ])
29}
30
31exports.needs = {
32 message_confirm: 'first',
33 sbot_blobs_add: 'first',
34 blob_url: 'first',
35 sbot_links: 'first',
36 avatar_name: 'first'
37}
38
39exports.gives = {
40 avatar_edit: true,
41 mcss: true
42}
43
44exports.create = function (api) {
45 return {
46 avatar_edit,
47 mcss: () => fs.readFileSync(__filename.replace(/js$/, 'mcss'), 'utf8')
48 }
49
50 function avatar_edit (id) {
51 var img = visualize(new Buffer(id.substring(1), 'base64'), 256)
52
53 var proposedAvatar = MutantObject()
54 getAvatar({links: api.sbot_links}, self_id, id, (err, avatar) => {
55 if (err) return console.error(err)
56 //don't show user has already selected an avatar.
57 if(proposedAvatar.keys().length) return
58 if(ref.isBlob(avatar.image))
59 img.src = api.blob_url(avatar.image)
60 })
61
62 var images = MutantArray()
63 pull(
64 api.sbot_links({dest: id, rel: 'about', values: true}),
65 pull.map(e => e.value.content.image),
66 pull.filter(e => e && 'string' == typeof e.link),
67 pull.unique('link'),
68 pull.drain(image => images.push(image) )
69 )
70 var namesRecord = MutantObject()
71 pull(
72 api.sbot_links({dest: id, rel: 'about', values: true}),
73 pull.map(e => e.value.content.name),
74 pull.filter(Boolean),
75 pull.drain(name => {
76 var n = namesRecord.get('name') || 0
77 namesRecord.put(name, n+1)
78 })
79 )
80 var names = dictToCollection(namesRecord)
81
82 var lb = hyperlightbox()
83 var name = Value(api.avatar_name(id))
84 var proposedName = Value()
85 var name_input = h('input', {placeholder: ' + another name', 'ev-keyup': (e) => proposedName.set(e.target.value) })
86 var description = '' //TODO load this in, make this editable
87
88 var isPossibleUpdate = computed([proposedName, proposedAvatar], (name, image) => {
89 return name || Object.keys(image).length
90 })
91
92 return h('ProfileEdit', [
93 h('section.lightbox', lb),
94 h('section.avatar', [
95 h('section', img),
96 h('footer', name),
97 ]),
98 h('section.description', description),
99 h('section.aliases', [
100 h('header', 'Aliases'),
101 h('section.avatars', [
102 h('header', 'Avatars'),
103 map(images, image => h('img', {
104 'src': api.blob_url(image),
105 'ev-click': changeSelectedImage(image)
106 })),
107 h('div.file-upload', [
108 hyperfile.asDataURL(dataUrlCallback)
109 ])
110 ]),
111 h('section.names', [
112 h('header', 'Names'),
113 h('section', [
114 map(names, name => h('div', [
115 h('div.name', name.key),
116 h('div.count', name.value)
117 ])),
118 name_input
119 ])
120 ]),
121 when(isPossibleUpdate, h('button.confirm', { 'ev-click': handleUpdateClick }, 'Confirm changes'))
122 ])
123 ])
124
125 function changeSelectedImage (image) {
126 return () => {
127 proposedAvatar.set(image)
128 img.src = api.blob_url(image.link || image)
129 }
130 }
131
132 function dataUrlCallback (data) {
133 var el = crop(data, (err, data) => {
134 if(data) {
135 img.src = data
136 var _data = dataurl.parse(data)
137 pull(
138 pull.once(_data.data),
139 api.sbot_blobs_add((err, hash) => {
140 //TODO. Alerts are EVIL.
141 //I use them only in a moment of weakness.
142
143 if(err) return alert(err.stack)
144 proposedAvatar.set({
145 link: hash,
146 size: _data.data.length,
147 type: _data.mimetype,
148 width: 512,
149 height: 512
150 })
151 })
152 )
153 }
154 lb.close()
155 })
156 lb.show(el)
157 }
158
159 function handleUpdateClick () {
160 const name = proposedName()
161 const avatar = proposedAvatar()
162
163 const msg = {
164 type: 'about',
165 about: id
166 }
167
168 if (name) msg.name = name
169 if (Object.keys(avatar).length) msg.image = avatar
170
171 api.message_confirm(msg)
172
173 if (name) name.set('@'+name)
174 }
175 }
176
177}
178
179

Built with git-ssb-web