Skip to content

Commit

Permalink
client: Port nav filters to react
Browse files Browse the repository at this point in the history
  • Loading branch information
jtojnar committed Jan 4, 2021
1 parent ca017f6 commit 8adf6fe
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 95 deletions.
26 changes: 26 additions & 0 deletions assets/js/helpers/ValueListenable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export class ValueChangeEvent extends Event {
constructor(value) {
super('change');
this.value = value;
}
}

/**
* Object storing a value and allowing subscribing to its changes.
*/
export class ValueListenable extends EventTarget {
constructor(value) {
super();

this.value = value;
}

update(value) {
if (this.value !== value) {
this.value = value;

const event = new ValueChangeEvent(value);
this.dispatchEvent(event);
}
}
}
67 changes: 55 additions & 12 deletions assets/js/selfoss-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getInstanceInfo, login, logout } from './requests/common';
import * as itemsRequests from './requests/items';
import { getAllTags } from './requests/tags';
import * as ajax from './helpers/ajax';
import { ValueListenable } from './helpers/ValueListenable';
import { HttpError, TimeoutError } from './errors';
import { LoadingState } from './requests/LoadingState';

Expand All @@ -23,6 +24,12 @@ var selfoss = {
*/
filter: new Filter({}),

/**
* whether off-line mode is enabled
* @var ValueListenable
*/
offlineState: new ValueListenable(false),

/**
* tag repository
* @var Tags
Expand All @@ -35,6 +42,42 @@ var selfoss = {
*/
sources: new Sources({}),

/**
* number of unread items
* @var ValueListenable
*/
unreadItemsCount: new ValueListenable(0),

/**
* number of unread items available offline
* @var ValueListenable
*/
unreadItemsOfflineCount: new ValueListenable(0),

/**
* number of starred items
* @var ValueListenable
*/
starredItemsCount: new ValueListenable(0),

/**
* number of starred items available offline
* @var ValueListenable
*/
starredItemsOfflineCount: new ValueListenable(0),

/**
* number of all items
* @var ValueListenable
*/
allItemsCount: new ValueListenable(0),

/**
* number of all items available offline
* @var ValueListenable
*/
allItemsOfflineCount: new ValueListenable(0),

/**
* instance of the currently running XHR that is used to reload the items list
*/
Expand Down Expand Up @@ -336,13 +379,13 @@ var selfoss = {
* refresh stats.
*
* @return void
* @param new all stats
* @param new unread stats
* @param new starred stats
* @param {Number} new all stats
* @param {Number} new unread stats
* @param {Number} new starred stats
*/
refreshStats: function(all, unread, starred) {
$('.nav-filter-newest span.count').html(all);
$('.nav-filter-starred span.count').html(starred);
selfoss.allItemsCount.update(all);
selfoss.starredItemsCount.update(starred);

selfoss.refreshUnread(unread);
},
Expand All @@ -352,15 +395,16 @@ var selfoss = {
* refresh unread stats.
*
* @return void
* @param new unread stats
* @param {Number} new unread stats
*/
refreshUnread: function(unread) {
$('.unread-count .count').html(unread);
$('#nav-mobile-count .count').html(unread);
selfoss.unreadItemsCount.update(unread);

if (unread > 0) {
$('.unread-count').addClass('unread');
$('#nav-mobile-count').addClass('unread');
} else {
$('.unread-count').removeClass('unread');
$('#nav-mobile-count').removeClass('unread');
}

selfoss.ui.refreshTitle(unread);
Expand Down Expand Up @@ -462,7 +506,7 @@ var selfoss = {

if (ids.length === 0 && selfoss.filter.type === FilterType.UNREAD) {
$('.entry').remove();
if (parseInt($('.unread-count .count').html()) > 0) {
if (selfoss.unreadItemsCount.value > 0) {
selfoss.db.reloadList();
} else {
selfoss.ui.refreshStreamButtons(true);
Expand All @@ -479,8 +523,7 @@ var selfoss = {

selfoss.ui.beforeReloadList();

var unreadstats = parseInt($('.nav-filter-unread span.count').html()) -
ids.length;
const unreadstats = selfoss.unreadItemsCount.value - ids.length;
var displayed = false;
var displayNextUnread = function() {
if (!displayed) {
Expand Down
3 changes: 1 addition & 2 deletions assets/js/selfoss-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,7 @@ selfoss.dbOnline = {
if ('stats' in data) {
unreadCount = data.stats.unread;
} else {
unreadCount = parseInt($('.unread-count .count')
.html());
unreadCount = selfoss.unreadItemsCount.value;
}
if (unreadCount > $('.entry.unread').length) {
$('.stream-more').show();
Expand Down
21 changes: 10 additions & 11 deletions assets/js/selfoss-events-entriestoolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,15 @@ selfoss.events.entriesToolbar = function(parent) {

selfoss.ui.entryStar(id, starr);

// update statistics in main menue
var updateStats = function(starr) {
var starred = parseInt($('.nav-filter-starred span.count').html());
// update statistics in main menu
function updateStats(starr) {
const starred = selfoss.starredItemsCount.value;
if (starr) {
starred++;
selfoss.starredItemsCount.update(starred + 1);
} else {
starred--;
selfoss.starredItemsCount.update(starred - 1);
}
$('.nav-filter-starred span').html(starred);
};
}
updateStats(starr);

if (selfoss.db.enableOffline) {
Expand Down Expand Up @@ -126,10 +125,10 @@ selfoss.events.entriesToolbar = function(parent) {
selfoss.ui.entryMark(id, !unread);

// update statistics in main menue and the currently active tag
var updateStats = function(unread) {
function updateStats(unread) {
// update all unread counters
var unreadstats = parseInt($('.nav-filter-unread span.count').html());
var diff = unread ? -1 : 1;
const unreadstats = selfoss.unreadItemsCount.value;
const diff = unread ? -1 : 1;

selfoss.refreshUnread(unreadstats + diff);

Expand All @@ -143,7 +142,7 @@ selfoss.events.entriesToolbar = function(parent) {
entryTags,
{[entry.attr('data-entry-source')]: diff}
);
};
}
updateStats(unread);

if (selfoss.db.enableOffline) {
Expand Down
28 changes: 1 addition & 27 deletions assets/js/selfoss-events-navigation.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,10 @@
import selfoss from './selfoss-base';
import * as sourceRequests from './requests/sources';
import { FilterType } from './Filter';
import { filterTypeToString } from './helpers/uri';

/**
* initialize navigation events
*/
selfoss.events.navigation = function() {
// filter
$('#nav-filter > li > a').unbind('click').click(function(e) {
e.preventDefault();

if ($(this).hasClass('nav-filter-newest')) {
selfoss.filter.update({ type: FilterType.NEWEST });
} else if ($(this).hasClass('nav-filter-unread')) {
selfoss.filter.update({ type: FilterType.UNREAD });
} else if ($(this).hasClass('nav-filter-starred')) {
selfoss.filter.update({ type: FilterType.STARRED });
}

selfoss.events.reloadSamePath = true;
if (selfoss.events.lastSubsection == null) {
selfoss.events.lastSubsection = 'all';
}
selfoss.events.setHash(filterTypeToString(selfoss.filter.type), 'same');

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

selfoss.ui.hideMobileNav();
});

// hide/show filters
$('#nav-filter-title').unbind('click').click(function() {
$('#nav-filter').slideToggle('slow');
Expand Down Expand Up @@ -120,7 +94,7 @@ selfoss.events.navigation = function() {

// probe stats and prompt reload to the user
selfoss.dbOnline.sync().then(function() {
if ($('.unread-count').hasClass('unread')) {
if (selfoss.unreadItemsCount.value > 0) {
selfoss.ui.showMessage(selfoss.ui._('sources_refreshed'), [
{
label: selfoss.ui._('reload_list'),
Expand Down
67 changes: 24 additions & 43 deletions assets/js/selfoss-ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import locales from './locales';
import selfoss from './selfoss-base';
import { initIcons } from './icons';
import * as NavSources from './templates/NavSources';
import * as NavFilters from './templates/NavFilters';
import * as NavTags from './templates/NavTags';

/**
Expand Down Expand Up @@ -61,34 +62,7 @@ selfoss.ui = {
<div id="nav-logo"></div>
<button accesskey="a" id="nav-mark">{selfoss.ui._('markread')}</button>

<div id="nav-filter-wrapper">
<h2><button type="button" id="nav-filter-title" class="nav-section-toggle nav-filter-expanded" aria-expanded="true"><i class="fas fa-caret-down fa-lg fa-fw"></i> {selfoss.ui._('filter')}</button></h2>
<ul id="nav-filter" aria-labelledby="nav-filter-title">
<li>
<a id="nav-filter-newest" class="nav-filter-newest" href="#">
{selfoss.ui._('newest')}
<span class="offline-count offlineable" title={selfoss.ui._('offline_count')}></span>
<span class="count" title={selfoss.ui._('online_count')}></span>
</a>
</li>
<li>
<a id="nav-filter-unread" class="nav-filter-unread" href="#">
{selfoss.ui._('unread')}
<span class="unread-count offlineable">
<span class="offline-count offlineable" title={selfoss.ui._('offline_count')}></span>
<span class="count" title={selfoss.ui._('online_count')}></span>
</span>
</a>
</li>
<li>
<a id="nav-filter-starred" class="nav-filter-starred" href="#">
{selfoss.ui._('starred')}
<span class="offline-count offlineable" title={selfoss.ui._('offline_count')}></span>
<span class="count" title={selfoss.ui._('online_count')}></span>
</a>
</li>
</ul>
</div>
<div id="nav-filter-wrapper" />

<div class="separator"><hr /></div>

Expand Down Expand Up @@ -146,6 +120,8 @@ selfoss.ui = {
</div>
</div>);

NavFilters.anchor(document.querySelector('#nav-filter-wrapper'), selfoss.filter);

// Cannot add these to the append above, since jQuery automatically cache-busts links, which would prevent them from loading off-line.
if (selfoss.config.userCss !== null) {
let link = document.createElement('link');
Expand Down Expand Up @@ -226,7 +202,7 @@ selfoss.ui = {


refreshTitle: function(unread) {
unread = (typeof unread !== 'undefined') ? unread : parseInt($('.unread-count .count').html());
unread = (typeof unread !== 'undefined') ? unread : selfoss.unreadItemsCount.value;

if (unread > 0) {
$(document).attr('title', selfoss.htmlTitle + ' (' + unread + ')');
Expand All @@ -248,13 +224,15 @@ selfoss.ui = {


setOffline: function() {
selfoss.offlineState.update(true);
$('.offlineable').addClass('offline');
$('.offlineable').removeClass('online');
selfoss.events.navigation();
},


setOnline: function() {
selfoss.offlineState.update(false);
$('.offlineable').addClass('online');
$('.offlineable').removeClass('offline');
selfoss.events.navigation();
Expand Down Expand Up @@ -764,24 +742,27 @@ selfoss.ui = {


refreshOfflineCounts: function(offlineCounts) {
for (let [kind, count] of Object.entries(offlineCounts)) {
var selector = '#nav-filter-' + kind;
if (kind == 'unread') {
selector = selector + ', #nav-mobile-count';
for (let [kind, newCount] of Object.entries(offlineCounts)) {
if (newCount === 'keep') {
continue;
}
var widget = $(selector);
var offlineWidget = $('span.offline-count', widget);

if (count == 'keep') {
count = parseInt(offlineWidget.html());
} else {
offlineWidget.html(count);
if (kind === 'newest') {
kind = 'all';
}

if (parseInt($('span.count', widget).html()) != count) {
offlineWidget.addClass('diff');
} else {
offlineWidget.removeClass('diff');
const count = selfoss[`${kind}ItemsCount`];
const offlineCount = selfoss[`${kind}ItemsOfflineCount`];

offlineCount.update(newCount);
if (kind === 'unread') {
$('#nav-mobile-count span.offline-count').html(newCount);

if (count.value !== offlineCount.value) {
$('#nav-mobile-count span.offline-count').addClass('diff');
} else {
$('#nav-mobile-count span.offline-count').removeClass('diff');
}
}
}
}
Expand Down
Loading

0 comments on commit 8adf6fe

Please sign in to comment.