fossar / selfoss

multipurpose rss reader, live stream, mashup, aggregation web application
https://selfoss.aditu.de
GNU General Public License v3.0
2.36k stars 343 forks source link

Client side templates 3 #1216

Closed jtojnar closed 3 years ago

jtojnar commented 4 years ago

This is the last one. After this, we can start moving setting event handlers in jQuery onto the respective components and then finally switch to react or something.

Depends on #1215 Fixes #928

jtojnar commented 4 years ago

Ugh, I was getting Internal Server Error causing selfoss to go offline:

An error occurred: Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32202752 bytes)
[selfoss/src/helpers/View.php:121] 

I tried making the code lazier, which made it crash after almost 28 MB of content was send.

It looks like https://www.mmo-spy.de/news,id15008,blackjack-championship.html includes images as data URIs.

Replacing the building of $sync['newItems'] array with a generator seems to have finally fixed it.

jtojnar commented 4 years ago

I managed to reproduce the incompatibility in IndexedDB schema when upgrading:

Unhandled rejection: TypeError: item.icon is undefined

And logging out does not seem to be sufficient because selfoss.db.storage is set to null on failure so the logout cannot clear it:

https://github.com/SSilence/selfoss/blob/7bacaab321d48813777934ac129a0db1d81c5c64/assets/js/selfoss-events-navigation.js#L237

jtojnar commented 4 years ago

And looks like GCEntries is another place that expects storage to be present but it is cleared before running it:

https://github.com/SSilence/selfoss/blob/7bacaab321d48813777934ac129a0db1d81c5c64/assets/js/selfoss-db.js#L324-L330

jtojnar commented 3 years ago

The clearing of selfoss.db.storage should be fixed now.

I also fixed ServiceWorker not being registered, which I broke in 16f1cd6a52ee6dffac61d82a7fdd368c8b4ecd68 and sync event handler after update that I missed in dd8d4285c34308fb5d9283ff18c5148e6d610881.

jtojnar commented 3 years ago

I just finished porting the tag menu in the sidebar to real React – no more mutating its DOM with jQuery. We now have two JSX libraries React + react-dom here, and jsx-dom in all other templates. The latter is still used so that we can create DOM elements using JSX instead of string templating and $(html)/element.innerHTML.

I would like to get rid of DOM mutations eventually and use React everywhere but we are currently mutating the DOM all over the place. Fortunately, the conversion can be done piecemeal as demonstrated in client: Use real React for NavTags commit.

We cannot really pass new data to the components when we process HTTP responses so we need to create EventTarget objects and pass them to the components so that the components can add event listeners and we can pass them changed data through dispatching events.

jtojnar commented 3 years ago

I have made an initial port of the settings/sources page. This is getting into more messy territory and more clean-ups will be necessary but I think it is already a lot nicer than the previous pasta dish.

Unlike with the sidebar, I have opted to track the state using a stateful React component, rather than custom EventTarget classes. This approach is kind of similar to the previous one (calling the component’s method to pass it data in AJAX handler) but the source page is only really instantiated in a single place so it should not matter much.

@niol do you think you could give this a brief look and comment whether you think this approach is sensible?

jtojnar commented 3 years ago

selfoss is now fully ported to React, including the URL routing. There is still some jQuery usage but only for minor things (and lightbox).

The App component is mounted in selfoss.ui.init and routing is done in the App. Going to one of LoginForm, SourcesPage or EntriesPage. The latter two load its data in useEffect at the start of rendering.

The selfoss.db.* functions are still used for most cases and they update selfoss.tags and selfoss.sources where they previously filled the sidebar with tags and sources. The NavTags and NavSources components listen for updates of selfoss.tags and selfoss.sources, and redraw when the repositories are populated.

In the future, I want to move even more stuff into react components and simplify the control flow even more (no more methods calling methods changing the app state) but this is already a huge improvement and I want to release 2.19 as soon as possible.

jtojnar commented 3 years ago

Rebased and will merge once CI passes.