Mercurial > snowl
changeset 359:57bbbcb76b0b
initial implementationi of writing; stream view only, still pretty hacky
author | Myk Melez <myk@mozilla.org> |
---|---|
date | Tue, 04 Nov 2008 12:24:08 -0800 |
parents | c00b3db58dcf |
children | 926940f1559a |
files | content/icons/email_add.png content/stream.js content/stream.xul content/toolbar.js content/toolbar.xul locale/en-US/toolbar.dtd modules/opml.js modules/twitter.js |
diffstat | 8 files changed, 126 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/content/stream.js Tue Nov 04 12:11:07 2008 -0800 +++ b/content/stream.js Tue Nov 04 12:24:08 2008 -0800 @@ -51,6 +51,8 @@ Cu.import("resource://snowl/modules/datastore.js"); Cu.import("resource://snowl/modules/collection.js"); Cu.import("resource://snowl/modules/utils.js"); +Cu.import("resource://snowl/modules/twitter.js"); +Cu.import("resource://snowl/modules/service.js"); const XML_NS = "http://www.w3.org/XML/1998/namespace" const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; @@ -162,10 +164,19 @@ this._setMidnightTimout(); gBrowserWindow.Snowl._initSnowlToolbar(); + + // For some reason setting hidden="true" in the XUL file prevents us + // from showing the box later via writeBox.hidden = false. + // FIXME: file a bug on this abnormality. + let writeBox = document.getElementById("writeBox"); + writeBox.hidden = true; + + this._updateWriteButton(); }, onunLoad: function() { Observers.remove(this, "snowl:message:added"); + Observers.remove(this, "snowl:sources:changed"); }, _setMidnightTimout: function() { @@ -176,6 +187,13 @@ window.setTimeout(function() { t.onMidnight() }, msUntilMidnight); }, + // Selectively show/hide the button for writing a message depending on + // whether or not the user has an account that supports writing. + _updateWriteButton: function() { + document.getElementById("snowlWriteMessageButton").disabled = + (SnowlService.targets.length == 0); + }, + //**************************************************************************// // Event & Notification Handlers @@ -226,6 +244,7 @@ }, _onSourcesChanged: function() { + this._updateWriteButton(); this._rebuildView(); }, @@ -233,6 +252,18 @@ event.target.nextSibling.style.display = event.target.checked ? "block" : "none"; }, + onWriteMessage: function(event) { + let writeBox = document.getElementById("writeBox"); + writeBox.hidden = !event.target.checked; + }, + + onSendMessage: function() { + let writeTextbox = document.getElementById("writeTextbox"); + let content = writeTextbox.value; + let twitter = new SnowlTwitter(); + twitter.send(content); + }, + //**************************************************************************// // Safe DOM Manipulation
--- a/content/stream.xul Tue Nov 04 12:11:07 2008 -0800 +++ b/content/stream.xul Tue Nov 04 12:24:08 2008 -0800 @@ -53,8 +53,16 @@ <script type="application/javascript" src="chrome://snowl/content/strands.js"/> <script type="application/javascript" src="chrome://snowl/content/stream.js"/> + <toolbar id="snowlToolbar"/> + + <vbox id="writeBox"> + <textbox id="writeTextbox" multiline="true" rows="3"/> + <hbox> + <spacer flex="1"/> + <button label="Send" oncommand="SnowlMessageView.onSendMessage()"/> + </hbox> + </vbox> + <vbox id="contentBox"/> - <toolbar id="snowlToolbar"/> - </page>
--- a/content/toolbar.js Tue Nov 04 12:11:07 2008 -0800 +++ b/content/toolbar.js Tue Nov 04 12:24:08 2008 -0800 @@ -57,6 +57,9 @@ onExportOPML: function() { SnowlOPML.export(window); - } + }, + onWriteMessage: function(event) { + SnowlMessageView.onWriteMessage(event); + } };
--- a/content/toolbar.xul Tue Nov 04 12:11:07 2008 -0800 +++ b/content/toolbar.xul Tue Nov 04 12:24:08 2008 -0800 @@ -44,8 +44,7 @@ <script type="application/x-javascript" src="chrome://snowl/content/toolbar.js"/> - <toolbar id="snowlToolbar" - persist="hidden"> + <toolbar id="snowlToolbar" persist="hidden"> <toolbarbutton id="snowlSubscribeButton" image="chrome://snowl/content/icons/add.png" oncommand="SnowlToolbar.subscribe()" @@ -62,6 +61,11 @@ image="chrome://snowl/content/icons/opml-icon-16x16.png" oncommand="SnowlToolbar.onExportOPML()" tooltiptext="&exportButton.tooltip;"/> + <toolbarspring/> + <toolbarbutton id="snowlWriteMessageButton" type="checkbox" + image="chrome://snowl/content/icons/email_add.png" + oncommand="SnowlToolbar.onWriteMessage(event)" + tooltiptext="&writeMessageButton.tooltip;"/> </toolbar> </overlay>
--- a/locale/en-US/toolbar.dtd Tue Nov 04 12:11:07 2008 -0800 +++ b/locale/en-US/toolbar.dtd Tue Nov 04 12:24:08 2008 -0800 @@ -2,3 +2,4 @@ <!ENTITY unsubscribeButton.tooltip "Unsubscribe from message sources."> <!ENTITY refreshButton.tooltip "Refresh message sources."> <!ENTITY exportButton.tooltip "Export message sources as OPML."> +<!ENTITY writeMessageButton.tooltip "Write a message.">
--- a/modules/opml.js Tue Nov 04 12:11:07 2008 -0800 +++ b/modules/opml.js Tue Nov 04 12:24:08 2008 -0800 @@ -100,8 +100,7 @@ root.appendChild(body); // Populate the <body> element with <outline> elements. - let sources = SnowlService.getSources(); - for each (let source in sources) { + for each (let source in SnowlService.sources) { let outline = doc.createElement("outline"); // XXX Should we specify the |type| attribute, and should we specify // type="atom" for Atom feeds or just type="rss" for all feeds?
--- a/modules/twitter.js Tue Nov 04 12:11:07 2008 -0800 +++ b/modules/twitter.js Tue Nov 04 12:24:08 2008 -0800 @@ -556,6 +556,79 @@ // Now that we've saved the login, we don't need the auth info anymore. this._authInfo = null; + }, + + + //**************************************************************************// + // Sending + + send: function(content) { + Observers.notify(this, "snowl:send:start", null); + + let data = "status=" + encodeURIComponent(content); + // + "&in_reply_to_status_id=" + encodeURIComponent(inReplyToID); + + let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(); + + request.QueryInterface(Ci.nsIDOMEventTarget); + let (t = this) { + request.addEventListener("load", function(e) { t.onSendLoad(e) }, false); + request.addEventListener("error", function(e) { t.onSendError(e) }, false); + } + + request.QueryInterface(Ci.nsIXMLHttpRequest); + request.open("POST", this.machineURI.spec + "/statuses/update.json", true); + request.channel.notificationCallbacks = this; + request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + request.send(data); + }, + + onSendLoad: function(event) { + let request = event.target; + + // FIXME: the next three chunks of code are the same for multiple + // load handlers; find some way to factor them out. + + // If the request failed, let the error handler handle it. + // XXX Do we need this? Don't such failures call the error handler directly? + if (request.status < 200 || request.status > 299) { + this.onSendError(event); + return; + } + + // If the response is empty, assume failure. + // XXX What's the right way to handle this? + if (request.responseText.length == 0) { + this.onSendError(event); + return; + } + + // _authInfo only gets set if we prompted the user to authenticate + // and the user checked the "remember password" box. Since we're here, + // it means the request succeeded, so we save the login. + if (this._authInfo) + this._saveLogin(); + + this._log.info("onSendLoad: " + request.responseText); + this._processSend(request.responseText); + }, + + onSendError: function(event) { + let request = event.target; + + // Sometimes an attempt to retrieve status text throws NS_ERROR_NOT_AVAILABLE + let statusText = ""; + try { + statusText = request.statusText; + } + catch(ex) {} + + this._log.error("onSendError: " + request.status + " (" + statusText + ")"); + }, + + _processSend: function(responseText) { + var JSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON); + let response = JSON.decode(responseText); } };