git ssb

16+

Dominic / patchbay



Tree: b1da73e22bda6761baeced6c02888d038c2f9ace

Files: b1da73e22bda6761baeced6c02888d038c2f9ace / modules_basic / avatar / edit.js

4963 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
71 var namesRecord = MutantObject()
72 pull(
73 api.sbot_links({dest: id, rel: 'about', values: true}),
74 pull.map(e => e.value.content.name),
75 pull.filter(Boolean),
76 pull.drain(name => {
77 var n = namesRecord.get(name) || 0
78 namesRecord.put(name, n+1)
79 })
80 )
81 var names = dictToCollection(namesRecord)
82
83 var lb = hyperlightbox()
84 var name = Value(api.avatar_name(id))
85 var proposedName = Value()
86 var name_input = h('input', {placeholder: ' + another name', 'ev-keyup': (e) => proposedName.set(e.target.value) })
87 var description = '' //TODO load this in, make this editable
88
89 var isPossibleUpdate = computed([proposedName, proposedAvatar], (name, image) => {
90 return name || Object.keys(image).length
91 })
92
93 return h('ProfileEdit', [
94 h('section.lightbox', lb),
95 h('section.avatar', [
96 h('section', img),
97 h('footer', name),
98 ]),
99 h('section.description', description),
100 h('section.aliases', [
101 h('header', 'Aliases'),
102 h('section.avatars', [
103 h('header', 'Avatars'),
104 map(images, image => h('img', {
105 'src': api.blob_url(image),
106 'ev-click': changeSelectedImage(image)
107 })),
108 h('div.file-upload', [
109 hyperfile.asDataURL(dataUrlCallback)
110 ])
111 ]),
112 h('section.names', [
113 h('header', 'Names'),
114 h('section', [
115 map(names, name => h('div', [
116 h('div.name', name.key),
117 h('div.count', name.value)
118 ])),
119 name_input
120 ])
121 ]),
122 when(isPossibleUpdate, h('button.confirm', { 'ev-click': handleUpdateClick }, 'Confirm changes'))
123 ])
124 ])
125
126 function changeSelectedImage (image) {
127 return () => {
128 proposedAvatar.set(image)
129 img.src = api.blob_url(image.link || image)
130 }
131 }
132
133 function dataUrlCallback (data) {
134 var el = crop(data, (err, data) => {
135 if(data) {
136 img.src = data
137 var _data = dataurl.parse(data)
138 pull(
139 pull.once(_data.data),
140 api.sbot_blobs_add((err, hash) => {
141 //TODO. Alerts are EVIL.
142 //I use them only in a moment of weakness.
143
144 if(err) return alert(err.stack)
145 proposedAvatar.set({
146 link: hash,
147 size: _data.data.length,
148 type: _data.mimetype,
149 width: 512,
150 height: 512
151 })
152 })
153 )
154 }
155 lb.close()
156 })
157 lb.show(el)
158 }
159
160 function handleUpdateClick () {
161 const name = proposedName()
162 const avatar = proposedAvatar()
163
164 const msg = {
165 type: 'about',
166 about: id
167 }
168
169 if (name) msg.name = name
170 if (Object.keys(avatar).length) msg.image = avatar
171
172 api.message_confirm(msg)
173
174 if (name) name.set('@'+name)
175 }
176 }
177
178}
179
180

Built with git-ssb-web