Changeset 30

Show
Ignore:
Timestamp:
10/02/07 15:52:25 (2 years ago)
Author:
rcrowley
Message:

Nearly done. Bugfixes for saved metadata, user switching and free account tracking. A bit of code reorganization and redesign. Not too much redesign since Gino and Stew haven't made up their minds.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/api.js

    r28 r30  
    134134                                } 
    135135                        } 
    136 //                      photos.add_to_set.push(photo_id); 
    137136 
    138137                } else if ('fail' == stat) { 
     
    143142                        } 
    144143                } 
    145  
    146                 // Add this photo to sets 
    147                 /// 
    148144                photos.uploading[id] = null; 
    149145 
     
    273269 
    274270                // Kick off the chain of adding photos to a set 
    275 Components.utils.reportError(meta.sets_map.toSource()); 
    276271                var not_adding_to_sets = true; 
    277272                for (var set_id in meta.sets_map) { 
     
    323318                if (0 < photos.ok && confirm(locale.getString('uploaded.prompt'), 
    324319                        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(',')); 
    333322                } 
    334323 
     
    641630                                settings.content_type = 
    642631                                        parseInt(rsp.getElementsByTagName('person')[0].getAttribute('content_type')); 
    643                               settings.update(); 
     632//                            settings.update(); 
    644633                        } 
    645634                        unblock_exit(); 
     
    657646                                settings.hidden = 
    658647                                        parseInt(rsp.getElementsByTagName('person')[0].getAttribute('hidden')); 
    659                               settings.update(); 
     648//                            settings.update(); 
    660649                        } 
    661650                        unblock_exit(); 
     
    675664                                settings.is_friend = 2 == privacy || 4 == privacy; 
    676665                                settings.is_family = 3 == privacy || 5 == privacy; 
    677                               settings.update(); 
     666//                            settings.update(); 
    678667                        } 
    679668                        unblock_exit(); 
     
    692681                                settings.safety_level = 
    693682                                        parseInt(rsp.getElementsByTagName('person')[0].getAttribute('safety_level')); 
    694                               settings.update(); 
     683//                            settings.update(); 
    695684                        } 
    696685                        unblock_exit(); 
     
    798787        //   Only GET requests are supported here 
    799788        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); 
    807790        } 
    808791 
  • trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/events_photos.js

    r28 r30  
    8080                        } 
    8181 
    82                         // Enable toolbar buttons for selected images 
    83                         document.getElementById('t_remove').className = 'enabled'; 
    84                         document.getElementById('t_rotate_l').className = 'enabled'; 
    85                         document.getElementById('t_rotate_r').className = 'enabled'; 
    86          
    8782                } 
    8883                // If we clicked the revert to sorted button 
     
    10499                        } 
    105100                        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'; 
    109101                } 
    110102 
     
    405397                                        meta.batch(); 
    406398                                } 
    407                                 document.getElementById('t_remove').className = 'enabled'; 
    408                                 document.getElementById('t_rotate_l').className = 'enabled'; 
    409                                 document.getElementById('t_rotate_r').className = 'enabled'; 
    410399                        } 
    411400 
     
    413402 
    414403                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 
    415449        }, 
    416450 
     
    572606                                p.sets.push(set_id); 
    573607                        } 
    574 Components.utils.reportError(p.sets); 
    575608                } 
    576609                set.selectedIndex = 0; 
  • trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/events_settings.js

    r28 r30  
    11events.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        }, 
    280 
    381        // Properly enable/disable the checkboxes available for private photos to be shared with 
     
    583        is_public: function(value) { 
    684                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; 
    1189                } 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; 
    1492                } 
    1593        } 
  • trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/main.js

    r28 r30  
    1 events.tools = { 
    2  
    3         // Add photos 
    4         add: function() { 
    5                 photos.add(); 
    6         }, 
    7  
    8         // Remove selected photos 
    9         remove: function() { 
    10  
    11                 // Nothing to do if somehow there are no selected photos 
    12                 var ii = photos.selected.length; 
    13                 if (0 == ii) { 
    14                         return; 
    15                 } 
    16  
    17                 // Remove selected photos 
    18                 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 file 
    24                         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 selection 
    40                 photos.selected = []; 
    41                 events.photos.click({target: {}}); 
    42  
    43                 // Allow upload only if there are photos 
    44                 if (photos.count) { 
    45                         buttons.enable('upload'); 
    46                 } else { 
    47                         photos.unsaved = false; 
    48                         buttons.disable('upload'); 
    49                 } 
    50  
    51         }, 
    52  
    53         // Rotate selected photos 
    54         rotate_l: function() { 
    55                 photos.rotate(-90); 
    56         }, 
    57         rotate_r: function() { 
    58                 photos.rotate(90); 
    59         }, 
    60  
    61         // Show the settings page 
    62         settings: function() { 
    63                 pages.go('settings'); 
    64                 buttons.show(['back', 'ok']);    
    65         } 
    66  
    67 }; 
    68  
    691events.buttons = { 
    70  
    71         // Back button for the settings and users pages, perhaps more uses later 
    72         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 later 
    88         ok: function() { 
    89  
    90                 // Change the logged-in user 
    91                 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         }, 
    1102 
    1113        // Login button, shown on the photos page until logged in 
    1124        login: function() { 
    1135                if (users.username) { 
    114                         pages.go('users'); 
    115                         buttons.show(['back', 'ok']); 
     6                        settings.show(); 
    1167                } else { 
    1178                        users.login(); 
     
    12314 
    12415                // Save the selected photo before uploading 
    125                 events.photos.click({'target': {}}); 
    126                 settings.update(); 
     16                events.photos.click({target: {}}); 
    12717 
    12818                photos.upload(); 
     
    13929        // Launch a web browser to buy a Pro account 
    14030        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/'); 
    14832                alert(locale.getString('go_pro'), locale.getString('go_pro.title')); 
    14933        } 
     
    19377 
    19478}; 
     79 
     80events.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  
    44<?xml-stylesheet href="chrome://hacks/skin/hacks.css" type="text/css"?> 
    55<?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"?> 
    86<!DOCTYPE window SYSTEM "chrome://uploadr/locale/main.dtd"> 
    97<window id="main" title="&title;" width="960" height="700" windowtype="app" 
    108xmlns="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();" 
     9xmlns:html="http://www.w3.org/1999/xhtml" onload="users.load(); photos.load(); photos.drag();" 
    1210onclose="return exit();" persist="screenX screenY width height sizemode"> 
    1311        <stringbundleset> 
    1412                <stringbundle id="locale" src="chrome://uploadr/locale/main.properties" /> 
    1513        </stringbundleset> 
     14        <script src="chrome://global/content/globalOverlay.js" /> 
    1615        <script src="chrome://global/content/nsDragAndDrop.js" /> 
    1716        <script src="chrome://uploadr/content/md5.js" /> 
    1817        <script src="chrome://uploadr/content/uploadr.js" /> 
     18        <script src="chrome://uploadr/content/file.js" /> 
    1919        <script src="chrome://uploadr/content/threads.js" /> 
    2020        <script src="chrome://uploadr/content/api.js" /> 
     
    2626        <script src="chrome://uploadr/content/main.js" /> 
    2727        <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 
    2838        <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" /> 
    3445                <key id="key_up" keycode="VK_UP" oncommand="events.arrows.up(event);" /> 
    3546                <key id="key_right" keycode="VK_RIGHT" oncommand="events.arrows.right(event);" /> 
     
    5566        <toolbox id="menu"> 
    5667                <menubar> 
    57                         <menu id="menu_file" label="&menu.file;"> 
     68                        <menu id="menu_upload" label="&menu.upload;"> 
    5869                                <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();" /> 
    6496                                </menupopup> 
    6597                        </menu> 
     
    68100        <vbox flex="1"> 
    69101 
    70                 <!-- Header and toolbar --> 
    71                 <hbox> 
    72                         <vbox> 
    73                                 <box flex="1"><label id="username" value="&notloggedin;" /></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"> 
    98104                        <box id="logo" /> 
     105                        <box flex="1" /> 
     106                        <hbox><label id="username" value="&notloggedin;" /><html:input 
     107                        type="button" id="switch" class="button" value="&login;" 
     108                        onclick="events.buttons.login();" /></hbox> 
    99109                </hbox> 
    100110 
    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                <!-- --> 
    107114 
    108115                <!-- Footer and status bar --> 
    109116                <hbox id="footer"> 
     117<!-- 
    110118                        <hbox id="free"> 
    111119                                <vbox> 
     
    118126                                </vbox> 
    119127                                <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();" /> 
    121129                        </hbox> 
     130--> 
    122131                        <hbox id="progress"> 
    123132                                <vbox> 
     
    137146                        <html:input type="button" id="button_login" value="&buttons.login;" class="button" 
    138147                        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();" /> 
    143148                        <html:input type="button" id="button_upload" value="&buttons.upload;" 
    144149                        class="disabled_button" disabled="true" onclick="events.buttons.upload();" /> 
    145150                </hbox> 
    146                 <statusbar> 
    147                         <statusbarpanel id="status" label="" flex="1" /> 
    148                 </statusbar> 
    149151 
    150152        </vbox> 
     153        <statusbar> 
     154                <statusbarpanel id="status" label="" flex="1" /> 
     155        </statusbar> 
    151156</window> 
  • trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/meta.js

    r28 r30  
    5353                                [p.width, p.height]); 
    5454                        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)]); 
    5656                        document.getElementById('single_title').value = p.title; 
    5757                        document.getElementById('single_description').value = p.description; 
     
    156156                document.getElementById('single_sets').style.display = 'none'; 
    157157                document.getElementById('batch_meta').style.display = 'none'; 
    158                 document.getElementById('no_meta').style.display = 'none'
     158                meta._enable()
    159159        }, 
    160160 
     
    168168                document.getElementById('batch_melons').style.display = 'none'; 
    169169                document.getElementById('batch_sets').style.display = 'none'; 
     170                meta._enable(); 
     171        }, 
     172 
     173        // Common to batch and single enabling 
     174        _enable: function() { 
    170175                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'; 
    171181        }, 
    172182 
     
    176186                document.getElementById('batch_meta').style.display = 'none'; 
    177187                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'; 
    178193        }, 
    179194 
  • trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/photos.js

    r28 r30  
    7474                        threads.worker.DISPATCH_NORMAL); 
    7575 
     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                } 
    76106        }, 
    77107 
     
    124154                                        threads.worker.dispatch(new Resize(p.id, settings.resize, p.path), 
    125155                                                threads.worker.DISPATCH_NORMAL); 
    126                                 } else if (uploadr.fsize(p.path) > users.filesize) { 
     156                                } else if (file.size(p.path) > users.filesize) { 
    127157                                        resizing = true; 
    128158                                        threads.worker.dispatch(new Resize(p.id, -1, p.path), 
     
    200230        // Load saved metadata 
    201231        load: function() { 
    202                 var obj = uploadr.fread('photos.json'); 
     232                var obj = file.read('photos.json'); 
    203233 
    204234                // Add the previous batch of photos 
     
    236266                        meta.created_sets = []; 
    237267                } 
    238                 uploadr.fwrite('photos.json', { 
     268                file.write('photos.json', { 
    239269                        sort: photos.sort, 
    240270                        sets: meta.created_sets, 
  • trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/photos.xul

    r28 r30  
    77xmlns:html="http://www.w3.org/1999/xhtml"> 
    88        <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" 
    1228                        onclick="events.photos.click(event);" 
    1329                        onmousedown="events.photos.mousedown(event);" 
     
    2844                                </stack> 
    2945                        </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" /> 
    5760                                <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> 
    58125                        </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" /> 
    88135                                <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();" /> 
    89216                        </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> 
    200220</overlay> 
  • trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/settings.js

    r28 r30  
    1717        safety_level: null, 
    1818        resize: -1, 
    19  
    20         // Update settings 
    21         //   This is smart about pushing data from DOM to JS or vice-versa, gets user permission 
    22         //   to overwrite data, and updates all photos 
    23         update: function() { 
    24                 var page = pages.current(); 
    25  
    26                 // On the settings page, update settings object and photos 
    27                 if ('settings' == page) { 
    28  
    29                         // Decide what's changed 
    30                         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 : 0 
    34                         ); 
    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 + 1 
    41                         ); 
    42          
    43                         // Get permission to overwrite any changes that were made 
    44                         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 object 
    51                         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 photo 
    68                 if (1 == photos.selected.length) { 
    69                         meta.save(photos.selected[0]); 
    70                 } 
    71  
    72                 // Update all photos 
    73                 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 necessary 
    93                 if (1 == photos.selected.length) { 
    94                         meta.load(photos.selected[0]); 
    95                         meta.enable(); 
    96                 } 
    97  
    98                 // Copy changes from settings object into the UI 
    99                 //   This actually works since abandon copies the settings object back to the UI 
    100                 if ('settings' != page) { 
    101                         settings.abandon(); 
    102                 } 
    103  
    104         }, 
    105  
    106         // Copy settings from the settings object back to the UI 
    107         //   This is useful for either abandoning changes to the UI or updating the UI when 
    108         //   the object changes 
    109         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         }, 
    12119 
    12220        // Load settings from the current user, which were loaded from the users.json file and 
     
    14947                        flickr.prefs.getSafetyLevel(); 
    15048                } 
    151  
    152                 // Update the UI 
    153                 settings.update(); 
    154                 events.settings.is_public(settings.is_public); 
    15549 
    15650        }, 
     
    17165                } 
    17266 
     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 
    173206        } 
    174207 
  • trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/settings.xul

    r28 r30  
    22<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> 
    33<?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" 
     6ondialogaccept="events.settings.ok(); return true;" 
     7ondialogcancel="events.settings.cancel(); return true;" onload="events.settings.load();" 
    68xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 
    79xmlns: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" /> 
    814        <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> 
    1128                <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" 
    3233                                oncommand="events.settings.is_public(this.value);"> 
    3334                                        <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;" 
    3536                                                disabled="true" /> 
    36                                                 <checkbox id="s_is_family" label="&settings.privacy.family;" 
     37                                                <checkbox id="is_family" label="&settings.privacy.family;" 
    3738                                                disabled="true" /> 
    3839                                        <radio value="1" label="&settings.privacy.public;" /> 
    3940                                </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"> 
    4546                                        <menupopup> 
    4647                                                <menuitem value="1" label="&settings.content_type.photo;" 
     
    5051                                        </menupopup> 
    5152                                </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"> 
    5455                                        <menupopup> 
    5556                                                <menuitem value="1" label="&settings.hidden.no;" 
     
    5859                                        </menupopup> 
    5960                                </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"> 
    6263                                        <menupopup> 
    6364                                                <menuitem value="1" label="&settings.safety_level.safe;" 
     
    6768                                        </menupopup> 
    6869                                </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;" /
    7273                                <html:p>&settings.resize.prompt;</html:p> 
    73                                 <menulist id="s_resize"> 
     74                                <menulist id="resize"> 
    7475                                        <menupopup> 
    7576                                                <menuitem value="-1" label="&settings.resize.dont;" selected="true" /> 
     
    8081                                        </menupopup> 
    8182                                </menulist> 
    82                                 <html:p id="s_resize_note"> </html:p> 
    83                         </vbox> 
     83                                <html:p id="resize_note"> </html:p> 
     84                        </groupbox> 
    8485                </hbox> 
    8586        </vbox> 
    86 </overlay
     87</dialog
  • trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/threads.js

    r28 r30  
    7575                                img.src = 'file://' + thumb[8]; 
    7676 
    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; 
    8781                                } 
    8882 
     
    284278 
    285279                                // Update bandwidth 
    286                                 var size = uploadr.fsize(resize[3]); 
     280                                var size = file.size(resize[3]); 
    287281                                photos.batch_size -= photos.list[this.id].filesize; 
    288282                                if (!users.is_pro && users.bandwidth.remaining - photos.batch_size < size) { 
  • trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/ui.js

    r28 r30  
    11var pages = { 
    22 
    3         _list: ['photos', 'users', 'settings', 'progress', 'complete'], 
     3        _list: ['photos', 'queue'], 
    44        _current: 0, 
    55 
     
    2121                } 
    2222 
    23                 // Only show the toolbar on the photos page 
    24                 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  
    3223        }, 
    3324 
     
    3930}; 
    4031 
     32// Free account capacity indicators 
    4133var free = { 
    4234 
     
    6052                                for each (var p in photos.list) { 
    6153                                        if (null != p) { 
    62                                                 var size = uploadr.fsize(p.path); 
     54                                                var size = file.size(p.path); 
    6355                                                if (!users.is_pro && 
    6456                                                        users.bandwidth.remaining - photos.batch_size < size) { 
     
    7264                        } 
    7365 
    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                } 
    9376 
    9477        }, 
     
    10285var buttons = { 
    10386 
    104         _list: ['login', 'back', 'ok', 'upload'], 
     87        _list: ['login', 'upload'], 
    10588 
    10689        // Show specified buttons 
     
    131114                        b.disabled = false; 
    132115                        b.className = 'button'; 
     116                        if ('upload' == l) { 
     117                                document.getElementById('menu_upload_upload').disabled = false; 
     118                        } 
    133119                } 
    134120        }, 
     
    143129                        b.disabled = true; 
    144130                        b.className = 'disabled_button'; 
     131                        if ('upload' == l) { 
     132                                document.getElementById('menu_upload_upload').disabled = true; 
     133                        } 
    145134                } 
    146135        } 
     
    163152}; 
    164153 
    165 // Functions to find photos above and below a given photo 
     154// Functions to find photos in the grid 
    166155var findr = { 
    167156 
     
    233222                }, 
    234223                onDragOver: function(e, data) { 
    235                         document.getElementById('photos').className = 'drag oldest'; 
     224                        document.getElementById('photos').className = 'drag'; 
    236225                }, 
    237226                onDragExit: function(e, flavor, session) { 
    238                         document.getElementById('photos').className = 'no_drag oldest'; 
     227                        document.getElementById('photos').className = 'no_drag'; 
    239228                }, 
    240229                onDrop: function(e, data) { 
     
    298287// Allow functions to block exiting 
    299288var _block_exit = 0; 
    300 var _block_exit_stack = []; 
    301289var block_exit = function() { 
    302290        ++_block_exit; 
    303         Components.utils.reportError('push: ' + _block_exit); 
    304         _block_exit_stack.push(_block_exit); 
    305291} 
    306292var unblock_exit = function() { 
    307293        --_block_exit; 
    308         Components.utils.reportError('pop: ' + _block_exit_stack.pop()); 
    309294} 
    310295 
     
    313298 
    314299        // Don't exit if exit is blocked 
    315 Components.utils.reportError('_block_exit: ' + _block_exit); 
    316300        if (0 < _block_exit) { 
     301Components.utils.reportError(_block_exit); 
    317302                return; 
    318303        } 
    319  
    320304 
    321305        // Save state 
     
    356340        return result.result; 
    357341}; 
     342 
     343// Open a browser window to the given URL 
     344var 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 been 
    2 // refactored into new homes 
    3  
    41const Cc = Components.classes; 
    52const Ci = Components.interfaces; 
     
    2724                auto_save: 60 
    2825 
    29         }, 
    30  
    31         // Handle files dragged on startup 
    32         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 IO 
    50         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 file 
    94         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); 
    9826        } 
    9927 
  • trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/content/uploadr/users.js

    r28 r30  
    1515        // List of authorized users 
    1616        list: {}, 
     17 
     18        // A one-time custom callback after login 
     19        after_login: null, 
    1720 
    1821        // Shortcut for the auth sequence 
     
    3942                        document.getElementById('username').value = username; 
    4043                        document.getElementById('switch').value = locale.getString('switch'); 
    41                         document.getElementById('u_current').firstChild.nodeValue = username; 
    4244                        status.set(locale.getString('status.ready')); 
    4345 
    4446                } else { 
    4547                        users.logout(); 
     48                } 
     49                if ('function' == typeof users.after_login) { 
     50                        users.after_login(); 
     51                        users.after_login = null; 
    4652                } 
    4753        }, 
     
    6066 
    6167                // Update the UI 
    62                 var notloggedin = locale.getString('notloggedin'); 
    63                 document.getElementById('username').value = notloggedin; 
     68                document.getElementById('username').value = locale.getString('notloggedin'); 
    6469                document.getElementById('switch').value = locale.getString('login'); 
    65                 document.getElementById('u_current').firstChild.nodeValue = notloggedin; 
    6670                document.getElementById('free').style.display = 'none'; 
    6771                status.set(locale.getString('status.disconnected')); 
     
    97101                } 
    98102 
    99                 // Update the list on the users page 
    100                 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  
    116103        }, 
    117104 
    118105        // Load users from a file 
    119106        load: function() { 
    120                 users.list = uploadr.fread('users.json'); 
     107                users.list = file.read('users.json'); 
    121108 
    122109                // Login as the current user 
     
    139126        // Save users to a file 
    140127        save: function() { 
    141                 uploadr.fwrite('users.json', users.list); 
     128                file.write('users.json', users.list); 
    142129        } 
    143130 
  • trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/locale/en-US/main.dtd

    r28 r30  
    11<!ENTITY title "Flickr Uploadr"> 
    22 
    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"> 
    714 
    815<!ENTITY notloggedin "Not logged in"> 
    916<!ENTITY login "Login"> 
     17 
     18<!ENTITY tools.add "+ Add"> 
     19<!ENTITY tools.remove "− Remove"> 
    1020 
    1121<!ENTITY buttons.login "Login"> 
     
    2131<!ENTITY progress.this_file "This file:"> 
    2232 
    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  
    2833<!ENTITY photos.sort.default "Photos are sorted by date taken.  Drag to reorder."> 
    2934<!ENTITY photos.sort.revert "Re-sort by date taken"> 
    3035 
    3136<!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"> 
    3741<!ENTITY settings.privacy "Privacy"> 
    3842<!ENTITY settings.privacy.who "Who can see this photo?"> 
     
    7276<!ENTITY meta.single.sets "Add this photo to sets"> 
    7377<!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..."> 
    7481 
    7582<!ENTITY dialog.bandwidth "Available bandwidth exceeded!"> 
  • trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/locale/en-US/main.properties

    r28 r30  
    2222 
    2323meta.dim=%1$d x %2$d 
    24 meta.size=%1$s 
     24meta.size=%1$sMB 
    2525meta.batch.prompt=%1$d photos selected 
    2626meta.abandon=You set some metadata but you must save it before deselecting these photos.  Save it? 
     
    4242rotate.confirm.title=Rotate 
    4343 
     44free.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 
    4446progress.failed=Bonk!  Some of your photos failed to upload.  Would you like us to re-add them to the batch so you can retry? 
    4547progress.failed.title=Some uploads failed 
     
    5658 
    5759go_pro=You'll have to restart Flickr Uploadr for your new Pro account to get noticed. 
     60go_pro.title=Go Pro! 
  • trunk/uploadr/MacUploadr.app/Contents/Resources/chrome/skin/uploadr/dialog.css

    r4 r30  
     1/* Normal dialogs */ 
    12dialog { 
    23        width: 300px; 
    34} 
     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  
    1212 */ 
    1313 
    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 */ 
    2920#logo { 
    3021        width: 120px; 
    3122        height: 67px; 
    3223        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; 
    3429} 
    3530 
     
    5247        height: 40px; 
    5348        padding: 5px; 
    54         border-top: 1px dotted #bbb
     49        border-top: 1px dotted #ddd
    5550        background: white; 
    5651} 
     
    8782        display: none; 
    8883} 
    89 input.button
     84input.button, input.disabled_button
    9085        margin: 0 0 5px 5px; 
    91         background: #0063dc; 
    92         color: white; 
    9386        font-size: 12px; 
    9487        font-weight: bold; 
    9588        text-transform: uppercase; 
     89        vertical-align: middle; 
     90}        
     91input.button { 
     92        background: #0063dc; 
     93        color: white; 
    9694} 
    9795input.disabled_button { 
    98         margin: 0 0 5px 5px; 
    9996        background: #eee; 
    10097        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 */ 
    105110 
    106111/* Nested form indentation, used all over */ 
     
    126131} 
    127132 
    128 /* Make the upload button gaudy */ 
    129 #button_upload { 
    130         font-size: 16px; 
    131 
     133 
    132134 
    133135/* 
    134136 * Toolbar 
    135137 */ 
     138#tools { 
     139        background: white; 
     140        border-bottom: 1px dotted #ddd; 
     141} 
    136142#tools toolbox toolbar { 
    137         width: 217px; 
    138143        height: 34px; 
    139144        padding: 5px 0 0 10px; 
    140145        background: white; 
    141         border-top: 1px solid #999; 
    142146        border-bottom: 0; 
    143147} 
     
    153157toolbarseparator { 
    154158        width: 1px; 
    155         margin: 0 15px 0 10px; 
     159        margin: 0 15px 5px 10px; 
    156160        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; 
    181161} 
    182162#t_rotate_l { 
     
    204184        background-position: -72px -67px; 
    205185} 
    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 } 
    226186 
    227187 
     
    231191 */ 
    232192 
    233 /* The container has multiple nested boxes for multiple backgrounds */ 
    234193#photos { 
    235194        margin: 0; 
     195        background: white; 
     196        border-right: 1px solid #ddd; 
    236197        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; 
    243198} 
    244199 
     
    380335        cursor: pointer; 
    381336} 
    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  
    128128} 
    129129exif["Exif.Image.Orientation"] = uint32_t(orient); 
     130 
     131 
     132 
     133filename                ticket_id                                       photo_id                site order              proper order 
     134 
     135IMG_1722.JPG    3609264-72157602195393043       1453335763              2                               1 
     136api.jpg                 3609264-72157602195394259       1453336053              1                               2 
     137beck.jpg                3609264-72157602195394999       1453336425              3                               3 
     138 
     139 
     140 
     141API 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 
     143API 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 
     150API 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 
     152API RESULT: <?xml version="1.0" encoding="utf-8" ?> 
     153<rsp stat="ok"> 
     154<ticketid>3609264-72157602187992740</ticketid> 
     155</rsp> 
     156 
     157 
     158