Skip to content

Commit

Permalink
client: Port entries to React
Browse files Browse the repository at this point in the history
  • Loading branch information
jtojnar committed Jan 26, 2021
1 parent a6b61fe commit f3b279c
Show file tree
Hide file tree
Showing 17 changed files with 939 additions and 857 deletions.
3 changes: 0 additions & 3 deletions assets/js/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'regenerator-runtime/runtime';
import './jquery';
import './lazy-image-loader';
import 'spectrum-colorpicker';
import 'jquery-hotkeys';
import selfoss from './selfoss-base';
Expand All @@ -11,8 +10,6 @@ import './selfoss-db';
import './selfoss-ui';
import './selfoss-events';
import './selfoss-events-navigation';
import './selfoss-events-entries';
import './selfoss-events-entriestoolbar';
import './selfoss-shortcuts';
import '@fancyapps/fancybox';

Expand Down
12 changes: 0 additions & 12 deletions assets/js/lazy-image-loader.js

This file was deleted.

85 changes: 37 additions & 48 deletions assets/js/selfoss-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ var selfoss = {
*/
htmlTitle: 'selfoss',

/**
* React component for entries page.
*/
entriesPage: null,

/**
* React component for sources page.
*/
Expand Down Expand Up @@ -421,10 +426,9 @@ var selfoss = {
anonymize: function(parent) {
var anonymizer = selfoss.config.anonymizer;
if (anonymizer !== null) {
parent.find('a').each(function(i, link) {
link = $(link);
if (typeof link.attr('href') != 'undefined' && link.attr('href').indexOf(anonymizer) != 0) {
link.attr('href', anonymizer + link.attr('href'));
parent.querySelectorAll('a').forEach((link) => {
if (typeof link.getAttribute('href') !== 'undefined' && !link.getAttribute('href').startsWith(anonymizer)) {
link.setAttribute('href', anonymizer + link.getAttribute('href'));
}
});
}
Expand Down Expand Up @@ -457,74 +461,59 @@ var selfoss = {
* Mark all visible items as read
*/
markVisibleRead: function() {
var ids = [];
var tagUnreadDiff = {};
var sourceUnreadDiff = [];
$('.entry.unread').each(function(index, item) {
ids.push($(item).attr('data-entry-id'));

$('.entry-tags-tag', item).each(function(index, tagEl) {
var tag = $(tagEl).html();
let ids = [];
let tagUnreadDiff = {};
let sourceUnreadDiff = [];

let markedEntries = selfoss.entriesPage.state.entries.map((entry) => {
if (!entry.unread) {
return entry;
}

ids.push(entry.id);

Object.keys(entry.tags).forEach((tag) => {
if (Object.keys(tagUnreadDiff).includes(tag)) {
tagUnreadDiff[tag] += -1;
} else {
tagUnreadDiff[tag] = -1;
}
});

const source = $(item).data('entry-source');
const { source } = entry;
if (Object.keys(sourceUnreadDiff).includes(source)) {
sourceUnreadDiff[source] += -1;
} else {
sourceUnreadDiff[source] = -1;
}

return {
...entry,
unread: false
};
});
const oldEntries = selfoss.entriesPage.state.entries;
const hadMore = selfoss.entriesPage.state.hasMore;

// close opened entry and list
selfoss.filterReset({}, true);

if (ids.length === 0 && selfoss.filter.type === FilterType.UNREAD) {
$('.entry').remove();
if (selfoss.unreadItemsCount.value > 0) {
selfoss.db.reloadList();
} else {
selfoss.ui.refreshStreamButtons(true);
}
}

if (ids.length === 0) {
return;
if (ids.length !== 0 && selfoss.filter.type === FilterType.UNREAD) {
markedEntries = markedEntries.filter(({ id }) => ids.includes(id));
}

var content = $('#content');
var articleList = content.html();
var hadMore = $('.stream-more').is(':visible');

selfoss.ui.beforeReloadList();
selfoss.entriesPage.setLoadingState(LoadingState.LOADING);
selfoss.entriesPage.setEntries(markedEntries);

const unreadstats = selfoss.unreadItemsCount.value - ids.length;
var displayed = false;
var displayNextUnread = function() {
if (!displayed) {
displayed = true;
selfoss.refreshUnread(unreadstats);
selfoss.ui.refreshTagSourceUnread(tagUnreadDiff,
sourceUnreadDiff);

selfoss.ui.hideMobileNav();

selfoss.db.reloadList(false, false);
}
};

if (selfoss.db.enableOffline) {
selfoss.refreshUnread(unreadstats);
selfoss.dbOffline.entriesMark(ids, false).then(displayNextUnread);
selfoss.dbOffline.entriesMark(ids, false);
}

itemsRequests.markAll(ids).then(function() {
selfoss.db.setOnline();
displayNextUnread();
selfoss.entriesPage.setLoadingState(LoadingState.SUCCESS);
}).catch(function(error) {
selfoss.handleAjaxError(error).then(function() {
let statuses = ids.map(id => ({
Expand All @@ -534,9 +523,9 @@ var selfoss = {
}));
selfoss.dbOffline.enqueueStatuses(statuses);
}).catch(function(error) {
content.html(articleList);
selfoss.ui.refreshStreamButtons(true, hadMore);
selfoss.ui.listReady();
selfoss.entriesPage.setLoadingState(LoadingState.SUCCESS);
selfoss.entriesPage.setEntries(oldEntries);
selfoss.entriesPage.setHasMore(hadMore);
selfoss.ui.showError(selfoss.ui._('error_mark_items') + ' ' + error.message);
});
});
Expand Down
1 change: 0 additions & 1 deletion assets/js/selfoss-db-offline.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ selfoss.dbOffline = {
});

selfoss.ui.setOnline();
$('#content').addClass('loading');
selfoss.db.tryOnline()
.then(function() {
selfoss.reloadTags();
Expand Down
11 changes: 5 additions & 6 deletions assets/js/selfoss-db-online.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'jsx-dom';
import selfoss from './selfoss-base';
import * as itemsRequests from './requests/items';
import Item from './templates/Item';
import { LoadingState } from './requests/LoadingState';
import { FilterType } from './Filter';

selfoss.dbOnline = {
Expand Down Expand Up @@ -187,8 +186,8 @@ selfoss.dbOnline = {
}

if ('stats' in data && data.stats.unread > 0 &&
($('.stream-empty').is(':visible') ||
$('.stream-error').is(':visible'))) {
selfoss.entriesPage && (selfoss.entriesPage.state.entries.length === 0 ||
selfoss.entriesPage.state.entries.loadingState === LoadingState.FAILURE)) {
selfoss.db.reloadList();
} else {
if ('itemUpdates' in data) {
Expand All @@ -202,8 +201,8 @@ selfoss.dbOnline = {
} else {
unreadCount = selfoss.unreadItemsCount.value;
}
if (unreadCount > $('.entry.unread').length) {
$('.stream-more').show();
if (selfoss.entriesPage && unreadCount > selfoss.entriesPage.state.entries.filter(({ unread }) => unread == 1).length) {
selfoss.entriesPage.setHasMore(true);
}
}
}
Expand Down
50 changes: 29 additions & 21 deletions assets/js/selfoss-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@
* dbOffline is the entry point for the offline database held in the client.
*/

import React from 'jsx-dom';
import selfoss from './selfoss-base';
import { OfflineStorageNotAvailableError } from './errors';
import { FilterType } from './Filter';
import Item from './templates/Item';
import { LoadingState } from './requests/LoadingState';

selfoss.db = {

Expand Down Expand Up @@ -120,7 +119,7 @@ selfoss.db = {
selfoss.dbOffline.olderEntriesOnline = false;
}

selfoss.ui.beforeReloadList(!append);
selfoss.entriesPage?.setLoadingState(LoadingState.LOADING);

var reload = function() {
let reloader = selfoss.dbOffline.reloadList;
Expand All @@ -136,31 +135,40 @@ selfoss.db = {
reloader = selfoss.dbOnline.reloadList;
}

selfoss.entriesPage?.setLoadingState(LoadingState.LOADING);
reloader().then(({ entries, hasMore }) => {
const firstPage = typeof selfoss.filter.fromId === 'undefined' && typeof selfoss.filter.fromDatetime === 'undefined';
const allowedToUpdate = !selfoss.config.authEnabled || selfoss.config.allowPublicUpdate || selfoss.loggedin.value;
selfoss.entriesPage.setLoadingState(LoadingState.SUCCESS);
selfoss.entriesPage.setHasMore(hasMore);

let content = $('#content');
let newContent = content.clone().empty();
if (selfoss.filter.source && allowedToUpdate && firstPage && reloader === selfoss.dbOnline.reloadList) {
newContent.append(<button type="button" id="refresh-source" class="refresh-source">{selfoss.ui._('source_refresh')}</button>);
}
newContent.append(entries.map(entry => <Item item={entry} />));

if (!firstPage) {
content.append(newContent.children());
if (append) {
selfoss.entriesPage.appendEntries(entries);
} else {
content.replaceWith(newContent);
selfoss.entriesPage.setExpandedEntries({});
selfoss.entriesPage.setEntries(entries);
}

selfoss.ui.refreshStreamButtons(true, hasMore);

selfoss.ui.afterReloadList(!append);
// open selected entry only if entry was requested (i.e. if not streaming
// more)
if (selfoss.events.entryId && selfoss.filter.fromId === undefined) {
var entry = document.querySelector(`.entry[data-entry-id="${selfoss.events.entryId}"]`);

if (!entry) {
return;
}

selfoss.ui.entryActivate(selfoss.events.entryId);
// ensure scrolling to requested entry even if scrolling to article
// header is disabled
if (!selfoss.config.scrollToArticleHeader) {
// needs to be delayed for some reason
requestAnimationFrame(function() {
entry.scrollIntoView();
});
}
}
}).catch(function(error) {
selfoss.entriesPage.setLoadingState(LoadingState.FAILURE);
selfoss.ui.showError(selfoss.ui._('error_loading') + ' ' + error.message);
selfoss.events.entries();
selfoss.ui.refreshStreamButtons();
$('.stream-error').show();
});
};

Expand Down
Loading

0 comments on commit f3b279c

Please # to comment.