Changeset 30
- Timestamp:
- 10/02/07 15:52:25 (2 years ago)
- Files:
-
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/api.js (modified) (9 diffs)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/events_photos.js (modified) (5 diffs)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/events_settings.js (modified) (2 diffs)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/file.js (added)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/main.js (modified) (4 diffs)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/main.xul (modified) (6 diffs)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/meta.js (modified) (4 diffs)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/photos.js (modified) (4 diffs)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/photos.xul (modified) (2 diffs)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/settings.js (modified) (3 diffs)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/settings.xul (modified) (5 diffs)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/threads.js (modified) (2 diffs)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/ui.js (modified) (13 diffs)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/uploadr.js (modified) (2 diffs)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/users.js (modified) (5 diffs)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/locale/en-US/main.dtd (modified) (3 diffs)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/locale/en-US/main.properties (modified) (3 diffs)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/skin/uploadr/dialog.css (modified) (1 diff)
- trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/skin/uploadr/main.css (modified) (8 diffs)
- trunk/uploadr/NOTES (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/api.js
r28 r30 134 134 } 135 135 } 136 // photos.add_to_set.push(photo_id);137 136 138 137 } else if ('fail' == stat) { … … 143 142 } 144 143 } 145 146 // Add this photo to sets147 ///148 144 photos.uploading[id] = null; 149 145 … … 273 269 274 270 // Kick off the chain of adding photos to a set 275 Components.utils.reportError(meta.sets_map.toSource());276 271 var not_adding_to_sets = true; 277 272 for (var set_id in meta.sets_map) { … … 323 318 if (0 < photos.ok && confirm(locale.getString('uploaded.prompt'), 324 319 locale.getString('uploaded.prompt.title'))) { 325 var io = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService); 326 var uri = io.newURI('http://flickr.com/tools/uploader_edit.gne?ids=' + 327 photos.uploaded.join(','), null, null); 328 var eps = Cc['@mozilla.org/uriloader/external-protocol-service;1'].getService( 329 Ci.nsIExternalProtocolService); 330 var launcher = eps.getProtocolHandlerInfo('http'); 331 launcher.preferredAction = Ci.nsIHandlerInfo.useSystemDefault; 332 launcher.launchWithURI(uri, null); 320 launch_browser('http://flickr.com/tools/uploader_edit.gne?ids=' + 321 photos.uploaded.join(',')); 333 322 } 334 323 … … 641 630 settings.content_type = 642 631 parseInt(rsp.getElementsByTagName('person')[0].getAttribute('content_type')); 643 settings.update();632 // settings.update(); 644 633 } 645 634 unblock_exit(); … … 657 646 settings.hidden = 658 647 parseInt(rsp.getElementsByTagName('person')[0].getAttribute('hidden')); 659 settings.update();648 // settings.update(); 660 649 } 661 650 unblock_exit(); … … 675 664 settings.is_friend = 2 == privacy || 4 == privacy; 676 665 settings.is_family = 3 == privacy || 5 == privacy; 677 settings.update();666 // settings.update(); 678 667 } 679 668 unblock_exit(); … … 692 681 settings.safety_level = 693 682 parseInt(rsp.getElementsByTagName('person')[0].getAttribute('safety_level')); 694 settings.update();683 // settings.update(); 695 684 } 696 685 unblock_exit(); … … 798 787 // Only GET requests are supported here 799 788 if (browser) { 800 var io = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService); 801 var uri = io.newURI(url, null, null); 802 var eps = Cc['@mozilla.org/uriloader/external-protocol-service;1'].getService( 803 Ci.nsIExternalProtocolService); 804 var launcher = eps.getProtocolHandlerInfo('http'); 805 launcher.preferredAction = Ci.nsIHandlerInfo.useSystemDefault; 806 launcher.launchWithURI(uri, null); 789 launch_browser(url); 807 790 } 808 791 trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/events_photos.js
r28 r30 80 80 } 81 81 82 // Enable toolbar buttons for selected images83 document.getElementById('t_remove').className = 'enabled';84 document.getElementById('t_rotate_l').className = 'enabled';85 document.getElementById('t_rotate_r').className = 'enabled';86 87 82 } 88 83 // If we clicked the revert to sorted button … … 104 99 } 105 100 meta.disable(); 106 document.getElementById('t_remove').className = 'disabled';107 document.getElementById('t_rotate_l').className = 'disabled';108 document.getElementById('t_rotate_r').className = 'disabled';109 101 } 110 102 … … 405 397 meta.batch(); 406 398 } 407 document.getElementById('t_remove').className = 'enabled';408 document.getElementById('t_rotate_l').className = 'enabled';409 document.getElementById('t_rotate_r').className = 'enabled';410 399 } 411 400 … … 413 402 414 403 events.photos.anchor = null; 404 }, 405 406 // Remove selected photos 407 remove: function() { 408 409 // Nothing to do if somehow there are no selected photos 410 var ii = photos.selected.length; 411 if (0 == ii) { 412 return; 413 } 414 415 // Remove selected photos 416 for (var i = 0; i < ii; ++i) { 417 var id = photos.selected[i]; 418 var li = document.getElementById('photo' + id); 419 li.parentNode.removeChild(li); 420 421 // Free the size of this file 422 if (users.username && !users.is_pro) { 423 var size = file.size(photos.list[id].path); 424 photos.batch_size -= size; 425 if (users.bandwidth.remaining - photos.batch_size) { 426 status.clear(); 427 } 428 } 429 430 photos.list[id] = null; 431 --photos.count; 432 photos.unsaved = true; 433 } 434 free.update(); 435 photos.normalize(); 436 437 // Clear the selection 438 photos.selected = []; 439 events.photos.click({target: {}}); 440 441 // Allow upload only if there are photos 442 if (photos.count) { 443 buttons.enable('upload'); 444 } else { 445 photos.unsaved = false; 446 buttons.disable('upload'); 447 } 448 415 449 }, 416 450 … … 572 606 p.sets.push(set_id); 573 607 } 574 Components.utils.reportError(p.sets);575 608 } 576 609 set.selectedIndex = 0; trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/events_settings.js
r28 r30 1 1 events.settings = { 2 3 load: function() { 4 5 // Settings 6 var s = window.arguments[0]; 7 if ({} != s) { 8 document.getElementById('is_public').value = s.is_public; 9 document.getElementById('is_friend').checked = 1 == s.is_friend; 10 document.getElementById('is_family').checked = 1 == s.is_family; 11 events.settings.is_public(); 12 document.getElementById('content_type').selectedIndex = s.content_type - 1; 13 document.getElementById('hidden').selectedIndex = s.hidden - 1; 14 document.getElementById('safety_level').selectedIndex = s.safety_level - 1; 15 document.getElementById('resize').value = s.resize; 16 } 17 document.getElementById('resize_note').firstChild.nodeValue = window.arguments[2]; 18 19 // Users 20 var u = window.arguments[1]; 21 if ([] != u) { 22 var dropdown = document.getElementById('user'); 23 dropdown.removeAllItems(); 24 u.sort(function(a, b) { 25 return a.username < b.username; 26 }); 27 var ii = u.length; 28 for (var i = 0; i < ii; ++i) { 29 dropdown.appendItem(u[i].username, u[i].username); 30 if (u[i].current) { 31 dropdown.selectedIndex = i; 32 } 33 } 34 } 35 36 centerWindowOnScreen(); 37 }, 38 39 cancel: function() { 40 }, 41 42 ok: function() { 43 44 // Settings 45 var s = window.arguments[0]; 46 s.is_public = parseInt(document.getElementById('is_public').value); 47 s.is_friend = document.getElementById('is_friend').checked ? 1 : 0; 48 s.is_family = document.getElementById('is_family').checked ? 1 : 0; 49 s.content_type = document.getElementById('content_type').selectedIndex + 1; 50 s.hidden = document.getElementById('hidden').selectedIndex + 1; 51 s.safety_level = document.getElementById('safety_level').selectedIndex + 1; 52 s.resize = parseInt(document.getElementById('resize').value); 53 54 // Users 55 window.arguments[3].change_user = document.getElementById('user').value; 56 57 }, 58 59 // Remove a user from the list, which will be made permanent by pressing OK 60 remove_user: function() { 61 var dropdown = document.getElementById('user'); 62 var u = window.arguments[1]; 63 var i = 0; 64 for each (var user in u) { 65 if (dropdown.value == user.username) { 66 delete u[i]; 67 break; 68 } 69 ++i; 70 } 71 dropdown.removeItemAt(dropdown.selectedIndex); 72 dropdown.selectedIndex = 0; 73 }, 74 75 // Close this dialog to start the auth process for a new user, after which we'll return here 76 add_user: function() { 77 window.arguments[3].add_user = true; 78 window.close(); 79 }, 2 80 3 81 // Properly enable/disable the checkboxes available for private photos to be shared with … … 5 83 is_public: function(value) { 6 84 if (1 == parseInt(value)) { 7 document.getElementById(' s_is_friend').checked = false;8 document.getElementById(' s_is_family').checked = false;9 document.getElementById(' s_is_friend').disabled = true;10 document.getElementById(' s_is_family').disabled = true;85 document.getElementById('is_friend').checked = false; 86 document.getElementById('is_family').checked = false; 87 document.getElementById('is_friend').disabled = true; 88 document.getElementById('is_family').disabled = true; 11 89 } else { 12 document.getElementById(' s_is_friend').disabled = false;13 document.getElementById(' s_is_family').disabled = false;90 document.getElementById('is_friend').disabled = false; 91 document.getElementById('is_family').disabled = false; 14 92 } 15 93 } trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/main.js
r28 r30 1 events.tools = {2 3 // Add photos4 add: function() {5 photos.add();6 },7 8 // Remove selected photos9 remove: function() {10 11 // Nothing to do if somehow there are no selected photos12 var ii = photos.selected.length;13 if (0 == ii) {14 return;15 }16 17 // Remove selected photos18 for (var i = 0; i < ii; ++i) {19 var id = photos.selected[i];20 var li = document.getElementById('photo' + id);21 li.parentNode.removeChild(li);22 23 // Free the size of this file24 if (users.username && !users.is_pro) {25 var size = uploadr.fsize(photos.list[id].path);26 photos.batch_size -= size;27 if (users.bandwidth.remaining - photos.batch_size) {28 status.clear();29 }30 free.update();31 }32 33 photos.list[id] = null;34 --photos.count;35 photos.unsaved = true;36 }37 photos.normalize();38 39 // Clear the selection40 photos.selected = [];41 events.photos.click({target: {}});42 43 // Allow upload only if there are photos44 if (photos.count) {45 buttons.enable('upload');46 } else {47 photos.unsaved = false;48 buttons.disable('upload');49 }50 51 },52 53 // Rotate selected photos54 rotate_l: function() {55 photos.rotate(-90);56 },57 rotate_r: function() {58 photos.rotate(90);59 },60 61 // Show the settings page62 settings: function() {63 pages.go('settings');64 buttons.show(['back', 'ok']);65 }66 67 };68 69 1 events.buttons = { 70 71 // Back button for the settings and users pages, perhaps more uses later72 back: function() {73 var current = pages.current();74 if ('users' == current) {75 //76 } else if ('settings' == current) {77 settings.abandon();78 }79 pages.go('photos');80 if (users.username) {81 buttons.show('upload');82 } else {83 buttons.show('login');84 }85 },86 87 // OK button for the settings and users pages, perhaps more uses later88 ok: function() {89 90 // Change the logged-in user91 var username = document.getElementById('u_user').value;92 if ('users' == pages.current() && '' != username) {93 users.list[users.username].current = false;94 var u = users.list[username];95 users.username = u.username;96 users.nsid = u.nsid;97 users.token = u.token;98 users.list[users.username].current = true;99 users.login();100 }101 102 settings.update();103 pages.go('photos');104 if (users.username) {105 buttons.show('upload');106 } else {107 buttons.show('login');108 }109 },110 2 111 3 // Login button, shown on the photos page until logged in 112 4 login: function() { 113 5 if (users.username) { 114 pages.go('users'); 115 buttons.show(['back', 'ok']); 6 settings.show(); 116 7 } else { 117 8 users.login(); … … 123 14 124 15 // Save the selected photo before uploading 125 events.photos.click({'target': {}}); 126 settings.update(); 16 events.photos.click({target: {}}); 127 17 128 18 photos.upload(); … … 139 29 // Launch a web browser to buy a Pro account 140 30 go_pro: function() { 141 var io = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService); 142 var uri = io.newURI('http://flickr.com/upgrade/', null, null); 143 var eps = Cc['@mozilla.org/uriloader/external-protocol-service;1'].getService( 144 Ci.nsIExternalProtocolService); 145 var launcher = eps.getProtocolHandlerInfo('http'); 146 launcher.preferredAction = Ci.nsIHandlerInfo.useSystemDefault; 147 launcher.launchWithURI(uri, null); 31 launch_browser('http://flickr.com/upgrade/'); 148 32 alert(locale.getString('go_pro'), locale.getString('go_pro.title')); 149 33 } … … 193 77 194 78 }; 79 80 events.menus = { 81 82 help: { 83 84 about: function() { 85 }, 86 87 faq: function() { 88 launch_browser('http://flickr.com/help/faq/'); 89 } 90 91 } 92 93 }; trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/main.xul
r28 r30 4 4 <?xml-stylesheet href="chrome://hacks/skin/hacks.css" type="text/css"?> 5 5 <?xul-overlay href="chrome://uploadr/content/photos.xul"?> 6 <?xul-overlay href="chrome://uploadr/content/users.xul"?>7 <?xul-overlay href="chrome://uploadr/content/settings.xul"?>8 6 <!DOCTYPE window SYSTEM "chrome://uploadr/locale/main.dtd"> 9 7 <window id="main" title="&title;" width="960" height="700" windowtype="app" 10 8 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 11 xmlns:html="http://www.w3.org/1999/xhtml" onload="users.load(); photos.load(); uploadr.drag();"9 xmlns:html="http://www.w3.org/1999/xhtml" onload="users.load(); photos.load(); photos.drag();" 12 10 onclose="return exit();" persist="screenX screenY width height sizemode"> 13 11 <stringbundleset> 14 12 <stringbundle id="locale" src="chrome://uploadr/locale/main.properties" /> 15 13 </stringbundleset> 14 <script src="chrome://global/content/globalOverlay.js" /> 16 15 <script src="chrome://global/content/nsDragAndDrop.js" /> 17 16 <script src="chrome://uploadr/content/md5.js" /> 18 17 <script src="chrome://uploadr/content/uploadr.js" /> 18 <script src="chrome://uploadr/content/file.js" /> 19 19 <script src="chrome://uploadr/content/threads.js" /> 20 20 <script src="chrome://uploadr/content/api.js" /> … … 26 26 <script src="chrome://uploadr/content/main.js" /> 27 27 <script src="chrome://uploadr/content/events_bandwidth.js" /> 28 29 <!-- Commands appearing more than one place --> 30 <commandset> 31 <command id="cmd_add" oncommand="photos.add();" /> 32 <command id="cmd_upload" oncommand="photos.upload();" /> 33 <command id="cmd_prefs" oncommand="settings.show();" /> 34 <command id="cmd_quit" oncommand="exit();" /> 35 <command id="cmd_remove" oncommand="events.photos.remove();" /> 36 </commandset> 37 28 38 <keyset> 29 <key id="key_quit" modifiers="accel" key="q" oncommand="exit();" /> 30 <key id="key_prefs" modifiers="accel" key="," oncommand="events.tools.settings();" /> 31 <key id="key_back" keycode="VK_BACK" oncommand="events.tools.remove();" /> 32 <key id="key_delete" keycode="VK_DELETE" oncommand="events.tools.remove();" /> 33 39 <key id="key_add" modifiers="accel" key="o" command="cmd_add" /> 40 <key id="key_upload" modifiers="shift accel" key="u" command="cmd_upload" /> 41 <key id="key_prefs" modifiers="accel" key="," command="cmd_prefs" /> 42 <key id="key_quit" modifiers="accel" key="q" command="cmd_quit" /> 43 <key id="key_back" keycode="VK_BACK" command="cmd_remove" /> 44 <key id="key_delete" keycode="VK_DELETE" command="cmd_remove" /> 34 45 <key id="key_up" keycode="VK_UP" oncommand="events.arrows.up(event);" /> 35 46 <key id="key_right" keycode="VK_RIGHT" oncommand="events.arrows.right(event);" /> … … 55 66 <toolbox id="menu"> 56 67 <menubar> 57 <menu id="menu_ file" label="&menu.file;">68 <menu id="menu_upload" label="&menu.upload;"> 58 69 <menupopup> 59 <menuitem id="menu_add" label="&menu.file.add;" oncommand="photos.add();" /> 60 <menuitem id="menu_preferences" label="&menu.file.preferences;" 61 key="key_prefs" oncommand="events.tools.settings();" /> 62 <menuitem id="menu_FileQuitItem" label="&menu.file.exit;" 63 key="key_quit" oncommand="exit();" /> 70 <menuitem id="menu_add" label="&menu.upload.add;" key="key_add" 71 command="cmd_add" /> 72 <menuitem id="menu_upload_upload" label="&menu.upload;" key="key_upload" 73 command="cmd_upload" /> 74 <menuitem id="menu_preferences" label="&menu.upload.preferences;" 75 key="key_prefs" command="cmd_prefs" /> 76 <menuitem id="menu_FileQuitItem" label="&menu.upload.exit;" 77 key="key_quit" command="cmd_quit" /> 78 </menupopup> 79 </menu> 80 <menu id="menu_edit" label="&menu.edit;"> 81 <menupopup> 82 <menuitem id="menu_cut" label="&menu.edit.cut;" 83 oncommand="goDoCommand('cmd_cut');" /> 84 <menuitem id="menu_copy" label="&menu.edit.copy;" 85 oncommand="goDoCommand('cmd_copy');" /> 86 <menuitem id="menu_paste" label="&menu.edit.paste;" 87 oncommand="goDoCommand('cmd_paste');" /> 88 </menupopup> 89 </menu> 90 <menu id="menu_help" label="&menu.help;"> 91 <menupopup> 92 <menuitem id="menu_about" label="&menu.help.about;" 93 oncommand="events.menus.help.about();" /> 94 <menuitem id="menu_faq" label="&menu.help.faq;" 95 oncommand="events.menus.help.faq();" /> 64 96 </menupopup> 65 97 </menu> … … 68 100 <vbox flex="1"> 69 101 70 <!-- Header and toolbar --> 71 <hbox> 72 <vbox> 73 <box flex="1"><label id="username" value="¬loggedin;" /></box> 74 <box flex="1"><label id="switch" value="&login;" onclick="events.buttons.login();" 75 /></box> 76 <hbox id="tools" minheight="34" maxheight="34"> 77 <toolbox> 78 <toolbar> 79 <toolbarbutton id="t_add" class="enabled" 80 oncommand="events.tools.add();" /> 81 <toolbarbutton id="t_remove" class="disabled" 82 oncommand="events.tools.remove();" /> 83 <toolbarseparator /> 84 <toolbarbutton id="t_rotate_l" class="disabled" 85 oncommand="events.tools.rotate_l();" /> 86 <toolbarbutton id="t_rotate_r" class="disabled" 87 oncommand="events.tools.rotate_r();" /> 88 <toolbarseparator /> 89 <toolbarbutton id="t_settings" class="enabled" 90 oncommand="events.tools.settings();" /> 91 </toolbar> 92 </toolbox> 93 <box id="diag" /> 94 </hbox> 95 <box id="no_tools" class="fill" flex="1" /> 96 </vbox> 97 <box class="fill" flex="1" /> 102 <!-- Header --> 103 <hbox id="head"> 98 104 <box id="logo" /> 105 <box flex="1" /> 106 <hbox><label id="username" value="¬loggedin;" /><html:input 107 type="button" id="switch" class="button" value="&login;" 108 onclick="events.buttons.login();" /></hbox> 99 109 </hbox> 100 110 101 <!-- Placeholders for page overlays --> 102 <hbox id="page_photos" flex="1" /> 103 <vbox id="page_users" flex="1" /> 104 <vbox id="page_settings" flex="1" /> 105 <box id="page_progress" flex="1" /> 106 <box id="page_complete" flex="1" /> 111 <!-- Placeholder for overlays --> 112 <vbox id="page_photos" flex="1" /> 113 <!-- --> 107 114 108 115 <!-- Footer and status bar --> 109 116 <hbox id="footer"> 117 <!-- 110 118 <hbox id="free"> 111 119 <vbox> … … 118 126 </vbox> 119 127 <html:input type="button" id="go_pro" value="&bandwidth.go_pro;" 120 class=" link" onclick="events.buttons.go_pro();" />128 class="button" onclick="events.buttons.go_pro();" /> 121 129 </hbox> 130 --> 122 131 <hbox id="progress"> 123 132 <vbox> … … 137 146 <html:input type="button" id="button_login" value="&buttons.login;" class="button" 138 147 onclick="events.buttons.login();" /> 139 <html:input type="button" id="button_back" value="&buttons.back;" class="button"140 onclick="events.buttons.back();" />141 <html:input type="button" id="button_ok" value="&buttons.ok;" class="button"142 onclick="events.buttons.ok();" />143 148 <html:input type="button" id="button_upload" value="&buttons.upload;" 144 149 class="disabled_button" disabled="true" onclick="events.buttons.upload();" /> 145 150 </hbox> 146 <statusbar>147 <statusbarpanel id="status" label="" flex="1" />148 </statusbar>149 151 150 152 </vbox> 153 <statusbar> 154 <statusbarpanel id="status" label="" flex="1" /> 155 </statusbar> 151 156 </window> trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/meta.js
r28 r30 53 53 [p.width, p.height]); 54 54 document.getElementById('meta_size').value = locale.getFormattedString('meta.size', 55 [(Math.round( uploadr.fsize(p.path) / 102.4) / 10) + ' MB']);55 [(Math.round(file.size(p.path) / 102.4) / 10)]); 56 56 document.getElementById('single_title').value = p.title; 57 57 document.getElementById('single_description').value = p.description; … … 156 156 document.getElementById('single_sets').style.display = 'none'; 157 157 document.getElementById('batch_meta').style.display = 'none'; 158 document.getElementById('no_meta').style.display = 'none';158 meta._enable(); 159 159 }, 160 160 … … 168 168 document.getElementById('batch_melons').style.display = 'none'; 169 169 document.getElementById('batch_sets').style.display = 'none'; 170 meta._enable(); 171 }, 172 173 // Common to batch and single enabling 174 _enable: function() { 170 175 document.getElementById('no_meta').style.display = 'none'; 176 var remove = document.getElementById('t_remove'); 177 remove.className = 'button'; 178 remove.disabled = false; 179 document.getElementById('t_rotate_l').className = 'enabled'; 180 document.getElementById('t_rotate_r').className = 'enabled'; 171 181 }, 172 182 … … 176 186 document.getElementById('batch_meta').style.display = 'none'; 177 187 document.getElementById('no_meta').style.display = '-moz-box'; 188 var remove = document.getElementById('t_remove'); 189 remove.className = 'disabled_button'; 190 remove.disabled = true; 191 document.getElementById('t_rotate_l').className = 'disabled'; 192 document.getElementById('t_rotate_r').className = 'disabled'; 178 193 }, 179 194 trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/photos.js
r28 r30 74 74 threads.worker.DISPATCH_NORMAL); 75 75 76 // Check the size of this file if we're logged in 77 if (users.username) { 78 var size = file.size(photos.list[id].path); 79 if (!users.is_pro && users.bandwidth.remaining - photos.batch_size < size) { 80 status.set(locale.getString('status.limit')); 81 } else { 82 status.clear(); 83 } 84 photos.batch_size += size; 85 free.update(); 86 } 87 88 }, 89 90 // Handle files dragged on startup 91 drag: function() { 92 buttons.disable('upload'); 93 var cl = window.arguments[0].QueryInterface(Ci.nsICommandLine); 94 var ii = cl.length; 95 for (var i = 0; i < ii; ++i) { 96 if ('-url' == cl.getArgument(i)) { 97 photos._add(Cc['@mozilla.org/network/protocol;1?name=file'].getService( 98 Ci.nsIFileProtocolHandler).getFileFromURLSpec(cl.getArgument(++i)).path); 99 } 100 } 101 if (photos.sort) { 102 threads.worker.dispatch(new Sort(), threads.worker.DISPATCH_NORMAL); 103 } else { 104 threads.worker.dispatch(new EnableUpload(), threads.worker.DISPATCH_NORMAL); 105 } 76 106 }, 77 107 … … 124 154 threads.worker.dispatch(new Resize(p.id, settings.resize, p.path), 125 155 threads.worker.DISPATCH_NORMAL); 126 } else if ( uploadr.fsize(p.path) > users.filesize) {156 } else if (file.size(p.path) > users.filesize) { 127 157 resizing = true; 128 158 threads.worker.dispatch(new Resize(p.id, -1, p.path), … … 200 230 // Load saved metadata 201 231 load: function() { 202 var obj = uploadr.fread('photos.json');232 var obj = file.read('photos.json'); 203 233 204 234 // Add the previous batch of photos … … 236 266 meta.created_sets = []; 237 267 } 238 uploadr.fwrite('photos.json', {268 file.write('photos.json', { 239 269 sort: photos.sort, 240 270 sets: meta.created_sets, trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/photos.xul
r28 r30 7 7 xmlns:html="http://www.w3.org/1999/xhtml"> 8 8 <script src="chrome://uploadr/content/events_photos.js" /> 9 <hbox id="page_photos" flex="1"> 10 <vbox class="newest" flex="1"> 11 <scrollbox id="photos" class="no_drag oldest" flex="1" orient="vertical" 9 <vbox id="page_photos" flex="1"> 10 <hbox id="tools" minheight="34" maxheight="34"> 11 <toolbox> 12 <toolbar> 13 <html:input type="button" id="t_add" class="button" 14 value="&tools.add;" onclick="photos.add();" /> 15 <html:input type="button" id="t_remove" class="disabled_button" 16 value="&tools.remove;" onclick="events.photos.remove();" /> 17 <toolbarseparator /> 18 <toolbarbutton id="t_rotate_l" class="disabled" 19 oncommand="photos.rotate(-90);" /> 20 <toolbarbutton id="t_rotate_r" class="disabled" 21 oncommand="photos.rotate(90);" /> 22 </toolbar> 23 </toolbox> 24 <box><label id="free" value="asdf" /></box> 25 </hbox> 26 <hbox flex="1"> 27 <scrollbox id="photos" class="no_drag" flex="1" orient="vertical" 12 28 onclick="events.photos.click(event);" 13 29 onmousedown="events.photos.mousedown(event);" … … 28 44 </stack> 29 45 </scrollbox> 30 </vbox> 31 <vbox id="meta"> 32 <hbox> 33 <html:div id="meta_div"></html:div> 34 <vbox> 35 <label id="meta_dim" value="" /> 36 <label id="meta_size" value="" /> 37 </vbox> 38 </hbox> 39 <label control="single_title" value="&meta.title;" /> 40 <textbox id="single_title" /> 41 <label control="single_description" value="&meta.description;" /> 42 <textbox id="single_description" multiline="true" rows="2" /> 43 <label control="single_tags" value="&meta.tags;" /> 44 <textbox id="single_tags" /> 45 <html:p> </html:p> 46 <label id="single_privacy_link" class="link" value="&meta.privacy;" 47 onclick="events.photos.privacy();" /> 48 <vbox id="single_privacy"> 49 <label control="single_is_public" value="&settings.privacy.who;" /> 50 <radiogroup id="single_is_public" value="1" 51 oncommand="events.photos.is_public(this.value);"> 52 <radio value="0" label="&settings.privacy.private;" /> 53 <checkbox id="single_is_friend" label="&settings.privacy.friend;" /> 54 <checkbox id="single_is_family" label="&settings.privacy.family;" /> 55 <radio value="1" label="&settings.privacy.public;" /> 56 </radiogroup> 46 <vbox id="meta"> 47 <hbox> 48 <html:div id="meta_div"></html:div> 49 <vbox> 50 <label id="meta_dim" value="" /> 51 <label id="meta_size" value="" /> 52 </vbox> 53 </hbox> 54 <label control="single_title" value="&meta.title;" /> 55 <textbox id="single_title" /> 56 <label control="single_description" value="&meta.description;" /> 57 <textbox id="single_description" multiline="true" rows="2" /> 58 <label control="single_tags" value="&meta.tags;" /> 59 <textbox id="single_tags" /> 57 60 <html:p> </html:p> 61 <label id="single_privacy_link" class="link" value="&meta.privacy;" 62 onclick="events.photos.privacy();" /> 63 <vbox id="single_privacy"> 64 <label control="single_is_public" value="&settings.privacy.who;" /> 65 <radiogroup id="single_is_public" value="1" 66 oncommand="events.photos.is_public(this.value);"> 67 <radio value="0" label="&settings.privacy.private;" /> 68 <checkbox id="single_is_friend" label="&settings.privacy.friend;" /> 69 <checkbox id="single_is_family" label="&settings.privacy.family;" /> 70 <radio value="1" label="&settings.privacy.public;" /> 71 </radiogroup> 72 <html:p> </html:p> 73 </vbox> 74 <label id="single_melons_link" class="link" value="&meta.melons;" 75 onclick="events.photos.melons();" /> 76 <vbox id="single_melons"> 77 <label control="single_content_type" value="&settings.content_type;" /> 78 <menulist id="single_content_type"> 79 <menupopup> 80 <menuitem value="1" label="&settings.content_type.photo;" 81 selected="true" /> 82 <menuitem value="2" label="&settings.content_type.screenshot;" /> 83 <menuitem value="3" label="&settings.content_type.other;" /> 84 </menupopup> 85 </menulist> 86 <label control="single_hidden" value="&settings.hidden;" /> 87 <menulist id="single_hidden"> 88 <menupopup> 89 <menuitem value="1" label="&settings.hidden.no;" 90 selected="true" /> 91 <menuitem value="2" label="&settings.hidden.yes;" /> 92 </menupopup> 93 </menulist> 94 <label control="single_safety_level" value="&settings.safety_level;" /> 95 <menulist id="single_safety_level"> 96 <menupopup> 97 <menuitem value="1" label="&settings.safety_level.safe;" 98 selected="true" /> 99 <menuitem value="2" label="&settings.safety_level.moderate;" /> 100 <menuitem value="3" label="&settings.safety_level.restricted;" /> 101 </menupopup> 102 </menulist> 103 <html:p> </html:p> 104 </vbox> 105 <label control="single_sets_link" class="link" value="&meta.single.sets;" 106 onclick="events.photos.sets();" /> 107 <vbox id="single_sets"> 108 <html:ul id="single_sets_list"></html:ul> 109 <menulist id="single_set"> 110 <menupopup> 111 <menuitem value="0" label="&settings.sets.none;" /> 112 </menupopup> 113 </menulist> 114 <html:table border="0" cellpadding="0" cellspacing="0"> 115 <html:tr> 116 <html:td><label id="single_sets_create" class="link" 117 value="&settings.sets.create;" onclick="events.photos.create_set();" 118 /></html:td> 119 <html:td><html:input type="button" id="single_sets_add" class="button" 120 value="&settings.sets.add;" onclick="events.photos.add_to_set();" 121 /></html:td> 122 </html:tr> 123 </html:table> 124 </vbox> 58 125 </vbox> 59 <label id="single_melons_link" class="link" value="&meta.melons;" 60 onclick="events.photos.melons();" /> 61 <vbox id="single_melons"> 62 <label control="single_content_type" value="&settings.content_type;" /> 63 <menulist id="single_content_type"> 64 <menupopup> 65 <menuitem value="1" label="&settings.content_type.photo;" 66 selected="true" /> 67 <menuitem value="2" label="&settings.content_type.screenshot;" /> 68 <menuitem value="3" label="&settings.content_type.other;" /> 69 </menupopup> 70 </menulist> 71 <label control="single_hidden" value="&settings.hidden;" /> 72 <menulist id="single_hidden"> 73 <menupopup> 74 <menuitem value="1" label="&settings.hidden.no;" 75 selected="true" /> 76 <menuitem value="2" label="&settings.hidden.yes;" /> 77 </menupopup> 78 </menulist> 79 <label control="single_safety_level" value="&settings.safety_level;" /> 80 <menulist id="single_safety_level"> 81 <menupopup> 82 <menuitem value="1" label="&settings.safety_level.safe;" 83 selected="true" /> 84 <menuitem value="2" label="&settings.safety_level.moderate;" /> 85 <menuitem value="3" label="&settings.safety_level.restricted;" /> 86 </menupopup> 87 </menulist> 126 <vbox id="batch_meta"> 127 <vbox class="status"><html:h3 128 id="batch_prompt"> </html:h3><html:p>&meta.batch.prompt;</html:p></vbox> 129 <label control="batch_title" value="&meta.title;" /> 130 <textbox id="batch_title" /> 131 <label control="batch_description" value="&meta.description;" /> 132 <textbox id="batch_description" multiline="true" rows="2" /> 133 <label control="batch_tags" value="&meta.tags;" /> 134 <textbox id="batch_tags" /> 88 135 <html:p> </html:p> 136 <label id="batch_privacy_link" class="link" value="&meta.privacy;" 137 onclick="events.photos.privacy();" /> 138 <vbox id="batch_privacy"> 139 <label control="batch_is_public" value="&settings.privacy.who;" /> 140 <checkbox id="batch_is_public_unchanged" label="&meta.leave_unchanged;" 141 checked="true" /> 142 <radiogroup id="batch_is_public" value="1" 143 oncommand="events.photos.batch_is_public_change(); 144 events.photos.batch_is_public(this.value);"> 145 <radio value="0" label="&settings.privacy.private;" /> 146 <checkbox id="batch_is_friend" label="&settings.privacy.friend;" 147 oncommand="events.photos.batch_is_public_change();" /> 148 <checkbox id="batch_is_family" label="&settings.privacy.family;" 149 oncommand="events.photos.batch_is_public_change();" /> 150 <radio value="1" label="&settings.privacy.public;" /> 151 </radiogroup> 152 <html:p> </html:p> 153 </vbox> 154 <label id="batch_melons_link" class="link" value="&meta.melons;" 155 onclick="events.photos.melons();" /> 156 <vbox id="batch_melons"> 157 <label control="batch_content_type" value="&settings.content_type;" /> 158 <checkbox id="batch_content_type_unchanged" label="&meta.leave_unchanged;" 159 checked="true" /> 160 <menulist id="batch_content_type" 161 oncommand="events.photos.batch_content_type_change();"> 162 <menupopup> 163 <menuitem value="1" label="&settings.content_type.photo;" 164 selected="true" /> 165 <menuitem value="2" label="&settings.content_type.screenshot;" /> 166 <menuitem value="3" label="&settings.content_type.other;" /> 167 </menupopup> 168 </menulist> 169 <label control="batch_hidden" value="&settings.hidden;" /> 170 <checkbox id="batch_hidden_unchanged" label="&meta.leave_unchanged;" 171 checked="true" /> 172 <menulist id="batch_hidden" oncommand="events.photos.batch_hidden_change();"> 173 <menupopup> 174 <menuitem value="1" label="&settings.hidden.no;" 175 selected="true" /> 176 <menuitem value="2" label="&settings.hidden.yes;" /> 177 </menupopup> 178 </menulist> 179 <label control="batch_safety_level" value="&settings.safety_level;" /> 180 <checkbox id="batch_safety_level_unchanged" label="&meta.leave_unchanged;" 181 checked="true" /> 182 <menulist id="batch_safety_level" 183 oncommand="events.photos.batch_safety_level_change();"> 184 <menupopup> 185 <menuitem value="1" label="&settings.safety_level.safe;" 186 selected="true" /> 187 <menuitem value="2" label="&settings.safety_level.moderate;" /> 188 <menuitem value="3" label="&settings.safety_level.restricted;" /> 189 </menupopup> 190 </menulist> 191 <html:p> </html:p> 192 </vbox> 193 <label control="batch_sets_link" class="link" value="&meta.batch.sets;" 194 onclick="events.photos.sets();" /> 195 <vbox id="batch_sets"> 196 <html:ul id="batch_sets_list"></html:ul> 197 <menulist id="batch_set"> 198 <menupopup> 199 <menuitem value="0" label="&settings.sets.none;" /> 200 </menupopup> 201 </menulist> 202 <html:table border="0" cellpadding="0" cellspacing="0"> 203 <html:tr> 204 <html:td><label id="batch_sets_create" class="link" 205 value="&settings.sets.create;" onclick="events.photos.create_set();" 206 /></html:td> 207 <html:td><html:input type="button" id="batch_sets_add" class="button" 208 value="&settings.sets.add;" onclick="events.photos.add_to_set();" 209 /></html:td> 210 </html:tr> 211 </html:table> 212 </vbox> 213 <spacer flex="1" /> 214 <html:input type="button" id="meta_save" value="&meta.save;" class="button" 215 onclick="meta.save();" /> 89 216 </vbox> 90 <label control="single_sets_link" class="link" value="&meta.single.sets;" 91 onclick="events.photos.sets();" /> 92 <vbox id="single_sets"> 93 <html:ul id="single_sets_list"></html:ul> 94 <menulist id="single_set"> 95 <menupopup> 96 <menuitem value="0" label="&settings.sets.none;" /> 97 </menupopup> 98 </menulist> 99 <html:table border="0" cellpadding="0" cellspacing="0"> 100 <html:tr> 101 <html:td><label id="single_sets_create" class="link" 102 value="&settings.sets.create;" onclick="events.photos.create_set();" /></html:td> 103 <html:td><html:input type="button" id="single_sets_add" class="button" 104 value="&settings.sets.add;" onclick="events.photos.add_to_set();" /></html:td> 105 </html:tr> 106 </html:table> 107 </vbox> 108 </vbox> 109 <vbox id="batch_meta"> 110 <vbox class="status"><html:h3 111 id="batch_prompt"> </html:h3><html:p>&meta.batch.prompt;</html:p></vbox> 112 <label control="batch_title" value="&meta.title;" /> 113 <textbox id="batch_title" /> 114 <label control="batch_description" value="&meta.description;" /> 115 <textbox id="batch_description" multiline="true" rows="2" /> 116 <label control="batch_tags" value="&meta.tags;" /> 117 <textbox id="batch_tags" /> 118 <html:p> </html:p> 119 <label id="batch_privacy_link" class="link" value="&meta.privacy;" 120 onclick="events.photos.privacy();" /> 121 <vbox id="batch_privacy"> 122 <label control="batch_is_public" value="&settings.privacy.who;" /> 123 <checkbox id="batch_is_public_unchanged" label="&meta.leave_unchanged;" 124 checked="true" /> 125 <radiogroup id="batch_is_public" value="1" 126 oncommand="events.photos.batch_is_public_change(); 127 events.photos.batch_is_public(this.value);"> 128 <radio value="0" label="&settings.privacy.private;" /> 129 <checkbox id="batch_is_friend" label="&settings.privacy.friend;" 130 oncommand="events.photos.batch_is_public_change();" /> 131 <checkbox id="batch_is_family" label="&settings.privacy.family;" 132 oncommand="events.photos.batch_is_public_change();" /> 133 <radio value="1" label="&settings.privacy.public;" /> 134 </radiogroup> 135 <html:p> </html:p> 136 </vbox> 137 <label id="batch_melons_link" class="link" value="&meta.melons;" 138 onclick="events.photos.melons();" /> 139 <vbox id="batch_melons"> 140 <label control="batch_content_type" value="&settings.content_type;" /> 141 <checkbox id="batch_content_type_unchanged" label="&meta.leave_unchanged;" 142 checked="true" /> 143 <menulist id="batch_content_type" 144 oncommand="events.photos.batch_content_type_change();"> 145 <menupopup> 146 <menuitem value="1" label="&settings.content_type.photo;" 147 selected="true" /> 148 <menuitem value="2" label="&settings.content_type.screenshot;" /> 149 <menuitem value="3" label="&settings.content_type.other;" /> 150 </menupopup> 151 </menulist> 152 <label control="batch_hidden" value="&settings.hidden;" /> 153 <checkbox id="batch_hidden_unchanged" label="&meta.leave_unchanged;" 154 checked="true" /> 155 <menulist id="batch_hidden" oncommand="events.photos.batch_hidden_change();"> 156 <menupopup> 157 <menuitem value="1" label="&settings.hidden.no;" 158 selected="true" /> 159 <menuitem value="2" label="&settings.hidden.yes;" /> 160 </menupopup> 161 </menulist> 162 <label control="batch_safety_level" value="&settings.safety_level;" /> 163 <checkbox id="batch_safety_level_unchanged" label="&meta.leave_unchanged;" 164 checked="true" /> 165 <menulist id="batch_safety_level" 166 oncommand="events.photos.batch_safety_level_change();"> 167 <menupopup> 168 <menuitem value="1" label="&settings.safety_level.safe;" 169 selected="true" /> 170 <menuitem value="2" label="&settings.safety_level.moderate;" /> 171 <menuitem value="3" label="&settings.safety_level.restricted;" /> 172 </menupopup> 173 </menulist> 174 <html:p> </html:p> 175 </vbox> 176 <label control="batch_sets_link" class="link" value="&meta.batch.sets;" 177 onclick="events.photos.sets();" /> 178 <vbox id="batch_sets"> 179 <html:ul id="batch_sets_list"></html:ul> 180 <menulist id="batch_set"> 181 <menupopup> 182 <menuitem value="0" label="&settings.sets.none;" /> 183 </menupopup> 184 </menulist> 185 <html:table border="0" cellpadding="0" cellspacing="0"> 186 <html:tr> 187 <html:td><label id="batch_sets_create" class="link" 188 value="&settings.sets.create;" onclick="events.photos.create_set();" /></html:td> 189 <html:td><html:input type="button" id="batch_sets_add" class="button" 190 value="&settings.sets.add;" onclick="events.photos.add_to_set();" /></html:td> 191 </html:tr> 192 </html:table> 193 </vbox> 194 <spacer flex="1" /> 195 <html:input type="button" id="meta_save" value="&meta.save;" class="button" 196 onclick="meta.save();" /> 197 </vbox> 198 <vbox id="no_meta" /> 199 </hbox> 217 <vbox id="no_meta" /> 218 </hbox> 219 </vbox> 200 220 </overlay> trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/settings.js
r28 r30 17 17 safety_level: null, 18 18 resize: -1, 19 20 // Update settings21 // This is smart about pushing data from DOM to JS or vice-versa, gets user permission22 // to overwrite data, and updates all photos23 update: function() {24 var page = pages.current();25 26 // On the settings page, update settings object and photos27 if ('settings' == page) {28 29 // Decide what's changed30 var changed_privacy = 'settings' == page && (31 settings.is_public != parseInt(document.getElementById('s_is_public').value) ||32 settings.is_friend != document.getElementById('s_is_friend').checked ? 1 : 0 ||33 settings.is_family != document.getElementById('s_is_family').checked ? 1 : 034 );35 var changed_melons = 'settings' == page && (36 settings.content_type !=37 document.getElementById('s_content_type').selectedIndex + 1 ||38 settings.hidden != document.getElementById('s_hidden').selectedIndex + 1 ||39 settings.safety_level !=40 document.getElementById('s_safety_level').selectedIndex + 141 );42 43 // Get permission to overwrite any changes that were made44 if (0 < photos.count && (changed_privacy || changed_melons) &&45 !confirm(locale.getString('settings.overwrite'),46 locale.getString('settings.overwrite.title'))) {47 return;48 }49 50 // Save back to the settings object51 settings.tags = document.getElementById('s_tags').value;52 settings.set = document.getElementById('s_set').value;53 if (changed_privacy) {54 settings.is_public = parseInt(document.getElementById('s_is_public').value);55 settings.is_friend = document.getElementById('s_is_friend').checked ? 1 : 0;56 settings.is_family = document.getElementById('s_is_family').checked ? 1 : 0;57 }58 if (changed_melons) {59 settings.content_type = document.getElementById('s_content_type').selectedIndex + 1;60 settings.hidden = document.getElementById('s_hidden').selectedIndex + 1;61 settings.safety_level = document.getElementById('s_safety_level').selectedIndex + 1;62 }63 settings.resize = parseInt(document.getElementById('s_resize').value);64 65 }66 67 // Save metadata for a single photo68 if (1 == photos.selected.length) {69 meta.save(photos.selected[0]);70 }71 72 // Update all photos73 var ii = photos.list.length;74 var privacy_keys = ['is_public', 'is_friend', 'is_family'];75 var melons_keys = ['content_type', 'hidden', 'safety_level'];76 for (var i = 0; i < ii; ++i) {77 var photo = photos.list[i];78 if (null != photo) {79 for each (var k in privacy_keys) {80 if (changed_privacy || null == photo[k]) {81 photo[k] = settings[k];82 }83 }84 for each (var k in melons_keys) {85 if (changed_melons || null == photo[k]) {86 photo[k] = settings[k];87 }88 }89 }90 }91 92 // Refresh the single-photo metadata if necessary93 if (1 == photos.selected.length) {94 meta.load(photos.selected[0]);95 meta.enable();96 }97 98 // Copy changes from settings object into the UI99 // This actually works since abandon copies the settings object back to the UI100 if ('settings' != page) {101 settings.abandon();102 }103 104 },105 106 // Copy settings from the settings object back to the UI107 // This is useful for either abandoning changes to the UI or updating the UI when108 // the object changes109 abandon: function() {110 document.getElementById('s_tags').value = settings.tags;111 document.getElementById('s_set').value = settings.set;112 document.getElementById('s_is_public').value = settings.is_public;113 document.getElementById('s_is_friend').checked = 1 == settings.is_friend;114 document.getElementById('s_is_family').checked = 1 == settings.is_family;115 document.getElementById('s_content_type').selectedIndex = settings.content_type - 1;116 document.getElementById('s_hidden').selectedIndex = settings.hidden - 1;117 document.getElementById('s_safety_level').selectedIndex = settings.safety_level - 1;118 document.getElementById('s_resize').value = settings.resize;119 events.settings.is_public(document.getElementById('s_is_public').value);120 },121 19 122 20 // Load settings from the current user, which were loaded from the users.json file and … … 149 47 flickr.prefs.getSafetyLevel(); 150 48 } 151 152 // Update the UI153 settings.update();154 events.settings.is_public(settings.is_public);155 49 156 50 }, … … 171 65 } 172 66 67 }, 68 69 // Show the settings dialog 70 show: function(preserve) { 71 if (null == preserve) { 72 preserve = false; 73 } 74 75 // Current settings and users to send along to the dialog 76 var s = {}; 77 var u = []; 78 if (!preserve) { 79 s = { 80 is_public: settings.is_public, 81 is_friend: settings.is_friend, 82 is_family: settings.is_family, 83 content_type: settings.content_type, 84 hidden: settings.hidden, 85 safety_level: settings.safety_level, 86 resize: settings.resize 87 }; 88 u = []; 89 for (var uname in users.list) { 90 u.push({ 91 username: uname, 92 current: uname == users.username 93 }); 94 } 95 } 96 97 // Open the dialog 98 var result = {}; 99 window.openDialog('chrome://uploadr/content/settings.xul', 'dialog_settings', 100 'chrome,modal', s, u, locale.getFormattedString('settings.resize.note', 101 [users.filesize >> 10]), result); 102 103 // If we're adding a new user, auth and re-open the dialog 104 if (result.add_user) { 105 users.after_login = settings.show; 106 users.logout(); 107 users.login(); 108 } 109 110 // Otherwise, save changes to settings and users 111 else { 112 113 // Remove removed users 114 var list = []; 115 for each (var user in u) { 116 list.push(user.username); 117 } 118 var deleted_current = false; 119 for (var username in users.list) { 120 if (-1 == list.indexOf(username)) { 121 deleted_current |= users.list[username].current; 122 delete users.list[username]; 123 } 124 } 125 if (0 == list.length) { 126 users.username = null; 127 users.logout(); 128 } 129 130 // Change users if necessary 131 if ('undefined' != typeof result.change_user && 132 result.change_user != users.username) { 133 if (deleted_current) { 134 users.username = null; 135 } 136 users.logout(); 137 if ('' != result.change_user) { 138 users.token = users.list[result.change_user].token; 139 users.login(); 140 } 141 } 142 143 // Decide what's changed 144 var changed_privacy = 145 settings.is_public != s.is_public || 146 settings.is_friend != s.is_friend || 147 settings.is_family != s.is_family; 148 var changed_melons = 149 settings.content_type != s.content_type || 150 settings.hidden != s.hidden || 151 settings.safety_level != s.safety_level; 152 153 // Get permission to overwrite any changes that were made 154 if (0 < photos.count && (changed_privacy || changed_melons) && 155 !confirm(locale.getString('settings.overwrite'), 156 locale.getString('settings.overwrite.title'))) { 157 return; 158 } 159 160 // Save back to the settings object 161 if (changed_privacy) { 162 settings.is_public = s.is_public; 163 settings.is_friend = s.is_friend; 164 settings.is_family = s.is_family; 165 } 166 if (changed_melons) { 167 settings.content_type = s.content_type; 168 settings.hidden = s.hidden; 169 settings.safety_level = s.safety_level; 170 } 171 settings.resize = s.resize; 172 173 // Save metadata for a single photo 174 if (1 == photos.selected.length) { 175 meta.save(photos.selected[0]); 176 } 177 178 // Update all photos 179 var ii = photos.list.length; 180 var privacy_keys = ['is_public', 'is_friend', 'is_family']; 181 var melons_keys = ['content_type', 'hidden', 'safety_level']; 182 for (var i = 0; i < ii; ++i) { 183 var photo = photos.list[i]; 184 if (null != photo) { 185 for each (var k in privacy_keys) { 186 if (changed_privacy || null == photo[k]) { 187 photo[k] = settings[k]; 188 } 189 } 190 for each (var k in melons_keys) { 191 if (changed_melons || null == photo[k]) { 192 photo[k] = settings[k]; 193 } 194 } 195 } 196 } 197 198 // Refresh the single-photo metadata if necessary 199 if (1 == photos.selected.length) { 200 meta.load(photos.selected[0]); 201 meta.enable(); 202 } 203 204 } 205 173 206 } 174 207 trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/settings.xul
r28 r30 2 2 <?xml-stylesheet href="chrome://global/skin/" type="text/css"?> 3 3 <?xml-stylesheet href="chrome://uploadr/skin/main.css" type="text/css"?> 4 <!DOCTYPE overlay SYSTEM "chrome://uploadr/locale/main.dtd"> 5 <overlay id="overlay_settings" 4 <!DOCTYPE dialog SYSTEM "chrome://uploadr/locale/main.dtd"> 5 <dialog id="dialog_settings" title="&settings;" buttons="accept,cancel" 6 ondialogaccept="events.settings.ok(); return true;" 7 ondialogcancel="events.settings.cancel(); return true;" onload="events.settings.load();" 6 8 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 7 9 xmlns:html="http://www.w3.org/1999/xhtml"> 10 <stringbundleset> 11 <stringbundle id="locale" src="chrome://uploadr/locale/main.properties" /> 12 </stringbundleset> 13 <script src="chrome://uploadr/content/uploadr.js" /> 8 14 <script src="chrome://uploadr/content/events_settings.js" /> 9 <vbox id="page_settings" class="page" flex="1"> 10 <html:h1>&settings;</html:h1> 15 <vbox flex="1"> 16 <groupbox flex="1"> 17 <caption label="&settings.users;" /> 18 <menulist id="user"> 19 <menupopup /> 20 </menulist> 21 <hbox> 22 <button id="remove" label="&settings.users.remove;" 23 oncommand="events.settings.remove_user();" /> 24 <button id="add" label="&settings.users.add;" 25 oncommand="events.settings.add_user();" /> 26 </hbox> 27 </groupbox> 11 28 <hbox flex="1"> 12 <vbox flex="1"> 13 <html:h2>&settings.tags;</html:h2> 14 <textbox id="s_tags" multiline="true" rows="2" /> 15 </vbox> 16 <vbox flex="1"> 17 <html:h2>&settings.set;</html:h2> 18 <menulist id="s_set" disabled="true"> 19 <menupopup> 20 <menuitem value="0" label="&settings.sets.none;" /> 21 </menupopup> 22 </menulist> 23 <hbox><button id="s_set_add" label="&settings.sets.add;" 24 oncommand="events.settings.add_set();" /></hbox> 25 </vbox> 26 </hbox> 27 <hbox flex="1"> 28 <vbox flex="1"> 29 <html:h2>&settings.privacy;</html:h2> 30 <label control="s_is_public" value="&settings.privacy.who;" /> 31 <radiogroup id="s_is_public" value="1" 29 <groupbox flex="1"> 30 <caption label="&settings.privacy;" /> 31 <label control="is_public" value="&settings.privacy.who;" /> 32 <radiogroup id="is_public" value="1" 32 33 oncommand="events.settings.is_public(this.value);"> 33 34 <radio value="0" label="&settings.privacy.private;" /> 34 <checkbox id=" s_is_friend" label="&settings.privacy.friend;"35 <checkbox id="is_friend" label="&settings.privacy.friend;" 35 36 disabled="true" /> 36 <checkbox id=" s_is_family" label="&settings.privacy.family;"37 <checkbox id="is_family" label="&settings.privacy.family;" 37 38 disabled="true" /> 38 39 <radio value="1" label="&settings.privacy.public;" /> 39 40 </radiogroup> 40 </ vbox>41 < vbox flex="1">42 < html:h2>&settings.melons;</html:h2>43 <label control=" s_content_type" value="&settings.content_type;" />44 <menulist id=" s_content_type">41 </groupbox> 42 <groupbox flex="1"> 43 <caption label="&settings.melons;" /> 44 <label control="content_type" value="&settings.content_type;" /> 45 <menulist id="content_type"> 45 46 <menupopup> 46 47 <menuitem value="1" label="&settings.content_type.photo;" … … 50 51 </menupopup> 51 52 </menulist> 52 <label control=" s_hidden" value="&settings.hidden;" />53 <menulist id=" s_hidden">53 <label control="hidden" value="&settings.hidden;" /> 54 <menulist id="hidden"> 54 55 <menupopup> 55 56 <menuitem value="1" label="&settings.hidden.no;" … … 58 59 </menupopup> 59 60 </menulist> 60 <label control="s _safety_level" value="&settings.safety_level;" />61 <menulist id="s _safety_level">61 <label control="safety_level" value="&settings.safety_level;" /> 62 <menulist id="safety_level"> 62 63 <menupopup> 63 64 <menuitem value="1" label="&settings.safety_level.safe;" … … 67 68 </menupopup> 68 69 </menulist> 69 </ vbox>70 < vbox flex="1">71 < html:h2>&settings.resize;</html:h2>70 </groupbox> 71 <groupbox flex="1"> 72 <caption label="&settings.resize;" /> 72 73 <html:p>&settings.resize.prompt;</html:p> 73 <menulist id=" s_resize">74 <menulist id="resize"> 74 75 <menupopup> 75 76 <menuitem value="-1" label="&settings.resize.dont;" selected="true" /> … … 80 81 </menupopup> 81 82 </menulist> 82 <html:p id=" s_resize_note"> </html:p>83 </ vbox>83 <html:p id="resize_note"> </html:p> 84 </groupbox> 84 85 </hbox> 85 86 </vbox> 86 </ overlay>87 </dialog> trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/threads.js
r28 r30 75 75 img.src = 'file://' + thumb[8]; 76 76 77 // Check the size of this file if we're logged in 78 if (users.username) { 79 var size = uploadr.fsize(photos.list[this.id].path); 80 if (!users.is_pro && users.bandwidth.remaining - photos.batch_size < size) { 81 status.set(locale.getString('status.limit')); 82 } else { 83 status.clear(); 84 } 85 photos.batch_size += size; 86 free.update(); 77 // If only one photo is selected, refresh the other thumbnail, too 78 if (1 == photos.selected.length) { 79 document.getElementById('meta_div').getElementsByTagName('img')[0].src = 80 img.src; 87 81 } 88 82 … … 284 278 285 279 // Update bandwidth 286 var size = uploadr.fsize(resize[3]);280 var size = file.size(resize[3]); 287 281 photos.batch_size -= photos.list[this.id].filesize; 288 282 if (!users.is_pro && users.bandwidth.remaining - photos.batch_size < size) { trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/ui.js
r28 r30 1 1 var pages = { 2 2 3 _list: ['photos', ' users', 'settings', 'progress', 'complete'],3 _list: ['photos', 'queue'], 4 4 _current: 0, 5 5 … … 21 21 } 22 22 23 // Only show the toolbar on the photos page24 if ('photos' == id) {25 document.getElementById('tools').style.display = '-moz-box';26 document.getElementById('no_tools').style.display = 'none';27 } else {28 document.getElementById('tools').style.display = 'none';29 document.getElementById('no_tools').style.display = '-moz-box';30 }31 32 23 }, 33 24 … … 39 30 }; 40 31 32 // Free account capacity indicators 41 33 var free = { 42 34 … … 60 52 for each (var p in photos.list) { 61 53 if (null != p) { 62 var size = uploadr.fsize(p.path);54 var size = file.size(p.path); 63 55 if (!users.is_pro && 64 56 users.bandwidth.remaining - photos.batch_size < size) { … … 72 64 } 73 65 74 var used = Math.min(94, Math.round(94 * users.bandwidth.used / users.bandwidth.total)); 75 var batch = Math.max(0, Math.round(94 * photos.batch_size / users.bandwidth.total)); 76 var remaining = Math.max(0, 77 Math.round(94 * users.bandwidth.remaining / users.bandwidth.total)); 78 batch = Math.min(batch, remaining); 79 remaining += 94 - (used + batch + remaining); 80 document.getElementById('bw_used').style.width = used + 'px'; 81 var bw_batch = document.getElementById('bw_batch'); 82 bw_batch.style.width = batch + 'px'; 83 bw_batch.style.backgroundPosition = '-' + used + 'px -34px'; 84 var bw_remaining = document.getElementById('bw_remaining'); 85 bw_remaining.style.width = remaining + 'px'; 86 bw_remaining.style.backgroundPosition = '-' + (used + batch) + 'px -17px'; 87 document.getElementById('free').style.visibility = 'visible'; 88 } 89 90 // And show the proper maximum size in the settings window 91 document.getElementById('s_resize_note').firstChild.nodeValue = 92 locale.getFormattedString('settings.resize.note', [users.filesize >> 10]); 66 var f = document.getElementById('free'); 67 f.value = locale.getFormattedString('free.status', [ 68 Math.round(100 * users.bandwidth.used / users.bandwidth.total), 69 Math.round(users.bandwidth.total / 102.4) / 10, 70 Math.round(users.bandwidth.remaining / 102.4) / 10, 71 photos.count, 72 Math.round(photos.batch_size / 102.4) / 10 73 ]); 74 f.style.visibility = 'visible'; 75 } 93 76 94 77 }, … … 102 85 var buttons = { 103 86 104 _list: ['login', ' back', 'ok', 'upload'],87 _list: ['login', 'upload'], 105 88 106 89 // Show specified buttons … … 131 114 b.disabled = false; 132 115 b.className = 'button'; 116 if ('upload' == l) { 117 document.getElementById('menu_upload_upload').disabled = false; 118 } 133 119 } 134 120 }, … … 143 129 b.disabled = true; 144 130 b.className = 'disabled_button'; 131 if ('upload' == l) { 132 document.getElementById('menu_upload_upload').disabled = true; 133 } 145 134 } 146 135 } … … 163 152 }; 164 153 165 // Functions to find photos above and below a given photo154 // Functions to find photos in the grid 166 155 var findr = { 167 156 … … 233 222 }, 234 223 onDragOver: function(e, data) { 235 document.getElementById('photos').className = 'drag oldest';224 document.getElementById('photos').className = 'drag'; 236 225 }, 237 226 onDragExit: function(e, flavor, session) { 238 document.getElementById('photos').className = 'no_drag oldest';227 document.getElementById('photos').className = 'no_drag'; 239 228 }, 240 229 onDrop: function(e, data) { … … 298 287 // Allow functions to block exiting 299 288 var _block_exit = 0; 300 var _block_exit_stack = [];301 289 var block_exit = function() { 302 290 ++_block_exit; 303 Components.utils.reportError('push: ' + _block_exit);304 _block_exit_stack.push(_block_exit);305 291 } 306 292 var unblock_exit = function() { 307 293 --_block_exit; 308 Components.utils.reportError('pop: ' + _block_exit_stack.pop());309 294 } 310 295 … … 313 298 314 299 // Don't exit if exit is blocked 315 Components.utils.reportError('_block_exit: ' + _block_exit);316 300 if (0 < _block_exit) { 301 Components.utils.reportError(_block_exit); 317 302 return; 318 303 } 319 320 304 321 305 // Save state … … 356 340 return result.result; 357 341 }; 342 343 // Open a browser window to the given URL 344 var launch_browser = function(url) { 345 var io = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService); 346 var uri = io.newURI(url, null, null); 347 var eps = Cc['@mozilla.org/uriloader/external-protocol-service;1'].getService( 348 Ci.nsIExternalProtocolService); 349 var launcher = eps.getProtocolHandlerInfo('http'); 350 launcher.preferredAction = Ci.nsIHandlerInfo.useSystemDefault; 351 launcher.launchWithURI(uri, null); 352 }; trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/uploadr.js
r28 r30 1 // This used to be the main script for the Uploadr, but things have slowly grown and been2 // refactored into new homes3 4 1 const Cc = Components.classes; 5 2 const Ci = Components.interfaces; … … 27 24 auto_save: 60 28 25 29 },30 31 // Handle files dragged on startup32 drag: function() {33 buttons.disable('upload');34 var cl = window.arguments[0].QueryInterface(Ci.nsICommandLine);35 var ii = cl.length;36 for (var i = 0; i < ii; ++i) {37 if ('-url' == cl.getArgument(i)) {38 photos._add(Cc['@mozilla.org/network/protocol;1?name=file'].getService(39 Ci.nsIFileProtocolHandler).getFileFromURLSpec(cl.getArgument(++i)).path);40 }41 }42 if (photos.sort) {43 threads.worker.dispatch(new Sort(), threads.worker.DISPATCH_NORMAL);44 } else {45 threads.worker.dispatch(new EnableUpload(), threads.worker.DISPATCH_NORMAL);46 }47 },48 49 // Profile file IO50 fread: function(name) {51 try {52 var profile = Cc['@mozilla.org/file/directory_service;1'].getService(53 Ci.nsIProperties).get('ProfD', Ci.nsIFile);54 profile.append(name);55 var data = '';56 var fstream = Cc['@mozilla.org/network/file-input-stream;1'].createInstance(57 Ci.nsIFileInputStream);58 var sstream = Cc['@mozilla.org/scriptableinputstream;1'].createInstance(59 Ci.nsIScriptableInputStream);60 fstream.init(profile, -1, 0, 0);61 sstream.init(fstream);62 var str = sstream.read(4096);63 while (str.length > 0) {64 data += str;65 str = sstream.read(4096);66 }67 sstream.close();68 fstream.close();69 return eval(data);70 } catch (err) {71 return {};72 }73 },74 fwrite: function(name, data) {75 var profile = Cc['@mozilla.org/file/directory_service;1'].getService(76 Ci.nsIProperties).get('ProfD', Ci.nsIFile);77 profile.append(name);78 var _stream = Cc['@mozilla.org/network/file-output-stream;1'].createInstance(79 Ci.nsIFileOutputStream);80 _stream.init(profile, 0x02 /* Write-only */ | 0x08 /* Create */ | 0x20 /* Truncate */,81 0666, 0);82 var stream = Cc['@mozilla.org/intl/converter-output-stream;1'].createInstance(83 Ci.nsIConverterOutputStream);84 stream.init(_stream, 'UTF-8', 0, '?'.charCodeAt(0));85 if ('string' == typeof data) {86 stream.writeString(data);87 } else {88 stream.writeString(data.toSource());89 }90 stream.close();91 },92 93 // Get the size of a file94 fsize: function(path) {95 var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);96 file.initWithPath(path);97 return 1 + Math.round(file.fileSize >> 10);98 26 } 99 27 trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/users.js
r28 r30 15 15 // List of authorized users 16 16 list: {}, 17 18 // A one-time custom callback after login 19 after_login: null, 17 20 18 21 // Shortcut for the auth sequence … … 39 42 document.getElementById('username').value = username; 40 43 document.getElementById('switch').value = locale.getString('switch'); 41 document.getElementById('u_current').firstChild.nodeValue = username;42 44 status.set(locale.getString('status.ready')); 43 45 44 46 } else { 45 47 users.logout(); 48 } 49 if ('function' == typeof users.after_login) { 50 users.after_login(); 51 users.after_login = null; 46 52 } 47 53 }, … … 60 66 61 67 // Update the UI 62 var notloggedin = locale.getString('notloggedin'); 63 document.getElementById('username').value = notloggedin; 68 document.getElementById('username').value = locale.getString('notloggedin'); 64 69 document.getElementById('switch').value = locale.getString('login'); 65 document.getElementById('u_current').firstChild.nodeValue = notloggedin;66 70 document.getElementById('free').style.display = 'none'; 67 71 status.set(locale.getString('status.disconnected')); … … 97 101 } 98 102 99 // Update the list on the users page100 var dropdown = document.getElementById('u_user');101 dropdown.removeAllItems();102 var sorted = [];103 for (var u in users.list) {104 if (users.username != u) {105 sorted.push(u);106 }107 }108 sorted.sort();109 var ii = sorted.length;110 dropdown.appendItem(locale.getString('users.prompt'), '');111 dropdown.selectedIndex = 0;112 for (var i = 0; i < ii; ++i) {113 dropdown.appendItem(sorted[i], sorted[i]);114 }115 116 103 }, 117 104 118 105 // Load users from a file 119 106 load: function() { 120 users.list = uploadr.fread('users.json');107 users.list = file.read('users.json'); 121 108 122 109 // Login as the current user … … 139 126 // Save users to a file 140 127 save: function() { 141 uploadr.fwrite('users.json', users.list);128 file.write('users.json', users.list); 142 129 } 143 130 trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/locale/en-US/main.dtd
r28 r30 1 1 <!ENTITY title "Flickr Uploadr"> 2 2 3 <!ENTITY menu.file "File"> 4 <!ENTITY menu.file.add "Add"> 5 <!ENTITY menu.file.preferences "Preferences"> 6 <!ENTITY menu.file.exit "Quit"> 3 <!ENTITY menu.upload "Upload"> 4 <!ENTITY menu.upload.add "Add"> 5 <!ENTITY menu.upload.preferences "Preferences"> 6 <!ENTITY menu.upload.exit "Quit"> 7 <!ENTITY menu.edit "Edit"> 8 <!ENTITY menu.edit.cut "Cut"> 9 <!ENTITY menu.edit.copy "Copy"> 10 <!ENTITY menu.edit.paste "Paste"> 11 <!ENTITY menu.help "Help"> 12 <!ENTITY menu.help.about "About"> 13 <!ENTITY menu.help.faq "FAQ"> 7 14 8 15 <!ENTITY notloggedin "Not logged in"> 9 16 <!ENTITY login "Login"> 17 18 <!ENTITY tools.add "+ Add"> 19 <!ENTITY tools.remove "â Remove"> 10 20 11 21 <!ENTITY buttons.login "Login"> … … 21 31 <!ENTITY progress.this_file "This file:"> 22 32 23 <!ENTITY users "Users">24 <!ENTITY users.user "Select a user to change to:">25 <!ENTITY users.remove "Remove selected user">26 <!ENTITY users.add "Add new user">27 28 33 <!ENTITY photos.sort.default "Photos are sorted by date taken. Drag to reorder."> 29 34 <!ENTITY photos.sort.revert "Re-sort by date taken"> 30 35 31 36 <!ENTITY settings "Settings"> 32 <!ENTITY settings.tags "Batch tags"> 33 <!ENTITY settings.set "Add these photos to a set"> 34 <!ENTITY settings.sets.none "No sets"> 35 <!ENTITY settings.sets.add "Add"> 36 <!ENTITY settings.sets.create "Create a set..."> 37 <!ENTITY settings.users "Users"> 38 <!ENTITY settings.users.user "Select a user to change to:"> 39 <!ENTITY settings.users.remove "Remove selected user"> 40 <!ENTITY settings.users.add "Add new user"> 37 41 <!ENTITY settings.privacy "Privacy"> 38 42 <!ENTITY settings.privacy.who "Who can see this photo?"> … … 72 76 <!ENTITY meta.single.sets "Add this photo to sets"> 73 77 <!ENTITY meta.batch.sets "Add these photos to sets"> 78 <!ENTITY settings.sets.none "No sets"> 79 <!ENTITY settings.sets.add "Add"> 80 <!ENTITY settings.sets.create "Create a set..."> 74 81 75 82 <!ENTITY dialog.bandwidth "Available bandwidth exceeded!"> trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/locale/en-US/main.properties
r28 r30 22 22 23 23 meta.dim=%1$d x %2$d 24 meta.size=%1$s 24 meta.size=%1$sMB 25 25 meta.batch.prompt=%1$d photos selected 26 26 meta.abandon=You set some metadata but you must save it before deselecting these photos. Save it? … … 42 42 rotate.confirm.title=Rotate 43 43 44 free.status=You've used %1$d% of your %2$dMB limit this month - that leaves %3$dMB. This batch of %4$d photos is %5$dMB. 45 44 46 progress.failed=Bonk! Some of your photos failed to upload. Would you like us to re-add them to the batch so you can retry? 45 47 progress.failed.title=Some uploads failed … … 56 58 57 59 go_pro=You'll have to restart Flickr Uploadr for your new Pro account to get noticed. 60 go_pro.title=Go Pro! trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/skin/uploadr/dialog.css
r4 r30 1 /* Normal dialogs */ 1 2 dialog { 2 3 width: 300px; 3 4 } 5 6 /* 7 * The special settings dialog 8 */ 9 10 #dialog_settings { 11 width: 600px; 12 } trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/skin/uploadr/main.css
r28 r30 12 12 */ 13 13 14 h1, h2 { 15 margin-top: 0; 16 } 17 18 /* The user indicator */ 19 #switch { 20 color: #0063dc; 21 text-decoration: underline; 22 cursor: pointer; 23 } 24 25 /* Logo and top styles */ 26 .fill { 27 border-bottom: 1px solid #999; 28 } 14 #head { 15 background: #f8f8f8; 16 border-bottom: 1px solid #ddd; 17 } 18 19 /* Logo */ 29 20 #logo { 30 21 width: 120px; 31 22 height: 67px; 32 23 background: url(logo.png) no-repeat scroll 0 10px; 33 border-bottom: 1px solid #999; 24 } 25 26 /* User indicator */ 27 #head hbox { 28 margin: 10px; 34 29 } 35 30 … … 52 47 height: 40px; 53 48 padding: 5px; 54 border-top: 1px dotted # bbb;49 border-top: 1px dotted #ddd; 55 50 background: white; 56 51 } … … 87 82 display: none; 88 83 } 89 input.button {84 input.button, input.disabled_button { 90 85 margin: 0 0 5px 5px; 91 background: #0063dc;92 color: white;93 86 font-size: 12px; 94 87 font-weight: bold; 95 88 text-transform: uppercase; 89 vertical-align: middle; 90 } 91 input.button { 92 background: #0063dc; 93 color: white; 96 94 } 97 95 input.disabled_button { 98 margin: 0 0 5px 5px;99 96 background: #eee; 100 97 color: #888; 101 font-size: 12px; 102 font-weight: bold; 103 text-transform: uppercase; 104 } 98 } 99 100 /* Make the upload button gaudy */ 101 #button_upload { 102 font-size: 16px; 103 } 104 105 106 107 /* 108 * Utilities 109 */ 105 110 106 111 /* Nested form indentation, used all over */ … … 126 131 } 127 132 128 /* Make the upload button gaudy */ 129 #button_upload { 130 font-size: 16px; 131 } 133 132 134 133 135 /* 134 136 * Toolbar 135 137 */ 138 #tools { 139 background: white; 140 border-bottom: 1px dotted #ddd; 141 } 136 142 #tools toolbox toolbar { 137 width: 217px;138 143 height: 34px; 139 144 padding: 5px 0 0 10px; 140 145 background: white; 141 border-top: 1px solid #999;142 146 border-bottom: 0; 143 147 } … … 153 157 toolbarseparator { 154 158 width: 1px; 155 margin: 0 15px 010px;159 margin: 0 15px 5px 10px; 156 160 background: #eee; 157 }158 #t_add {159 width: 21px;160 }161 #t_add.disabled {162 background-position: 0px -3px;163 }164 #t_add.enabled {165 background-position: 0px -35px;166 }167 #t_add.enabled:active {168 background-position: 0px -67px;169 }170 #t_remove {171 width: 20px;172 }173 #t_remove.disabled {174 background-position: -21px -3px;175 }176 #t_remove.enabled {177 background-position: -21px -35px;178 }179 #t_remove.enabled:active {180 background-position: -21px -67px;181 161 } 182 162 #t_rotate_l { … … 204 184 background-position: -72px -67px; 205 185 } 206 #t_settings {207 width: 19px;208 }209 #t_settings.disabled {210 background-position: -103px -3px;211 }212 #t_settings.enabled {213 background-position: -103px -35px;214 }215 #t_settings.enabled:active {216 background-position: -103px -67px;217 }218 #diag {219 background: url(diag.gif) no-repeat;220 }221 #no_tools {222 display: none;223 width: 217px;224 height: 34px;225 }226 186 227 187 … … 231 191 */ 232 192 233 /* The container has multiple nested boxes for multiple backgrounds */234 193 #photos { 235 194 margin: 0; 195 background: white; 196 border-right: 1px solid #ddd; 236 197 overflow: auto; 237 }238 .newest {239 background: white url(newest.gif) no-repeat;240 }241 .oldest {242 background: url(oldest.gif) no-repeat bottom right;243 198 } 244 199 … … 380 335 cursor: pointer; 381 336 } 382 383 384 385 /* User settings page */386 #page_users {387 display: none;388 }389 390 /* Settings page */391 #page_settings {392 display: none;393 }394 395 /* Upload progress page */396 #page_progress {397 display: none;398 }399 400 /* Upload complete page */401 #page_complete {402 display: none;403 }trunk/uploadr/NOTES
r27 r30 128 128 } 129 129 exif["Exif.Image.Orientation"] = uint32_t(orient); 130 131 132 133 filename ticket_id photo_id site order proper order 134 135 IMG_1722.JPG 3609264-72157602195393043 1453335763 2 1 136 api.jpg 3609264-72157602195394259 1453336053 1 2 137 beck.jpg 3609264-72157602195394999 1453336425 3 3 138 139 140 141 API CALL: ({async:1, auth_token:"72157601434015522-c1b9da7a8b48ebe2", title:"", description:"", tags:"", is_public:0, is_friend:0, is_family:0, content_type:1, hidden:1, safety_level:1, photo:{filename:"IMG_1722.JPG", path:"/Users/rcrowley/Desktop/pictures/IMG_1722.JPG"}}) 142 143 API RESULT: <?xml version="1.0" encoding="utf-8" ?> 144 <rsp stat="fail"> 145 <err code="98" msg="Invalid auth token" /> 146 </rsp> 147 148 149 150 API CALL: ({async:1, auth_token:"72157601434015522-c1b9da7a8b48ebe2", title:"", description:"", tags:"", is_public:0, is_friend:0, is_family:0, content_type:1, hidden:1, safety_level:1, photo:{filename:"api.jpg", path:"/Users/rcrowley/Desktop/pictures/api.jpg"}}) 151 152 API RESULT: <?xml version="1.0" encoding="utf-8" ?> 153 <rsp stat="ok"> 154 <ticketid>3609264-72157602187992740</ticketid> 155 </rsp> 156 157 158