X-Git-Url: http://git.bytex64.net/?a=blobdiff_plain;f=www%2Fjs%2Fblerg.js;h=fac5371b391d381553a849bf3111b27783b53555;hb=a579fec94d5058776ea0fb6f47f922ea48ff876f;hp=944f112634cbe70f12e81cce6e824ca0d53cc75c;hpb=3f2f34bd763a1f3e1da52a0ca0e66ca4daacc1ca;p=blerg.git diff --git a/www/js/blerg.js b/www/js/blerg.js index 944f112..fac5371 100644 --- a/www/js/blerg.js +++ b/www/js/blerg.js @@ -5,13 +5,13 @@ // Config var baseURL = ''; var recordTemplate = new Template( - '
#{data}
Posted #{date}. [permalink]
' + '
#{data}
Posted #{date}. [permalink] [reply]
' ); var tagRecordTemplate = new Template( - '
#{data}
Posted by @#{author} on #{date}. [permalink]
' + '
#{data}
Posted by @#{author} on #{date}. [permalink] [reply]
' ); var latestRecordsTemplate = new Template( - '
@#{author} #{data}
' + '
@#{author} #{data}
' ); // Page elements @@ -31,6 +31,8 @@ function LoginStatus() { if (cookies.auth && cookies.username) { this.loggedIn = true; this.username = cookies.username; + this.requestFeedStatus(); + this.feedStatusUpdateInterval = setInterval(this.requestFeedStatus.bind(this), 900000); } else { this.loggedIn = false; this.username = null; @@ -51,6 +53,8 @@ LoginStatus.prototype.login = function(username, password) { this.username = username; document.cookie = "username=" + username; $('login.password').value = ''; + this.requestFeedStatus(); + this.feedStatusUpdateInterval = setInterval(this.requestFeedStatus.bind(this), 900000); this.update(); } else { alert("Could not log in"); @@ -69,10 +73,11 @@ LoginStatus.prototype.logout = function() { parameters: { username: this.username }, - onSuccess: function(r) { + onComplete: function(r) { this.loggedIn = false; document.cookie = "auth=; expires=1-Jan-1970 00:00:00 GMT"; this.update(); + clearInterval(this.feedStatusUpdateInterval); }.bind(this) }); document.cookie = "username=; expires=1-Jan-1970 00:00:00 GMT"; @@ -80,9 +85,9 @@ LoginStatus.prototype.logout = function() { LoginStatus.prototype.update = function() { if (this.loggedIn) { - $('userlink').href = '/#' + this.username; + $('userlink').href = baseURL + '/#' + this.username; $('userlink').update('@' + this.username); - $('reflink').href = '/#/ref/' + this.username; + $('reflink').href = baseURL + '/#/ref/' + this.username; $('login').hide(); $('logout').show(); } else { @@ -123,17 +128,42 @@ LoginStatus.prototype.post = function(msg) { }); } +LoginStatus.prototype.requestFeedStatus = function() { + new Ajax.Request('/feedinfo', { + parameters: { username: this.username }, + onSuccess: function(r) { + var j = r.responseText.evalJSON(); + if (j['new'] > 0) { + $('newFeedMessages').update('(' + j['new'] + ' new)'); + } else { + $('newFeedMessages').update(''); + } + } + }); +} // Base object for paged data function Pager() { this.itemsPerPage = 10; -} - -Pager.prototype.initPager = function() { this.itemCache = new Hash(); this.pageStart = null; } +Pager.prototype.updateState = function(m) { + return false; +} + +Pager.prototype.show = function() { + items.show(); +} + +Pager.prototype.hide = function() { + items.hide(); + items.update(); + $('newer_link').hide(); + $('older_link').hide(); +} + Pager.prototype.olderPage = function() { if (this.pageStart >= this.itemsPerPage) { qlink(this.baseFrag + '/p' + (this.pageStart - this.itemsPerPage)); @@ -168,14 +198,14 @@ Pager.prototype.displayItems = function() { } if (this.pageStart < this.itemCount - 1) { - $('newer_link').href = '/#' + this.baseFrag + '/p' + (this.pageStart + this.itemsPerPage); + $('newer_link').href = baseURL + '/#' + this.baseFrag + '/p' + (this.pageStart + this.itemsPerPage); $('newer_link').show(); } else { $('newer_link').hide(); } if (this.pageStart >= 10) { - $('older_link').href = '/#' + this.baseFrag + '/p' + (this.pageStart - this.itemsPerPage); + $('older_link').href = baseURL + '/#' + this.baseFrag + '/p' + (this.pageStart - this.itemsPerPage); $('older_link').show(); } else { $('older_link').hide(); @@ -211,220 +241,34 @@ Pager.prototype.showRecord = function(r) { Pager.prototype.loadItems = function(from, to, continuation) { } - -// Object to render user pages -function User(username) { - this.initPager(); - this.username = username; - this.baseFrag = username; -} -User.prototype = new Pager(); -User.prototype.constructor = User; - -User.prototype.show = function() { - $$('[name=section]').each(function(v) { v.update(' @' + this.username) }.bind(this)); - $('welcome').hide(); - items.show(); - $('rss').show(); - $('rsslink').href = '/rss/' + this.username; - $$('[name=user.reflink]').each(function(e) { - e.href = '/#/ref/' + this.username; - }.bind(this)); - $('usercontrols').show(); -} - -User.prototype.reload = function() { - this.pageStart = null; - - $$('[name=user.subscribelink]').each(Element.hide); - $$('[name=user.unsubscribelink]').each(Element.hide); - - if (loginStatus.loggedIn) { - new Ajax.Request(baseURL + '/feedinfo/' + this.username, { - method: 'post', - parameters: { - username: loginStatus.username - }, - onSuccess: function(r) { - var json = r.responseText.evalJSON(); - if (json.subscribed) { - $$('[name=user.subscribelink]').each(Element.hide); - $$('[name=user.unsubscribelink]').each(Element.show); - } else { - $$('[name=user.subscribelink]').each(Element.show); - $$('[name=user.unsubscribelink]').each(Element.hide); - } - } - }); - } - - new Ajax.Request(baseURL + '/info/' + this.username, { - method: 'get', - onSuccess: function(r) { - var j = r.responseText.evalJSON(); - if (j) { - this.itemCount = parseInt(j.record_count); - if (!this.pageStart) - this.showPageAt(this.itemCount - 1); - } - }.bind(this) - }); -} - -User.prototype.loadItems = function(from, to, continuation) { - var url; - if (from != undefined && to != undefined) { - url = baseURL + '/get/' + this.username + '/' + from + '-' + to; - this.pageStart = to; - } else { - url = baseURL + '/get/' + this.username; - } - - new Ajax.Request(url, { - method: 'get', - onSuccess: function(r) { - var records = r.responseText.evalJSON(); - if (records && records.length > 0) { - records.each(function(v) { - v.id = v.record; - v.author = this.username; - mangleRecord(v, recordTemplate); - }.bind(this)); - this.addItems(records); - if (!this.pageStart) - this.pageStart = records[0].recInt; - } - continuation(); - }.bind(this), - onFailure: function(r) { - this.displayItems(); - }.bind(this), - on404: function(r) { - displayError('User not found'); - } - }); -} - -function mangleRecord(record, template) { - record.recInt = parseInt(record.record); - - var lines = record.data.split(/\r?\n/); - if (lines[lines.length - 1] == '') - lines.pop(); - - var out = ['

']; - var endpush = null; - var listMode = false; - lines.each(function(l) { - if (l == '') { - if (out[out.length - 1] == '
') { - out[out.length - 1] = '

'; - } - if (out[out.length - 1] == '') { - out.push(''); - out.push('

'); - listMode = false; - } - return; - } - - // Put quoted material into a special paragraph - if (l[0] == '>') { - var pi = out.lastIndexOf('

'); - if (pi != -1) { - out[pi] = '

'; - l = l.replace(/^>\s*/, ''); - } - } - - // Sanitize HTML input - l = l.replace(/&/g, '&').replace(//g, '>'); - - // Turn HTTP URLs into links - l = l.replace(/(\s|^)(https?:\/\/[a-zA-Z0-9.-]*[a-zA-Z0-9](\/([^\s"]*[^.!,;?()\s])?)?)/g, '$1$2'); - - // Turn markdown links into links - l = l.replace(/(\s|^)\[([^\]]+)\]\((https?:\/\/[a-zA-Z0-9.-]*[a-zA-Z0-9](\/[^)"]*?)?)\)/g, '$1$2'); - - // Turn *foo* into italics and **foo** into bold - l = l.replace(/([^\w\\]|^)\*\*(\w[^*]*)\*\*(\W|$)/g, '$1$2$3'); - l = l.replace(/([^\w\\]|^)\*(\w[^*]*)\*(\W|$)/g, '$1$2$3'); - - // Turn refs and tags into links - l = l.replace(/(\s|^)#([A-Za-z0-9_-]+)/g, '$1#$2'); - l = l.replace(/(\s|^)@([A-Za-z0-9_-]+)/g, '$1@$2'); - - // Create lists when lines begin with * - if (l[0] == '*') { - if (!listMode) { - var pi = out.lastIndexOf('

'); - out[pi] = '

'); - - record.data = out.join(''); - record.date = (new Date(record.timestamp * 1000)).toString(); - record.html = template.evaluate(record); -} - function displayError(msg) { items.innerText = msg; } // Object for browsing tags -function Tag(type, tag) { - this.initPager(); - this.type = type; - this.tag = tag; +function Tag(m) { + Pager.call(this); + this.type = m[1]; + this.tag = m[2]; + this.pageStart = parseInt(m[3]); var url = baseURL + "/tag/"; - switch(type) { + switch(this.type) { case 'tag': //url += '%23'; url += 'H'; // apache is eating the hash, even encoded. Probably a security feature. - this.baseFrag = '/tag/' + tag; + this.baseFrag = '/tag/' + this.tag; break; case 'ref': url += '%40'; - this.baseFrag = '/ref/' + tag; + this.baseFrag = '/ref/' + this.tag; break; default: - alert('Invalid tag type: ' + type); + alert('Invalid tag type: ' + this.type); return; } - url += tag; + url += this.tag; new Ajax.Request(url, { method: 'get', @@ -437,7 +281,8 @@ function Tag(type, tag) { mangleRecord(v, tagRecordTemplate) }); this.addItems(j); - this.pageStart = j.length - 1; + if (!this.pageStart) + this.pageStart = j.length - 1; this.itemCount = j.length; } this.displayItems(); @@ -451,27 +296,33 @@ function Tag(type, tag) { Tag.prototype = new Pager(); Tag.prototype.constructor = Tag; +Tag.prototype.updateState = function(m) { + if (this.type != m[1] || this.tag != m[2]) + return false; + + this.pageStart = parseInt(m[3]) || this.itemCount - 1; + this.displayItems(); + + return true; +} + Tag.prototype.show = function() { + Pager.prototype.show.call(this); + var ctype = {ref: '@', tag: '#'}[this.type]; $$('[name=section]').each(function(v) { v.update(' about ' + ctype + this.tag); }.bind(this)); - $('welcome').hide(); - $('post').hide(); - $('older_link').hide(); - $('newer_link').hide(); - $('rss').hide(); - items.show(); - $('usercontrols').hide(); } // Pager for browsing subscription feeds -function Feed() { - this.initPager(); +function Feed(m) { + Pager.call(this); this.username = loginStatus.username; this.baseFrag = '/feed'; + this.pageStart = parseInt(m[1]); new Ajax.Request(baseURL + '/feed', { method: 'post', @@ -487,8 +338,10 @@ function Feed() { mangleRecord(v, tagRecordTemplate) }); this.addItems(response); - this.pageStart = response.length - 1; + if (!this.pageStart) + this.pageStart = response.length - 1; this.itemCount = response.length; + loginStatus.requestFeedStatus(); } this.displayItems(); }.bind(this), @@ -500,28 +353,31 @@ function Feed() { Feed.prototype = new Pager(); Feed.prototype.constructor = Feed; +Feed.prototype.updateState = function(m) { + this.pageStart = parseInt(m[1]) || this.itemCount - 1; + this.displayItems(); + + return true; +} + Feed.prototype.show = function() { + Pager.prototype.show.call(this); $$('[name=section]').each(function(v) { v.update(' ' + loginStatus.username + "'s spycam"); }.bind(this)); - $('welcome').hide(); - $('post').hide(); - $('older_link').hide(); - $('newer_link').hide(); - $('rss').hide(); - items.show(); - $('usercontrols').hide(); } -function postPopup() { - if (loginStatus.loggedIn) { +function postPopup(initial) { + if (loginStatus.loggedIn || initial) { var post = $('post'); if (post.visible()) { post.hide(); } else { post.show(); - if (currentPager.username && currentPager.username != loginStatus.username && !$('post.content').value) { + if (initial) { + $('post.content').value = initial; + } else if (!$('post.content').value && currentPager.username && currentPager.username != loginStatus.username) { $('post.content').value = '@' + currentPager.username + ': '; } $('post.content').focus(); @@ -552,7 +408,37 @@ function signup() { function signup_cancel() { $('signup').hide(); - hashSwitch(); + urlSwitch(); +} + +function passwd() { + var old_password = $('passwd.old_password').value; + var new_password = $('passwd.new_password').value; + + new Ajax.Request(baseURL + '/passwd', { + parameters: { + username: loginStatus.username, + password: old_password, + new_password: new_password + }, + onSuccess: function(r) { + if (r.responseJSON.status == 'success') { + alert('Password changed'); + passwd_cancel(); + } else { + alert('Password change failed. Your password has NOT been changed.'); + } + }, + onFailure: function(r) { + alert('Password change error'); + } + }); +} + +function passwd_cancel() { + $('passwd').hide(); + $('navigation').show(); + urlSwitch(); } function subscribe() { @@ -599,25 +485,6 @@ function unsubscribe() { }); } -var resizePostContentTimeout = null; -function resizePostContent() { - if (resizePostContentTimeout) - clearTimeout(resizePostContentTimeout); - resizePostContentTimeout = setTimeout(function() { - var c = $('post.content'); - var lines = Math.floor(c.value.length / (100 * (c.clientWidth / 1000))) + 1; - var m = c.value.match(/\r?\n/g); - if (m) - lines += m.length; - if (lines <= 3) { - c.style.height = ""; - } else { - c.style.height = (lines * 17) + "pt"; - } - resizePostContentTimeout = null; - }, 150); -} - var tickerTimer = null; var tickerHead, tickerTail; @@ -668,12 +535,13 @@ function stopTicker() { function loadLatest() { new Ajax.Request(baseURL + '/latest.json', { + method: 'GET', onSuccess: function(r) { var j = r.responseText.evalJSON(); $('latest-tags').update(); j.tags.each(function(v) { - var a = new Element('a', {href: '/#/tag/' + v}); + var a = new Element('a', {href: baseURL + '/#/tag/' + v}); a.insert('#' + v); a.onclick = "return qlink()"; a.className = 'ref'; @@ -693,104 +561,12 @@ function loadLatest() { }); } -function qlink(loc) { - if (loc) { - location.hash = loc; - } else if (event && event.target) { - location.href = event.target.href; - } else { - // Bogus qlink - return; - } - hashSwitch(); - return false; +function ExternalURLPost(m) { + this.title = decodeURIComponent(m[1]).replace(']','').replace('[',''); + this.url = decodeURIComponent(m[2]); } -function hashSwitch() { - var m; - stopTicker(); - if (m = location.search.match(/^\?post\/([^/]+)\/(.+)/)) { - $('post').show(); - $('post.content').value = '[' + decodeURIComponent(m[1]).replace(']','').replace('[','') + '](' + decodeURIComponent(m[2]) + ')'; - } else if (m = location.hash.match(/^#\/(ref|tag)\/([A-Za-z0-9_-]+)(?:\/p(\d+))?$/)) { - if (!currentPager || !(currentPager instanceof Tag) || currentPager.type != m[1] || currentPager.tag != m[2]) - currentPager = new Tag(m[1], m[2]); - currentPager.show(); - - if (m[3]) { - var r = parseInt(m[3]); - currentPager.showPageAt(r); - } else { - currentPager.showPageAt(currentPager.itemCount - 1); - } - } else if (m = location.hash.match(/^#\/feed(?:\/p(\d+))?$/)) { - if (loginStatus.loggedIn) { - if (!currentPager || !(currentPager instanceof Feed) || currentPager.username != loginStatus.username) - currentPager = new Feed(); - currentPager.show(); - if (m[3]) { - var r = parseInt(m[3]); - currentPager.showPageAt(r); - } else { - currentPager.showPageAt(currentPager.itemCount - 1); - } - } else { - location.href = baseURL; - } - } else if (m = location.hash.match(/^#([A-Za-z0-9_-]+)(?:\/(p)?(\d+))?$/)) { - if (!currentPager || !(currentPager instanceof User) || currentPager.username != m[1]) - currentPager = new User(m[1]); - currentPager.show(); - loginStatus.update(); - - if (m[3]) { - var r = parseInt(m[3]); - if (m[2] == 'p') { - currentPager.showPageAt(r); - } else { - currentPager.showRecord(r); - } - } else { - currentPager.reload(); - } - } else { - $$('[name=section]').each(function(v) { v.update('Welcome') }); - $('signup').hide(); - items.update(); - items.hide(); - $('newer_link').hide(); - $('older_link').hide(); - $('welcome').show(); - $('rss').hide(); - $('usercontrols').hide(); - loadLatest(); - } -} - -var lastHash; -function hashCheck() { - if (location.hash != lastHash) { - lastHash = location.hash; - hashSwitch(); - } -} - -function init() { - items = $('items'); - loginStatus = new LoginStatus(); - - lastHash = location.hash; - hashSwitch(); - - setInterval(hashCheck, 250); - - document.body.observe('keyup', function(event) { - if (event.shiftKey && event.keyCode == 32) { - postPopup(); - event.stop(); - } - }); - $('post.content').addEventListener('keyup', function(event) { - event.stopPropagation(); - }, true); +ExternalURLPost.prototype.show = function() { + $('post.content').value = '[' + this.title + '](' + this.url + ')'; + $('post').show(); }