Skip to content

[Draft]Feedreader webui - #124

Draft
defnax wants to merge 34 commits into
RetroShare:masterfrom
defnax:feedreader-webui
Draft

[Draft]Feedreader webui#124
defnax wants to merge 34 commits into
RetroShare:masterfrom
defnax:feedreader-webui

Conversation

@defnax

@defnax defnax commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

For testing keep it for later

require:
RetroShare/libretroshare#364
RetroShare/RetroShare#3289

defnax and others added 30 commits July 26, 2026 20:50
Added Board posts display
Added for Network to list last Chats
* corrected some place holder text
Added Navbar for webui on phones
for Boards and Channels:
* Validate API responses before processing.
* Keep rendering/navigation functional if a response is incomplete.
* Log a clear warning instead of throwing an uncaught error.
* Use independent sorted arrays, avoiding mutation of the master list.
Fixed channels thumbnail layout issue
Added same comments design from boards to channels
Fixed layout issues for myfiles, friendfiles & search
Brings the branch up to date with master so RetroShare#121 can be merged again.

Eight files needed a decision. The branch predates 41111cb ("restore WebUI
styles in SCSS sources"), which recovered into the SCSS a number of rules
that until then existed only in the compiled styles.css, so most conflicts
are that recovery meeting the changes made here. Where both sides describe
the same element the branch's version is kept; where master's rule is a
positioning context the branch has no equivalent for, master's is kept:

  * _chat.scss - master's attach-modal, emoji-picker, rightbar context menu
    and create-lobby-button rules are kept alongside the compact-message
    styles added here. Taking either side whole would have dropped about
    450 lines. .chat-own-profile-card, .chat-hub-rightbar and
    .chat-hub-rightbar .user keep `position: relative`, because
    .chat-create-lobby-btn and .rightbar-context-menu are still declared
    `position: absolute` further down and would otherwise escape to the
    initial containing block. For .user-tooltip the branch's `position:
    fixed` rework wins, and master's `.chat-hub-rightbar .user-tooltip
    { left: -275px }` offset is dropped since it would fight a fixed
    element.
  * _people.scss - master's restored .friends-list-container context menu
    is kept; the pane rules it also restored are shadowed by the branch's
    own !important versions and were dropped as dead code.
  * boards_util.js - the revived updateContent() and the in-flight dedup in
    updateDisplayBoards() are kept. Master's side of the first two hunks
    was comment reformatting only.
  * board_view.js - the rewrite here is kept whole. Master's only change
    since the fork point was `let reader` -> `const reader`, in code the
    rewrite replaced.
  * chat.js - the modals moved out one nesting level here; that structure
    is kept.
  * chat_state.js - `require('people/people_util')` is not restored. It is
    unused, which is why 35c5c17 removed it.
  * build.sh - master's version. The change here concatenated raw .scss
    onto the generated CSS; see the following commits.
  * styles.css - regenerated, see the following commits.
The `@media (max-width: 768px)` block opened for the People page was never
closed, so `sass` refused the whole stylesheet:

    Error: expected "}".
    app/scss/pages/_people.scss 427:2  @forward

This is why the styles kept "getting destroyed": `npm run build` could not
produce styles.css at all, and the file had to be maintained by hand.

The closing brace goes before `.people-context-menu`, not at the end of the
file: that rule is written at column 0 under its own header comment, so it
is meant to be a top level rule. Left inside the media query it would only
style the right-click menu below 768px, which is where it is least likely
to be used.

styles.css is regenerated by `npm run build`, which is why it comes back
from 25200 hand-assembled lines to the 7 compressed lines the sass pipeline
emits.
build.ps1 (and the matching hunk of build.sh, dropped while rebasing)
worked around the broken stylesheet by concatenating raw .scss sources onto
the end of the generated styles.css:

    $extraCss += Get-Content "$src\app\scss\pages\_board.scss"

That ships SCSS to the browser. Nesting, `&`, `@use` and variables are not
CSS, so everything after the first nested block is dropped by the parser,
which made the result look randomly broken and fed the same manual fixing
loop.

With the missing brace fixed in the previous commit, `sass` compiles the
whole tree again and the workaround has nothing left to work around.
build.ps1 was also unreachable: make-src/build.js dispatches win32 to
build.bat, never to a PowerShell script.
master gained an eslint config in 35c5c17 and the code added here predates
it, so `npm run lint` fails on this branch. This commit is the mechanical
part only, produced by `eslint app --fix` with no hand editing:
object-shorthand, quote style, trailing whitespace, prefer-const.

Twenty-two problems are left because they need a decision rather than a
rewrite rule, the two worth looking at first being real:

  boards/board_view.js:499,503  'forumId' is not defined  (no-undef)

`renderComment` calls `util.voteForPost(forumId, ...)` for the up and down
vote buttons, but no `forumId` exists in that scope - it looks like it came
over from the forums code. Voting on a board comment therefore throws
ReferenceError and silently does nothing.

The other twenty are unused bindings left behind by the refactors
(`get64Num`, `loadLobbyDetails`, `Message`, `SubscribedLobbies`,
`PublicLobbies`, `LayoutSingle` in chat.js, `closePopup` in
board_kanban.js, `bsubscribed`/`bposts`/`createDate`/`lastActivity` in
boards_util.js, `displaycomment` in channel_view.js) plus a few dead
assignments. `npm run lint` lists them all.

Drop this commit if you would rather keep the diff to your own changes.
Merge master into improvements_v2, and fix the scss that breaks the build
trying to restore tooltip issue on chat rooms
Improved idenity selector on boards/channels loading
… item

Opening the channels list made the web UI unusable and left channel pages
blank, with the console filling up with

    getChannelContent  net::ERR_INSUFFICIENT_RESOURCES
    [RS] Retroshare-jsonapi not available.

The second line is misleading: it is what rswebui prints for status 0, i.e.
a request that never left the browser. The service is fine, the tab is out
of sockets.

updatedisplaychannels() asked getContentSummaries for the ids of everything
in a channel - posts, comments *and* votes, each one a separate GXS item -
then fired one getChannelContent per id:

    res2.body.summaries.map(async (content) => {
      await updatecontent(content, keyid);   // contentsIds: [content.mMsgId]
    });

`.map` with an async callback awaits nothing, so all of them start at once.
And ChannelSummary calls updatedisplaychannels from its oninit, once per
channel of the list, so the whole subscription set does this simultaneously.
A few dozen posts is enough: it is the number of items across every
subscribed channel that counts, and each one costs a socket.

getChannelContent already takes a set:

    rsgxschannels.h:385
    virtual bool getChannelContent(const RsGxsGroupId& channelId,
                                   const std::set<RsGxsMessageId>& contentsIds, ...)

so the ids are now sent in batches of 200, sequentially per channel, with a
redraw between batches so posts appear as they arrive. A channel of 2000
items goes from 2000 requests to 10.

Splitting a batched answer needs all three lists walked rather than the
first non-empty one, so the storing moves into storePost / storeComment /
storeVote. They key off each item's own mMeta instead of the summary it was
requested from, which is the same value but no longer assumes a one to one
mapping between request and result.

The two responses are also checked before use: rsJsonApiRequest resolves to
undefined when the request fails, which the previous code dereferenced
straight away - the exact case that was happening here.
…t exist

A channel or board with no logo falls back to `data/streaming.png`:

    src: cimage.mData.base64 === '' ? 'data/streaming.png' : ...

That file is in neither webui-src/assets nor the served tree, so the request
comes back 404 and the browser draws a broken image icon.

Both sites now render no <img> when there is nothing to show, and guard the
whole chain rather than comparing to '': mImage is absent rather than empty
on some groups, and `undefined.base64` throws during the view, which in
mithril takes the whole render down. The board side already had that guard,
it just kept aiming at the missing file.

These were the last two references to it - the post thumbnails on this
branch already go through channelThumbnailSrc / ChannelFallbackThumbnail.
Every own-identity lookup logs two errors in the console:

    POST http://localhost:9092/rsIdentity/getOwnIds  404 (Not Found)
    [RS] HTTP error: 404 Not Found

getOwnIds is the deprecated one and carries no @jsonapi annotation, so the
core does not expose it at all:

    rsidentity.h:636
    RS_DEPRECATED_FOR("getOwnSignedIds getOwnPseudonimousIds")
    virtual bool getOwnIds(std::list<RsGxsId>& ownIds, bool only_signed_ids)

getOwnSignedIds and getOwnPseudonimousIds are the annotated ones
(rsidentity.h:458 and :466), so their union *is* the complete list rather
than a fallback for older cores.

people_util therefore drops the attempt and goes straight to the two calls
it was already making underneath. The catch that was meant to swallow the
failure never ran either: rsJsonApiRequest does not throw on a non-200, it
resolves with the status, so the code reached the union by way of
`Array.isArray(undefined)` being false. It worked by accident.

boards_util had the same call with no fallback at all, which made
voteForPost report "No identity found to vote." whenever no voterId was
passed. It now goes through people_util.ownIds(), so the endpoints and
their 30s cache live in one place.
Chat messages are carried as HTML. renderChatMessage() strips the tags but
never decodes the entities left behind, and the result goes into a mithril
text node, so they reach the screen verbatim.

The visible case is a plain space: RetroShare sends the message as HTML as
soon as the composer holds any formatting, and QTextDocument::toHtml()
turns leading and repeated spaces into &nbsp;, which the web UI then
displays as that literal string. &amp;, &lt; and &gt; were affected the
same way.

The three call sites that turned HTML into text carried the same sequence
of replacements, so they now share htmlToText(). Decoding goes through a
textarea rather than a div on purpose: the content model of a textarea is
plain text, so no part of a message can be parsed into an element. Nothing
is trusted as markup at any point.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Stop calling the deprecated /rsIdentity/getOwnIds (404 on every lookup)
Fix the request storm that makes channels unusable
@defnax defnax changed the title Feedreader webui [Draft]Feedreader webui Aug 10, 2026
@defnax
defnax marked this pull request as draft August 10, 2026 20:27
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