|
| 1 | +(function($) { |
| 2 | + const syncComplete = res => { |
| 3 | + console.log('sync complete'); |
| 4 | + }; |
| 5 | + |
| 6 | + const syncFailure = () => { |
| 7 | + _alert( |
| 8 | + { message: gettext('Failed to backup profile data to 3Box. Please try again.') }, |
| 9 | + 'error' |
| 10 | + ); |
| 11 | + switchIcons(false); |
| 12 | + }; |
| 13 | + |
| 14 | + const openBox = callback => { |
| 15 | + window.ethereum.enable().then(addresses => { |
| 16 | + window.Box.openBox(addresses[0], window.ethereum, {}).then(box => { |
| 17 | + box.onSyncDone(syncComplete); |
| 18 | + window.box = box; |
| 19 | + window.curentEthAddr = addresses[0]; |
| 20 | + console.log('openBox succeeded'); |
| 21 | + callback(box); |
| 22 | + }).catch(err => { |
| 23 | + syncFailure(); |
| 24 | + }); |
| 25 | + }); |
| 26 | + }; |
| 27 | + |
| 28 | + const openSpace = (box, callback) => { |
| 29 | + const name = 'GitCoin'; |
| 30 | + |
| 31 | + window.currentSpace = name; |
| 32 | + const opts = { |
| 33 | + onSyncDone: () => { |
| 34 | + console.log('sync done in space', name); |
| 35 | + callback(box, box.spaces[name]); |
| 36 | + } |
| 37 | + }; |
| 38 | + |
| 39 | + box.openSpace(name, opts).catch(err => { |
| 40 | + syncFailure(); |
| 41 | + }); |
| 42 | + }; |
| 43 | + |
| 44 | + const backupProfile = async space => { |
| 45 | + const data = await fetchProfieData(); |
| 46 | + |
| 47 | + if (data) { |
| 48 | + let profile = data; |
| 49 | + |
| 50 | + console.log('profile', profile); |
| 51 | + |
| 52 | + if (profile) { |
| 53 | + // get public key-value |
| 54 | + const public_keys = Object.keys(profile).filter(k => k[0] !== '_'); |
| 55 | + const public_values = public_keys.map(k => profile[k]); |
| 56 | + // get private key-value |
| 57 | + let private_keys = Object.keys(profile).filter(k => k[0] === '_'); |
| 58 | + const private_values = private_keys.map(k => profile[k]); |
| 59 | + |
| 60 | + private_keys = private_keys.map(k => k.substring(1)); |
| 61 | + |
| 62 | + // save data to space |
| 63 | + const r_public = await space.public.setMultiple(public_keys, public_values); |
| 64 | + const r_private = await space.private.setMultiple(private_keys, private_values); |
| 65 | + |
| 66 | + // remove the unused key/value pairs from the space |
| 67 | + await removeUnusedFields(space, public_keys, private_keys); |
| 68 | + |
| 69 | + if (r_public && r_private) { |
| 70 | + const three_box_link = `https://3box.io/${window.curentEthAddr}/data`; |
| 71 | + |
| 72 | + _alert( |
| 73 | + { |
| 74 | + message: gettext(`<span>Your profile data has been synchronized to 3Box -- </span> <a href="${three_box_link}" target="_blank">Check out the details on 3Box Hub</a>.`)}, |
| 75 | + 'success' |
| 76 | + ); |
| 77 | + } else { |
| 78 | + syncFailure(); |
| 79 | + } |
| 80 | + } else { |
| 81 | + syncFailure(); |
| 82 | + } |
| 83 | + } else { |
| 84 | + syncFailure(); |
| 85 | + } |
| 86 | + |
| 87 | + switchIcons(false); |
| 88 | + }; |
| 89 | + |
| 90 | + const removeUnusedFields = async(space, public_keys, private_keys) => { |
| 91 | + const public_data = await space.public.all(); |
| 92 | + const private_data = await space.private.all(); |
| 93 | + |
| 94 | + const unused_public_keys = Object.keys(public_data).filter(x => !public_keys.includes(x)); |
| 95 | + const unused_private_keys = Object.keys(private_data).filter(x => !private_keys.includes(x)); |
| 96 | + |
| 97 | + await removeFields(space.public, unused_public_keys); |
| 98 | + await removeFields(space.private, unused_private_keys); |
| 99 | + |
| 100 | + const count = unused_public_keys.length + unused_private_keys.length; |
| 101 | + |
| 102 | + console.log(`remove ${count} outdated fields from space`, unused_public_keys, unused_private_keys); |
| 103 | + }; |
| 104 | + |
| 105 | + const removeFields = async(subspace, keys) => { |
| 106 | + if (keys && keys.length > 0) { |
| 107 | + for (let x of keys) { |
| 108 | + await subspace.remove(x); |
| 109 | + } |
| 110 | + } |
| 111 | + }; |
| 112 | + |
| 113 | + const toggleAutomaticUpdateFlag = async() => { |
| 114 | + const data = new FormData(); |
| 115 | + |
| 116 | + data.append('csrfmiddlewaretoken', $('input[name="csrfmiddlewaretoken"]').val()); |
| 117 | + try { |
| 118 | + const response = await fetch('/api/v0.1/profile/settings', { |
| 119 | + method: 'post', |
| 120 | + body: data |
| 121 | + }); |
| 122 | + |
| 123 | + if (response.status === 200) { |
| 124 | + const result = await response.json(); |
| 125 | + const automatic_backup = result.automatic_backup ? 'ENABLED' : 'DISABLED'; |
| 126 | + |
| 127 | + _alert( |
| 128 | + { message: gettext(`Profile automatic backup has been ${automatic_backup}`) }, |
| 129 | + 'success' |
| 130 | + ); |
| 131 | + } else { |
| 132 | + _alert( |
| 133 | + { message: gettext('An error occurred. Please try again.') }, |
| 134 | + 'error' |
| 135 | + ); |
| 136 | + } |
| 137 | + |
| 138 | + } catch (err) { |
| 139 | + console.log('Error when toggling automatic backup flag', err); |
| 140 | + } |
| 141 | + }; |
| 142 | + |
| 143 | + const fetchProfieData = async() => { |
| 144 | + const data = new FormData(); |
| 145 | + |
| 146 | + data.append('csrfmiddlewaretoken', $('input[name="csrfmiddlewaretoken"]').val()); |
| 147 | + try { |
| 148 | + const response = await fetch('/api/v0.1/profile/backup', { |
| 149 | + method: 'post', |
| 150 | + body: data |
| 151 | + }); |
| 152 | + |
| 153 | + if (response.status === 200) { |
| 154 | + const result = await response.json(); |
| 155 | + |
| 156 | + return result.data; |
| 157 | + } |
| 158 | + } catch (err) { |
| 159 | + console.log('Error when fetching profile data', err); |
| 160 | + } |
| 161 | + return null; |
| 162 | + }; |
| 163 | + |
| 164 | + const startProfileDataBackup = async() => { |
| 165 | + console.log('start sync data to 3box'); |
| 166 | + |
| 167 | + const data = await fetchProfieData(); |
| 168 | + |
| 169 | + console.log('data', data); |
| 170 | + |
| 171 | + // User is prompted to approve the messages inside their wallet (openBox() and |
| 172 | + // openSpace() methods via 3Box.js). This logs them in to 3Box. |
| 173 | + |
| 174 | + try { |
| 175 | + if (window.Box) { |
| 176 | + // 1. Open box and space |
| 177 | + // 2. Backing up my Gitcoin data to 3Box, inside of a "Gitcoin" space |
| 178 | + switchIcons(true); |
| 179 | + openBox(box => { |
| 180 | + openSpace(box, (box, space) => { |
| 181 | + console.log('backup data into space'); |
| 182 | + backupProfile(space); |
| 183 | + }); |
| 184 | + }); |
| 185 | + } else { |
| 186 | + setTimeout(() => { |
| 187 | + startProfileDataBackup(); |
| 188 | + }, 1000); |
| 189 | + } |
| 190 | + } catch (err) { |
| 191 | + console.log('Error when backing up profile data', err); |
| 192 | + syncFailure(); |
| 193 | + } |
| 194 | + }; |
| 195 | + |
| 196 | + const switchIcons = (loading) => { |
| 197 | + if (loading) { |
| 198 | + $('.profile-header__sync img.loading').show(); |
| 199 | + $('.profile-header__sync img.action').hide(); |
| 200 | + } else { |
| 201 | + $('.profile-header__sync img.loading').hide(); |
| 202 | + $('.profile-header__sync img.action').show(); |
| 203 | + } |
| 204 | + }; |
| 205 | + |
| 206 | + // add click listener |
| 207 | + $('#sync-to-3box').on('click', (event) => { |
| 208 | + if (!long_pressed) { |
| 209 | + startProfileDataBackup(); |
| 210 | + } |
| 211 | + long_pressed = false; |
| 212 | + }); |
| 213 | + |
| 214 | + // add long press listener |
| 215 | + let timer = null; |
| 216 | + let long_pressed = false; |
| 217 | + |
| 218 | + $('#sync-to-3box').on('mousedown', () => { |
| 219 | + timer = setTimeout(() => { |
| 220 | + long_pressed = true; |
| 221 | + toggleAutomaticUpdateFlag(); |
| 222 | + }, 500); |
| 223 | + }).on('mouseup mouseleave', () => { |
| 224 | + clearTimeout(timer); |
| 225 | + }); |
| 226 | + |
| 227 | + $(document).ready(function() { |
| 228 | + setTimeout(() => { |
| 229 | + console.log('check profile backup flag', window.profile_automatic_backup); |
| 230 | + // backup automatically if the flag is true |
| 231 | + if (window.profile_automatic_backup) { |
| 232 | + startProfileDataBackup(); |
| 233 | + } |
| 234 | + }, 3000); |
| 235 | + }); |
| 236 | + |
| 237 | +}(jQuery)); |
0 commit comments