diff -r 000000000000 -r 54498df70f5d Symbian.org/Forums.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian.org/Forums.js Fri Jun 05 16:18:05 2009 +0100 @@ -0,0 +1,443 @@ +// //////////////////////////////////////////////////////////////////////////// +// (c)2009 Symbian Foundation +// //////////////////////////////////////////////////////////////////////////// + +// Forums + +// Forums have the following structure: +// +// Forum group list +// Forum list +// Thread list +// Message list + +// All four views are based on customised RssReader. We customise two aspects: +// - Parsing XML - data is not RSS +// - Handling item selection (e.g. creating a new view for a newly selected forum) + +// ///////////////////////////////////////////////////////////////////////////// +// Forum groups + +// response parser for forum groups +function forumGroupsResponseParser(broker, responseStatus, xmlDoc) { + if (responseStatus == 200 && xmlDoc != null) { + // node ref for iterating + var node; + + // for compatibility with rss + var lastModified = new Date(); + + // init result items array + var items = []; + + var elements = xmlDoc.getElementsByTagName("group"); + for (var i = 0; i < elements.length; i++) { + var groupid = elements[i].getAttribute("id"); + var grouptitle = elements[i].getAttribute("title"); + items.push({ id: groupid, title: grouptitle}); + } + + // update was completed successfully + return { status: "ok", lastModified: lastModified, items: items }; + } else { + // update failed + return { status: "error" }; + } +} + +// FeedPresenter implementation for forum groups +function ForumGroupsFeedPresenter(rssreader){ + if (rssreader) { + this.init(rssreader); + } +} + +// ForumGroupsFeedPresenter is a subclass of ButtonFeedPresenter +ForumGroupsFeedPresenter.prototype = new ButtonFeedPresenter(null); + +// ForumGroupsFeedPresenter "Constructor" +ForumGroupsFeedPresenter.prototype.init = function(rssreader) { + ButtonFeedPresenter.prototype.init.call(this, rssreader); +} + +// Handle the click on a specific item +ForumGroupsFeedPresenter.prototype.feedClicked = function(event){ + var buttonid = event.source.id; + + if (buttonid == "latestPosts") { + // show latest posts + var url = forumFeedURL; + var latestPostsView = new RssReader("Latest posts", url, new LatestPostsFeedPresenter(null), this.rssreader, null); + latestPostsView.show(); + } + else { + // show forum group + var groupid = this.items[buttonid].id; + var grouptitle = this.items[buttonid].title; + + var url = forumsListUrl + groupid; + var forumListView = new RssReader(grouptitle, url, new ForumsListFeedPresenter(null), this.rssreader, forumListResponseParser); + forumListView.show(); + } +} + +// Create and add controls to be shown before items list. +ForumGroupsFeedPresenter.prototype.addPreambleItems = function(){ + var feedItemControl = new NavigationButton("latestPosts", "blueright.gif", "Latest posts"); + var self = this; + feedItemControl.addEventListener("ActionPerformed", function(event) { self.feedClicked(event); }); + this.rssreader.addControl(feedItemControl); +} + + +// /////////////////////////////////////////////////////////////////////////// +// List of forums in a group + +// response parser for forum list - in a group +function forumListResponseParser(broker, responseStatus, xmlDoc) { + if (responseStatus == 200 && xmlDoc != null) { + // node ref for iterating + var node; + + // for compatibility with rss + var lastModified = new Date(); + + // init result items array + var items = []; + + // extract items for all group elements + var elements = xmlDoc.getElementsByTagName("group"); + for (var i = 0; i < elements.length; i++) { + var forumid = elements[i].getAttribute("id"); + var forumtitle = elements[i].getAttribute("title"); + items.push({ id: forumid, title: forumtitle}); + } + + // update was completed successfully + return { status: "ok", lastModified: lastModified, items: items }; + } else { + // update failed + return { status: "error" }; + } +} + +// FeedPresenter implementation for forum groups +function ForumsListFeedPresenter(rssreader){ + if (rssreader) { + this.init(rssreader); + } +} + +// ForumsListFeedPresenter is a subclass of ButtonFeedPresenter +ForumsListFeedPresenter.prototype = new ButtonFeedPresenter(null); + +// ForumsListFeedPresenter constructor +ForumsListFeedPresenter.prototype.init = function(rssreader) { + ButtonFeedPresenter.prototype.init.call(this, rssreader); +} + + +// forum has been selected, create a reader showing threads in the forum +ForumsListFeedPresenter.prototype.feedClicked = function(event){ + var buttonid = event.source.id; + if (buttonid == "latestPosts") { + // show latest posts + var url = forumFeedURL + "&forumids="; + // append requested forum ids + for( var i = 0; i < this.items.length; i++) { + url += this.items[i].id + ","; + } + + var latestPostsView = new RssReader( + "Latest posts in " + this.rssreader.feedName, + url, + new LatestPostsFeedPresenter(null), + this.rssreader, + null); + latestPostsView.show(); + } + else { + var forumid = this.items[buttonid].id; + var forumtitle = this.items[buttonid].title; + + var url = forumFeedURL + forumsForumSpecQuery + forumid; + var forumListView = new RssReader(forumtitle, url, new ThreadListFeedPresenter(null), this.rssreader, null); + forumListView.show(); + } +} + +// Create and add controls to be shown before items list. +ForumsListFeedPresenter.prototype.addPreambleItems = function(){ + var feedItemControl = new NavigationButton("latestPosts", "blueright.gif", "Latest posts in " + this.rssreader.feedName); + var self = this; + feedItemControl.addEventListener("ActionPerformed", function(event) { self.feedClicked(event); }); + this.rssreader.addControl(feedItemControl); +} + + + +// /////////////////////////////////////////////////////////////////////////// +// List of threads in a forum + +// response parser for thread list is the usual rss parser + +// FeedPresenter implementation for forum groups +function ThreadListFeedPresenter(rssreader){ + if (rssreader) { + this.init(rssreader); + } +} + +// ThreadListFeedPresenter is a subclass of ButtonFeedPresenter +ThreadListFeedPresenter.prototype = new ButtonFeedPresenter(null); + +// ThreadListFeedPresenter constructor +ThreadListFeedPresenter.prototype.init = function(rssreader) { + ButtonFeedPresenter.prototype.init.call(this, rssreader); +} + + +// Handle the click on a specific item +ThreadListFeedPresenter.prototype.feedClicked = function(event){ + var buttonid = event.source.id; + + if (buttonid == "newThread") { + // extract forum id from rssreader.feedURL + var ind = this.rssreader.feedURL.indexOf(forumsForumSpecQuery); + var forumid = this.rssreader.feedURL.substring( ind + forumsForumSpecQuery.length); + var postForm = new ForumPostForm(this.rssreader, forumid); + postForm.show(); + } + else { + var weburl = this.items[buttonid].url; + + // extract thread id from url. looking for t=xxx + var ind1 = weburl.indexOf("?t="); + if (ind1 == -1) { + ind1 = weburl.indexOf("&t="); + } + if (ind1 != -1) { + var threadid = ""; + var ind2 = weburl.indexOf("&", ind1); + if (ind2 == -1) { + threadid = weburl.substring(ind1 + 3); // ?t= + } + else { + threadid = weburl.substring(ind1 + 3, ind2); // ?t= + } + var url = forumThreadUrl + threadid; + var title = this.items[buttonid].title; + if (title.length > 30) { + title = title.substring(0, 30) + "..."; + } + var threadView = new RssReader(title, url, new ThreadFeedPresenter(null), this.rssreader, threadResponseParser); + threadView.show(); + } + } +} + +// Create and add controls to be shown before items list. +ThreadListFeedPresenter.prototype.addPreambleItems = function(){ + var feedItemControl = new NavigationButton("newThread", "blueright.gif", "Post a new thread"); + var self = this; + feedItemControl.addEventListener("ActionPerformed", function(event) { self.feedClicked(event); }); + this.rssreader.addControl(feedItemControl); +} + +// /////////////////////////////////////////////////////////////////////////// +// List of messages in a thread + +// response parser for thread list +function threadResponseParser(broker, responseStatus, xmlDoc) { + if (responseStatus == 200 && xmlDoc != null) { + // node ref for iterating + var node; + + // for compatibility with rss + var lastModified = new Date(); + + // init result items array + var items = []; + + // iterate over message elements + var elements = xmlDoc.getElementsByTagName("message"); + for (var i = 0; i < elements.length; i++) { + var postid; + var threadid; + var username; + var title; + var dateline; + var pagetext; + var isdeleted; + + // extract info about the post + node = elements[i].firstChild; + while (node != null) { + if ( node.nodeName == "postid" ) postid=getTextOfNode(node); + else if ( node.nodeName == "threadid" ) threadid=getTextOfNode(node); + else if ( node.nodeName == "username" ) username=getTextOfNode(node); + else if ( node.nodeName == "title" ) title=getTextOfNode(node); + else if ( node.nodeName == "dateline" ) dateline=getTextOfNode(node); + else if ( node.nodeName == "pagetext" ) pagetext=getTextOfNode(node); + else if ( node.nodeName == "isdeleted" ) isdeleted=getTextOfNode(node); + node = node.nextSibling; + } + if ( isdeleted == 1 ) continue; + + items.push({ + postid: postid, + threadid: threadid, + username: username, + title: title, + dateline: dateline, + pagetext: pagetext + }); + } + + // update was completed successfully + return { status: "ok", lastModified: lastModified, items: items }; + } else { + // update failed + return { status: "error" }; + } +} + +// FeedPresenter implementation for forum groups +function ThreadFeedPresenter(rssreader){ + if (rssreader) { + this.init(rssreader); + } +} + +// ThreadFeedPresenter is a subclass of HtmlFeedPresenter +ThreadFeedPresenter.prototype = new HtmlFeedPresenter(null); + +// ThreadFeedPresenter constructor +ThreadFeedPresenter.prototype.init = function(rssreader) { + HtmlFeedPresenter.prototype.init.call(this, rssreader); +} + + +// Handle the click on a specific item +ThreadFeedPresenter.prototype.feedClicked = function(event){ + // do nothing +} + +// Create a control that represents this item and add it to +// parent rss reader +ThreadFeedPresenter.prototype.show = function(item) { + // get a feed item control from the pool or create one and + // place it in the pool if there aren't enough feed item controls + var feedItemControl = new ContentPanel(null, null, null, true); + + // initialize feed item control + var title = item.title; + if ( title.length == 0 ) { + title = "Re:"; + item.title = title; + } + feedItemControl.setCaption(bbcode2html(title)); + feedItemControl.setContent(this.getContentHTMLForFeedItem(item)); + feedItemControl.setExpanded(true); + + // add the feed item control to the main view + this.rssreader.feedItemControls.push(feedItemControl); + this.rssreader.addControl(feedItemControl); +} + +// Generate HTML content from the feed item +ThreadFeedPresenter.prototype.getContentHTMLForFeedItem = function (item){ + var buf = ""; + + // item date + if (item.dateline != null) { + var date = new Date(); + date.setTime(item.dateline*1000); + buf += "