Skip to content

Add service newsblur - #183

Open
Simx72 wants to merge 5 commits into
FluentFlame:masterfrom
Simx72:add-service-newsblur
Open

Simx72 wants to merge 5 commits into
FluentFlame:masterfrom
Simx72:add-service-newsblur

Conversation

@Simx72

@Simx72 Simx72 commented Jul 31, 2026

Copy link
Copy Markdown

Hello, this is my pull request to add the service Newsblur to the Fluentflame project.

I have added the files newsblur.ts and test_newsblur.ts.

For the implementation, I have copied other implementations from the folder services/ and adapted them to Newsblur.

For the development, I used:

There is some stuff that I still don't understand about Redux and Fluentflame Reader, like when to use dispatch and what should it return, or where are RSSSources and RSSItem stored.

However, I am pretty shure that the authenticate(), updateSources(), syncItems() and markAllRead() are implemented correctly.

I stay available for changes, concerns, etc. I'd really like to learn how it's implemented in its entirety.

@Simx72

Simx72 commented Jul 31, 2026

Copy link
Copy Markdown
Author

Oh, and I was signing with the wrong key. My bad

@CrystalSplitter

Copy link
Copy Markdown
Collaborator

I haven't forgotten about this, but there's a lot to go over here (and indeed, we should squash much of this). BUT I appreciate the effort, and I'll go through everything detailed soon-ish.

@CrystalSplitter
CrystalSplitter self-requested a review August 6, 2026 00:45

@CrystalSplitter CrystalSplitter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good work! I think we can work with this, actually.

There's a bunch of style issues, but I do not consider these a blocker and I can clean them up myself, as it's no hassle for me.

I've left minor comments, but overall my only question here is the large amount of commented out tests and todos.

I'm not quite ready to approve, but I think we're close.

Comment thread .zed/settings.json Outdated
Comment thread tests/scripts/models/services/test_newsblur.ts Outdated
Comment thread src/scripts/models/services/newsblur.ts Outdated
Comment thread src/scripts/models/services/newsblur.ts Outdated
Comment thread src/scripts/models/services/newsblur.ts Outdated
Comment thread src/scripts/models/services/newsblur.ts
Comment thread src/scripts/models/services/newsblur.ts Outdated
const url = new URL(configs.endpoint + path);
// set headers
const headers = new Headers();
headers.set("Content-Type", "application/x-www-form-urlencoded");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, interesting. This is fine, but why?

Comment thread src/scripts/models/services/newsblur.ts Outdated
Comment thread src/scripts/models/services/newsblur.ts
@CrystalSplitter

Copy link
Copy Markdown
Collaborator

Also can you squash/rebase your commits into three commits:

  1. Any deps changes, e.g. "pnpm" changes
  2. The actual service
  3. The tests

Use

git rebase -i origin/master

and then mark the commits as s accordingly to squash (or f for fixup).

@Simx72

Simx72 commented Aug 7, 2026 •

Copy link
Copy Markdown
Author

Wow. Thank you so much for taking the time to review it. I sort of lost my "nord" coding this, but now I really know what to do. I'll take the time to answer each question... eventually (I think I can do it on my phone with the GitHub app, so soon late-ish, it will take more time than expected).

Also, I didn't know the commits could be rebased, I thought once it was committed, you couldn't change it anymore. I'll make a more proper pull request next time.

Once again, thank you!

@Simx72

Simx72 commented Aug 19, 2026 •

Copy link
Copy Markdown
Author

I didn't notice everything I pushed was shown here xd

Should I squash now or at the very end?

@CrystalSplitter

Copy link
Copy Markdown
Collaborator

Should I squash now or at the very end?

It'll probably be easier for you to squash now. I'll re-review them this coming week.

@Simx72

Simx72 commented Aug 25, 2026 •

Copy link
Copy Markdown
Author

Thank you!! However, I might take more time. I just came back from vacations to university and there is a jam this week I want to participate to (Brackeys' jam). If I finish everything soon, I'll probably do this, but I'm not sure, and because it's the first time I squash, I want to take the time to do it properly for the next review.

Is that ok for you?

@CrystalSplitter

CrystalSplitter commented Aug 25, 2026 •

Copy link
Copy Markdown
Collaborator

I see, in that case, don't squash. There's too much risk in you deleting everything. I highly recommend in practice getting used to working with git if this is your first real open source contribution! I can just take this code and rework it. It's okay!

Enjoy the jam!!!

@Simx72

Simx72 commented Aug 25, 2026 •

Copy link
Copy Markdown
Author

Wow, I... thank you so much

And yes, this is my first contribution ever. In code and, in fact, in whatever. I had used a lot of open source and written a lot of code but never contributed.

Also, for context. Do you want this feature fast or at any time? I would like to finish this and make a proper contribution. However, I don't want to slow down your stuff. I am really motivated to work on this, I just haven't had the time. I expect to finish this around December (like as a goal, planned, in my calendar).

Is that ok?

@CrystalSplitter

CrystalSplitter commented Aug 25, 2026 •

Copy link
Copy Markdown
Collaborator

Taking your time is perfectly fine. There's two big risks here:

  • This PR dies, because you get bored or demotivated. All your work kinda gets wasted. This is the most likely outcome the longer this goes on. Everyone gets bored and frustrated and that's just normal.
  • This PR lands, but it's in a really bad state and we can't maintain it, so we have to delete the code anyways. And everyone gets frustrated.

These are both two very real possibilities and I really don't want either. And so, I've been trying to direct your work to avoid these two scenarios. This means generally being willing to accept less experienced contributions, but still trying to give guidance on how to write code that integrates into a larger project.


In the general software engineering world, code is a liability. The less code, the better. Simple solutions are highly praised, and overcomplexity gums everything up. So I'm trying to push you to make small, clearly correct contributions. The less code, the better. The more clearly correct, the better. This is hard work! But it's something I spend a lot of time teaching students and interns on in my day job, so I'm used to it.

Smaller code is also a lot more motivating for new programmers, because their changes are more likely to land. Less work from everyone, and you get to test your skills out without waiting months or years to get everything in order.

@Simx72

Simx72 commented Aug 31, 2026

Copy link
Copy Markdown
Author

Hello @CrystalSplitter,

Uhm, several things...

First, I have copied a structure from other services that I still don't understand: why are you creating an object with RSSItem properties and "casting" its type to RSSItem instead of calling the RSSItem constructor?

// feedbin.ts : line 175 
const item = {
    source: source.sid,
    title: i.title,
    link: i.url,
    date: new Date(i.published),
    fetchedDate: new Date(i.created_at),
    content: i.content,
    snippet: dom.documentElement.textContent.trim(),
    creator: i.author,
    hasRead: !unread.has(i.id),
    starred: starred.has(i.id),
    hidden: false,
    notify: false,
    serviceRef: String(i.id),
} as RSSItem;

Is there a reason to not use the RSSItem constructor. Also, in that case, the produced object will not have RSSItem methods. If the function expects to get returned an RSSItem, then the devs have to remember that what this function creates is not actually an RSSItem but an RSSItem-like object, and bind its methods instead?

I mean, I really don't understand that part.

Second, I think you already told me but I "refound" it again, is the property RSSItem.thumb just an url? I can just pass the url to an image? I mean, it makes sense but I was overthinking it probably...

Third, just to make sure. So RSSItem.serviceRef is like the id of that specific blog post in Newsblur server. I can just set to that property the story_hash send by Newsblur and then retrieve it without changes when starring or unstarring that item?

Once again, thank you. I know I am a beginner and a lot of these questions are probably obvious, but I can tell you that I won't leave this project, not before Fluentflame is working perfectly with Newsblur. It is also a personal goal for me. And, I'm not using any AI for this (may be irrelevant, but if you ever wonder; I also find it disrespectful to send someone elses code to an AI that will feed from it without the author's consent).

@CrystalSplitter

CrystalSplitter commented Aug 31, 2026 •

Copy link
Copy Markdown
Collaborator

First, I have copied a structure from other services that I still don't understand: why are you creating an object with RSSItem properties and "casting" its type to RSSItem instead of calling the RSSItem constructor?

So this original code from Feedbin is a mess (not your fault! or mine really...).
This isn't a "real" RSSItem. It only contains all the fields of an RSSItem, but its not actually one. feedbin.ts is treating this Pseudo-RSSItem as duck-typed. And that's okay, because all methods of RSSItem are static, meaning that we don't have to have a function reference to them from each object. So nothing can ever go boom because of this little bit of type-abuse.

To sum: because all methods of RSSItem are static, this will never come back to bite us.

Personally, I hate this. But it's there and I'm not tearing out things that work just because they are bad style.

Second, I think you already told me but I "refound" it again, is the property RSSItem.thumb just an url? I can just pass the url to an image? I mean, it makes sense but I was overthinking it probably...

We use thumbnails instead of thumb now, as this lets us control multiple thumbnails as a preference order. thumbnails is a list of URLs.

You may also like thumbnailJobs, which is a list of promises of URL fetches. This is how we can asynchronously fetch thumbnails while still completing the display sync in quick enough time. I'd recommend using generateThumbnailAttrList to generate the thumbnail jobs and just leaving it at that. Assuming that works, as those will only be populated on fetchItems.

If you set thumbnailJobs, do not set thumbnails to anything besides an empty list. Similarly, if you set thumbnails, do not set thumbnailJobs as anything besides an empty list.

Third, just to make sure. So RSSItem.serviceRef is like the id of that specific blog post in Newsblur server. I can just set to that property the story_hash send by Newsblur and then retrieve it without changes when starring or unstarring that item?

serviceRef is a unique identifier on the service side, in this case Newsblur. serviceRef should map to exactly one item on the Newsblur side. This is most commonly a hash. It must not change once set, on either side. If it does, then the mapping will no longer be correct and you'll get duplicate articles/missing articles.

@CrystalSplitter

Copy link
Copy Markdown
Collaborator

We use thumbnails instead of thumb now, as this lets us control multiple thumbnails as a preference order. thumbnails is a list of URLs.

Correction, thumbnails is a list of ThumbnailAttributes, which is an interface defined here.

@Simx72

Simx72 commented Aug 31, 2026

Copy link
Copy Markdown
Author

Regarding the sync functions. Are they like importing stars (and unreads) from the server, or sending local stars to the server? Or both at the same time/how?

@Simx72

Simx72 commented Aug 31, 2026

Copy link
Copy Markdown
Author

And. I think I will stop using pnpm, I am having a lot of problems using it and installing it every time I clone the project. Should I remove the pnpm files as well?

@CrystalSplitter

Copy link
Copy Markdown
Collaborator

And. I think I will stop using pnpm, I am having a lot of problems using it and installing it every time I clone the project. Should I remove the pnpm files as well?

Yeah, that's a good idea probably.

@CrystalSplitter

CrystalSplitter commented Aug 31, 2026 •

Copy link
Copy Markdown
Collaborator

Regarding the sync functions. Are they like importing stars (and unreads) from the server, or sending local stars to the server? Or both at the same time/how?

Services are intended to be two-way communication wherever possible. This is especially critical for unreads, and is the entire point of the service, generally. If you read an article on one client, it needs to propagate to another. This requires two way communication. You can see how this works in fever.ts with the markItem function on how we conduct POST operations via the fetchAPI call.

@Simx72

Simx72 commented Sep 2, 2026

Copy link
Copy Markdown
Author

I am sort of starting to understand how fluentflame works for real. I will redo the sync functions, to make them look more like fever's.

@Simx72

Simx72 commented Sep 6, 2026

Copy link
Copy Markdown
Author

Hello @CrystalSplitter

I have finally finished fetchItems() function. I am proud of it, it was a function I could barely understand the first time. Now I made it and I think it's easy to read and understand it.

I still have questions about serviceRef. Shouldn't it be like a hashmap where a "serviceName" points to "actualServiceRef". Like, isn't the app supposed to work with multiple services, or you can just have one sync service and that's all. Then, if multiple are allowed, wouldn't one service overwrite the serviceRef field of an item that another service needs?

Another question regarding groups. Newsblur has something similar called "folders". Should I map those folders to groups? A feed could be in the root folder which could mean "no group".

And that's it. I think I am almost finished. At least for that file...

Comment thread src/scripts/models/services/service-utils.ts Outdated
Comment thread package.json Outdated
@CrystalSplitter

Copy link
Copy Markdown
Collaborator

Honestly, this seems to be in a relatively good state. You have issues with pnpm, and there's a dozen nits I can complain about, but the core does appear to be here.

Can you do a few things:

  • address all comments (if you have, mark them as resolved)
  • reformat your typescript.
  • make sure these build on the bots (remove your package-lock changes, and any other pnpm changes)

And we should be okay to merge. I can clean up a lot here, and this feature will still be hidden, but you clearly have been playing around with this a lot and testing it, so I trust it's in a reasonable state?

@Simx72

Simx72 commented Sep 9, 2026

Copy link
Copy Markdown
Author

Hello @CrystalSplitter

Can I write to your matrix please?

My username is @Simx72:matrix.org

@CrystalSplitter

Copy link
Copy Markdown
Collaborator

I have reached out there! But keep in mind I do not have synchronous communication most of the time.

@Simx72
Simx72 force-pushed the add-service-newsblur branch from 53cbcb8 to 40e2b1e Compare September 13, 2026 22:10
@Simx72
Simx72 force-pushed the add-service-newsblur branch 3 times, most recently from 06670ab to 63d06ee Compare September 28, 2026 19:57
@Simx72
Simx72 force-pushed the add-service-newsblur branch 3 times, most recently from 3bfb8a1 to b8d528a Compare September 28, 2026 20:49
Created a service for https://www.newsblur.com/api

This file connects the Newsblur service
to the Fluentflame's API by exporting
the constant newsblurServiceHooks.

Each hook must make one or several http requests
to the server by using the functions available
in the NewsblurAPI namespace, which represent
abstractions of each Newsblur endpoint used.

Apart from newsblurServiceHooks and NewsBlurConfigs,
other exported variables and types are exported.
These are meant to be used in the tests:
src/scripts/models/services/test_newsblur.ts
@Simx72
Simx72 force-pushed the add-service-newsblur branch from b8d528a to cf4393e Compare September 28, 2026 20:57
@Simx72

Simx72 commented Sep 28, 2026

Copy link
Copy Markdown
Author

Hello, @CrystalSplitter

Just to let you know that I have reduced the number of commits to 1. I will do a second commit for the test file and, after that, ask you for a review.

@CrystalSplitter

Copy link
Copy Markdown
Collaborator

thanks! keep me in the loop, feel free to ping me also on Matrix/IRC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants