blob: 5b073f5864a727c4ecce832b85bea746b813f8be [file] [log] [blame]
avm9996304def3e2016-11-27 22:53:05 +01001const CURRENT_LOCALE = chrome.i18n.getMessage('@@ui_locale');
2const MULTIPART_FORMDATA_BOUNDARY = 'Google_Chrome_Screen_Capture';
3const HIDE_ERROR_INFO_DELAY_TIME = 5000;
4
5var UploadUI = {
6 currentSite: '',
7 uploading: false,
8 sites: {},
9
10 registerSite: function(id, siteObject) {
11 this.sites[id] = siteObject;
12 },
13
14 getSiteObject: function(id) {
15 return this.sites[id];
16 },
17
18 setUploading: function(state) {
19 UploadUI.uploading = state;
20 },
21
22 init: function() {
23 // Register supported site for image sharing.
24 UploadUI.registerSite(SinaMicroblog.siteId, SinaMicroblog);
25 UploadUI.registerSite(Facebook.siteId, Facebook);
26 UploadUI.registerSite(Picasa.siteId, Picasa);
27 UploadUI.registerSite(Imgur.siteId, Imgur);
28
29 // Import style sheet for current locale
30 if (CURRENT_LOCALE == 'zh_CN')
31 UI.addStyleSheet('./i18n_styles/zh_CN_upload_image.css');
32 else
33 UI.addStyleSheet('./i18n_styles/en_US_upload_image.css');
34
35 // Get i18n message
36 i18nReplace('shareToSinaMicroblogText', SinaMicroblog.siteId +
37 '_upload_header');
38 i18nReplace('shareToFacebookText', Facebook.siteId + '_upload_header');
39 i18nReplace('shareToPicasaText', Picasa.siteId + '_upload_header');
40 i18nReplace('lastStep', 'return_to_site_selection');
41 i18nReplace('closeUploadWrapper', 'close_upload_wrapper');
42 i18nReplace('imageCaptionText', 'image_caption');
43 i18nReplace('photoSizeTip', 'photo_size_tip');
44 i18nReplace('shareToImgurText', Imgur.siteId + '_upload_header');
45 $('requiredFlag').setAttribute('title',
46 chrome.i18n.getMessage('invalid_caption'));
47
48 // Add event listeners
49 //$('btnUpload').addEventListener('click', UploadUI.showUploadWrapper, false);
50 $('btnSave').addEventListener('click', UploadUI.saveImage, false);
51 $('closeUploadWrapper').addEventListener('click',
52 UploadUI.hideUploadWrapper, false);
53
54 $('picasaBtn').addEventListener('click', function() {
55 UploadUI.showUploadContentWrapper(Picasa.siteId);
56 });
57 $('facebookBtn').addEventListener('click', function() {
58 UploadUI.showUploadContentWrapper(Facebook.siteId);
59 }, false);
60 $('sinaMicroblogBtn').addEventListener('click', function() {
61 UploadUI.showUploadContentWrapper(SinaMicroblog.siteId);
62 }, false);
63 $('imgurBtn').addEventListener('click', function() {
64 UploadUI.showUploadContentWrapper(Imgur.siteId);
65 }, false);
66 $('shareToOtherAccount').addEventListener('click', function() {
67 var currentSite = UploadUI.currentSite;
68
69 // Validate image description first
70 if (UploadUI.validatePhotoDescription(currentSite)) {
71 var callback = function() {
72 var authenticationTip =
73 chrome.i18n.getMessage('user_authentication_tip');
74 UploadUI.showAuthenticationProgress(authenticationTip);
75 UploadUI.getAccessToken(currentSite);
76 };
77 var users = Account.getUsers(currentSite);
78 var numberOfUsers = Object.keys(users).length;
79
80 // Logout when user has authenticated app
81 if (numberOfUsers) {
82 var logoutTip = chrome.i18n.getMessage('user_logout_tip');
83 UploadUI.showAuthenticationProgress(logoutTip);
84 var site = UploadUI.getSiteObject(currentSite);
85 site.logout(callback);
86 } else {
87 callback();
88 }
89 }
90 }, false);
91 $('lastStep').addEventListener('click', UploadUI.showUploadSitesWrapper,
92 false);
93 },
94
95 showUploadWrapper: function() {
96 var uploadWrapper = $('uploadWrapper');
97 UI.show(uploadWrapper);
98
99 // Reset upload wrapper position
100 var viewportWidth = window.innerWidth;
101 var viewportHeight = window.innerHeight;
102 var wrapperWidth = uploadWrapper.offsetWidth;
103 var wrapperHeight = uploadWrapper.offsetHeight;
104
105 var left = (viewportWidth - wrapperWidth) / 2;
106 var top = (viewportHeight - wrapperHeight) / 3;
107 left = left < 0 ? 0 : left;
108 top = top < 0 ? 0 : top;
109
110 var scrollTop = document.body.scrollTop;
111 var scrollLeft = document.body.scrollLeft;
112
113 UI.setStyle(uploadWrapper, {
114 top: top + scrollTop + 'px',
115 left: left + scrollLeft + 'px'
116 });
117 UploadUI.showUploadSitesWrapper();
118 UploadUI.showOverlay();
119 },
120
121 hideUploadWrapper: function() {
122 UI.hide($('uploadWrapper'));
123 UploadUI.hideOverlay();
124 },
125
126 showOverlay: function() {
127 var overlay = $('overlay');
128 UI.setStyle(overlay, {
129 width: document.body.scrollWidth + 'px',
130 height: document.body.scrollHeight + 'px'
131 });
132 UI.show($('overlay'));
133 },
134
135 hideOverlay: function() {
136 UI.hide($('overlay'));
137 },
138
139 updateUploadHeader: function(title) {
140 $('uploadHeader').firstElementChild.firstElementChild.innerText = title;
141 },
142
143 showUploadSitesWrapper: function() {
144 var uploadHeader = chrome.i18n.getMessage('upload_sites_header');
145 UploadUI.updateUploadHeader(uploadHeader);
146 UI.show($('uploadSitesWrapper'));
147 UploadUI.hideUploadContentWrapper();
148 UI.hide($('lastStep'));
149 },
150
151 hideUploadSitesWrapper: function() {
152 UI.hide($('uploadSitesWrapper'));
153 },
154
155 showUploadContentWrapper: function(site) {
156 UploadUI.currentSite = site;
157
158 // Update upload wrapper UI
159 var uploadHeader = chrome.i18n.getMessage(site + '_upload_header');
160 UploadUI.updateUploadHeader(uploadHeader);
161 UploadUI.hideUploadSitesWrapper();
162 UploadUI.hideErrorInfo();
163 UploadUI.hideAuthenticationProgress();
164 UploadUI.clearPhotoDescription();
165 UI.show($('uploadContentWrapper'));
166 UI.show($('lastStep'));
167 UploadUI.updateShareToOtherAccountText(site);
168 UploadUI.togglePhotoDescriptionRequiredFlag(site);
169
170 // Show authenticated accounts of current site
171 UploadUI.clearAccounts();
172 var users = Account.getUsers(site);
173 for (var userId in users) {
174 UploadUI.addAuthenticatedAccount(site, userId);
175 }
176 },
177
178 hideUploadContentWrapper: function() {
179 UI.hide($('uploadContentWrapper'));
180 },
181
182 clearPhotoDescription: function() {
183 $('imageCaption').value = '';
184 },
185
186 validatePhotoDescription: function(site) {
187 var caption = $('imageCaption');
188 var invalidCaptionMsg = chrome.i18n.getMessage('invalid_caption');
189
190 // Validate photo description
191 if (site == SinaMicroblog.siteId && caption.value == '') {
192 UploadUI.showErrorInfo(invalidCaptionMsg);
193 caption.focus();
194 return false;
195 }
196 return true;
197 },
198
199 togglePhotoDescriptionRequiredFlag: function(siteId) {
200 if (siteId == SinaMicroblog.siteId)
201 UI.show($('requiredFlag'));
202 else
203 UI.hide($('requiredFlag'));
204 },
205
206 updateShareToOtherAccountText: function(siteId) {
207 var users = Account.getUsers(siteId);
208 var userLength = Object.keys(users).length;
209 if (userLength)
210 i18nReplace('shareToOtherAccount', 'share_to_other_account');
211 else
212 i18nReplace('shareToOtherAccount', 'share_to_' + siteId + '_account');
213 },
214
215 showErrorInfo: function(text) {
216 UI.show($('errorWrapper'));
217 $('errorInfo').innerHTML = text;
218 setTimeout(function() {
219 UploadUI.hideErrorInfo();
220 }, HIDE_ERROR_INFO_DELAY_TIME);
221 },
222
223 hideErrorInfo: function() {
224 UI.hide($('errorWrapper'));
225 },
226
227 showProgressBar: function(accountId) {
228 var progress = document.querySelector('#' + accountId +
229 ' .progressBar');
230 UI.show(progress);
231 },
232
233 hideProgressBar: function(accountId) {
234 var progress = document.querySelector('#' + accountId +
235 ' .progressBar');
236 UI.hide(progress);
237 },
238
239 showAuthenticationProgress: function(title) {
240 var progress = $('authenticationProgress');
241 progress.setAttribute('title', title);
242 UI.show(progress);
243 },
244
245 hideAuthenticationProgress: function() {
246 UI.hide($('authenticationProgress'));
247 },
248
249 setProgress: function(accountId, loaded, total) {
250 console.log('In setProgress, loaded: ' + loaded + ', total: ' + total);
251 var progress = document.querySelector('#' + accountId + ' .progressBar');
252
253 // One progress bar has 4 parts to represent progress
254 var level = parseInt(loaded / total / 0.25);
255 UI.setStyle(progress, 'background-position-y', '-' + (12 * level) + 'px');
256 },
257
258 showPhotoLink: function(accountId, link) {
259 var photoLink = document.querySelector('#' + accountId + ' .photoLink');
260 photoLink.setAttribute('href', link);
261 UI.setStyle(photoLink, 'display', 'inline');
262 },
263
264 hidePhotoLink: function(accountId) {
265 var photoLink = document.querySelector('#' + accountId + ' .photoLink');
266 UI.hide(photoLink);
267 },
268
269 showUploadInfo: function(accountId, text) {
270 var uploadInfo = document.querySelector('#' + accountId + ' .uploadInfo');
271 uploadInfo.innerHTML = text;
272 UI.show(uploadInfo);
273 },
274
275 hideUploadInfo: function(accountId) {
276 var uploadInfo = document.querySelector('#' + accountId + ' .uploadInfo');
277 UI.hide(uploadInfo);
278 },
279
280 clearAccounts: function() {
281 $('uploadAccountList').innerHTML = '';
282 },
283
284 addAuthenticatedAccount: function(site, userId) {
285 var template = $('accountItemTemplate').innerHTML;
286
287 // Replace i18n message
288 template = template.replace(/\$\{accountId\}/gi, site + '_' + userId);
289 var shareToText = chrome.i18n.getMessage('share_to');
290 template = template.replace(/\$\{accountName\}/gi,
291 shareToText + ' ' + Account.getUser(site, userId)['name']);
292 template = template.replace('${site}', site);
293 template = template.replace('${userId}', userId);
294 template = template.replace(/\$\{deletionTitle\}/gi,
295 chrome.i18n.getMessage('deletion_title'));
296 template = template.replace(/\$\{photoLinkText\}/gi,
297 chrome.i18n.getMessage('photo_link_text'));
298 template = template.replace(/\$\{progressInfo\}/gi,
299 chrome.i18n.getMessage('progress_info'));
300
301 // At most show 3 authenticated users
302 var uploadAccountList = $('uploadAccountList');
303 var accountsNumber = uploadAccountList.childElementCount;
304 if (accountsNumber == 2) {
305 uploadAccountList.removeChild(uploadAccountList.lastElementChild);
306 }
307 uploadAccountList.innerHTML = template + uploadAccountList.innerHTML;
308
309 $('accountName').addEventListener('click', function(e) {
310 UploadUI.upload(site, userId);
311 });
312 $('deleteBtn').addEventListener('click', function(e) {
313 e.stopPropagation();
314 UploadUI.deleteAccountItem(site + '_' + userId);
315 });
316
317 UploadUI.updateShareToOtherAccountText(site);
318 },
319
320 deleteAccountItem: function(accountId, noConfirm) {
321 if (UploadUI.uploading && !noConfirm)
322 return;
323 var confirmText = chrome.i18n.getMessage('account_deletion_confirm');
324 if (noConfirm || confirm(confirmText)) {
325 $('uploadAccountList').removeChild($(accountId));
326
327 // Clear localStorage
328 var site = accountId.split('_')[0];
329 var userId = accountId.split('_')[1];
330 Account.removeUser(site, userId);
331 UploadUI.updateShareToOtherAccountText(site);
332 }
333 },
334
335 upload: function(siteId, userId) {
336 if (UploadUI.uploading)
337 return;
338
339 // Initialize UI
340 var accountId = siteId + '_' + userId;
341 UploadUI.hideErrorInfo();
342 UploadUI.hideUploadInfo(accountId);
343 UploadUI.hidePhotoLink(accountId);
344 if (!UploadUI.validatePhotoDescription(siteId))
345 return;
346 var caption = $('imageCaption').value;
347
348 // Get ready for upload image.
349 photoshop.draw();
350 UploadUI.setUploading(true);
351 UploadUI.showProgressBar(accountId);
352
353 var site = UploadUI.getSiteObject(siteId);
354 var user = Account.getUser(siteId, userId);
355 var imageData = UploadUI.getImageData();
356 var infoText;
357
358 var callback = function(result, photoIdOrMessage) {
359 if (result == 'success') {
360 infoText = chrome.i18n.getMessage('get_photo_link');
361 UploadUI.showUploadInfo(accountId, infoText);
362 site.getPhotoLink(user, photoIdOrMessage, function(photoLinkResult,
363 photoLinkOrMessage) {
364 if (photoLinkResult == 'success') {
365 UploadUI.setUploading(false);
366 UploadUI.hideUploadInfo(accountId);
367 UploadUI.showPhotoLink(accountId, photoLinkOrMessage);
368 } else {
369 UploadUI.showErrorInfo(photoLinkOrMessage);
370 }
371 });
372 } else {
373 if (photoIdOrMessage == 'bad_access_token' ||
374 photoIdOrMessage == 'invalid_album_id') {
375 Account.removeUser(site.siteId, site.currentUserId);
376 UploadUI.deleteAccountItem(accountId, true);
377 UploadUI.getAccessToken(siteId);
378 }
379 UploadUI.setUploading(false);
380 UploadUI.hideProgressBar(accountId);
381 UploadUI.showErrorInfo(chrome.i18n.getMessage(photoIdOrMessage));
382 }
383 UploadUI.hideProgressBar(accountId);
384 };
385
386 if (user) {
387 site.currentUserId = user.id;
388 site.upload(user, caption, imageData, callback);
389 } else {
390 UploadUI.getAccessToken(siteId);
391 }
392 },
393
394 getAccessToken: function(siteId) {
395 var site = UploadUI.getSiteObject(siteId);
396 var accessTokenCallback = function(result, userOrMessage) {
397 if (result == 'success') {
398 UploadUI.getUserInfo(siteId, userOrMessage);
399 } else {
400 // Show error information according to error reason
401 UploadUI.showErrorInfo(chrome.i18n.getMessage(userOrMessage));
402 UploadUI.hideAuthenticationProgress();
403 }
404 };
405
406 site.getAccessToken(accessTokenCallback);
407 },
408
409 getUserInfo: function(siteId, user) {
410 var site = UploadUI.getSiteObject(siteId);
411 site.getUserInfo(user, function(result, userOrMessage) {
412 if (result == 'success') {
413 var userId = user.id;
414 // Check if the authenticated user is added.
415 if (!Account.getUser(siteId, userId)) {
416 site.currentUserId = userId;
417 Account.addUser(siteId, user);
418 UploadUI.addAuthenticatedAccount(siteId, userId);
419 }
420 UploadUI.upload(siteId, userId);
421 } else {
422 var msg = chrome.i18n.getMessage(userOrMessage);
423 UploadUI.showErrorInfo(msg);
424 }
425 UploadUI.hideAuthenticationProgress();
426 });
427 },
428
429 getImageData: function() {
430 var dataUrl = $('canvas').toDataURL('image/png');
431 var imageDataIndex = dataUrl.indexOf('data:image/png;base64,');
432 if (imageDataIndex != 0) {
433 return;
434 }
435
436 // Decode to binary data
437 return atob(dataUrl.substr(imageDataIndex + 22));
438 },
439
440 saveImage: function() {
441 $('canvas').toBlob(function(blob) {
442 console.log(chrome.extension.getBackgroundPage());
443 saveAs(blob, chrome.extension.getBackgroundPage().screenshot.screenshotName+".png");
444 });
445 }
446};
447
448(function() {
449// Cache tab id of edit page, so that we can get tab focus after getting access
450// token.
451var tabIdOfEditPage;
452chrome.tabs.getSelected(null, function(tab) {
453 tabIdOfEditPage = tab.id;
454});
455
456function selectTab(tabId) {
457 chrome.tabs.update(tabId, {
458 selected: true
459 });
460}
461
462function closeTab(tabId) {
463 chrome.tabs.remove(tabId);
464}
465
466function parseAccessToken(senderId, url, siteId) {
467 var sites = UploadUI.sites;
468 for (var id in sites) {
469 var site = sites[id];
470 if ((siteId && id == siteId) || site.isRedirectUrl(url)) {
471 selectTab(tabIdOfEditPage);
472 closeTab(senderId);
473 site.parseAccessToken(url);
474 return true;
475 }
476 }
477 return false;
478}
479
480chrome.extension.onMessage.addListener(function(request, sender) {
481 switch (request.msg) {
482 case 'url_for_access_token':
483 parseAccessToken(sender.tab.id, request.url, request.siteId);
484 break;
485 }
486});
487})();