Skip to content

Commit

Permalink
make selfoss navigable (fossar#243)
Browse files Browse the repository at this point in the history
This pages modifies the client ui to make heavy use of location.hash: hash
changes are now responsible for loading the entry list.

Another big change is that the server side template is basically empty of any
data. It is loaded via the same client side code responsible for updating
item lists, tags, stats, etc.
  • Loading branch information
niol committed Dec 22, 2016
1 parent f6a0a0b commit 8b7f8d2
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 88 deletions.
17 changes: 10 additions & 7 deletions controllers/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,19 @@ public function home() {
$options = array();
if (\F3::get('homepage')!='')
$options = array( 'type' => \F3::get('homepage') );

// use ajax given params?
if(count($_GET)>0)
$options = $_GET;


if(!isset($options['ajax'])) {
// show as full html page
$this->view->publicMode = \F3::get('auth')->isLoggedin()!==true && \F3::get('public')==1;
$this->view->loggedin = \F3::get('auth')->isLoggedin()===true;
echo $this->view->render('templates/home.phtml');
return;
}

// get search param
if(isset($options['search']) && strlen($options['search'])>0)
$this->view->search = $options['search'];
Expand Down Expand Up @@ -81,11 +89,6 @@ public function home() {
"sources" => $this->view->sources
));
}

// show as full html page
$this->view->publicMode = \F3::get('auth')->isLoggedin()!==true && \F3::get('public')==1;
$this->view->loggedin = \F3::get('auth')->isLoggedin()===true;
echo $this->view->render('templates/home.phtml');
}


Expand Down
48 changes: 26 additions & 22 deletions public/js/selfoss-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ var selfoss = {

// set items per page
selfoss.filter.itemsPerPage = $('#config').data('items_perpage');

// initialize type by homepage config param
selfoss.filter.type = $('#nav-filter li.active').attr('id').replace('nav-filter-', '');
selfoss.filter.type = $('#config').data('homepage');

// read the html title configured
selfoss.htmlTitle = $('#config').data('html_title')
Expand Down Expand Up @@ -159,10 +159,12 @@ var selfoss = {
selfoss.activeAjaxReq.abort();

if (location.hash == "#sources") {
location.hash = "";
return;
}

if( selfoss.events.entryId )
selfoss.filter.extra_ids.push(selfoss.events.entryId);

$('.stream-error').css('display', 'block').hide();
$('#content').addClass('loading').html("");

Expand Down Expand Up @@ -193,16 +195,12 @@ var selfoss = {
selfoss.refreshSources(data.sources, currentSource);
},
error: function(jqXHR, textStatus, errorThrown) {
if (textStatus == "parsererror")
location.reload();
else {
if (textStatus == "abort")
return;
else if (errorThrown)
selfoss.showError('Load list error: '+
textStatus+' '+errorThrown);
$('.stream-error').show();
}
if (textStatus == "abort")
return;
else if (errorThrown)
selfoss.showError('Load list error: '+
textStatus+' '+errorThrown);
$('.stream-error').show();
},
complete: function(jqXHR, textStatus) {
// clean up
Expand Down Expand Up @@ -323,12 +321,18 @@ var selfoss = {
* @param tags the new taglist as html
*/
refreshTags: function(tags) {
var currentTag = $('#nav-tags li').index($('#nav-tags .active'));
$('.color').spectrum('destroy');
$('#nav-tags li:not(:first)').remove();
$('#nav-tags').append(tags);
if(currentTag>=0)
$('#nav-tags li:eq('+currentTag+')').addClass('active');
if( selfoss.filter.tag ) {
$('#nav-tags li:first').removeClass('active');
$('#nav-tags > li').filter(function( index ) {
if( $('.tag', this) )
return $('.tag', this).html() == selfoss.filter.tag;
else
return false;
}).addClass('active');
}
selfoss.events.navigation();
},

Expand All @@ -343,11 +347,9 @@ var selfoss = {
* @param currentSource the index of the active source
*/
refreshSources: function(sources, currentSource) {
var currentSourceIndex = currentSource >= 0 ? currentSource : $('#nav-sources li').index($('#nav-sources .active'));
$('#nav-sources li').remove();
$('#nav-sources').append(sources);
if(currentSourceIndex>=0)
$('#nav-sources li:eq('+currentSourceIndex+')').addClass('active');
$('#source' + selfoss.filter.source).addClass('active');
selfoss.events.navigation();
},

Expand Down Expand Up @@ -430,6 +432,11 @@ var selfoss = {
var articleList = content.html();
$('#content').addClass('loading').html("");

// close opened entry and list
location.hash = selfoss.events.path;
selfoss.filter.extra_ids.length = 0;
selfoss.filter.offset = 0;

$.ajax({
url: $('base').attr('href') + 'mark',
type: 'POST',
Expand All @@ -448,9 +455,6 @@ var selfoss = {
if(selfoss.isSmartphone() && $('#nav').is(':visible')==true)
$('#nav-mobile-settings').click();

// close opened entry
selfoss.events.itemId = null;

// refresh list
selfoss.reloadList();
},
Expand Down
14 changes: 11 additions & 3 deletions public/js/selfoss-events-entries.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ selfoss.events.entries = function(e) {
// anonymize
selfoss.anonymize(parent.find('.entry-content'));

var entryId = parent.attr('data-entry-id');

// show entry in popup
if(selfoss.isSmartphone()) {
location.hash = "show";

// hide nav
if($('#nav').is(':visible')) {
var scrollTop = $(window).scrollTop();
Expand All @@ -48,6 +48,7 @@ selfoss.events.entries = function(e) {
var fullscreen = $('#fullscreen-entry');
fullscreen.html('<div id="entrr'+parent.attr('data-entry-id')+'" class="entry fullscreen" data-entry-id="'+parent.attr('data-entry-id')+'">'+parent.html()+'</div>');
fullscreen.show();
location.hash = selfoss.events.path + '/' + entryId;

// lazy load images in fullscreen
if($('#config').data('load_images_on_mobile')=="1") {
Expand All @@ -66,7 +67,7 @@ selfoss.events.entries = function(e) {
$('#'+parent.attr('id')).hide();
}
content.show();
location.hash = "";
location.hash = selfoss.events.path;
$(window).scrollTop(scrollTop);
fullscreen.hide();
});
Expand All @@ -83,11 +84,13 @@ selfoss.events.entries = function(e) {
if(content.is(':visible')) {
parent.find('.entry-toolbar').hide();
content.hide();
location.hash = selfoss.events.path;
} else {
if($('#config').data('auto_collapse')=="1"){
$('.entry-content, .entry-toolbar').hide();
}
content.show();
location.hash = selfoss.events.path + '/' + entryId;
selfoss.events.entriesToolbar(parent);
parent.find('.entry-toolbar').show();

Expand Down Expand Up @@ -220,4 +223,9 @@ selfoss.events.entries = function(e) {
}
});
});

// open selected entry
if( selfoss.events.entryId) {
$('#entry' + selfoss.events.entryId).children('.entry-title').click();
}
};
37 changes: 15 additions & 22 deletions public/js/selfoss-events-navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,16 @@ selfoss.events.navigation = function() {
selfoss.filter.type='unread';
else if($(this).hasClass('nav-filter-starred'))
selfoss.filter.type='starred';

if( selfoss.events.section != selfoss.filter.type ) {
location.hash = '#' + selfoss.filter.type
+ '/' + selfoss.events.subsection;
}

$('#nav-filter > li').removeClass('active');
$(this).addClass('active');

selfoss.filter.offset = 0;
selfoss.filter.extra_ids.length = 0;
selfoss.reloadList();

if(selfoss.isSmartphone())
if(selfoss.isSmartphone() && $('#nav').is(':visible'))
$('#nav-mobile-settings').click();
});

Expand All @@ -69,16 +70,13 @@ selfoss.events.navigation = function() {
$('#nav-sources > li').removeClass('active');
$(this).addClass('active');

selfoss.filter.source = '';
selfoss.filter.tag = '';
if($(this).hasClass('nav-tags-all')==false)
selfoss.filter.tag = $(this).find('span').html();
if($(this).hasClass('nav-tags-all')==false) {
location.hash = '#' + selfoss.filter.type + '/tag-' + $(this).find('span').html();
} else {
location.hash = '#' + selfoss.filter.type + '/all';
}

selfoss.filter.offset = 0;
selfoss.filter.extra_ids.length = 0;
selfoss.reloadList();

if(selfoss.isSmartphone())
if(selfoss.isSmartphone() && $('#nav').is(':visible'))
$('#nav-mobile-settings').click();
});

Expand All @@ -96,15 +94,10 @@ selfoss.events.navigation = function() {
$('#nav-tags > li').removeClass('active');
$('#nav-sources > li').removeClass('active');
$(this).addClass('active');

location.hash = '#' + selfoss.filter.type + '/source-' + $(this).attr('id').substr(6);

selfoss.filter.tag = '';
selfoss.filter.source = $(this).attr('id').substr(6);

selfoss.filter.offset = 0;
selfoss.filter.extra_ids.length = 0;
selfoss.reloadList();

if(selfoss.isSmartphone())
if(selfoss.isSmartphone() && $('#nav').is(':visible'))
$('#nav-mobile-settings').click();
});

Expand Down
86 changes: 59 additions & 27 deletions public/js/selfoss-events.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ selfoss.events = {
/* last hash before hash change */
lasthash: "",

path: null,
lastpath: null,
section: null,
subsection: 'all',
entryId: null,

/**
* init events when page loads first time
*/
init: function() {
selfoss.events.navigation();
selfoss.events.entries();
selfoss.events.search();

// re-init on media query change
if ((typeof window.matchMedia) != "undefined") {
Expand All @@ -26,41 +30,71 @@ selfoss.events = {
});
$(window).bind("resize", selfoss.events.resize);
selfoss.events.resize();

if( location.hash == '' )
location.hash = '#' + $('#config').data('homepage') + '/all';

// hash change event
window.onhashchange = selfoss.events.hashChange;

// remove given hash (we just use it for history support)
if(location.hash.trim().length!=0)
location.hash = "";

// process current hash
selfoss.events.hashChange();
},


/**
* handle History change
*/
hashChange: function() {
// return to main page
if(location.hash.length==0) {
// from entry popup
if(selfoss.events.lasthash=="#show" && $('#fullscreen-entry').is(':visible')) {
$('#fullscreen-entry .entry-close').click();
}

// from sources
if(selfoss.events.lasthash=="#sources") {
$('#nav-filter li.active').click();
}

// from navigation
if(selfoss.events.lasthash=="#nav" && $('#nav').is(':visible')) {
$('#nav-mobile-settings').click();
if( location.hash == selfoss.events.lasthash )
return;

// parse hash
var hashPath = location.hash.substring(1).split('/');

selfoss.events.section = hashPath[0];

if( hashPath.length > 1 ) {
selfoss.events.subsection = hashPath[1];
} else
selfoss.events.subsection = 'all';

selfoss.events.lastpath = selfoss.events.path;
selfoss.events.path = selfoss.events.section
+ '/' + selfoss.events.subsection;

var entryId = null;
if( hashPath.length > 2 && (entryId = parseInt(hashPath[2])) )
selfoss.events.entryId = entryId;
else
selfoss.events.entryId = null;

selfoss.events.lasthash = location.hash;

// do not reload list if list is the same
if ( selfoss.events.lastpath == selfoss.events.path )
return;

// load items
if( $.inArray(selfoss.events.section,
["newest", "unread", "starred"]) > -1 ) {
selfoss.filter.tag = '';
selfoss.filter.source = '';
if( selfoss.events.subsection.substr(0, 4) == 'tag-') {
selfoss.filter.tag = selfoss.events.subsection.substr(4);
} else if( selfoss.events.subsection.substr(0, 7) == 'source-') {
var sourceId = parseInt(selfoss.events.subsection.substr(7));
if( sourceId ) {
selfoss.filter.source = sourceId;
}
}
}

// load sources
if(location.hash=="#sources") {

selfoss.filter.offset = 0;
selfoss.filter.extra_ids.length = 0;

$('#nav-filter-'+selfoss.events.section).click();
selfoss.reloadList();
} else if(location.hash=="#sources") { // load sources
if (selfoss.activeAjaxReq !== null)
selfoss.activeAjaxReq.abort();

Expand All @@ -84,8 +118,6 @@ selfoss.events = {
}
});
}

selfoss.events.lasthash = location.hash;
},


Expand Down
Loading

0 comments on commit 8b7f8d2

Please sign in to comment.