Improve the behavior of the interface.

This commit is contained in:
amla70
2010-08-09 14:27:54 +00:00
parent ff8b7f1e5a
commit e4dca60d6f
13 changed files with 201 additions and 77 deletions

View File

@@ -102,7 +102,10 @@ sendtophone.checkDrag = function(event)
{ {
//event.dataTransfer.dropEffect = "copy"; //event.dataTransfer.dropEffect = "copy";
var types = event.dataTransfer.types; var types = event.dataTransfer.types;
if (types.contains("text/plain") || types.contains("text/uri-list") || types.contains("text/x-moz-url") || types.contains("application/x-moz-file")) if (types.contains("text/plain") || types.contains("text/uri-list") || types.contains("text/x-moz-url"))
event.preventDefault();
if (this.prefs.getCharPref( "fileServerUrl" ) && types.contains("application/x-moz-file") )
event.preventDefault(); event.preventDefault();
} }
@@ -154,8 +157,10 @@ sendtophone.pickFile = function(folder)
if (folder) if (folder)
fp.init(window, this.strings.getString("SendFolderToPhone"), Ci.nsIFilePicker.modeGetFolder); fp.init(window, this.strings.getString("SendFolderToPhone"), Ci.nsIFilePicker.modeGetFolder);
else else
{
fp.init(window, this.strings.getString("SendFileToPhone"), Ci.nsIFilePicker.modeOpenMultiple); fp.init(window, this.strings.getString("SendFileToPhone"), Ci.nsIFilePicker.modeOpenMultiple);
fp.appendFilters(Ci.nsIFilePicker.filterAll | Ci.nsIFilePicker.filterImages); fp.appendFilters(Ci.nsIFilePicker.filterAll | Ci.nsIFilePicker.filterImages);
}
var rv = fp.show(); var rv = fp.show();

View File

@@ -10,10 +10,10 @@
</stringbundleset> </stringbundleset>
<popupset id="mainPopupSet"> <popupset id="mainPopupSet">
<popup id="sendtophoneContextMenu" onpopupshowing="sendtophone.initPopup();"> <menupopup id="sendtophoneContextMenu" onpopupshowing="sendtophone.initPopup();">
<menuitem label="&sendtophoneContextSendFile.label;" <menuitem label="&sendtophoneContextSendFile.label;"
accesskey="&sendtophoneContextSendFile.accesskey;" accesskey="&sendtophoneContextSendFile.accesskey;"
oncommand="sendtophone.pickFile(false)" id="sendtophoneContextMenuSendFile"/> oncommand="sendtophone.pickFile(false)" id="sendtophoneContextMenuSendFiles"/>
<menuitem label="&sendtophoneContextSendFolder.label;" <menuitem label="&sendtophoneContextSendFolder.label;"
accesskey="&sendtophoneContextSendFolder.accesskey;" accesskey="&sendtophoneContextSendFolder.accesskey;"
oncommand="sendtophone.pickFile(true)" id="sendtophoneContextMenuSendFolder"/> oncommand="sendtophone.pickFile(true)" id="sendtophoneContextMenuSendFolder"/>
@@ -28,11 +28,11 @@
<menuitem label="&sendtophoneContextLogout.label;" <menuitem label="&sendtophoneContextLogout.label;"
accesskey="&sendtophoneContextLogout.accesskey;" accesskey="&sendtophoneContextLogout.accesskey;"
oncommand="sendtophone.logout()" id="sendtophoneContextMenuLogout"/> oncommand="sendtophone.logout()" id="sendtophoneContextMenuLogout"/>
</popup> </menupopup>
</popupset> </popupset>
<popup id="contentAreaContextMenu"> <menupopup id="contentAreaContextMenu">
<menuitem id="context-sendtophone-link" label="&sendtophoneContext.label;" <menuitem id="context-sendtophone-link" label="&sendtophoneContext.label;"
accesskey="&sendtophoneContext.accesskey;" accesskey="&sendtophoneContext.accesskey;"
insertafter="context-sendlink" insertafter="context-sendlink"
@@ -49,7 +49,7 @@
accesskey="&sendtophoneContextPage.accesskey;" accesskey="&sendtophoneContextPage.accesskey;"
insertafter="context-sendpage" insertafter="context-sendpage"
oncommand="sendtophone.onMenuItemCommand(event, 'page')"/> oncommand="sendtophone.onMenuItemCommand(event, 'page')"/>
</popup> </menupopup>
<toolbarpalette id="BrowserToolbarPalette"> <toolbarpalette id="BrowserToolbarPalette">
<toolbarbutton id="sendtophone-toolbar-button" class="toolbarbutton-1 chromeclass-toolbar-additional" <toolbarbutton id="sendtophone-toolbar-button" class="toolbarbutton-1 chromeclass-toolbar-additional"

View File

@@ -149,6 +149,12 @@ var sendtophone = {
initPopup: function() initPopup: function()
{ {
var fileServerUrl = this.prefs.getCharPref( "fileServerUrl" );
if (!fileServerUrl)
{
document.getElementById("sendtophoneContextMenuSendFiles").hidden = true;
document.getElementById("sendtophoneContextMenuSendFolder").hidden = true;
}
// returning true will make the popup show // returning true will make the popup show
return true; return true;
}, },

View File

@@ -1,9 +1,10 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!DOCTYPE bindings [ <!DOCTYPE bindings [
<!ENTITY % downloadDTD SYSTEM "chrome://sendtophone/locale/uploads.dtd" > <!ENTITY % downloadManagerDTD SYSTEM "chrome://mozapps/locale/downloads/downloads.dtd">
%downloadDTD; %downloadManagerDTD;
<!ENTITY % uploadDTD SYSTEM "chrome://sendtophone/locale/uploads.dtd" >
%uploadDTD;
]> ]>
<bindings id="uploadBindings" <bindings id="uploadBindings"
@@ -54,7 +55,6 @@
<xul:label xbl:inherits="value=target,tooltiptext=file" <xul:label xbl:inherits="value=target,tooltiptext=file"
crop="center" flex="2" class="name"/> crop="center" flex="2" class="name"/>
<xul:hbox> <xul:hbox>
<xul:vbox flex="1"> <xul:vbox flex="1">
<xul:progressmeter mode="normal" value="0" flex="1" <xul:progressmeter mode="normal" value="0" flex="1"
anonid="progressmeter" anonid="progressmeter"
@@ -83,7 +83,6 @@
<xul:vbox pack="start" flex="1"> <xul:vbox pack="start" flex="1">
<xul:label xbl:inherits="value=target,tooltiptext=file" <xul:label xbl:inherits="value=target,tooltiptext=file"
crop="center" flex="2" class="name"/> crop="center" flex="2" class="name"/>
<xul:hbox> <xul:hbox>
<xul:vbox flex="1"> <xul:vbox flex="1">
<xul:progressmeter mode="undetermined" flex="1" /> <xul:progressmeter mode="undetermined" flex="1" />

View File

@@ -65,8 +65,8 @@ let gUploadListener = {
gUploadsView.removeChild(item); gUploadsView.removeChild(item);
// If no more pending uploads, close the tab. // If no more pending uploads, close the tab.
// Use a 100ms timeout to avoid flicker while compress -> upload a folder // Use a 0 ms timeout to avoid flicker while compress -> upload a folder
window.setTimeout( checkPendingUploads, 100); window.setTimeout( checkPendingUploads, 0);
} }
}; };

View File

@@ -10,19 +10,6 @@
onload="Startup();" onunload="Shutdown();" onload="Startup();" onunload="Shutdown();"
onclose="return closeWindow(false);"> onclose="return closeWindow(false);">
<!--
<window xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="downloadManager" windowtype="Download:Manager"
orient="vertical" title="&downloads.title;" statictitle="&downloads.title;"
width="&window.width2;" height="&window.height;" screenX="10" screenY="10"
persist="width height screenX screenY sizemode"
onload="Startup();" onunload="Shutdown();"
onclose="return closeWindow(false);">
<script type="application/javascript" src="chrome://mozapps/content/downloads/downloads.js"/>
<script type="application/javascript" src="chrome://mozapps/content/downloads/DownloadProgressListener.js"/>
-->
<script type="application/javascript" src="chrome://sendtophone/content/uploads.js"/> <script type="application/javascript" src="chrome://sendtophone/content/uploads.js"/>
<richlistbox id="UploadsBox" flex="1"> <richlistbox id="UploadsBox" flex="1">

View File

@@ -17,3 +17,5 @@ InvalidFile=Not a valid file
SendFileToPhone=Send files to your phone. SendFileToPhone=Send files to your phone.
SendFolderToPhone=Send a folder to your phone. SendFolderToPhone=Send a folder to your phone.
qrTitle=QR Image Link qrTitle=QR Image Link
FileUploadsDisabled=It's not possible to upload files to the phone.
FileTooBig=The file is too big.

View File

@@ -1,3 +1 @@
<!ENTITY compressing.label "Compressing folder"> <!ENTITY compressing.label "Compressing folder">
<!ENTITY cmd.cancel.label "Cancel">
<!ENTITY cmd.cancel.accesskey "C">

View File

@@ -17,3 +17,5 @@ InvalidFile=No es un fichero válido.
SendFileToPhone=Envía ficheros al teléfono. SendFileToPhone=Envía ficheros al teléfono.
SendFolderToPhone=Envía una carpeta al teléfono. SendFolderToPhone=Envía una carpeta al teléfono.
qrTitle=Imagen QR qrTitle=Imagen QR
FileUploadsDisabled=No se pueden enviar ficheros al teléfono.
FileTooBig=El fichero que quiere enviar es demasiado grande.

View File

@@ -1,3 +1 @@
<!ENTITY compressing.label "Comprimiendo carpeta"> <!ENTITY compressing.label "Comprimiendo carpeta">
<!ENTITY cmd.cancel.label "Cancelar">
<!ENTITY cmd.cancel.accesskey "C">

View File

@@ -3,6 +3,7 @@ pref("extensions.sendtophone.appUrl", "https://chrometophone.appspot.com");
pref("extensions.sendtophone.proxyUrl", "http://smallroomstudios.net/s2p.php?ml="); pref("extensions.sendtophone.proxyUrl", "http://smallroomstudios.net/s2p.php?ml=");
pref("extensions.sendtophone.fileServerUrl", "http://martinezdelizarrondo.com/sendtophone.php"); pref("extensions.sendtophone.fileServerUrl", "http://martinezdelizarrondo.com/sendtophone.php");
pref("extensions.sendtophone.fileUploadMaxKb", 50000);
pref("extensions.sendtophone.protocols.market", true); pref("extensions.sendtophone.protocols.market", true);
pref("extensions.sendtophone.protocols.sms", true); pref("extensions.sendtophone.protocols.sms", true);

View File

@@ -185,7 +185,7 @@ var sendtophoneCore = {
if (!(/^(https?):/i).test( url )) if (!(/^(https?):/i).test( url ))
{ {
// Rewrite the URI so it's send first to the proxy // Rewrite the URI so it's send first to the proxy
var proxyUrl = this.prefs.getCharPref( "proxyUrl" ) ; var proxyUrl = this.prefs.getCharPref( "proxyUrl" );
if (proxyUrl) if (proxyUrl)
url = proxyUrl + encodeURIComponent( url); url = proxyUrl + encodeURIComponent( url);
} }
@@ -230,6 +230,9 @@ var sendtophoneCore = {
logout: function() logout: function()
{ {
if (!this.prefs)
this.init();
// Open Google logout page, and close tab when finished // Open Google logout page, and close tab when finished
this.openTab(this.logOutUrl, this.loggedOutUrl, function() {sendtophoneCore.logoutSuccessful();} ); this.openTab(this.logOutUrl, this.loggedOutUrl, function() {sendtophoneCore.logoutSuccessful();} );
@@ -263,7 +266,7 @@ var sendtophoneCore = {
callback(); callback();
// Close tab // Close tab
gBrowser.removeTab(c2pTab); gBrowser.removeTab(tab);
// ReFocus on tab being sent // ReFocus on tab being sent
gBrowser.selectedTab = gBrowser.tabContainer.childNodes[lastTabIndex]; gBrowser.selectedTab = gBrowser.tabContainer.childNodes[lastTabIndex];
} }
@@ -298,13 +301,20 @@ var sendtophoneCore = {
if (!this.prefs) if (!this.prefs)
this.init(); this.init();
let uri = this.prefs.getCharPref( "fileServerUrl" );
if (!uri)
{
this.alert( this.getString("FileUploadsDisabled") );
return;
}
if (typeof sendtophoneUploadsManager == "undefined") if (typeof sendtophoneUploadsManager == "undefined")
Components.utils.import("resource://sendtophone/uploadsManager.js"); Components.utils.import("resource://sendtophone/uploadsManager.js");
if (nsFile.isDirectory()) if (nsFile.isDirectory())
{ {
// There's no progress notification while compressing, only on end. // There's no progress notification while compressing, only on end.
var progressId = sendtophoneUploadsManager.addZip(nsFile); let progressId = sendtophoneUploadsManager.addZip(nsFile);
// Compress the contents to a zip file // Compress the contents to a zip file
zipFolder(nsFile, function(nsZip) zipFolder(nsFile, function(nsZip)
{ {
@@ -323,7 +333,15 @@ var sendtophoneCore = {
return; return;
} }
var uploadName = nsFile.leafName; let size = Math.round(nsFile.fileSize / 1024);
let maxSize = this.prefs.getIntPref( "fileUploadMaxKb" );
if (maxSize>0 && size>maxSize)
{
this.alert( this.getString("FileTooBig") );
return;
}
let uploadName = nsFile.leafName;
// Try to determine the MIME type of the file // Try to determine the MIME type of the file
var mimeType = "text/plain"; var mimeType = "text/plain";
try { try {
@@ -348,7 +366,8 @@ var sendtophoneCore = {
startBoundryStream.setData("\r\n--"+boundary+"\r\n",-1); startBoundryStream.setData("\r\n--"+boundary+"\r\n",-1);
// Setup the boundary end stream // Setup the boundary end stream
var endBoundryStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream); var endBoundryStream = Cc["@mozilla.org/io/string-input-stream;1"]
.createInstance(Ci.nsIStringInputStream);
endBoundryStream.setData("\r\n--"+boundary+"--",-1); endBoundryStream.setData("\r\n--"+boundary+"--",-1);
// Setup the mime-stream - the 'part' of a multi-part mime type // Setup the mime-stream - the 'part' of a multi-part mime type
@@ -364,9 +383,6 @@ var sendtophoneCore = {
multiStream.appendStream(startBoundryStream); multiStream.appendStream(startBoundryStream);
multiStream.appendStream(mimeStream); multiStream.appendStream(mimeStream);
multiStream.appendStream(endBoundryStream); multiStream.appendStream(endBoundryStream);
var size = Math.round(nsFile.fileSize / 1024);
var uri = this.prefs.getCharPref( "fileServerUrl" );
var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"] var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Ci.nsIXMLHttpRequest); .createInstance(Ci.nsIXMLHttpRequest);
@@ -399,12 +415,16 @@ var sendtophoneCore = {
// Handle errors or aborted uploads // Handle errors or aborted uploads
req.addEventListener("error", function(evt) req.addEventListener("error", function(evt)
{ {
sendtophoneCore.alert("Error while sending the file to the server:\r\n" + uri);
// If there's a callback (to delete temporary files) we call it now // If there's a callback (to delete temporary files) we call it now
if (callback) if (callback)
callback(); callback();
}, false); }, false);
req.addEventListener("abort", function(evt) req.addEventListener("abort", function(evt)
{ {
// Silent.
// If there's a callback (to delete temporary files) we call it now // If there's a callback (to delete temporary files) we call it now
if (callback) if (callback)
callback(); callback();

View File

@@ -36,7 +36,7 @@ var sendtophoneUploadsManager = {
addUpload: function(nsFile, req) addUpload: function(nsFile, req)
{ {
let id = this._addToUploads( {file:nsFile, req:req, state:0, percent:0, let id = this._addToUploads( {file:nsFile, req:req, state:0, percent:0,
startTime: Date.now(), currBytes: 0, maxBytes: nsFile.fileSize} ); startTime: Date.now() - 100, currBytes: 0, maxBytes: nsFile.fileSize} );
req.upload.addEventListener("progress", function(evt) req.upload.addEventListener("progress", function(evt)
{ {
@@ -79,7 +79,7 @@ var sendtophoneUploadsManager = {
_addToUploads: function( obj ) _addToUploads: function( obj )
{ {
this.init(); initShowTest();
// Creates a counter to automatically assign new ids to each upload // Creates a counter to automatically assign new ids to each upload
let id = this._counter++; let id = this._counter++;
@@ -92,7 +92,7 @@ var sendtophoneUploadsManager = {
return id; return id;
}, },
init: function() showWindow: function()
{ {
// Open the tab // Open the tab
openAndReuseOneTabPerURL("chrome://sendtophone/content/uploads.xul"); openAndReuseOneTabPerURL("chrome://sendtophone/content/uploads.xul");
@@ -101,6 +101,23 @@ var sendtophoneUploadsManager = {
updateProgress: function(id, loaded, total) updateProgress: function(id, loaded, total)
{ {
let upload = this.uploads[id]; let upload = this.uploads[id];
// The progress events are fired when the data is sent,
// but that leads to wrong speed because we don't know how long
// it has really taken to process the packet
// As long as the upload progress the speed converges to a more correct value
// But here we will try to adjust it (fake it) sooner
if (!upload.firstPacket)
upload.firstPacket = Date.now();
else
if (!upload.adjusted)
{
upload.adjusted = true;
// let elapsed = Date.now() - upload.firstPacket; // time to send a packet to the server and get back
let elapsed = Date.now() - upload.startTime; //
upload.startTime = upload.startTime - elapsed;
}
upload.currBytes = loaded; upload.currBytes = loaded;
upload.maxBytes = total; upload.maxBytes = total;
@@ -114,6 +131,14 @@ var sendtophoneUploadsManager = {
let upload = this.uploads[id]; let upload = this.uploads[id];
delete this.uploads[id]; delete this.uploads[id];
// Review if there are pending files to cancel the show timer
let count = 0;
for(let id in this.uploads)
count++;
if (count == 0)
cancelShowTimer();
// Notify the listeners
this._listeners.forEach( function( listener ) { this._listeners.forEach( function( listener ) {
listener.fileFinished( upload ); listener.fileFinished( upload );
}); });
@@ -124,7 +149,88 @@ var sendtophoneUploadsManager = {
let upload = this.uploads[id]; let upload = this.uploads[id];
upload.req.abort(); upload.req.abort();
},
// For use while debugging
toConsole: function(text)
{
var aConsoleService = Cc["@mozilla.org/consoleservice;1"]
.getService(Ci.nsIConsoleService);
aConsoleService.logStringMessage( text );
},
// Check if we might need to show the window.
// Either some folder is being compressed,
// or there's some file that might take longer than 2 seconds.
// If there's some file that we still don't know the speed
// then consider it also as needed.
isWindowNeeded: function()
{
for (let id in this.uploads)
{
let upload = this.uploads[id] ;
// zipping folder: if takes so long to compress it, it will also take some time to upload it
if (upload.state==1)
return true;
// If it still hasn't uploaded anything then something might be wrong
if (upload.currBytes==0)
return true;
let elapsedTime = (Date.now() - upload.startTime) / 1000;
let speed = upload.currBytes/elapsedTime;
let remainingSecs = (upload.maxBytes - upload.currBytes) / speed;
// this.toConsole(elapsedTime + " " + speed + " " + remainingSecs);
if (remainingSecs > 2)
return true;
// if (remainingSecs > 1 && elapsedTime> 2)
// return true;
} }
}
}
/**
* Internal function
* Instead of poping up the uploads window inmediately wait a little
* trying to avoid flicker for small files
*/
let showTimer = null;
// we need a nsITimerCallback compatible...
// ... interface for the callbacks.
var showTimerEvent =
{
notify: function(timer)
{
if (sendtophoneUploadsManager.isWindowNeeded())
{
cancelShowTimer();
sendtophoneUploadsManager.showWindow();
}
}
}
function initShowTest()
{
if (showTimer)
return;
// Now it is time to create the timer...
showTimer = Components.classes["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
showTimer.initWithCallback(showTimerEvent, 400, Ci.nsITimer.TYPE_REPEATING_SLACK);
}
function cancelShowTimer()
{
if (!showTimer)
return;
showTimer.cancel();
showTimer = null
} }
// https://developer.mozilla.org/en/Code_snippets/Tabbed_browser#Reusing_tabs // https://developer.mozilla.org/en/Code_snippets/Tabbed_browser#Reusing_tabs