From 899c0d49d2d9b37d0cc688195cdbb98ad2b5b877 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Fri, 17 Jun 2016 10:42:20 -0400 Subject: [PATCH 01/25] update scripts 1 --- www/script/api-people.js.php | 191 +++++ www/script/api-river.js.php | 1371 +++++++++++++++++++++++++++++++ www/script/api-search.js.php | 68 ++ www/script/api-subscribe.js.php | 181 ++++ 4 files changed, 1811 insertions(+) create mode 100644 www/script/api-people.js.php create mode 100644 www/script/api-river.js.php create mode 100644 www/script/api-search.js.php create mode 100644 www/script/api-subscribe.js.php diff --git a/www/script/api-people.js.php b/www/script/api-people.js.php new file mode 100644 index 00000000..ddeb3852 --- /dev/null +++ b/www/script/api-people.js.php @@ -0,0 +1,191 @@ +//----------------------------------------------------------------------------------- +// ----- People API ----- +freedomController.v1.people = {}; + + +//Settings -------------------------------------------------------------------------- +freedomController.v1.people.static = (function () { + return { + mdlSocialOutlineView: "#mdlSocialOutlineView" + }; +}()); + + +//Methods --------------------------------------------------------------------------- +freedomController.v1.people.methods = (function () { + var static = freedomController.v1.people.static; + +//After a people search, we query the server for a list of servers it knows about and send search queries +//to each one. We attach the results of each search to the bottom of the results box. The results returned +//are in jsonp format to avoid CORS + function _searchPostLoad(query, elParent) { + //If this is a people search, then + //Get a list of the other servers we know about and ping each of them as well + $(elParent + ' .body .search-pre').append("Local"); + $.ajax({ + url: "/cgi/out/list.servers", + type: "GET", + dataType: 'json', + timeout: 10000, + success: function (data) { + if (data.status != "false") { + //Loop through the server list and call each one + $.each(data.servers, function (k, v) { + if (v.address !== systemUrl) { + (function () { + var lpUrl = "http://" + v.address + "/cgi/out/list.people?q=" + encodeURI(query) + "&callback=?"; + var serverclass = "server" + k; + + $(elParent).append('
' + v.address + '
'); + $.ajax({ + url: lpUrl, + dataType: "jsonp", + timeout: 10000, + success: function (data) { + if (data.status == "false") { + $(elParent + ' .' + serverclass).append('

Server:' + v.address + '

'); + $(elParent + ' .' + serverclass).append('

Private.

'); + } else if (data.data.length < 1) { + $(elParent + ' .' + serverclass).append('

Server:' + v.address + '

'); + $(elParent + ' .' + serverclass).append('

No matches.

'); + } else { + $(elParent + ' .' + serverclass).empty(); + $('#search-people').tmpl(data).appendTo(elParent + ' .' + serverclass); + $(elParent + ' .' + serverclass + ' .search-pre').append('Server:' + v.address); + } + $(elParent + ' .' + serverclass).addClass('search-remote-results').addClass('search-extra').addClass('search-more'); + $(elParent + ' .' + serverclass + ' .search-server-spinner').remove(); + _rebindEverything(elParent); + }, + error: function () { + $(elParent + ' .' + serverclass).empty(); + $(elParent + ' .' + serverclass).append('

Server:' + v.address + '

'); + $(elParent + ' .' + serverclass).append('

Connection error.

'); + } + }); + })(); + } + }); + } + } + }); + + _rebindEverything(elParent); + } + + function _rebindEverything(elParent) { + _bindSubscribeLinks(elParent); + _bindSocialOutlineLinks(elParent); + } + + function _bindSubscribeLinks(elParent) { + //Bind some new clicks to the subscription links + $(elParent + ' .aSubscribe').unbind('click'); + $(elParent + ' .aSubscribe').click(function () { + var bobj = $(this); + var sourceurl = bobj.attr("data-sourceurl"); + + //Make the call + $.ajax({ + url: '/cgi/in/subscribe?url=' + sourceurl, + type: "GET", + timeout: 20000, + dataType: 'json', + success: function (data) { + if (data.status == "false") { + showMessage(data.description, data.status, 5); + } else { + $(static.mdlSocialOutlineView).modal('hide'); + showMessage(data.description, data.status, 5); + } + } + }); + + return false; + }); + } + + + function _bindSocialOutlineLinks(elParent) { + //Ajaxify the social outline links + $(elParent + ' .sopmllink').unbind('click'); + $(elParent + ' .sopmllink').click(function () { + var modal = static.mdlSocialOutlineView; + var aobj = $(this); + var href = aobj.attr("data-href"); + var cgiurl = $('#cgiUrls').attr("data-getsopml"); + + $(modal + ' .modal-header').hide(); + $(modal + ' .modal-body .sobody').hide(); + $(modal + ' .modal-footer').hide(); + + $(modal + ' .modal-footer .aSubscribe').attr('data-sourceurl', href); + _bindSubscribeLinks(modal + ' .modal-footer'); + + $(modal + ' .soserver .serverlink').empty(); + $(modal + ' .soname').empty(); + $(modal + ' .soavatar').attr('src', '/images/blank.gif'); + $(modal + ' .sopubfeeds').empty(); + $(modal + ' .spinner').show(); + + modalFullHeight(modal, true); + $(modal).modal('show'); + $.ajax({ + url: cgiurl + '?url=' + href, + type: "GET", + dataType: 'json', + timeout: 30000, + success: function (data) { + $(modal + ' .spinner').hide(); + if (data.status == "false") { + $(modal + ' .sotitle').append(data.title); + $(modal + ' .sobody').append(data.description); + } else { + modalFullHeight(modal, false); + //Set the server link + $(modal + ' .soserver .serverlink').append(data.server); + $(modal + ' .soserver .serverlink').attr('href', 'http://' + data.server); + //Set the name + $(modal + ' .soname').append(data.ownername); + //Set the avatar + if (data.avatarurl == '') { + data.avatarurl = '/images/noavatar.png'; + } + $(modal + ' .soavatar').attr('src', data.avatarurl); + //Display the pub feeds list + for (var i = 0; i < data.feeds.pub.length; i++) { + $(modal + ' .sopubfeeds').append('
  • ' + data.feeds.pub[i].text + '
  • '); + } + //Display some recent activity for this user + $(modal + ' .soactivity').append(''); + + $(modal + ' .sofooter .link').attr('href', data.url); + $(modal + ' .sofooter').show(); + } + $(modal + ' .modal-header').show(); + $(modal + ' .modal-body .sobody').show(); + $(modal + ' .modal-footer').show(); + }, + error: function (x, t, m) { + $(modal + ' .modal-header').show(); + //$(modal + ' .modal-footer').show(); + $(modal + ' .spinner').hide(); + $(modal + ' .sotitle').append(''); + $(modal + ' .sobody').append('

    Error communicating with server. Connection problem?

    '); + } + }); + return false; + }); + } + + +//----------------------------------------------------------------------------------- + + return { + searchPostLoad: _searchPostLoad, + bindSubscribeLinks: _bindSubscribeLinks, + bindSocialOutlineLinks: _bindSocialOutlineLinks + }; + +//----------------------------------------------------------------------------------- +}()); diff --git a/www/script/api-river.js.php b/www/script/api-river.js.php new file mode 100644 index 00000000..581382b3 --- /dev/null +++ b/www/script/api-river.js.php @@ -0,0 +1,1371 @@ + + + +//----------------------------------------------------------------------------------- +// ----- River API ----- +freedomController.v1.river = {}; +freedomController.v1.river.statics = { + riverJsonUrl: "/river-json", + pathToStreamItem: "#stream .stream-list .article", + pathToActiveItem: "#stream .stream-list .article.activeItem", + pathToStreamList: "#stream .stream-list", + lsRiverDataKey: "riverdata", + lsRiverDataPullTime: "riverpulltime", + lsStickyDataKey: "stickydata", + lsSessionIdKey: "sessionid" +}; + +freedomController.v1.river.methods = (function () { +//----------------------------------------------------------------------------------- + + + //----- River globals ----- + var riverJsonUrl = freedomController.v1.river.statics.riverJsonUrl; + var pathToStreamItem = freedomController.v1.river.statics.pathToStreamItem; + var pathToActiveItem = freedomController.v1.river.statics.pathToActiveItem; + var pathToStreamList = freedomController.v1.river.statics.pathToStreamList; + var lsRiverDataKey = freedomController.v1.river.statics.lsRiverDataKey; + var lsRiverDataPullTime = freedomController.v1.river.statics.lsRiverDataPullTime; + var lsStickyDataKey = freedomController.v1.river.statics.lsStickyDataKey; + var lsSessionIdKey = freedomController.v1.river.statics.lsSessionIdKey; + + + //----- River functions ----- + function _searchPostLoad() { + return _rebindEverything(); + } + + + function _removeSessionData() { + sessionStorage.removeItem(lsStickyDataKey); + sessionStorage.removeItem(lsRiverDataKey); + sessionStorage.removeItem(lsRiverDataPullTime); + sessionStorage.removeItem(lsSessionIdKey); + + return true; + } + + + function _rebindEverything(elid) { + var _elid = (typeof elid === "undefined") ? "" : elid; + + //Bind microblog links + _bindMicroblogLinks(_elid); + + //Bind cartulize links + _bindCartLinks(_elid); + + //Bind sticky links + _bindStickyLinks(_elid); + + //Bind enclosure links + _bindEnclosureLinks(_elid); + + //Bind embed activation links + _bindEmbedActivations(_elid); + + //Bind sopml profile links + freedomController.v1.people.methods.bindSocialOutlineLinks(_elid); + + return false; + } + + + function _showOnlyItems(klass, title) { + var streamObj = $('#stream'); + var activeFeedsObj = $('#divActiveFeeds'); + + //console.log('hiding all but klass: ' + klass); + + _showAllItems(); + $(pathToStreamItem).not('.' + klass).hide(); + streamObj.prepend('
    Currently showing only items from ' + title + '.Show all
    '); + streamObj.addClass('filtered'); + streamObj.find('div.filternotice a.removefilter').click(function () { + _showAllItems(); + return false; + }); + activeFeedsObj.find('ul.feedlist li.' + klass).addClass('hilite'); + $('html, body').animate({scrollTop: '0px'}, 300); + } + + + function _showAllItems() { + var streamObj = $('#stream'); + var activeFeedsObj = $('#divActiveFeeds'); + + streamObj.find(' div.filternotice').remove(); + streamObj.removeClass('filtered'); + activeFeedsObj.find('ul.feedlist li').removeClass('hilite'); + $(pathToStreamItem).show(); + } + + + function _isAvatar(url) { + if (url.indexOf('gravatar') != -1) { + return true; + } + if (url.indexOf('twimg.com/profile_images') != -1) { + return true; + } + + return false; + } + + + function _getBodyText(html) { + var breakToken = '_______break_______', + lineBreakedHtml = html.replace(//gi, breakToken).replace(/(.*?)<\/p>/gi, breakToken + '$1' + breakToken); + return $('
    ').html(lineBreakedHtml).text().replace(new RegExp(breakToken, 'g'), '\n'); + } + + + function _countEnclosuresOfType(enclosures, typecheck) { + var cnt = 0; + $.each(enclosures, function () { + if (this.type.indexOf(typecheck) != -1) { + cnt++; + } + }); + + return cnt; + } + + + function _isImage(url, type) { + if (type.indexOf('image') != -1) { + return true; + } + if (url.indexOf('.jpg') != -1) { + return true; + } + if (url.indexOf('.jpeg') != -1) { + return true; + } + if (url.indexOf('.png') != -1) { + return true; + } + if (url.indexOf('.gif') != -1) { + return true; + } + + return false; + } + + + function _isAudio(url, type) { + if (type.indexOf('audio') != -1) { + return true; + } + if (url.indexOf('.mp3') != -1) { + return true; + } + if (url.indexOf('.m4a') != -1) { + return true; + } + if (url.indexOf('.wav') != -1) { + return true; + } + if (url.indexOf('.ogg') != -1) { + return true; + } + if (url.indexOf('.wma') != -1) { + return true; + } + + return false; + } + + + function _isVideo(url, type) { + if (type.indexOf('video') != -1) { + return true; + } + if (url.indexOf('.mp4') != -1) { + return true; + } + if (url.indexOf('.m4v') != -1) { + return true; + } + if (url.indexOf('.avi') != -1) { + return true; + } + if (url.indexOf('.mov') != -1) { + return true; + } + if (url.indexOf('.wmv') != -1) { + return true; + } + + return false; + } + + + function _isIframe(url, type) { + if (type.indexOf('text/html') != -1) { + return true; + } + if (type.indexOf('application/pdf') != -1) { + return true; + } + + return false; + } + + + function _getMediaType(type) { + return type.split('/')[0]; + } + + + function _getEnclosureSize(bytes) { + //_____via http://blog.elctech.com/2009/01/06/convert-filesize-bytes-to-readable-string-in-javascript/ + var s, e, t; + s = ['bytes', 'kB', 'MB', 'GB', 'TB']; + e = Math.floor(Math.log(bytes) / Math.log(1024)); + t = (bytes / Math.pow(1024, Math.floor(e))).toFixed(2) + " " + s[e]; + return t; + } + + + function _clearActiveFeeds() { + + $('#divActiveFeeds').find('ul.feedlist').empty(); + + return true; + } + + + function _addActiveFeed(feedId, feedTitle, feedUrl, urlForIcon, type, position) { + if (platform == "mobile") { + return false; + } + var activeFeedsObj = $('#divActiveFeeds'); + + if (activeFeedsObj.find('ul.feedlist li.' + feedId).length < 1) { + var feedImg = '/images/blank.gif'; + + if (type == 'person') { + feedImg = urlForIcon; + imgClass = 'avatar48'; + } else { + feedImg = _getFavicon(urlForIcon); + imgClass = 'favicon'; + } + + if (position == 'top') { + activeFeedsObj.find('ul.feedlist').prepend('
  • ' + feedTitle + '
  • '); + } else { + activeFeedsObj.find('ul.feedlist').append('
  • ' + feedTitle + '
  • '); + } + + activeFeedsObj.find('ul.feedlist li.' + feedId).unbind('click'); + activeFeedsObj.find('ul.feedlist li.' + feedId).click(function () { + _showOnlyItems(feedId, feedTitle); + return false; + }); + } + + return false; + } + + + function _getDomain(url) { + var domain; + if (( url !== null ) && ( url !== "" )) { + domain = url.split('?')[0]; // cleans urls of form http://domain.com?a=1&b=2 + domain = domain.split('/')[2]; + if (typeof(domain) != "undefined") { + domain = domain.replace("www.", "").replace("www2.", "").replace("feedproxy.", "").replace("feeds.", ""); + } else { + return null; + } + } + return domain; + } + + + function _getFavicon(url) { + return '//www.google.com/s2/favicons?domain=' + _getDomain(url); + } + + + function _focusFirstVisibleArticle() { + $(pathToStreamItem).each(function () { + console.log($(document).scrollTop() + " : " + $(this).offset().top); + if ($(document).scrollTop() < $(this).offset().top) { + $(pathToStreamItem + '.activeItem').removeClass("activeItem"); + $(this).addClass("activeItem"); + return false; + } + }); + return false; + } + + + function _focusThisArticle(elid) { + //Put focus on an article by post id reference + $(pathToStreamItem + '.activeItem').removeClass("activeItem"); + $(pathToStreamItem + '#' + elid).addClass("activeItem"); + console.log("_focusThisArticle(" + elid + ")"); + $('html, body').animate({scrollTop: $(pathToStreamItem + '#' + elid).offset().top - gPlatformMenubarTopOffset}, 300); + return false; + } + + + function _focusThisArticleFooter(elid) { + //Put focus on an article by post id, but scroll to it's footer + $(pathToStreamItem + '.activeItem').removeClass("activeItem"); + $(pathToStreamItem + '#' + elid).addClass("activeItem"); + $('html, body').animate({scrollTop: $(pathToStreamItem + '#' + elid + ' .footer').offset().top - gPlatformMenubarTopOffset - 50}, 300); + return false; + } + + + function _focusPreviousArticle() { + if ($(pathToStreamItem + ".activeItem").length > 0) { + // get top positions and references to all articles + var pos = $(pathToStreamItem).map(function () { + var $this = $(this); + if ($this.offset().top < $(pathToStreamItem + ".activeItem").offset().top) { + return { + pid: $this.attr("id"), + top: $this.offset().top + }; + } + }).get(); + pos.sort(function (a, b) { + return parseInt(b.top, 10) - parseInt(a.top, 10); + }); + $(pathToStreamItem + ".activeItem").removeClass("activeItem"); + $(pathToStreamItem + '#' + pos[0].pid).addClass("activeItem"); + $('html, body').animate({scrollTop: ($(pathToStreamItem + ".activeItem").offset().top - gPlatformMenubarTopOffset)}, 300); + return false; + } + + //If not, we target first visible + 1 + $(pathToStreamItem).each(function (index) { + if ($(document).scrollTop() < $(this).offset().top) { + $('html, body').animate({scrollTop: ($(pathToStreamItem + ":eq(" + (index - 1) + ")").offset().top - gPlatformMenubarTopOffset)}, 300); + $(pathToStreamItem + ".activeItem").removeClass("activeItem"); + $(pathToStreamItem + ":eq(" + (index - 1) + ")").addClass("activeItem"); + return false; + } + return false; + }); + return false; + } + + + function _targetNextArticle() { + console.log('targetNextArticle'); + return _focusNextArticle(true); + } + + + function _focusNextArticle(noscroll) { + var _noscroll = (typeof noscroll === "undefined") ? false : noscroll; + + if ($(pathToStreamItem + ".activeItem").length > 0) { + // get top positions and references to all articles + var pos = $(pathToStreamItem).map(function () { + var $this = $(this); + if ($this.offset().top > $(pathToStreamItem + ".activeItem").offset().top) { + return { + pid: $this.attr("id"), + top: $this.offset().top + }; + } + }).get(); + pos.sort(function (a, b) { + return parseInt(a.top, 10) - parseInt(b.top, 10); + }); + $(pathToStreamItem + ".activeItem").removeClass("activeItem"); + $(pathToStreamItem + '#' + pos[0].pid).addClass("activeItem"); + if (_noscroll === false) { + $('html, body').animate({scrollTop: ($(pathToStreamItem + ".activeItem").offset().top - gPlatformMenubarTopOffset)}, 300); + } + return false; + } + + //If not, we target first visible + 1 + $(pathToStreamItem).each(function (index) { + if ($(document).scrollTop() < $(this).offset().top) { + if (_noscroll === false) { + $('html, body').animate({scrollTop: ($(pathToStreamItem + ":eq(" + (index + 1) + ")").offset().top - gPlatformMenubarTopOffset)}, 300); + } + $(pathToStreamItem + ".activeItem").removeClass("activeItem"); + $(pathToStreamItem + ":eq(" + (index + 1) + ")").addClass("activeItem"); + return false; + } + }); + return false; + } + + + function _focusPreviousFeed() { + if ($(pathToStreamItem + ".activeItem").length > 0) { + // get top positions and references to all articles + var pos = $(pathToStreamItem).map(function () { + var $this = $(this); + if (($this.offset().top < $(pathToStreamItem + ".activeItem").offset().top) && ($this.attr('data-feedid') != $(pathToStreamItem + ".activeItem").attr('data-feedid'))) { + return { + pid: $this.attr("id"), + top: $this.offset().top + }; + } + }).get(); + pos.sort(function (a, b) { + return parseInt(b.top, 10) - parseInt(a.top, 10); + }); + $(pathToStreamItem + ".activeItem").removeClass("activeItem"); + $(pathToStreamItem + '#' + pos[0].pid).addClass("activeItem"); + $('html, body').animate({scrollTop: ($(pathToStreamItem + ".activeItem").offset().top - gPlatformMenubarTopOffset)}, 300); + + } else { + + //If not, we target first visible + 1 + $(pathToStreamItem).each(function (index) { + if ($(document).scrollTop() < $(this).offset().top) { + $('html, body').animate({scrollTop: ($(pathToStreamItem + ":eq(" + (index + 1) + ")").offset().top - gPlatformMenubarTopOffset)}, 300); + $(pathToStreamItem + ".activeItem").removeClass("activeItem"); + $(pathToStreamItem + ":eq(" + (index + 1) + ")").addClass("activeItem"); + } + }); + } + + return false; + } + + + function _focusNextFeed() { + if ($(pathToStreamItem + ".activeItem").length > 0) { + // get top positions and references to all articles + var pos = $(pathToStreamItem).map(function () { + var $this = $(this); + if (($this.offset().top > $(pathToStreamItem + ".activeItem").offset().top) && ($this.attr('data-feedid') != $(pathToStreamItem + ".activeItem").attr('data-feedid'))) { + return { + pid: $this.attr("id"), + top: $this.offset().top + }; + } + }).get(); + pos.sort(function (a, b) { + return parseInt(a.top, 10) - parseInt(b.top, 10); + }); + $(pathToStreamItem + ".activeItem").removeClass("activeItem"); + $(pathToStreamItem + '#' + pos[0].pid).addClass("activeItem"); + $('html, body').animate({scrollTop: ($(pathToStreamItem + ".activeItem").offset().top - gPlatformMenubarTopOffset)}, 300); + + } else { + + //If not, we target first visible + 1 + $(pathToStreamItem).each(function (index) { + if ($(document).scrollTop() < $(this).offset().top) { + $('html, body').animate({scrollTop: ($(pathToStreamItem + ":eq(" + (index + 1) + ")").offset().top - gPlatformMenubarTopOffset)}, 300); + $(pathToStreamItem + ".activeItem").removeClass("activeItem"); + $(pathToStreamItem + ":eq(" + (index + 1) + ")").addClass("activeItem"); + } + }); + } + + return false; + } + + + function _bindMicroblogLinks(elid) { + var elid = (typeof elid === "undefined") ? "" : elid; + + $(elid + ' .mblink').unbind('click'); + $(elid + ' .mblink').click(function () { + var aobj = $(this); + var postId = aobj.attr("data-id"); + var pathToPost = '#stream .stream-list .article#' + postId; + var pathToBlog = '#stream .stream-list .article#' + postId + ' .footer .mbinline'; + var pathToForm = '#stream .stream-list .article#' + postId + ' .footer .mbinline .mbinform'; + console.log('pathToPost:' + pathToPost); + + //Don't allow more than one attempt at reblogging + if ($(pathToBlog).length > 0) { + _focusThisArticleFooter(postId); + return false; + } + + //Tag a class on the end of the footer so we can hook re-blog mode + $(pathToPost + ' .footer').removeClass('mbposted').addClass('mbmode'); + + //Build a form from the post attributes + var postUrl = $(pathToPost).attr("data-url"); + var postDescription = $(pathToPost + ' .header h3').text(); + var postSourceUrl = $(pathToPost).attr("data-sourceurl"); + var postSourceTitle = $(pathToPost).attr("data-sourcetitle"); + var postOrigin = $(pathToPost).attr("data-origin"); + + //Create a little re-blog window in the footer of the post with a form in it + $(pathToPost + ' .footer').append('
    '); + + //Add a please wait element + $(pathToPost + ' .footer').append('
    Posting. Please wait...
    '); + + //Build out the form + //Description + $(pathToForm).append(''); + $(pathToForm).append(''); + $(pathToForm).append(''); + $(pathToForm).append(''); + $(pathToForm).append(''); + + //Add enclosures to the form + var encount = 0; + //Add a div with a list for holding external enclosures + $(pathToForm).append('
      '); + $(pathToPost + ' .enclosureview .encobj').each(function () { + //Add a list element for each enclosure + $(pathToForm + ' .mbextenc ul').append('
    • '); + + //Add a delete button for each enclosure + $(pathToForm + ' .mbextenc ul li:eq(' + encount + ')').append(''); + + //Now add the enclosure thumbnail + if ($(this).hasClass('enclosurepic')) { + $(pathToForm + ' .mbextenc ul li:eq(' + encount + ')').append(''); + } else if ($(this).hasClass('encaudio')) { + $(pathToForm + ' .mbextenc ul li:eq(' + encount + ')').append(''); + } else if ($(this).hasClass('encvideo')) { + $(pathToForm + ' .mbextenc ul li:eq(' + encount + ')').append(''); + } else if ($(this).hasClass('enciframe')) { + $(pathToForm + ' .mbextenc ul li:eq(' + encount + ')').append(''); + } + + //Add the input element to the form + $(pathToForm + ' .mbextenc ul li:eq(' + encount + ')').append(''); + $(pathToForm + ' .mbextenc ul li:eq(' + encount + ')').append(''); + $(pathToForm + ' .mbextenc ul li:eq(' + encount + ')').append(''); + + //Attach click handler for the delete button + $(pathToForm + ' .mbextenc ul li:eq(' + encount + ') a.delete').click(function () { + $(this).parent().remove(); + if ($(pathToForm + ' .mbextenc ul li').length == 0) { + $(pathToForm + ' .mbextenc').hide(); + } + return false; + }); + + //Un-hide the external enclosure form since we have at least one external enclosure + $(pathToForm + ' .mbextenc').show(); + + //Increment the enclosure counter + encount++; + }); + + //Add a twitter toggle if twitter is enabled + if (cuTwitterIsEnabled) { + $(pathToForm).append(''); + $(pathToForm + ' .tweeticon').unbind('click'); + $(pathToForm + ' .tweeticon').bind('click', function () { + if ($(pathToForm + ' .tweetcheck').prop("checked") == false) { + $(pathToForm + ' .tweetcheck').prop("checked", true); + } else { + $(pathToForm + ' .tweetcheck').prop("checked", false); + } + }); + } + + //Submit buttons go in the div and we'll trigger form submission from outside + $(pathToForm).append('Post Cancel'); + + //Attach click handlers to the buttons + $(pathToBlog + ' a.mbsubmit.' + postId).unbind('click'); + $(pathToBlog + ' a.mbsubmit.' + postId).click(function () { + $(pathToForm + '.' + postId).submit(); + return false; + }); + $(pathToBlog + ' a.mbcancel.' + postId).unbind('click'); + $(pathToBlog + ' a.mbcancel.' + postId).click(function () { + $(pathToPost + ' .footer').removeClass('mbmode'); + $(pathToBlog + '.' + postId).remove(); + return false; + }); + + //Ajaxify the form + $(pathToForm + '.' + postId).ajaxForm({ + dataType: 'json', + cache: false, + clearForm: true, + resetForm: true, + timeout: 60000, + beforeSubmit: function () { + $(pathToBlog + '.' + postId).hide(); + $(pathToPost + ' .footer .inlineblogmsg').show(); + }, + success: function (data) { + if (data.status == "false") { + showMessage(data.description, data.status, 5); + $(pathToPost + ' .footer .inlineblogmsg').hide(); + $(pathToBlog + '.' + postId).show(); + } else { + showMessage("Post Successful!", data.status, 5); + $(pathToPost + ' .footer').removeClass('mbmode').addClass('mbposted'); + $(pathToPost + ' .footer .inlineblogmsg').remove(); + $(pathToBlog + '.' + postId).remove(); + + var si = { + id: data.post.id, + avatarUrl: data.post.avatarUrl, + link: data.post.link, + permaLink: data.post.permaLink, + title: data.post.title, + body: data.post.body, + pubDate: data.post.pubDate + } + + $('#template-subitem').tmpl(si).prependTo(pathToPost + ' .subitems'); + _focusThisArticleFooter(postId); + } + }, + error: function (x, t, m) { + showMessage("Error: " + m + "(" + t + ")", false, 60); + $(pathToPost + ' .footer .inlineblogmsg').hide(); + $(pathToBlog + '.' + postId).show(); + } + }); + + //Set focus on this article and scroll to the + //re-blog area + _focusThisArticleFooter(postId); + + //Set focus in description field + $(pathToForm + '.' + postId + ' span textarea.mbdescription').focus(); + + //Set the twitter toggle + $(pathToForm + ' .tweetbox .tweeticon').removeClass('icon-twitter').addClass('icon-notwitter'); + $(pathToForm + ' .tweetbox .tweetcheck').prop('checked', false); + $(pathToForm + ' .tweetbox .tweeticon').bind('click', function () { + $(pathToForm + ' .tweetbox .tweetcheck').prop('checked', !$(pathToForm + ' .tweetbox .tweetcheck').prop('checked')); + $(pathToForm + ' .tweetbox .tweeticon').toggleClass('icon-twitter'); + $(pathToForm + ' .tweetbox .tweeticon').toggleClass('icon-notwitter'); + $(pathToForm + ' .tweetbox .mbdescription').trigger('keyup'); + }); + + return false; + }); + + return true; + } + + + function _bindCartLinks(elid) { + var elid = (typeof elid === "undefined") ? "" : elid; + + $(elid + ' .cartlink').unbind('click'); + $(elid + ' .cartlink').click(function () { + var aobj = $(this); + var postId = aobj.attr("data-id"); + var pathToPost = '#stream .stream-list .article#' + postId; + console.log('pathToPost:' + pathToPost); + + //Don't allow more than one attempt at cartulizing + if ($(pathToPost).hasClass('cartulized')) { + _focusThisArticle(postId); + return false; + } + + //Kill any existing messages + $(pathToPost + ' .description .inlinecartmsg').remove(); + + //Make sure a description exists + if ($(pathToPost + ' .description').length === 0) { + $(pathToPost + ' .header').after('
      '); + } + + //Build a cartulize url from the post attributes + var postUrl = encodeURIComponent($(pathToPost).attr("data-url")); + var postTitle = encodeURIComponent($(pathToPost + ' .header h3').text()); + var postSourceUrl = encodeURIComponent($(pathToPost).attr("data-sourceurl")); + var postSourceTitle = encodeURIComponent($(pathToPost).attr("data-sourcetitle")); + + //Set focus on this article + _focusThisArticle(postId); + + //Make the cartulization call + $(pathToPost + ' .description').append('
      Cartulizing. Please wait...
      '); + $.ajax({ + url: '?json=true' + '&url=' + postUrl + '&title=' + postTitle + '&surl=' + postSourceUrl + '&stitle=' + postSourceTitle, + type: "GET", + dataType: 'json', + timeout: 30000, + success: function (data) { + if (data.status == 'true') { + //Kill wait message + $(pathToPost + ' .description .inlinecartmsg').remove(); + //Save the article id in the post + $(pathToPost).attr('data-articleid', data.article.id); + //Replace the body text with what we got back + if ($(pathToPost + ' .description').length < 1) { + $(pathToPost + ' .header').after('
      '); + } + $(pathToPost + ' .description').html(data.article.body); + $(pathToPost + ' .description a').attr('target', '_blank'); + $(pathToPost + ' .description a').on('press', function () { + //Watch for popup blockers like mobile safari blocking this + var url = '/cgi/in/cartulize?url=' + $(this).attr('href'); + window.open(url); + }); + //Change to a reading-friendly style + $(pathToPost).addClass('cartulized'); + //Set the title based on what came back + $(pathToPost).find('div.header h3 a').empty().html(data.article.title); + //Add an edit button next to the title + $(pathToPost).find('div.header button.changetitle').remove(); + $(pathToPost).find('div.header').prepend(''); + $(pathToPost).find('div.header button.changetitle').on('click', function () { + var newtitle = prompt("Enter new title...", data.article.title); + if (newtitle != null) { + //Make the call + $.ajax({ + url: '/cgi/in/setarticletitle?id=' + data.article.id + '&title=' + newtitle, + type: "GET", + timeout: 20000, + dataType: 'json', + success: function (data) { + if (data.status == "false") { + showMessage(data.description, data.status, 5); + } else { + $(pathToPost).find('div.header h3 a').empty().html(newtitle); + } + } + }); + } + }); + //Change cart link at bottom to an edit article button + $(pathToPost).find('div.footer div.actions a.cartlink img.icon-bookmark').removeClass('icon-bookmark').addClass('icon-editor'); + $(pathToPost).find('div.footer div.actions a.cartlink').removeClass('cartlink').addClass('editlink'); + $(pathToPost).find('div.footer div.actions a.editlink').on('click', function () { + var url = '/editor?aid=' + data.article.id; + window.open(url); + }); + } else { + //Append error message + $(pathToPost + ' .description .inlinecartmsg').html(data.article.body).addClass('carterrormsg'); + } + //Set focus on this article + _focusThisArticle(postId); + }, + error: function (x, t, m) { + //Append error message + $(pathToPost + ' .description .inlinecartmsg').html('

      Error communicating with server. Connection problem?

      ').addClass('carterrormsg'); + //Set focus on this article + _focusThisArticle(postId); + } + }); + return false; + }); + return true; + } + + + function _bindStickyLinks(elid) { + var elid = (typeof elid === "undefined") ? "" : elid; + + //Bind some new clicks to the stickybuttons + $(elid + ' .aUnSticky').unbind('click'); + $(elid + ' .aUnSticky').click(function (e, data) { + var bobj = $(this); + var id = bobj.attr("data-id"); + var fid = bobj.attr("data-feedid"); + console.log("fid: " + fid); + var idx = bobj.attr("data-idx"); + console.log("idx: " + idx); + + //Hide the item first + $('#' + id).hide(); + + //Focus the next sticky article + if (data && (data.source === "swipe" || data.source === "hotkey")) { + var nextId = $('#' + id).next().attr('id'); + _focusThisArticle(nextId); + } + + //Get any sticky subitems so we can un-sticky them too + var subitems = $('#' + id + ' .subitem.sticky').map(function () { + return this.id; + }).get(); + + (function () { + //Make the call + $.ajax({ + url: '/cgi/in/unsticky?id=' + id, + type: "GET", + timeout: 20000, + dataType: 'json', + success: function (data) { + if (data.status == "false") { + showMessage(data.description, data.status, 5); + } + + //If this is the last item from this feed/owner, remove the active feed from the sidebar + console.log('unsticky: ' + fid); + if ($(pathToStreamItem + '.' + fid).length < 1) { + $('#divActiveFeeds').find('ul.feedlist li.' + fid).remove(); + } + + //Remove the item + $('#' + id).removeClass('sticky').addClass('unsticky'); + $('#' + id).remove(); + _removeStickyItemLS(idx); + } + }); + + //Loop through the sticky subitems and un-sticky them as well + for (var i = 0; i < subitems.length; i++) { + //Make the call + $.ajax({ + url: '/cgi/in/unsticky?id=' + subitems[i], + type: "GET", + timeout: 20000, + dataType: 'json', + success: function (data) { + if (data.status == "false") { + showMessage(data.description, data.status, 5); + } + } + }); + } + })(); + + return false; + }); + + return false; + } + + + function _getStreamWidth() { + var viewportWidth = $(window).width(); + var sidebarWidth = $('#stream-sidebar-right').width(); + return ((viewportWidth - sidebarWidth) - 80); + } + + + function _sortGrid(sizeOnly) { + var sizeOnly = (typeof sizeOnly === "undefined") ? false : sizeOnly; + var streamWidth = _getStreamWidth(); + var colcount = _calculateColumnCount(); + var streamWrapObj = $('#stream-wrap'); + var streamObj = $('#stream'); + var streamItemsObj = streamObj.find('#stream-items'); + + //Build the columns + if (sizeOnly == false) { + streamItemsObj.find('.col').remove(); + for (c = 1; c <= colcount; c++) { + streamItemsObj.append('
      '); + } + } + + if ($(window).outerWidth(true) < 900) { + $('.navbar').removeClass('navbar-fixed-top'); + $('#stream').css('max-width', '700px'); + } else { + $('.navbar').addClass('navbar-fixed-top'); + $('#stream').css('max-width', ''); + } + + //Adjust their sizing and layout + if (platform == "mobile" || platform == "tablet") { + return colcount; + } + + //Reset some values + streamItemsObj.find('.col').addClass('span3'); + streamObj.css('margin-left', 'auto'); + streamObj.css('margin-right', 'auto'); + streamObj.find('.stream-list').css('max-width', '600px'); + streamItemsObj.find('.col').css('max-width', '600px'); + streamWrapObj.css('width', streamWidth + 'px'); + + //Size the grid + if (colcount == 1) { + streamObj.css('width', '800px'); + streamObj.find('.stream-list').css('width', '600px'); + streamItemsObj.find('.col').css('width', '600px'); + streamWrapObj.css('width', ''); + } else if (colcount == 2) { + streamObj.css('width', Math.min(1500, (streamWidth * .99).toFixed()) + 'px'); + streamObj.find('.stream-list').css('width', (streamWidth * .47).toFixed() + 'px'); + streamItemsObj.find('.col').css('width', (streamWidth * .47).toFixed() + 'px'); + } else if (colcount == 3) { + streamObj.css('width', Math.min(2000, (streamWidth * .99).toFixed()) + 'px'); + streamObj.find('.stream-list').css('width', (streamWidth * .30).toFixed() + 'px'); + streamItemsObj.find('.col').css('width', (streamWidth * .30).toFixed() + 'px'); + } else if (colcount == 4) { + streamObj.css('width', Math.min(2500, (streamWidth * .99).toFixed()) + 'px'); + streamObj.find('.stream-list').css('width', (streamWidth * .22).toFixed() + 'px'); + streamItemsObj.find('.col').css('width', (streamWidth * .22).toFixed() + 'px'); + } else if (colcount == 5) { + streamObj.css('width', Math.min(3000, (streamWidth * .99).toFixed()) + 'px'); + streamObj.find('.stream-list').css('width', (streamWidth * .17).toFixed() + 'px'); + streamItemsObj.find('.col').css('width', (streamWidth * .17).toFixed() + 'px'); + } else { + streamObj.find('.stream-list').css('width', ''); + } + + return colcount; + } + + + function _resizeGrid() { + console.log('resize grid'); + _changeStreamNotice(' Adjusting layout...'); + return _buildRiver(true); + } + + + function _changeStreamNotice(notice, hide) { + var hide = (typeof hide === "undefined") ? false : hide; + var noticeObj = $('#stream').find('p.notice'); + + noticeObj.html(notice); + if (hide == false) { + noticeObj.show(); + } else { + noticeObj.hide(); + } + + return true; + } + + + function _buildRiver(cached) { + var cached = (typeof cached === "undefined") ? false : cached; + var cols = 1; + + _showAllItems(); + _clearActiveFeeds(); + _changeStreamNotice(' Building river...'); + + //Size columns and build the html structure + cols = _sortGrid(); + + //Get the data and show it + console.log("build river from cache? " + cached); + $.when(_getRiverStickyItems(cached), _getRiverItems(cached)).done(function () { + //Bindings + _rebindEverything(); + + //Focus on first article + _focusFirstVisibleArticle(); + + //Remove loading notice + _changeStreamNotice('', true); + + //Timestamp the data pull in local storage + if (cached == false) { + sessionStorage.setItem(lsRiverDataPullTime, Math.round(new Date().getTime() / 1000)); + } + + //Re-trigger masonry when viewport is resized on desktop browsers + if (platform != "mobile" && platform != "tablet") { + $(window).off('debouncedresize'); + $(window).on('debouncedresize', function (event) { + if ($(pathToStreamList).length != _calculateColumnCount()) { + console.log('reflowing grid'); + freedomController.v1.river.methods.resizeGrid(); + } else { + console.log('no re-flow needed'); + _sortGrid(true); + } + }); + } + + }); + + return true; + } + + + function _populateGridSticky(cols, data) { + var col = 1; + + //Get data out of local storage + var lsdata = sessionStorage.getItem(lsStickyDataKey); + if (lsdata !== null) { + data = JSON.parse(lsdata); + } + + $.each(data.data.items, function (i, item) { + //Add an index + item.index = i; + + if (item.hidden != 1) { + //Add each discovered feed to the active feed sidebar + if (item.feed.linkedOutlineType === 'sopml') { + freedomController.v1.river.methods.addActiveFeed(item.feed.linkedOutlineId, item.feed.ownerName, item.feed.linkedOutlineUrl, item.feed.avatarUrl, "person", 'top'); + } else { + freedomController.v1.river.methods.addActiveFeed(item.feed.feedId, item.feed.feedTitle, item.feed.feedUrl, item.feed.websiteUrl, "feed", 'bottom'); + } + + //Check if the item exists already + if ($(pathToStreamItem + '#' + item.id).length > 0) { + $(pathToStreamItem + '#' + item.id).prependTo('#stream .col' + col + ' .stream-list'); + _makePostSticky(pathToStreamItem + '#' + item.id, item.id, item.index, item.feed.feedId); + + } else { + //Check if the origin exists already + if (item.origin != "" && $(pathToStreamItem + '[data-origin="' + item.origin + '"]').length > 0) { + //Add as sub-item + $('#template-subitem').tmpl(item).appendTo(pathToStreamItem + '[data-origin="' + item.origin + '"]'); + console.log('append subitem to: ' + pathToStreamItem + '#' + item.id); + } else { + //Add as item + $('#template-sticky').tmpl(item).prependTo('#stream .col' + col + ' .stream-list'); + + //Increment column counter + if (col == cols) { + col = 1; + } else { + col++; + } + } + } + + //Add a swipe handler for mobile + if (platform == "mobile") { + (function () { + $(pathToStreamItem + '#' + item.id + ' div.header h3 a').on('press', function () { + $(pathToStreamItem + '#' + item.id + ' .cartlink').trigger('click'); + }); + $(pathToStreamItem + '#' + item.id).on('flick', function (e) { + //A LtoR flick triggers un-sticky call + if (e.orientation === 'horizontal' && e.direction === 1) { + $(pathToStreamItem + '#' + item.id).hide(); + $(pathToStreamItem + '#' + item.id + ' .aUnSticky').trigger('click', {source: "swipe"}); + } + //If article cart'd already, then RtoL flick prompts for title change + if (e.orientation === 'horizontal' && e.direction === -1 && $(pathToStreamItem + '#' + item.id).hasClass('cartulized')) { + var articleid = $(pathToStreamItem + '#' + item.id).data('articleid'); + var newtitle = prompt("Enter new title...", item.title); + if (newtitle != null) { + //Make the call + $.ajax({ + url: '/cgi/in/setarticletitle?id=' + articleid + '&title=' + newtitle, + type: "GET", + timeout: 20000, + dataType: 'json', + success: function (data) { + if (data.status == "false") { + showMessage(data.description, data.status, 5); + } else { + $(pathToStreamItem + '#' + item.id + ' div.header h3 a').empty().append(newtitle); + } + } + }); + } + } + //If article not cart'd already, then RtoL flick carts it + if (e.orientation === 'horizontal' && e.direction === -1 && !$(pathToStreamItem + '#' + item.id).hasClass('cartulized')) { + $(pathToStreamItem + '#' + item.id + ' .cartlink').trigger('click'); + } + }) + })(); + } + } + + }); + + return false; + } + + + function _populateGrid(cols, data) { + var col = 1; + + //Get data out of local storage + var lsdata = sessionStorage.getItem(lsRiverDataKey); + if (lsdata !== null) { + data = JSON.parse(lsdata); + } + + $.each(data.updatedFeeds.updatedFeed, function (f, feed) { + //Add each discovered feed to the active feed sidebar + if (feed.linkedOutlineType === 'sopml') { + freedomController.v1.river.methods.addActiveFeed(feed.linkedOutlineId, feed.ownerName, feed.linkedOutlineUrl, feed.avatarUrl, "person", 'top'); + } else { + freedomController.v1.river.methods.addActiveFeed(feed.feedId, feed.feedTitle, feed.feedUrl, feed.websiteUrl, "feed", 'bottom'); + } + + //----- Post loop ----- + $.each(feed.item, function (i, item) { + //Check if the item exists already + if ($(pathToStreamItem + '#' + item.id).length < 1) { + //Make the feed info available to the item + item.feed = feed; + delete item.feed.item; + + if (item.origin != "" && $(pathToStreamItem + '[data-origin="' + item.origin + '"]').length > 0) { + //Add as sub-item + $('#template-subitem').tmpl(item).appendTo(pathToStreamItem + '[data-origin="' + item.origin + '"]'); + console.log('append subitem to: ' + pathToStreamItem + '#' + item.id); + } else { + //Add as item + $('#template').tmpl(item).appendTo('#stream .col' + col + ' .stream-list'); + + //Increment column counter + if (col == cols) { + col = 1; + } else { + col++; + } + } + + //Make source link into a feed filter trigger + (function () { + $(pathToStreamItem + '#' + item.id + ' .footer .source a.filter').click(function () { + _showOnlyItems(item.feed.feedId, item.feed.feedTitle); + return false; + }); + })(); + } + + //Add a swipe handler for mobile + if (platform == "mobile") { + (function () { + $(pathToStreamItem + '#' + item.id + ' div.header h3 a').on('press', function () { + $(pathToStreamItem + '#' + item.id + ' .cartlink').trigger('click'); + }); + $(pathToStreamItem + '#' + item.id).on('flick', function (e) { + //If article cart'd already, then RtoL flick prompts for title change + if (e.orientation === 'horizontal' && e.direction === -1 && $(pathToStreamItem + '#' + item.id).hasClass('cartulized')) { + var articleid = $(pathToStreamItem).data('articleid'); + var newtitle = prompt("Enter new title...", item.title); + if (newtitle != null) { + //Make the call + $.ajax({ + url: '/cgi/in/setarticletitle?id=' + articleid + '&title=' + newtitle, + type: "GET", + timeout: 20000, + dataType: 'json', + success: function (data) { + if (data.status == "false") { + showMessage(data.description, data.status, 5); + } else { + $(pathToStreamItem + '#' + item.id + ' div.header h3 a').empty().append(newtitle); + } + } + }); + } + } + //If article not cart'd already, then RtoL flick carts it + if (e.orientation === 'horizontal' && e.direction === -1 && !$(pathToStreamItem + '#' + item.id).hasClass('cartulized')) { + $(pathToStreamItem + '#' + item.id + ' .cartlink').trigger('click'); + } + }) + })(); + } + }); + }); + + return false; + } + + + function _getRiverStickyItems(cached) { + var timestamp = Math.round(new Date().getTime() / 1000); + + if (cached == true) { + _populateGridSticky(_calculateColumnCount()); + return true; + } + + //Get the sticky river json data and parse it + return $.ajax({ + url: '/cgi/out/list.river.sticky?ts=' + timestamp, + dataType: "json", + success: function (data) { + //console.log('store data: ' + data); + sessionStorage.setItem(lsStickyDataKey, JSON.stringify(data)); + _populateGridSticky(_calculateColumnCount(), data); + }, + error: function (x, y, z) { + _changeStreamNotice('Error: ' + x.responseText); + } + }); + } + + + function _getRiverItems(cached) { + if (cached == true) { + _populateGrid(_calculateColumnCount()); + return true; + } + + //Get the river json data and parse it + return $.ajax({ + url: riverJsonUrl + '?callback=?', + jsonpCallback: 'onGetRiverStream', + dataType: "jsonp", + success: function (data) { + //console.log('store data: ' + data); + sessionStorage.setItem(lsRiverDataKey, JSON.stringify(data)); + _populateGrid(_calculateColumnCount(), data); + }, + error: function (x, y, z) { + _changeStreamNotice('Error: ' + x.responseText); + } + }); + + } + + + function _removeStickyItemLS(index) { + //Get data out of local storage + var lsdata = sessionStorage.getItem(lsStickyDataKey); + if (lsdata !== null) { + data = JSON.parse(lsdata); + data.data.items[index].hidden = 1; + sessionStorage.setItem(lsStickyDataKey, JSON.stringify(data)); + console.log('sticky item removed'); + } + return true; + } + + + function _bindEnclosureLinks(elid) { + var elid = (typeof elid === "undefined") ? "" : elid; + + if (platform == "mobile" || platform == "tablet") { + return true; + } + + $(elid + ' .enclosureview a').unbind('click'); + $(elid + ' .enclosureview a').click(function () { + if ($(this).children('img').length > 0) { + openMediaShadowbox($(this).children('img')); + return false; + } + }); + + return true; + } + + + function _bindEmbedActivations(elid) { + var elid = (typeof elid === "undefined") ? "" : elid; + + $(elid + ' .enciframe.inactive').each(function (k, v) { + var _this = this; + $(this).children('div.play').unbind('click'); + $(this).children('div.play').bind('click', function () { + var dsrc = $(_this).attr("data-src"); + var $iframe = $(''); + } else { + $(pathToPost + ' .enclosureview').prepend(''); + } + + } + }); //Change cart link at bottom to an edit article button $(pathToPost).find('div.footer div.actions a.cartlink img.icon-bookmark').removeClass('icon-bookmark').addClass('icon-editor'); $(pathToPost).find('div.footer div.actions a.cartlink').removeClass('cartlink').addClass('editlink'); @@ -1330,6 +1371,7 @@ function _convertYoutube(url) { return { searchPostLoad: _searchPostLoad, + unstickyAllItems: _unstickyAllItems, removeSessionData: _removeSessionData, rebindEverything: _rebindEverything, showOnlyItems: _showOnlyItems, diff --git a/www/script/global-env.js.php b/www/script/global-env.js.php index 8055ec63..307b339f 100644 --- a/www/script/global-env.js.php +++ b/www/script/global-env.js.php @@ -7,7 +7,7 @@ var platform = ''; var gDatestamp = ''; var gDevice = ''; -var gSection = ''; +var gSection = ''; var gPlatformMenubarTopOffset = 3080; var msgtimer; From b0e33ecd8579f70aaf8e5a8dbe8dd2d54821565f Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 16 Nov 2016 22:07:10 -0500 Subject: [PATCH 16/25] opml lib changes --- includes/opml.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/includes/opml.php b/includes/opml.php index f5ea3d0b..1e15ffec 100755 --- a/includes/opml.php +++ b/includes/opml.php @@ -2423,7 +2423,12 @@ function buildHtmlFromOpmlRecursive($x = NULL, &$html, $indent = 0, $line = 0, $ } //Set an expanded class on outline nodes that match the expansionState counter - $parent = end(array_values($parents)); + if(isset($parents)) { + $parent = end(array_values($parents)); + } else { + $parent = ""; + } + if ($type == "menu" && $menuexists == 0) { $htmlcontent .= "
      \n
      \n
      \n\n$nodetext\n
      \n
        \n"; $menuexists++; @@ -3734,7 +3739,7 @@ function convert_opml_to_rss($content = NULL, $uid = NULL, $max = NULL) //Check params if (empty($content) || !is_outline($content)) { - loggit(3, "The outline content is blank or corrupt: [$content]"); + loggit(3, "The outline content is blank or corrupt: Size[".strlen($content)."]"); return (FALSE); } From 46208c99976a711f2cbeb04edfcade39af9460fa Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 16 Nov 2016 22:08:20 -0500 Subject: [PATCH 17/25] not sure --- includes/posts.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/includes/posts.php b/includes/posts.php index fc4616e1..5c08fdaa 100755 --- a/includes/posts.php +++ b/includes/posts.php @@ -703,7 +703,7 @@ function build_blog_rss_feed($uid = NULL, $max = NULL, $archive = FALSE, $posts if (!empty($enclosure['type'])) { $etyp = 'type="' . $enclosure['type'] . '"'; } - if (!empty($enclosure['url'])) { + if (!empty($enclosure['url']) && $enclosure['url'] != "undefined") { $rss_enclosures .= ' ' . "\n"; } if(url_is_a_picture($enclosure['url'])) { @@ -1363,6 +1363,7 @@ function build_blog_html_archive($uid = NULL, $max = NULL, $archive = FALSE, $po } } } + $html .= $guid . "\n"; $html .= '
        ' . "\n"; if (!empty($rsslink)) { From 67bf049e3dd09ba49663fea00261d5019f041c70 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 16 Nov 2016 22:10:18 -0500 Subject: [PATCH 18/25] script move --- www/script/river-foot.js | 90 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 www/script/river-foot.js diff --git a/www/script/river-foot.js b/www/script/river-foot.js new file mode 100644 index 00000000..88a64935 --- /dev/null +++ b/www/script/river-foot.js @@ -0,0 +1,90 @@ +$(document).ready(function () { + //Keyboard shortcuts + key('t', function () { //----- Target the first visible article + freedomController.v1.river.methods.focusFirstVisibleArticle(); + return false; + }); + key('down', function () { //----- Jump to next feed + if ($(freedomController.v1.river.statics.pathToActiveItem).hasClass('cartulized')) { + return true; + } + freedomController.v1.river.methods.focusNextFeed(); + return false; + }); + key('up', function () { //----- Jump to previous feed + if ($(freedomController.v1.river.statics.pathToActiveItem).hasClass('cartulized')) { + return true; + } + freedomController.v1.river.methods.focusPreviousFeed(); + return false; + }); + key('right', function () { //----- Jump to next article + freedomController.v1.river.methods.focusNextArticle(); + return false; + }); + key('left', function () { //----- Jump to previous article + freedomController.v1.river.methods.focusPreviousArticle(); + return false; + }); + key('u', function () { //----- Un-sticky the currently targeted item + if ($(freedomController.v1.river.statics.pathToStreamItem + ".activeItem").hasClass("sticky")) { + $(freedomController.v1.river.statics.pathToStreamItem + ".activeItem .aUnSticky").trigger('click', {source: 'hotkey'}); + } + return false; + }); + key('c', function () { //----- Cartulize the currently targeted item + $(freedomController.v1.river.statics.pathToStreamItem + ".activeItem .cartlink").trigger('click'); + return false; + }); + key('shift+t', function () { //----- Change article title trigger + $(freedomController.v1.river.statics.pathToStreamItem + ".activeItem button.changetitle").trigger('click'); + return false; + }); + key('e', function () { //----- Edit the article link + $(freedomController.v1.river.statics.pathToStreamItem + ".activeItem div.footer div.actions a.editlink").trigger('click'); + return false; + }); + key('m', function () { //----- Microblog the currently targeted item + $("#mdlShowArticle").modal('hide'); + $(freedomController.v1.river.statics.pathToStreamItem + ".activeItem .rtgo").trigger('click'); + return false; + }); + key('o', function () { //----- Open original link of the currently targeted item + if ($(freedomController.v1.river.statics.pathToStreamItem + ".activeItem .header a.articlelink").length > 0) { + window.open($(freedomController.v1.river.statics.pathToStreamItem + ".activeItem .header a.articlelink").attr('href')); + } + return false; + }); + + //Turn the home button into a river re-generator if it's the active button + $('#divMainMenu a.homebutton').click(function () { + $('html, body').animate({scrollTop: '0px'}, 300); + freedomController.v1.river.methods.buildRiver(false); + return false; + }); + + //Bind unsticky all items button + // if( $('.article.sticky').length < 1 ) { + // $('button#unstickyAllItems').hide(); + //} else { + $('button#unstickyAllItems').click(function() { + freedomController.v1.river.methods.unstickyAllItems(); + }); + //} + + + //Initial river build + var nowt = Math.round(new Date().getTime() / 1000); + var rdpt = sessionStorage.getItem(freedomController.v1.river.statics.lsRiverDataPullTime); + if (rdpt == "undefined" || (nowt - rdpt) > 300) { + freedomController.v1.river.methods.buildRiver(false); + } else { + freedomController.v1.river.methods.buildRiver(false); + } + console.log("time since last river pull [" + (nowt - rdpt) + "]"); + + //Point new users to the prefs page + if ($.removeCookie('cartularynewuser')) { + showMessage("You can go to the prefs page to set up your avatar and other goodies. Just click your name in the menu bar.", true, 30); + } +}); \ No newline at end of file From 1c02235edc76c2ae7fddf1dd9dc389b917be0496 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 16 Nov 2016 22:10:54 -0500 Subject: [PATCH 19/25] river changes --- www/river.php | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/www/river.php b/www/river.php index 12efa070..25be07a8 100755 --- a/www/river.php +++ b/www/river.php @@ -1,8 +1,11 @@ - - @@ -11,21 +14,13 @@ <? echo $tree_location ?> - + + + - +
        @@ -35,6 +30,7 @@
        +

        Loading river...

        @@ -43,16 +39,15 @@
        -
        -
        + + + + - From 4189cca91088b00d3c5f2f7b46f75dd9b62cbfc9 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 16 Nov 2016 22:12:53 -0500 Subject: [PATCH 20/25] script move --- www/script/upload.js | 102 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 www/script/upload.js diff --git a/www/script/upload.js b/www/script/upload.js new file mode 100644 index 00000000..f072f4b3 --- /dev/null +++ b/www/script/upload.js @@ -0,0 +1,102 @@ +$(document).ready(function () { + console.log("SECTION: " + gSection); + var enclist = new Array(); + + //Set the datestamp + $('#divEnclosures .datestamp').val(gDatestamp); + + //Reveal the enclosure section upon change + $('#fileMobile').change(function () { + $('#divEnclosures').show(); + $('#divEnclosures #spnQueueText').text('File selected: ' + $('#fileMobile').val()); + }); + + //The enclosure attachment button click handler + $('#btnAttachFile').bind('click', function () { + $('#divUpload').show(); + }); + + //Start an enclosure upload + if (gDevice != "android") { + $('#aUploadTrigger').bind('click', function () { + $('#divEnclosures').show(); + $('#file_upload').uploadifive('upload'); + }); + } + + //Attach removers to extra elements + $('.aRemoveListItem').click(function () { + $(this).parent('li').remove(); + return false; + }); + + //Expose drop zone when a drag and drop comes in + if (gSection != "Microblog") { + $('body').on('dragenter', function () { + if ($('#mdlMicroblogPost').is(':visible')) { + modalFullHeight('#mdlMicroblogPost', false); + showEnclosures(); + } + }); + } else if (gSection == "Microblog") { + $('body').on('dragenter', function () { + showEnclosures(); + }); + } + + //Uploadifive handler + if (gDevice != "android") { + $(function () { + $('#file_upload').uploadifive({ + 'auto': true, + 'method': 'post', + 'dnd': true, + 'queueID': 'queue', + 'uploadScript': '/cgi/in/upload', + 'simUploadLimit': 1, + 'formData': { + 'datestamp': gDatestamp + }, + 'onSelect': function (queue) { + $('#divEnclosures').show(); + }, + 'onAddQueueItem': function (file) { + console.log("onAddQueueItem(): " + file.name); + console.log(enclist); + if ($.inArray(file.name, enclist) > -1) { + $('#file_upload').uploadifive('cancel', file, true); + } else { + enclist.push(file.name); + } + }, + 'onClearQueue': function (queue) { + enclist = []; + $('input.postenclosure').remove(); + }, + 'onCancel': function (file) { + $("input.postenclosure[data-filename='" + file.name + "']").remove(); + enclist.splice($.inArray(file.name, enclist), 1); + }, + 'onUploadComplete': function (file, data) { + var jdata = $.parseJSON(data); + $('.complete .filename:contains("' + file.name + '")').each(function (index) { + if (isImage(jdata.url)) { + $(this).parent().append(''); + $(this).parent().children('span.fileinfo').hide(); + } + $(this).html('Link to File.'); + $(this).parent().append(''); + $(this).parent().children('input').val(data); + + enclist.push(file.name); + }); + } + }) + }); + } +}); + +//Unhide the enclosure section +function showEnclosures() { + $('#divEnclosures').show(); +} From 30d2a2005f9f7276de73af18b8137ebf71155be4 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Sat, 19 Nov 2016 13:41:28 -0500 Subject: [PATCH 21/25] bug fixes --- www/script/api-river.js.php | 11 +++++++++-- www/script/global-env.js.php | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/www/script/api-river.js.php b/www/script/api-river.js.php index 6f68c51d..cb05da45 100644 --- a/www/script/api-river.js.php +++ b/www/script/api-river.js.php @@ -150,8 +150,11 @@ function _getBodyText(html) { function _countEnclosuresOfType(enclosures, typecheck) { var cnt = 0; $.each(enclosures, function () { - if (this.type.indexOf(typecheck) != -1) { - cnt++; + var thisenc = this; + if (typeof thisenc.type.indexOf === "function") { + if (thisenc.type.indexOf(typecheck) != -1) { + cnt++; + } } }); @@ -160,6 +163,7 @@ function _countEnclosuresOfType(enclosures, typecheck) { function _isImage(url, type) { + if (typeof type.indexOf !== "function") return false; if (type.indexOf('image') != -1) { return true; } @@ -181,6 +185,7 @@ function _isImage(url, type) { function _isAudio(url, type) { + if (typeof type.indexOf !== "function") return false; if (type.indexOf('audio') != -1) { return true; } @@ -205,6 +210,7 @@ function _isAudio(url, type) { function _isVideo(url, type) { + if (typeof type.indexOf !== "function") return false; if (type.indexOf('video') != -1) { return true; } @@ -229,6 +235,7 @@ function _isVideo(url, type) { function _isIframe(url, type) { + if (typeof type.indexOf !== "function") return false; if (type.indexOf('text/html') != -1) { return true; } diff --git a/www/script/global-env.js.php b/www/script/global-env.js.php index 307b339f..701caf58 100644 --- a/www/script/global-env.js.php +++ b/www/script/global-env.js.php @@ -13,7 +13,7 @@ //User globals var cuTwitterIsEnabled = truefalse; -var cuRiverColumnCount = ; +var cuRiverColumnCount = ; //Library prefs $.Finger = { From e98261fef04df0a5d9c3e58c3e5c5364122fd661 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 23 Nov 2016 21:40:31 -0500 Subject: [PATCH 22/25] more script moves --- www/script/freedomcontroller.utils.js | 580 ++++++++++++++++++++++++++ www/script/global-custom.js.php | 382 +++++++++++++++++ 2 files changed, 962 insertions(+) create mode 100644 www/script/freedomcontroller.utils.js create mode 100644 www/script/global-custom.js.php diff --git a/www/script/freedomcontroller.utils.js b/www/script/freedomcontroller.utils.js new file mode 100644 index 00000000..45ea7c02 --- /dev/null +++ b/www/script/freedomcontroller.utils.js @@ -0,0 +1,580 @@ +//Call a function whos name is in a variable +//_____http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string +function executeFunctionByName(functionName, context /*, args */) { + var args = Array.prototype.slice.call(arguments).splice(2); + var namespaces = functionName.split("."); + var func = namespaces.pop(); + for (var i = 0; i < namespaces.length; i++) { + context = context[namespaces[i]]; + } + return context[func].apply(this, args); +} + +//Get selected text +//_____http://motyar.blogspot.fi/2010/02/get-user-selected-text-with-jquery-and.html +function getSelected() { + if (window.getSelection) { + return window.getSelection(); + } + else if (document.getSelection) { + return document.getSelection(); + } + else { + var selection = document.selection && document.selection.createRange(); + if (selection.text) { + return selection.text; + } + return false; + } +} + +//Save the selected text +function saveSelection() { + if (window.getSelection) { + sel = window.getSelection(); + if (sel.getRangeAt && sel.rangeCount) { + var ranges = []; + for (var i = 0, len = sel.rangeCount; i < len; ++i) { + ranges.push(sel.getRangeAt(i)); + } + return ranges; + } + } else if (document.selection && document.selection.createRange) { + return document.selection.createRange(); + } + console.log("can't get selection."); + return null; +} + + +//Restore a text selection +function restoreSelection(savedSel) { + if (savedSel) { + if (window.getSelection) { + sel = window.getSelection(); + sel.removeAllRanges(); + for (var i = 0, len = savedSel.length; i < len; ++i) { + sel.addRange(savedSel[i]); + } + } else if (document.selection && savedSel.select) { + savedSel.select(); + } + } +} + + +/** + * author Remy Sharp + * url http://remysharp.com/2009/01/26/element-in-view-event-plugin/ + */ +(function ($) { + function getViewportHeight() { + var height = window.innerHeight; // Safari, Opera + var mode = document.compatMode; + + if ((mode || !$.support.boxModel)) { // IE, Gecko + height = (mode == 'CSS1Compat') ? + document.documentElement.clientHeight : // Standards + document.body.clientHeight; // Quirks + } + + return height; + } + + $(window).scroll(function () { + var vpH = getViewportHeight(), + scrolltop = (document.documentElement.scrollTop ? + document.documentElement.scrollTop : + document.body.scrollTop), + elems = []; + + // naughty, but this is how it knows which elements to check for + $.each($.cache, function () { + if (this.events && this.events.inview) { + elems.push(this.handle.elem); + } + }); + + if (elems.length) { + $(elems).each(function () { + var $el = $(this), + top = $el.offset().top, + height = $el.height(), + inview = $el.data('inview') || false; + + if (scrolltop > (top + height) || scrolltop + vpH < top) { + if (inview) { + $el.data('inview', false); + $el.trigger('inview', [false]); + } + } else if (scrolltop < (top + height)) { + if (!inview) { + $el.data('inview', true); + $el.trigger('inview', [true]); + } + } + }); + } + }); + + // kick the event to pick up any elements already in view. + // note however, this only works if the plugin is included after the elements are bound to 'inview' + $(function () { + $(window).scroll(); + }); +})(jQuery); + + +//A general purpose debouncer extension +//_____via http://www.hnldesign.nl/blog/debouncing-events-with-jquery/ +var deBouncer = function ($, cf, of, interval) { + // deBouncer by hnldesign.nl + // based on code by Paul Irish and the original debouncing function from John Hann + // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/ + var debounce = function (func, threshold, execAsap) { + var timeout; + + return function debounced() { + var obj = this, args = arguments; + + function delayed() { + if (!execAsap) + func.apply(obj, args); + timeout = null; + } + + if (timeout) + clearTimeout(timeout); + else if (execAsap) + func.apply(obj, args); + + timeout = setTimeout(delayed, threshold || interval); + }; + }; + jQuery.fn[cf] = function (fn) { + return fn ? this.bind(of, debounce(fn)) : this.trigger(cf); + }; +}; + + +//Strip leading and trailing whitespace from a string +function trim(strText) { + // this will get rid of leading spaces + while (strText.substring(0, 1) == ' ') + strText = strText.substring(1, strText.length); + + // this will get rid of trailing spaces + while (strText.substring(strText.length - 1, strText.length) == ' ') + strText = strText.substring(0, strText.length - 1); + + return strText; +} + + +//Extend jquery so we can easily center an element +//_____via stackflow: http://stackoverflow.com/questions/210717/using-jquery-to-center-a-div-on-the-screen +jQuery.fn.center = function (horz, vert) { + this.css("position", "absolute"); + if (vert == true) { + this.css("top", Math.max(0, (($(window).height() - this.outerHeight()) / 2) + $(window).scrollTop()) + "px"); + } + if (horz == true) { + this.css("left", Math.max(0, (($(window).width() - this.outerWidth()) / 2) + $(window).scrollLeft()) + "px"); + } + return this; +} + + +//A jquery selector extension to determine if an element is visible in the viewport +//_____via http://remysharp.com/2009/01/26/element-in-view-event-plugin/ +$.extend($.expr[':'], { + inView: function (a) { + var st = (document.documentElement.scrollTop || document.body.scrollTop), + ot = $(a).offset().top, + wh = (window.innerHeight && window.innerHeight < $(window).height()) ? window.innerHeight : $(window).height(); + return ot > st && ($(a).height() + ot) < (st + wh); + } +}); + + +//Display something in the global dropdown message box +function showMessage(text, status, timeout) { + clearTimeout(msgtimer); + //closeMessage(); + //$('#divMessageBox').slideUp("normal", function(){ $('#divMessageBox').remove(); }); + + if (isMessageBoxVisible()) { + return changeMessage(text, status, timeout); + } + + $('.msganchor').after(''); + + $('#messagebox').empty(); + $('#messagebox').removeClass('msggood'); + $('#messagebox').removeClass('msgbad'); + if (platform == "mobile") { + $('#messagebox').append(text); + } else { + $('#messagebox').append('' + text); + } + + if (status == false || status == "false") { + $('#messagebox').addClass('msgbad'); + } else if (status == "warning") { + $('#messagebox').addClass('msgwarn'); + } else { + $('#messagebox').addClass('msggood'); + } + + if (platform == "mobile") { + alert(text); + } else { + $('#divMessageBox').center(true, false); + $('#divMessageBox').slideDown(); + + msgtimer = setTimeout(function () { + closeMessage(); + }, + (timeout * 1000)); + } + +} + +//See if messagebox is showing +function isMessageBoxVisible() { + return ($('#messagebox').length > 0); +} + +//Change message in box +function changeMessage(text, status, timeout) { + clearTimeout(msgtimer); + $('#messagebox').empty(); + $('#messagebox').removeClass('msggood'); + $('#messagebox').removeClass('msgbad'); + $('#messagebox').removeClass('msgwarn'); + + $('#messagebox').html('' + text); + + if (status == false || status == "false") { + $('#messagebox').addClass('msgbad'); + } else if (status == "warning") { + $('#messagebox').addClass('msgwarn'); + } else { + $('#messagebox').addClass('msggood'); + } + + msgtimer = setTimeout(function () { + closeMessage(); + }, + (timeout * 1000)); +} + +//Close the global message box +function closeMessage() { + $('#divMessageBox').slideUp("normal", function () { + $('#divMessageBox').remove(); + }); + return (false); +} + + +//Empty and blank string checks +//_____via http://stackoverflow.com/questions/154059/what-is-the-best-way-to-check-for-an-empty-string-in-javascript +function isEmpty(str) { + return (!str || 0 === str.length); +} +function isBlank(str) { + return (!str || /^\s*$/.test(str)); +} + + +//Is this object an image? +function isImage(url, type) { + var type = (typeof type === "undefined") ? false : type; + + if (type) { + if (type.indexOf(systemUrl) == -1 && type.indexOf('image') != -1 && url.indexOf('http') == 0) { + return true; + } + } + if (url.indexOf(systemUrl) == -1 && url.indexOf('.jpg') != -1 && url.indexOf('http') == 0) { + return true; + } + if (url.indexOf(systemUrl) == -1 && url.indexOf('.jpeg') != -1 && url.indexOf('http') == 0) { + return true; + } + if (url.indexOf(systemUrl) == -1 && url.indexOf('.png') != -1 && url.indexOf('http') == 0) { + return true; + } + if (url.indexOf(systemUrl) == -1 && url.indexOf('.gif') != -1 && url.indexOf('http') == 0) { + return true; + } + + return false; +}; + + +//Is it video? +function isVideo(url, type) { + var type = (typeof type === "undefined") ? false : type; + + if (type) { + if (type.indexOf(systemUrl) == -1 && type.indexOf('video') != -1 && url.indexOf('http') == 0) { + return true; + } + } + if (url.indexOf(systemUrl) == -1 && url.indexOf('.m4v') != -1 && url.indexOf('http') == 0) { + return true; + } + if (url.indexOf(systemUrl) == -1 && url.indexOf('.mp4') != -1 && url.indexOf('http') == 0) { + return true; + } + if (url.indexOf(systemUrl) == -1 && url.indexOf('.avi') != -1 && url.indexOf('http') == 0) { + return true; + } + if (url.indexOf(systemUrl) == -1 && url.indexOf('.mov') != -1 && url.indexOf('http') == 0) { + return true; + } + + return false; +}; + + +//Is it audio? +function isAudio(url, type) { + var type = (typeof type === "undefined") ? false : type; + + if (type) { + if (type.indexOf(systemUrl) == -1 && type.indexOf('audio') != -1 && url.indexOf('http') == 0) { + return true; + } + } + if (url.indexOf(systemUrl) == -1 && url.indexOf('.mp3') != -1 && url.indexOf('http') == 0) { + return true; + } + if (url.indexOf(systemUrl) == -1 && url.indexOf('.m4a') != -1 && url.indexOf('http') == 0) { + return true; + } + if (url.indexOf(systemUrl) == -1 && url.indexOf('.wav') != -1 && url.indexOf('http') == 0) { + return true; + } + if (url.indexOf(systemUrl) == -1 && url.indexOf('.ogg') != -1 && url.indexOf('http') == 0) { + return true; + } + if (url.indexOf(systemUrl) == -1 && url.indexOf('.wmv') != -1 && url.indexOf('http') == 0) { + return true; + } + + return false; +}; + + +//Is it html content? +function isHtml(url, type) { + var type = (typeof type === "undefined") ? false : type; + + if (type) { + if (type.indexOf(systemUrl) == -1 && type.indexOf('html') != -1 && url.indexOf('http') == 0) { + return true; + } + } + if (url.indexOf(systemUrl) == -1 && url.indexOf('youtube') != -1 && url.indexOf('http') == 0) { + return true; + } + if (url.indexOf(systemUrl) == -1 && url.indexOf('vimeo') != -1 && url.indexOf('http') == 0) { + return true; + } + + return false; +}; + + +// Modified from http://ejohn.org/blog/javascript-pretty-date/#comment-297458 +function prettyDate(date) { + var date, seconds, formats, i = 0, f; + date = new Date(date); + seconds = (new Date - date) / 1000; + formats = [ + [-1, 'Recently'], // Deals with times in the future + [60, 'seconds', 1], + [120, '1 minute ago'], + [3600, 'minutes', 60], + [7200, '1 hour ago'], + [86400, 'hours', 3600], + [172800, 'Yesterday'], + [604800, 'days', 86400], + [1209600, '1 week ago'], + [2678400, 'weeks', 604800] + ]; + + while (f = formats[i++]) { + if (seconds < f[0]) { + return f[2] ? Math.floor(seconds / f[2]) + ' ' + f[1] + ' ago' : f[1]; + } + // Crude fix for feed items with incorrect pubDate (i.e. 01 Dec 1999) + // look for anything over 10 years old + if (seconds > 315569260) { + return 'Recently'; + } + } + + return dateFormat(date, 'longDate'); +}; + + +/* + * Date Format 1.2.3 + * (c) 2007-2009 Steven Levithan + * MIT license + * + * Includes enhancements by Scott Trenda + * and Kris Kowal + * + * Accepts a date, a mask, or a date and a mask. + * Returns a formatted version of the given date. + * The date defaults to the current date/time. + * The mask defaults to dateFormat.masks.default. + * + * http://blog.stevenlevithan.com/archives/date-time-format + */ +var dateFormat = function () { + var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g, + timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g, + timezoneClip = /[^-+\dA-Z]/g, + pad = function (val, len) { + val = String(val); + len = len || 2; + while (val.length < len) val = "0" + val; + return val; + }; + + // Regexes and supporting functions are cached through closure + function finalDate(date, mask, utc) { + // You can't provide utc if you skip other args (use the "UTC:" mask prefix) + if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) { + mask = date; + date = undefined; + } + + // Passing date through Date applies Date.parse, if necessary + date = date ? new Date(date) : new Date; + if (isNaN(date)) throw SyntaxError("invalid date"); + + mask = String(dateFormat.masks[mask] || mask || dateFormat.masks["default"]); + + // Allow setting the utc argument via the mask + if (mask.slice(0, 4) == "UTC:") { + mask = mask.slice(4); + utc = true; + } + + var _ = utc ? "getUTC" : "get", + d = date[_ + "Date"](), + D = date[_ + "Day"](), + m = date[_ + "Month"](), + y = date[_ + "FullYear"](), + H = date[_ + "Hours"](), + M = date[_ + "Minutes"](), + s = date[_ + "Seconds"](), + L = date[_ + "Milliseconds"](), + o = utc ? 0 : date.getTimezoneOffset(), + flags = { + d: d, + dd: pad(d), + ddd: dateFormat.i18n.dayNames[D], + dddd: dateFormat.i18n.dayNames[D + 7], + m: m + 1, + mm: pad(m + 1), + mmm: dateFormat.i18n.monthNames[m], + mmmm: dateFormat.i18n.monthNames[m + 12], + yy: String(y).slice(2), + yyyy: y, + h: H % 12 || 12, + hh: pad(H % 12 || 12), + H: H, + HH: pad(H), + M: M, + MM: pad(M), + s: s, + ss: pad(s), + l: pad(L, 3), + L: pad(L > 99 ? Math.round(L / 10) : L), + t: H < 12 ? "a" : "p", + tt: H < 12 ? "am" : "pm", + T: H < 12 ? "A" : "P", + TT: H < 12 ? "AM" : "PM", + Z: utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""), + o: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4), + S: ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10] + }; + + return mask.replace(token, function ($0) { + return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1); + }); + }; + + return finalDate; +}(); + + +// Some common format strings +dateFormat.masks = { + "default": "HH:MM:ss dd mmm yyyy ", // 17:46:21 09 Jun 2007 + shortDate: "m/d/yy", // 6/9/07 + mediumDate: "d mmm yyyy", // 9 Jun 2007 + longDate: "d mmmm yyyy", // 9 June 2007 + fullDate: "dddd, mmmm d, yyyy", // Saturday, June 9, 2007 + shortTime: "h:MM TT", // 5:46 PM + mediumTime: "h:MM:ss TT", // 5:46:21 PM + longTime: "h:MM:ss TT Z", // 5:46:21 PM EST + isoDate: "yyyy-mm-dd", // 2007-06-09 + isoTime: "HH:MM:ss", // 17:46:21 + isoDateTime: "yyyy-mm-dd'T'HH:MM:ss", // 2007-06-09T17:46:21 + isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'", // 2007-06-09T22:46:21Z + + timeDate: "dd mmm; h:MM TT" // 09 Jun; 5:46:21 PM +}; + + +// Internationalization strings +dateFormat.i18n = { + dayNames: [ + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" + ], + monthNames: [ + "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", + "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" + ] +}; + + +// For convenience... +Date.prototype.format = function (mask, utc) { + return dateFormat(this, mask, utc); +}; + + +//Get padding size for an element +function getVerticalPadding(el) { + var pt = parseInt($(el).css("padding-top").replace("px", "")); + var pb = parseInt($(el).css("padding-bottom").replace("px", "")); + + return (pt + pb); +} + + +//Get margin size for an element +function getVerticalMargins(el) { + var mt = parseInt($(el).css("margin-top").replace("px", "")); + var mb = parseInt($(el).css("margin-bottom").replace("px", "")); + + return (mt + mb); +} + + +function stripTags(html) { + var tmp = document.createElement("DIV"); + tmp.innerHTML = html; + return tmp.textContent || tmp.innerText; +} diff --git a/www/script/global-custom.js.php b/www/script/global-custom.js.php new file mode 100644 index 00000000..f440c865 --- /dev/null +++ b/www/script/global-custom.js.php @@ -0,0 +1,382 @@ +//http://stackoverflow.com/questions/4652734/return-html-from-a-user-selection/4652824#4652824 +//Get html of selected text +function getSelectionHtml() { + var html = ""; + if (typeof window.getSelection != "undefined") { + var sel = window.getSelection(); + if (sel.rangeCount) { + var container = document.createElement("div"); + for (var i = 0, len = sel.rangeCount; i < len; ++i) { + container.appendChild(sel.getRangeAt(i).cloneContents()); + } + html = container.innerHTML; + } + } else if (typeof document.selection != "undefined") { + if (document.selection.type == "Text") { + html = document.selection.createRange().htmlText; + } + } else if ($('#outliner').length > 0) { + html = opGetLineText(); + } + return html; +} + + +//Convert links found in twitter messages into the target link of the message +function sanitize_twitter(divStream) { + $(divStream + ' a').each(function () { + var alobj = $(this); + var artitle = alobj.text(); + if (alobj.attr("href")) { + if (alobj.attr("href").indexOf("twitter.com") != -1) { + //If this twitter post contains a URL, then attach that URL to the link + if (artitle.indexOf("http://") != -1) { + var twurl = artitle.match(/\bhttp\:\/\/([A-Za-z0-9\.\/\+\&\@\~\-\%\?\=\_\#\!]*)/gi); + var twlen = twurl.length; + for (var i = 0; i < twlen; i++) { + alobj.parent().append(' → Link'); + } + } else { + return true; + } + } + } + }); +} + + +//Adjust the size of a cartulized article modal to fill the screen better +function modalFullHeight(el, loading) { + var winH = $(window).height(); + var winW = $(window).width(); + var winScLeft = $(window).scrollLeft(); + + $(el).show(); + + //Set left position + $(el).css("left", ( (winW - $(el).width() ) / 2 ) + winScLeft + "px"); + + if (loading == true) { + //Reset height params so it looks compact while grabbing data + $(el).css("height", ""); + $(el).css("max-height", ""); + $(el).css("height", ""); + $(el).css("max-height", ""); + $(el + ' .modal-body').css('max-height', ""); + $(el + ' .modal-body').css('height', ""); + + //Set initial size and position based on the current viewport size + $(el).css("max-width", ( (winW + winScLeft) - 120) + "px"); + $(el).css("max-width", ( $(el).width() - 30) + "px"); + $(el).css("top", (( (winH - $(el).height()) / 2 ) / 2) + "px"); + + return true; + } + + //Size the modal elements according to the current viewport + var exPad = getVerticalPadding(el) + getVerticalPadding(el + ' .modal-body') + getVerticalPadding(el + ' .modal-header'); + $(el).css('max-height', winH - exPad + "px"); + $(el).css('height', winH - exPad + "px"); + + var modH = $(el).outerHeight(true); + var modW = $(el).outerWidth(true); + var hfSize = $(el + ' .modal-header').outerHeight(true) + $(el + ' .modal-footer').outerHeight(true); + + $(el).css("top", (winH - modH) / 2); + $(el + ' .modal-body').css('max-height', (modH - hfSize - exPad - 5) + "px"); + $(el + ' .modal-body').css('height', (modH - hfSize - exPad - 5) + "px"); + + //When the window resizes, we should resize the modal + $(window).off('debouncedresize'); + $(window).on('debouncedresize', function (event) { + modalFullHeight(el, false); + }); + + //When modal closes we should un-hook from the window resize event + $(el).on('hidden', function () { + $(window).off('debouncedresize'); + }); + + return true; +} + + +//Spawn a microblog post box +function newMicroblogPostWindow(item, opmlsource, type) { + var modal = '#mdlMicroblogPost'; + var item = (typeof item === "undefined") ? false : item; + var opmlsource = (typeof opmlsource === "undefined") ? false : opmlsource; + var type = (typeof type === "undefined") ? 0 : type; + var compact = true; + + //Set the description + $(modal + ' .bpdescription textarea').val(""); + $(modal + ' .bpdescription textarea').val(getSelectionHtml()); + if (item != false) { + if ($(modal + ' .bpdescription textarea').val() == "") { + $(modal + ' .bpdescription textarea').val($(item + ' .header').text().trim()); + } + } + + //Zero out the title + $(modal + ' .bptitle input').val(""); + + //Set the link + $(modal + ' .bplink input').val(""); + if (item != false) { + $(modal + ' .bplink input').val($(item + ' .header a.articlelink').attr('href').trim()); + } + + //Set the short link + $(modal + ' .bpshortlink input').val(""); + + //Set the source + $(modal + ' .bpsourceurl').val(""); + $(modal + ' .bpsourcetitle').val(""); + if (item != false) { + $(modal + ' .bpsourceurl').val($(item + ' .footer span.source a').attr('href').trim()); + $(modal + ' .bpsourcetitle').val($(item + ' .footer span.source a').text().trim()); + } + + //Attach opml source if there was any + if (opmlsource != false) { + $(modal + ' .bpopmlsource input').val(opmlsource); + } + + //Set the type + if (type != 0) { + $(modal + ' .bptype input').val(type); + } + + //Set the origin + $(modal + ' .bporigin input').val(""); + if (item != false) { + $(modal + ' .bporigin input').val($(item + ' .footer span.origin').text().trim()); + } + + //Set external enclosures + $(modal + ' .bpextenc').hide(); + $(modal + ' .bpextenc ul').empty(); + if (item != false) { + var encount = 0; + $(item + ' .enclosureview .encobj').each(function () { + $(modal + ' .bpextenc ul').append('
      • '); + $(modal + ' .bpextenc ul li:eq(' + encount + ')').append(''); + if ($(this).hasClass('enclosurepic')) { + $(modal + ' .bpextenc ul li:eq(' + encount + ')').append(''); + } + if ($(this).hasClass('encaudio')) { + $(modal + ' .bpextenc ul li:eq(' + encount + ')').append(''); + } + if ($(this).hasClass('encvideo')) { + $(modal + ' .bpextenc ul li:eq(' + encount + ')').append(''); + } + if ($(this).hasClass('enciframe')) { + $(modal + ' .bpextenc ul li:eq(' + encount + ')').append(''); + } + $(modal + ' .bpextenc ul li:eq(' + encount + ')').append(''); + $(modal + ' .bpextenc ul li:eq(' + encount + ')').append(''); + $(modal + ' .bpextenc ul li:eq(' + encount + ')').append(''); + $(modal + ' .bpextenc ul li:eq(' + encount + ') a.delete').click(function () { + $(this).parent().remove(); + if ($(modal + ' .bpextenc ul li').length == 0) { + $(modal + ' .bpextenc').hide(); + } + return false; + }); + + encount++; + }); + if (encount > 0) { + compact = false; + $(modal + ' .bpextenc').show(); + } + } + + //Clear the upload queue + $(modal + ' #divEnclosures').hide(); + $(modal + ' #divUpload').hide(); + $(modal + ' #file_upload').uploadifive('clearQueue'); + + //Show the modal + $(modal).modal('show'); + modalFullHeight(modal, compact); + + //Ajaxify the form + $(modal + ' .mbpostform').ajaxForm({ + dataType: 'json', + cache: false, + clearForm: true, + resetForm: true, + timeout: 60000, + beforeSubmit: function () { + $(modal + ' .spinner').show(); + $(modal + ' input,textarea,button').attr("disabled", true); + }, + success: function (data) { + if (data.status == "false") { + showMessage(data.description, data.status, 5); + } else { + showMessage("Post Successful!", data.status, 5); + } + $(modal + ' .spinner').hide(); + $(modal + ' input,textarea,button').attr("disabled", false); + $(modal).modal('hide'); + reloadMicroblogWidget(); + }, + error: function (x, t, m) { + showMessage("Error: " + m + "(" + t + ")", false, 60); + $(modal + ' input,textarea,button').attr("disabled", false); + } + }); + $(modal + ' .mbsubmit').click(function () { + $(modal + ' .mbpostform').submit(); + return false; + }); + + //Set the twitter toggle + $(modal + ' .tweeticon').removeClass('icon-twitter').addClass('icon-notwitter'); + $(modal + ' .tweetcheck').prop('checked', false); + $(modal + ' .tweeticon').bind('click', function () { + $(modal + ' .tweetcheck').prop('checked', !$(modal + ' .tweetcheck').prop('checked')); + $(modal + ' .tweeticon').toggleClass('icon-twitter'); + $(modal + ' .tweeticon').toggleClass('icon-notwitter'); + $(modal + ' .bpdescription textarea').trigger('keyup'); + }); + + //Track text length + $(modal + ' .mbcharcount').text($(modal + ' .bpdescription textarea').val().length); + $(modal + ' .bpdescription textarea').bind('keyup', function () { + var cc = $(modal + ' .bpdescription textarea').val().length; + $(modal + ' .mbcharcount').text(cc); + if ($(modal + ' .tweeticon').hasClass('icon-twitter') && cc > 138) { + $(modal + ' .mbcharcount').addClass('msgwarn'); + $(modal + ' .mbcharcount').text(cc + ' - Twitter will truncate this message.'); + } else { + $(modal + ' .mbcharcount').removeClass('msgwarn'); + } + }); + + //When modal closes we should clean up + $(modal).on('hidden', function () { + $(modal + ' .mbsubmit').unbind('click'); + $(modal + ' .tweeticon').unbind('click'); + $(modal + ' .bpdescription textarea').unbind('keyup'); + }); + + //Set focus to the textarea + $(modal).on('shown', function () { + $(modal + ' .bpdescription textarea').focus(); + }); + + + return false; +} + + +//Open a modal with an article displayed in it +function showArticleWindow(riveritem) { + var modal = '#mdlShowArticle'; + var href = $(riveritem + ' .footer a.cartlink').attr('data-href').trim(); + var compact = true; + + $(modal + ' .arfooter').hide(); + $(modal + ' .arfooter .rt').click(function () { + $(modal + ' .arbody img').each(function () { + $(riveritem + ' .enclosureview').append(''); + }); + $(modal).modal('hide'); + $(riveritem + ' .rtgo').trigger('click'); + return false; + }); + + $(modal + ' .artitle').empty(); + $(modal + ' .arbody').empty(); + $(modal + ' .arfooter .opml').attr('href', "#"); + $(modal + ' .arfooter .print').attr('href', "#"); + $(modal + ' .arfooter .link').attr('href', "#"); + $(modal + ' .spinner').show(); + $(modal + ' .modal-header').hide(); + $(modal + ' .modal-footer').hide(); + + modalFullHeight(modal, true); + $(modal).modal('show'); + $.ajax({ + url: href + '&json=true', + type: "GET", + dataType: 'json', + timeout: 30000, + success: function (data) { + $(modal + ' .modal-header').show(); + $(modal + ' .modal-footer').show(); + $(modal + ' .spinner').hide(); + if (data.status == "false") { + $(modal + ' .artitle').append(data.article.title); + $(modal + ' .arbody').append(data.article.body); + } else { + modalFullHeight(modal, false); + $(modal + ' .artitle').append(data.article.title); + $(modal + ' .arbody').append(data.article.body); + $(modal + ' .arfooter .opml').attr('href', "/showarticle-opml?aid=" + data.article.id); + $(modal + ' .arfooter .print').attr('href', "/showarticle-print?aid=" + data.article.id); + $(modal + ' .arfooter .link').attr('href', data.article.url); + $(modal + ' .arfooter').show(); + } + }, + error: function (x, t, m) { + $(modal + ' .modal-header').show(); + $(modal + ' .modal-footer').show(); + $(modal + ' .spinner').hide(); + $(modal + ' .artitle').append(''); + $(modal + ' .arbody').append('

        Error communicating with server. Connection problem?

        '); + } + }); + + //Jump up to the top + $(modal + ' .arbody').scrollTop(0); + + //When modal closes we should clean up + $(modal).on('hidden', function () { + $(modal + ' .arfooter .rt').unbind('click'); + $(modal + ' .artitle').empty(); + $(modal + ' .arbody').empty(); + }); + + + return false; +} + + +//Open a modal to display a large sized image in a shadow box +function openMediaShadowbox(imgtag) { + var modal = '#mdlMediaShadowbox'; + var href = imgtag.attr('src'); + var compact = false; + + //Prep the modal + $(modal + ' .sbtitle').empty(); + $(modal + ' .sbbody').empty(); + $(modal + ' .spinner').hide(); + $(modal + ' .modal-footer').hide(); + + //Set the image + $(modal + ' .sbbody').append(''); + + //Size the modal + modalFullHeight(modal, compact); + + //Size the image + $(modal + ' .sbbody img').css("max-width", ($(modal + ' .modal-body').width() - 10) + "px"); + $(modal + ' .sbbody img').css("max-height", ($(modal + ' .modal-body').height() - 10) + "px"); + + //Reveal the modal + $(modal).modal('show'); + + //When modal closes we should clean up + $(modal).on('hidden', function () { + //$(modal + ' .arfooter .rt').unbind('click'); + }); + + + return false; +} From eb76ee6b987fff6bbfe118f2fb5ccc4941f8aaf0 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 24 Nov 2016 00:03:00 -0500 Subject: [PATCH 23/25] fix unsticky-all button show/hide --- www/river.php | 2 +- www/script/api-river.js.php | 13 ++++++++++++- www/script/river-foot.js | 28 ++++++++++++++++++---------- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/www/river.php b/www/river.php index 25be07a8..479e0319 100755 --- a/www/river.php +++ b/www/river.php @@ -30,7 +30,7 @@
        - +

        Loading river...

        diff --git a/www/script/api-river.js.php b/www/script/api-river.js.php index cb05da45..2a4aac8c 100644 --- a/www/script/api-river.js.php +++ b/www/script/api-river.js.php @@ -53,6 +53,8 @@ function _removeSessionData() { function _unstickyAllItems() { + console.log("_unstickyAllItems() called"); + showMessage("Un-stickying all items...", "warning", 30); //Loop through the sticky items and un-sticky them as well $.ajax({ url: '/cgi/in/unstickyall', @@ -63,6 +65,7 @@ function _unstickyAllItems() { if (data.status == "true") { showMessage(data.description, data.status, 5); $('div.article.sticky').remove(); + $('button#unstickyAllItems').hide(); } else { showMessage(data.description, data.status, 5); } @@ -879,6 +882,9 @@ function _bindStickyLinks(elid) { } }); } + + //If this is the last sticky item, remove un-stickyall button + if ($('.article.sticky').length < 1) $('button#unstickyAllItems').hide(); })(); return false; @@ -984,7 +990,7 @@ function _changeStreamNotice(notice, hide) { } - function _buildRiver(cached) { + function _buildRiver(cached, callback) { var cached = (typeof cached === "undefined") ? false : cached; var cols = 1; @@ -1026,6 +1032,11 @@ function _buildRiver(cached) { }); } + if(typeof callback === "function") { + console.log("ua callback"); + callback(); + } + }); return true; diff --git a/www/script/river-foot.js b/www/script/river-foot.js index 88a64935..77e6a5d2 100644 --- a/www/script/river-foot.js +++ b/www/script/river-foot.js @@ -64,22 +64,30 @@ $(document).ready(function () { }); //Bind unsticky all items button - // if( $('.article.sticky').length < 1 ) { - // $('button#unstickyAllItems').hide(); - //} else { - $('button#unstickyAllItems').click(function() { - freedomController.v1.river.methods.unstickyAllItems(); - }); - //} - + var showHideUnstickyAllButton = function() { + console.log("stickies: "+$('.article.sticky').length); + if ($('.article.sticky').length > 0) { + $('button#unstickyAllItems').show(); + console.log("there are sticky articles"); + $('button#unstickyAllItems').click(function () { + freedomController.v1.river.methods.unstickyAllItems(); + }); + } + }; //Initial river build var nowt = Math.round(new Date().getTime() / 1000); var rdpt = sessionStorage.getItem(freedomController.v1.river.statics.lsRiverDataPullTime); if (rdpt == "undefined" || (nowt - rdpt) > 300) { - freedomController.v1.river.methods.buildRiver(false); + freedomController.v1.river.methods.buildRiver(false, function () { + console.log("post-riverbuild callback called"); + showHideUnstickyAllButton(); + }); } else { - freedomController.v1.river.methods.buildRiver(false); + freedomController.v1.river.methods.buildRiver(false, function () { + console.log("post-riverbuild callback called"); + showHideUnstickyAllButton(); + }); } console.log("time since last river pull [" + (nowt - rdpt) + "]"); From d368816547ccad0fc91c3357de318fc14de976e1 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Fri, 25 Nov 2016 12:13:47 -0500 Subject: [PATCH 24/25] version bump --- templates/cartulary.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/cartulary.conf b/templates/cartulary.conf index 8fd6cd15..8273434c 100755 --- a/templates/cartulary.conf +++ b/templates/cartulary.conf @@ -9,8 +9,8 @@ system_url="http://domain.goes.here" system_fqdn="fqdn.goes.here" sopml_cloud_url="fqdn.goes.here" rss_cloud_url="fqdn.goes.here" -version="0.6.11" -cg_sys_version="0.6.11" +version="0.6.12" +cg_sys_version="0.6.12" cg_main_serverguid=server.guid.goes.here email_filemaster="cartulary@localhost" email_fromname="Cartulary Admin" From 804c3780e0f9457db5b473ceac8125756beb95d8 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 29 Nov 2016 23:00:13 -0500 Subject: [PATCH 25/25] v0.6.12 release --- README.md | 4 ++-- releases/v0.6.12-apt.sh | 41 ++++++++++++++++++++++++++++++++++++++ releases/v0.6.12-notes.txt | 26 ++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 releases/v0.6.12-apt.sh create mode 100644 releases/v0.6.12-notes.txt diff --git a/README.md b/README.md index f96b9b2f..cec5e6fc 100755 --- a/README.md +++ b/README.md @@ -34,14 +34,14 @@ #### INSTALL: The software will run on any unix-like system with a LAMP stack fairly easily, but it - installs and upgrades easiest on Unbuntu 12 LTS. That's what is assumed in the install + installs and upgrades easiest on Unbuntu LTS 12, 14 or 16 etc. That's what is assumed in the install documentation. Running on any other system will require installing by hand, which is not hard. Although the system will run without Amazon S3 configured, it loses a lot of the best functionality. Amazon S3 is really cheap. You should do it. :-) - Ubuntu 12 LTS [on Amazon Ec2]: + Example: Ubuntu 12,14,16 LTS [on Amazon Ec2]: 1. [Launch an "small" Ubuntu 12 LTS ec2 instance.] 2. [Create an Elastic IP and assign it to your instance.] diff --git a/releases/v0.6.12-apt.sh b/releases/v0.6.12-apt.sh new file mode 100644 index 00000000..75d4d763 --- /dev/null +++ b/releases/v0.6.12-apt.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +##: This script needs to be run with sudo +ROOT_UID="0" + +#Check if run as root +if [ "$UID" -ne "$ROOT_UID" ] ; then + echo "You must run this script with sudo." + exit 1 +fi +export CARTROOT=`echo "" | php` + +echo Side-loading packages up through version 0.6.10... + +##: Refresh apt +echo Updating apt-get repos... +apt-get update + +##: Install any new modules needed for this release +echo Installing php5 imap library... +apt-get install -y php5-imap +php5enmod imap + +echo Installing php5 xsl library... +apt-get install -y php5-xsl +php5enmod xsl + +echo Installing node.js... +curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash - +apt-get install -y nodejs +cd $CARTROOT/aggrivate +sudo npm -g install npm@latest +sudo npm -g install npm@latest +npm install + +echo Correcting feed database prior to upgrade... +echo " This could take a while. Please wait..." +sudo php /opt/cartulary/bin/clean_nonfqdn_feeds.php +sudo php /opt/cartulary/bin/clean_duplicate_feeds.php + +##: This file should be EXEcutable! \ No newline at end of file diff --git a/releases/v0.6.12-notes.txt b/releases/v0.6.12-notes.txt new file mode 100644 index 00000000..16091d67 --- /dev/null +++ b/releases/v0.6.12-notes.txt @@ -0,0 +1,26 @@ +#Release Notes - Freedom Controller v0.6.12 + + +Catching up on old times. + +This is a big time catchup release. The biggest improvements here are structural. But there are some +visible things as well. + + +- Bug Fixes + - Improved updater script + - Lots of fixes in the river template scripts + - Fixed imgur.com parsing in cartulize script + - Re-enabled search v2 word map building + - OPML expansion state bug in rendered html + - Better defense on some RSS enclosure edge cases + - Fixed multiple bugs with RDF handling in the aggregator + +- New Feature: Unsticky All Button in River + - Does what it says. Unsticky all posts at once. + +- Improvements + - Save as... button in the editor now operates like a normal save as button by saving the outline + and then opening the new version, leaving the old one un-touched. + - Lots of structure changes to the app directory layout. + - Better handling and rendering of media uploads in the editor.