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