Skip to content

feat: invitations manager UI#231

Merged
ValwareIRC merged 7 commits into
mainfrom
feature/invitations-manager
Jun 5, 2026
Merged

feat: invitations manager UI#231
ValwareIRC merged 7 commits into
mainfrom
feature/invitations-manager

Conversation

@ValwareIRC
Copy link
Copy Markdown
Contributor

@ValwareIRC ValwareIRC commented May 18, 2026

Summary

Client UI for the obbyircd INVITELINK protocol (server-side already shipped). Adds an "Invitations" category to User Settings where a logged-in user on an `obby.world/invitation`-capable server can mint, list, copy, and delete invite share-ids.

Cap-gated: the panel renders a "this server doesn't support invite links" message on non-obby servers; otherwise shows the create form + list.

Wire plumbing

  • New `INVITELINK` dispatch handler parses both shapes (`CREATE` single-row reply + `LIST` `ENTRY` rows) and emits `INVITELINK_CREATED` / `INVITELINK_ENTRY` events.
  • `LIST_END` / `DELETED` / `FAIL` come through the existing NOTE / FAIL standard-replies pipeline; the store handler filters on `command === "INVITELINK"`.
  • New `InviteLink` type, `inviteLinks` store slice, three store actions.

Test plan

  • On obby.t3ks.com (cap `obby.world/invitation`): Invitations category visible; create / list / copy / delete all work.
  • On a non-obby server: panel shows the explanatory message.
  • Delete is two-click (confirm-state on the trash icon).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Invitations panel in Settings to create/manage per-server invite links with optional channel and description, auto-loading and sorted by newest
    • Copy invite URLs with temporary “Copied” feedback, view redeem counts, and see relative creation times
    • Two-step delete confirmation with timed cancel
  • Localization
    • Invitations UI localized across many languages (new/updated translations)

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 18, 2026

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This PR adds server-scoped invite link management: IRC support for INVITELINK replies, a new InvitationsPanel React UI integrated into UserSettings, and localized strings across many locales for the invite workflow.

Changes

Invite Links Management Feature

Layer / File(s) Summary
IRC Protocol: INVITELINK Events and Handler
src/lib/irc/IRCClient.ts, src/lib/irc/handlers/invitelink.ts, src/lib/irc/handlers/index.ts
Adds INVITELINK_CREATED and INVITELINK_ENTRY EventMap entries, implements handleInvitelink parsing CREATE/ENTRY replies, and registers the handler in the dispatch table. Also requests obby.world/invitation capability.
Settings Type and UserSettings Integration
src/lib/settings/types.ts, src/components/ui/UserSettings.tsx
Adds "invitations" to SettingCategory, imports InvitationsPanel and FaShareSquare, inserts the Invitations category metadata, and renders the panel for mobile and desktop when selected.
InvitationsPanel Component
src/components/ui/InvitationsPanel.tsx
Implements the InvitationsPanel: relative-time formatting, server/capability gating, create form (channel/description, channel normalization), load/refresh, per-entry copy-to-clipboard with transient “Copied” feedback, two-step delete confirmation with 4s timeout, list rendering, and loading/error/empty states.
Internationalization
src/locales/*/messages.mjs, src/locales/*/messages.po
Updates compiled locale payloads and adds/updates .po translation entries for many locales (CS, DE, EN, ES, FI, FR, IT, JA, KO, NL, PL, PT, RO, RU) adding keys used by the InvitationsPanel and related UI. Most locales include relative-time labels, form/help text, and confirmation/copy/delete strings.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • matheusfillipe

Poem

🐰 I hopped in with tiny keys and cheer,
Crafted links to share far and near,
Click to copy, click twice to shun—
Invites are born, then gone, then done. 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: invitations manager UI' clearly and concisely describes the main change—adding a user interface for managing invitation links.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/invitations-manager

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

Pages Preview
Preview URL: https://feature-invitations-manager.obsidianirc.pages.dev

Automated deployment preview for the PR in the Cloudflare Pages.

The settings panel was 100% empty when opened from a context where
no server is the active one (home/discover routes) because the outer
gate dropped the render entirely. Make the panel responsible for its
own no-server placeholder so the tab always shows something useful.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 18

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/ui/UserSettings.tsx (1)

1786-1791: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Desktop Invitations category never renders the invitations panel.

Line 1786 routes "invitations" through the generic SettingRenderer path on desktop, but there is no desktop branch equivalent to the mobile render at Lines 1591-1593. This leaves the Invitations tab blank/non-functional on desktop.

Proposed fix
           <div className="flex-1 overflow-y-auto p-6">
             {/* Profile category - custom rendering */}
             {activeCategory === "profile" && renderProfileFields()}

             {/* Account category - custom rendering */}
             {activeCategory === "account" && renderAccountFields()}

             {/* Media category - custom slider rendering */}
             {activeCategory === "media" && renderMediaFields()}

             {/* Privacy category - custom rendering */}
             {activeCategory === "privacy" && renderPrivacyFields()}
+
+            {/* Invitations category */}
+            {activeCategory === "invitations" && (
+              <InvitationsPanel serverId={currentServer?.id} />
+            )}

             {/* Other categories - use SettingRenderer */}
             {activeCategory !== "profile" &&
               activeCategory !== "account" &&
               activeCategory !== "media" &&
-              activeCategory !== "privacy" && (
+              activeCategory !== "privacy" &&
+              activeCategory !== "invitations" && (
                 <div className="space-y-4">
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ui/UserSettings.tsx` around lines 1786 - 1791, The Invitations
tab is being funneled into the generic SettingRenderer on desktop because there
is no desktop-specific branch for activeCategory === "invitations"; update
UserSettings.tsx to add a desktop branch that checks activeCategory ===
"invitations" (before the generic SettingRenderer branch) and render the same
Invitations panel component used on mobile (mirror the mobile rendering logic
around the mobile invitations branch), ensuring the InvitationsPanel (or
whatever Invitations component is used) is rendered instead of falling through
to SettingRenderer.
🟡 Minor comments (4)
src/locales/cs/messages.mjs-1-1 (1)

1-1: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

New invitations strings are still untranslated in Czech locale.

Line 1 includes multiple invite-related entries in English (for example: Create, Copy, Copy link, Refresh, Create a new invite link, Your invite links). This causes mixed-language UI in cs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/locales/cs/messages.mjs` at line 1, The Czech locale bundle (exported
const messages in src/locales/cs/messages.mjs) still contains untranslated
invite-related English strings—specifically keys with values "Create" (hYgDIe),
"Copy" (he3ygx), "Copy link" (y1eoq1), "Refresh" (lCF0wC), "Create a new invite
link" (RIfHS5) and "Your invite links" (ukyW4o); update those values to proper
Czech translations consistent with surrounding entries and locale style, then
rebuild/serialize the messages JSON so the messages variable contains the
translated strings.
src/components/ui/InvitationsPanel.tsx-117-123 (1)

117-123: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Copy success is shown even when Clipboard API is unavailable.

Line 119 uses optional chaining on navigator.clipboard, so on unsupported environments it resolves undefined and still runs the success UI state.

Proposed fix
   const handleCopy = async (url: string, shareId: string) => {
     try {
-      await navigator.clipboard?.writeText(url);
+      if (!navigator.clipboard) return;
+      await navigator.clipboard.writeText(url);
       setCopiedId(shareId);
       setTimeout(() => {
         setCopiedId((current) => (current === shareId ? null : current));
       }, 1500);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ui/InvitationsPanel.tsx` around lines 117 - 123, The success
UI is triggered even when the Clipboard API is unavailable because optional
chaining lets await navigator.clipboard?.writeText(url) resolve to undefined;
modify handleCopy to explicitly check for navigator.clipboard and
navigator.clipboard.writeText before attempting to write, return or show an
error/fallback if missing, and only call setCopiedId/timeout after a successful
writeText inside the try block; reference the handleCopy function and
setCopiedId state so the success state is gated on a confirmed clipboard write.
src/locales/en/messages.po-2451-2453 (1)

2451-2453: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix missing spaces around the inline capability tag.

The string will render with merged words (theobby.world/invitationcapability). Add spaces around the <0>...</0> segment.

Suggested fix
-msgid "This server doesn't support invite links (the<0>obby.world/invitation</0>capability isn't advertised). You can still chat normally; this panel is for obbyircd-powered networks."
-msgstr "This server doesn't support invite links (the<0>obby.world/invitation</0>capability isn't advertised). You can still chat normally; this panel is for obbyircd-powered networks."
+msgid "This server doesn't support invite links (the <0>obby.world/invitation</0> capability isn't advertised). You can still chat normally; this panel is for obbyircd-powered networks."
+msgstr "This server doesn't support invite links (the <0>obby.world/invitation</0> capability isn't advertised). You can still chat normally; this panel is for obbyircd-powered networks."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/locales/en/messages.po` around lines 2451 - 2453, The translated message
for InvitationsPanel (msgid/msgstr) lacks spaces around the inline capability
tag causing merged words; update both msgid and msgstr in the locale entry for
src/components/ui/InvitationsPanel.tsx to add a space before the <0> tag and a
space after the </0> tag so the rendered string reads "the
<0>obby.world/invitation</0> capability" instead of
"theobby.world/invitationcapability".
src/locales/ru/messages.mjs-1-1 (1)

1-1: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Russian invite-link strings are partially untranslated.

The RU catalog still contains several English invite-management strings, which will surface mixed-language UI in this feature.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/locales/ru/messages.mjs` at line 1, The RU locale contains several
invite-link UI strings still in English; update the untranslated entries by
providing Russian translations for the invite-related message keys (e.g.
"WYxRzo" ("Create and manage your invite links"), "UETAwW" ("You haven't created
any invite links yet. Use the form above to mint your first one."), "xbi8D6"
(obbyircd-specific invite panel text) and any other invite/invitation-related
keys) so the invite-management UI is fully localized; locate these keys inside
messages in src/locales/ru/messages.mjs and replace their English text with
appropriate Russian strings while preserving existing interpolation placeholders
and array structure.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/ui/InvitationsPanel.tsx`:
- Around line 66-69: The Biome suppression comment above the useEffect in
InvitationsPanel.tsx is using the wrong text; replace the current comment with
the repository-required suppression for store action refs: change the line
before useEffect to "// biome-ignore lint/correctness/useExhaustiveDependencies:
store actions have unstable refs" so the dependency list ([serverId, cap]) may
omit the unstable store action loadInvitations without failing the linter.

In `@src/locales/cs/messages.po`:
- Around line 69-83: The Czech locale file src/locales/cs/messages.po contains
untranslated invite-related entries (e.g. msgid "{0}d ago", "{0}h ago", "{0}m
ago" referenced from src/components/ui/InvitationsPanel.tsx and many other
ranges) which must be filled before merge; open src/locales/cs/messages.po,
provide appropriate Czech translations for each empty msgstr "" corresponding to
the listed msgid values (and the other ranges called out in the review), then
run the project extraction/localization step (npm run i18n:extract) to verify no
non-English .po file has empty msgstr entries and commit the updated .po
file(s).

In `@src/locales/de/messages.po`:
- Around line 69-83: The German .po file has empty translations for the
invitation time strings (msgid "{0}d ago", "{0}h ago", "{0}m ago") referenced in
src/components/ui/InvitationsPanel.tsx and several other entries flagged in the
comment; open src/locales/de/messages.po, provide appropriate German msgstr
values (e.g. use "{0}d vor", "{0}h vor", "{0}m vor" or other correct localized
phrasing) for each empty msgid, and then run npm run i18n:extract to confirm no
other non-English .po files contain empty msgstr entries before committing.

In `@src/locales/es/messages.mjs`:
- Line 1: The Spanish messages JSON still contains invite-link UI strings in
English; locate the entries by their unique keys (e.g. "/AkXyp" -> "Confirm?",
"GdhD7H" -> "Click again to confirm", "hYgDIe" -> "Create", "lCF0wC" ->
"Refresh", "y1eoq1" -> "Copy link", "BPm98R" -> "No server is selected. Pick a
server from the sidebar first; invite links are managed per-server.", etc.) and
replace the English text with proper Spanish translations, preserving any
placeholders/array structures and escaping so the outer JSON.parse string
remains valid; after updating these keys (and any other invite-link related keys
left in English) re-validate the JSON string and run the localization/lint
tests.

In `@src/locales/es/messages.po`:
- Around line 69-82: Several Spanish translations are missing for new Invitation
UI strings (e.g. msgid "{0}d ago", "{0}h ago", "{0}m ago" used in
InvitationsPanel.tsx); populate the empty msgstr "" entries with accurate
Spanish equivalents (preserving placeholders like {0}) for these msgids and all
other reported ranges (e.g., lines listed in the comment). Run npm run
i18n:extract to list missing translations, update every non-English .po file's
empty msgstr entries accordingly, ensure placeholder order/format remains
unchanged, and save the updated .po files before merging.

In `@src/locales/fi/messages.po`:
- Around line 69-82: The Finnish .po entries for the InvitationsPanel time-ago
strings (msgid "{0}d ago", "{0}h ago", "{0}m ago" referenced from
InvitationsPanel.tsx) are empty; fill each corresponding msgstr with the proper
Finnish translations (preserving the {0} placeholder formatting), and then run
npm run i18n:extract and update all other non-English .po files to remove empty
msgstr entries (including the other ranges called out) before committing.

In `@src/locales/fr/messages.po`:
- Around line 69-82: Several new invitation-time strings ("{0}d ago", "{0}h
ago", "{0}m ago" and other msgid entries) were left untranslated (msgstr ""), so
update each corresponding msgstr with the correct French translations before
merging; search for the listed msgid values and fill their msgstr (e.g., "{0}d
ago" -> "{0} j", "{0}h ago" -> "{0} h", "{0}m ago" -> "{0} min" or your
preferred localized forms), run the i18n extractor (npm run i18n:extract) to
rediscover any other missing msgstr entries across all non-English .po files,
and ensure every empty msgstr noted in the reviewer comment is populated so the
Invitations UI is fully localized in French.

In `@src/locales/it/messages.mjs`:
- Line 1: The Italian messages bundle (exported as messages in
src/locales/it/messages.mjs) still contains untranslated invite-link UI strings
(examples: keys "/AkXyp" => "Confirm?", "ObsidianIRC - Bringing IRC to the
future" and keys like "WYxRzo" => "Create and manage your invite links",
"y1eoq1" => "Copy link", "ukyW4o" => "Your invite links", "RIfHS5" => "Create a
new invite link", etc.); update the JSON payload so every English value for
invite-related keys is translated to Italian, preserving the existing key
names/array structure and any interpolation placeholders (e.g. [\"0\"],
[\"searchQuery\"]) to avoid breaking runtime lookups. Ensure translations
maintain formatting/escaping (backslashes, quotes) and run the i18n tests or
build to verify no JSON parse or runtime substitution errors.

In `@src/locales/it/messages.po`:
- Around line 69-83: Fill the missing Italian translations for the newly added
invitation strings in src/locales/it/messages.po: replace the empty msgstr ""
for msgid "{0}d ago", "{0}h ago", "{0}m ago" (and the other ranges listed:
116-118, 564-567, etc.) with appropriate Italian equivalents (e.g., "{0}g fa",
"{0}h fa", "{0}min fa" or your preferred localized phrasing) so the
InvitationsPanel component strings from InvitationsPanel.tsx are fully
localized; after updating, run npm run i18n:extract (and/or your normal i18n
validation) to ensure no other non-English .po files contain empty msgstr
entries before committing.

In `@src/locales/ja/messages.po`:
- Around line 69-83: The Japanese locale file src/locales/ja/messages.po
contains empty msgstr entries for many invite-related msgid strings (e.g., "{0}d
ago", "{0}h ago", "{0}m ago" referenced from
src/components/ui/InvitationsPanel.tsx and other invite strings listed in the
comment); run npm run i18n:extract to refresh missing keys, then provide
accurate Japanese translations for each empty msgstr corresponding to those
msgid values (search for the msgid texts in messages.po and fill their msgstr),
ensuring every non-English .po file has no remaining empty msgstr entries before
committing.

In `@src/locales/ko/messages.po`:
- Around line 69-82: The PO entries for the Invitations UI are missing Korean
translations (empty msgstr for msgid "{0}d ago", "{0}h ago", "{0}m ago" used in
InvitationsPanel.tsx), causing fallback/untranslated text; run the i18n
extraction (npm run i18n:extract), then fill the corresponding msgstr values
with proper Korean translations for these msgids in src/locales/ko/messages.po
and for the other empty msgstr occurrences noted in the comment (all non-English
.po entries referenced) so every user-visible string added by InvitationsPanel
(and the other listed msgid ranges) has a Korean translation before merging.

In `@src/locales/nl/messages.po`:
- Around line 69-82: Fill in the missing Dutch translations for the invitation
time strings in src/locales/nl/messages.po (the msgid entries "{0}d ago", "{0}h
ago", "{0}m ago" referenced from src/components/ui/InvitationsPanel.tsx) by
populating their corresponding msgstr values with proper Dutch equivalents
(e.g., "{0}d geleden", "{0}u geleden", "{0}m geleden"), then run npm run
i18n:extract and scan the listed ranges/other .po files to replace any remaining
empty msgstr "" entries so all non-English locales have translations before
committing.

In `@src/locales/pl/messages.mjs`:
- Line 1: The messages JSON exported as messages contains several invite-related
strings still in English (e.g. values for keys like "ObsidianIRC - Bringing IRC
to the future", "Create a new invite link", "Your invite links", "This many
people registered through this link", "Copy link" and any other
invite/invitation-related entries); update those values in the messages payload
to Polish translations, editing the exported messages JSON in
src/locales/pl/messages.mjs (the messages constant) so all invite/invitation UI
strings are fully translated and consistent with the rest of the pl locale.

In `@src/locales/pl/messages.po`:
- Around line 69-82: Add Polish translations for the new invite-link time
strings that were left empty: set msgstr for "{0}d ago", "{0}h ago", and "{0}m
ago" (the msgid strings used by src/components/ui/InvitationsPanel.tsx) in
src/locales/pl/messages.po; run the i18n extraction command (npm run
i18n:extract) to locate any other empty msgstr entries listed in the review and
fill them all consistently, preserving the placeholder {0} in each translation.

In `@src/locales/pt/messages.mjs`:
- Line 1: The runtime Portuguese bundle exports a messages JSON that still
contains untranslated English invite-related entries (the exported const
messages in the file contains keys like RIfHS5, WYxRzo, UETAwW, etc. that map to
English invite strings); open the exported messages payload (the JSON string
assigned to messages), translate the English invite UI strings to Portuguese for
those keys (and any other invite-related keys left in English), update the JSON
string (or regenerate the locale bundle via the i18n build step) and rebuild the
bundle so src/locales/pt/messages.mjs ships complete Portuguese translations.

In `@src/locales/pt/messages.po`:
- Around line 69-82: The pt translation file has empty msgstr entries for the
InvitationsPanel time-ago strings (msgid "{0}d ago", "{0}h ago", "{0}m ago"
referenced from src/components/ui/InvitationsPanel.tsx); fill those msgstr
values with Portuguese translations (for example "há {0}d", "há {0}h", "há {0}m"
or prefer full words like "há {0} dias", "há {0} horas", "há {0} minutos" as
appropriate), then run npm run i18n:extract and ensure you populate all other
empty msgstr "" entries across non-English .po files mentioned in the review
before committing.

In `@src/locales/ro/messages.po`:
- Around line 69-83: Several Romanian translations for invite-related strings
are blank; open src/locales/ro/messages.po and fill the empty msgstr entries for
the entries referenced (e.g., the "{0}d ago", "{0}h ago", "{0}m ago" entries
tied to src/components/ui/InvitationsPanel.tsx and the other ranges called out)
with proper Romanian equivalents using the same placeholder {0} (for example
"acum {0}z", "acum {0}h", "acum {0}m" or correct localized forms), then run npm
run i18n:extract to verify no other non-English .po files have empty msgstr
entries before committing. Ensure you preserve placeholders exactly as {0} and
update any other listed ranges (116-118, 564-567, etc.) in the same file set.

In `@src/locales/ru/messages.po`:
- Around line 69-83: The new Russian translations in src/locales/ru/messages.po
are left empty (msgstr ""), causing untranslated UI strings; open the file and
fill every newly added msgstr for the Invitation-related msgid entries (e.g.,
"{0}d ago", "{0}h ago", "{0}m ago" and all other empty msgstr occurrences called
out in the review) with proper Russian text preserving placeholders like {0};
run npm run i18n:extract to locate any other missing translations across
non-English .po files, update all empty msgstr entries accordingly, and commit
the updated .po files before merging.

---

Outside diff comments:
In `@src/components/ui/UserSettings.tsx`:
- Around line 1786-1791: The Invitations tab is being funneled into the generic
SettingRenderer on desktop because there is no desktop-specific branch for
activeCategory === "invitations"; update UserSettings.tsx to add a desktop
branch that checks activeCategory === "invitations" (before the generic
SettingRenderer branch) and render the same Invitations panel component used on
mobile (mirror the mobile rendering logic around the mobile invitations branch),
ensuring the InvitationsPanel (or whatever Invitations component is used) is
rendered instead of falling through to SettingRenderer.

---

Minor comments:
In `@src/components/ui/InvitationsPanel.tsx`:
- Around line 117-123: The success UI is triggered even when the Clipboard API
is unavailable because optional chaining lets await
navigator.clipboard?.writeText(url) resolve to undefined; modify handleCopy to
explicitly check for navigator.clipboard and navigator.clipboard.writeText
before attempting to write, return or show an error/fallback if missing, and
only call setCopiedId/timeout after a successful writeText inside the try block;
reference the handleCopy function and setCopiedId state so the success state is
gated on a confirmed clipboard write.

In `@src/locales/cs/messages.mjs`:
- Line 1: The Czech locale bundle (exported const messages in
src/locales/cs/messages.mjs) still contains untranslated invite-related English
strings—specifically keys with values "Create" (hYgDIe), "Copy" (he3ygx), "Copy
link" (y1eoq1), "Refresh" (lCF0wC), "Create a new invite link" (RIfHS5) and
"Your invite links" (ukyW4o); update those values to proper Czech translations
consistent with surrounding entries and locale style, then rebuild/serialize the
messages JSON so the messages variable contains the translated strings.

In `@src/locales/en/messages.po`:
- Around line 2451-2453: The translated message for InvitationsPanel
(msgid/msgstr) lacks spaces around the inline capability tag causing merged
words; update both msgid and msgstr in the locale entry for
src/components/ui/InvitationsPanel.tsx to add a space before the <0> tag and a
space after the </0> tag so the rendered string reads "the
<0>obby.world/invitation</0> capability" instead of
"theobby.world/invitationcapability".

In `@src/locales/ru/messages.mjs`:
- Line 1: The RU locale contains several invite-link UI strings still in
English; update the untranslated entries by providing Russian translations for
the invite-related message keys (e.g. "WYxRzo" ("Create and manage your invite
links"), "UETAwW" ("You haven't created any invite links yet. Use the form above
to mint your first one."), "xbi8D6" (obbyircd-specific invite panel text) and
any other invite/invitation-related keys) so the invite-management UI is fully
localized; locate these keys inside messages in src/locales/ru/messages.mjs and
replace their English text with appropriate Russian strings while preserving
existing interpolation placeholders and array structure.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: faa6f31f-813d-4f1c-9b2a-dbe0f846a51f

📥 Commits

Reviewing files that changed from the base of the PR and between 2b362bd and befdd5e.

📒 Files selected for processing (48)
  • src/components/ui/InvitationsPanel.tsx
  • src/components/ui/UserSettings.tsx
  • src/lib/irc/IRCClient.ts
  • src/lib/irc/handlers/index.ts
  • src/lib/irc/handlers/invitelink.ts
  • src/lib/settings/types.ts
  • src/locales/cs/messages.mjs
  • src/locales/cs/messages.po
  • src/locales/de/messages.mjs
  • src/locales/de/messages.po
  • src/locales/en/messages.mjs
  • src/locales/en/messages.po
  • src/locales/es/messages.mjs
  • src/locales/es/messages.po
  • src/locales/fi/messages.mjs
  • src/locales/fi/messages.po
  • src/locales/fr/messages.mjs
  • src/locales/fr/messages.po
  • src/locales/it/messages.mjs
  • src/locales/it/messages.po
  • src/locales/ja/messages.mjs
  • src/locales/ja/messages.po
  • src/locales/ko/messages.mjs
  • src/locales/ko/messages.po
  • src/locales/nl/messages.mjs
  • src/locales/nl/messages.po
  • src/locales/pl/messages.mjs
  • src/locales/pl/messages.po
  • src/locales/pt/messages.mjs
  • src/locales/pt/messages.po
  • src/locales/ro/messages.mjs
  • src/locales/ro/messages.po
  • src/locales/ru/messages.mjs
  • src/locales/ru/messages.po
  • src/locales/sv/messages.mjs
  • src/locales/sv/messages.po
  • src/locales/tr/messages.mjs
  • src/locales/tr/messages.po
  • src/locales/uk/messages.mjs
  • src/locales/uk/messages.po
  • src/locales/zh-TW/messages.mjs
  • src/locales/zh-TW/messages.po
  • src/locales/zh/messages.mjs
  • src/locales/zh/messages.po
  • src/store/handlers/index.ts
  • src/store/handlers/invitelink.ts
  • src/store/index.ts
  • src/types/index.ts

Comment thread src/components/ui/InvitationsPanel.tsx Outdated
Comment thread src/locales/cs/messages.po
Comment thread src/locales/de/messages.po
Comment thread src/locales/es/messages.mjs Outdated
Comment thread src/locales/es/messages.po Outdated
Comment thread src/locales/pl/messages.po Outdated
Comment thread src/locales/pt/messages.mjs Outdated
Comment thread src/locales/pt/messages.po Outdated
Comment thread src/locales/ro/messages.po
Comment on lines +69 to +83
#. placeholder {0}: Math.floor(secs / 86400)
#: src/components/ui/InvitationsPanel.tsx
msgid "{0}d ago"
msgstr ""

#. placeholder {0}: Math.floor(secs / 3600)
#: src/components/ui/InvitationsPanel.tsx
msgid "{0}h ago"
msgstr ""

#. placeholder {0}: Math.floor(secs / 60)
#: src/components/ui/InvitationsPanel.tsx
msgid "{0}m ago"
msgstr ""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Fill all newly added Russian msgstr values before merge.

These new user-facing Invitation strings are still empty (msgstr ""), so RU users will see untranslated text in this flow.

As per coding guidelines, "When adding new user-visible strings, translate them before committing — run npm run i18n:extract to identify missing strings, then fill in all empty msgstr "" entries across every non-English .po file before committing".

Also applies to: 116-118, 564-566, 665-667, 710-712, 726-728, 734-736, 738-740, 742-744, 815-817, 823-825, 1276-1278, 1314-1316, 1554-1556, 1667-1669, 2017-2020, 2444-2446, 2452-2454, 2602-2604, 2795-2797, 2815-2817

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/locales/ru/messages.po` around lines 69 - 83, The new Russian
translations in src/locales/ru/messages.po are left empty (msgstr ""), causing
untranslated UI strings; open the file and fill every newly added msgstr for the
Invitation-related msgid entries (e.g., "{0}d ago", "{0}h ago", "{0}m ago" and
all other empty msgstr occurrences called out in the review) with proper Russian
text preserving placeholders like {0}; run npm run i18n:extract to locate any
other missing translations across non-English .po files, update all empty msgstr
entries accordingly, and commit the updated .po files before merging.

The settings UI has two parallel render branches (mobile and desktop)
and the previous patch only touched the mobile one. On desktop the
Invitations tab fell through to nothing, which is what the user was
seeing.
These vendor caps weren't in `ourCaps`, so even when the server
advertised them in CAP LS the client never requested them, the
server never ACKed them, and `server.capabilities` never contained
them. Net effect: the Invitations panel kept rendering the
'capability isn't advertised' fallback against servers that fully
support the protocol.
Comment thread src/locales/cs/messages.po Outdated

#: src/components/ui/InvitationsPanel.tsx
msgid "used"
msgstr ""
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

also still not translations

matheusfillipe
matheusfillipe previously approved these changes Jun 5, 2026
Copy link
Copy Markdown
Contributor

@matheusfillipe matheusfillipe left a comment

Choose a reason for hiding this comment

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

lmgtm, fix translations and other small fixes before merge

Resolved locale conflicts by:
- Taking ours (this branch's invitations-related .po additions).
- Re-running `npx lingui extract` to pull in main's new strings
  (RawLogViewer's "Copy all"/"No raw IRC traffic captured yet…",
  ChatArea's "Drop files to upload").
- Translating all newly-empty msgstrs across cs/de/es/fi/fr/it/ja/ko/
  nl/pl/pt/ro/ru/sv/tr/uk/zh/zh-TW in parallel so the merge doesn't
  ship untranslated UI in any locale.
- Recompiling .mjs catalogs.

The remaining file-changes block is main's own commit fan-in (nix
flake, workflow tweaks, AndroidManifest, etc.) — no manual edits.
Matt's review approved with "fix translations and other small fixes
before merge". Translations done in the merge commit; this is the
"small fixes" half.

Per CLAUDE.md the standard biome suppression text for Zustand store-
action refs in useEffect deps is
"store actions have unstable refs". The InvitationsPanel hook had a
hand-rolled rationale ("cap toggles trigger reload by design") that
described the runtime behaviour but didn't match the repo-standard
phrasing, which CodeRabbit also flagged. Swap to the canonical text.

No functional change.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 5, 2026

Pages Preview
Preview URL: https://feature-invitations-manager.obsidianirc.pages.dev

Automated deployment preview for the PR in the Cloudflare Pages.

@ValwareIRC ValwareIRC merged commit bfa1a5e into main Jun 5, 2026
5 of 6 checks passed
@ValwareIRC ValwareIRC requested a review from matheusfillipe June 5, 2026 15:35
ValwareIRC added a commit that referenced this pull request Jun 5, 2026
Resolutions:
- src/lib/irc/IRCClient.ts: both branches added a new CAP REQ entry
  in the same neighbourhood (HEAD added "draft/bot-cmds" +
  "obby.world/channel-bots"; main added "obby.world/invitation").
  Keep all three -- they're independent vendor caps with no overlap.
- src/locales/*.po: took ours then re-extracted to fold in main's new
  msgids. Backfilled all 23 invitation-panel strings × 18 locales from
  obbyworld/main:src/locales/{loc}/messages.po by copying msgstrs
  verbatim (they were translated in PR #231 already). .mjs recompiled.

Build + 858 tests green.
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