Skip to content

add privacy page#114

Merged
matheusfillipe merged 2 commits into
mainfrom
add-privacy-policy-tmp
Dec 20, 2025
Merged

add privacy page#114
matheusfillipe merged 2 commits into
mainfrom
add-privacy-policy-tmp

Conversation

@matheusfillipe
Copy link
Copy Markdown
Contributor

@matheusfillipe matheusfillipe commented Dec 5, 2025

@ValwareIRC under https://add-privacy-policy-tmp.obsidianirc.pages.dev/privacy

Just a vibed template right now, help me enhance it as needed. (it has some missconceptions as of now)

Needed for google playstore android app.

Summary by CodeRabbit

  • New Features

    • Added a dedicated Privacy Policy page with full content, navigation and dark-mode-friendly styling.
    • Added a Privacy section in Settings for easy access to policy and privacy info.
  • UI / Navigation

    • App UI now runs inside a router with a dedicated privacy route and the main app nested under a wildcard route.
  • Tests / Chores

    • Tests updated to run within a routing context; test setup now includes a localStorage mock.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 5, 2025

Walkthrough

Adds client-side routing (react-router-dom), nests the main UI under a wildcard /* route and adds a dedicated /privacy route. Introduces a new PrivacyPolicy component, a "privacy" category in UserSettings, wraps the app with BrowserRouter, updates tests to use routing, and adds a localStorage mock in test setup.

Changes

Cohort / File(s) Summary
Routing bootstrap & App restructuring
src/main.tsx, src/App.tsx
src/main.tsx now wraps <App /> with BrowserRouter. src/App.tsx imports Routes/Route, renders a Routes tree with a /* catch-all for the main UI and a /privacy route for PrivacyPolicy; previous top-level layout, modals, shortcut and init logic are moved inside the /* routed element.
Privacy page
src/components/PrivacyPolicy.tsx
New default-exported component rendering a static Privacy Policy page. Sets document.title on mount, uses useNavigate for a Back action, includes structured sections and contact links, and contains no external requests.
Settings — privacy category
src/components/ui/UserSettings.tsx
Adds "privacy" to the SettingsCategory union, registers a Privacy category (id "privacy", icon FaShieldAlt), implements renderPrivacyFields and routes rendering to show the privacy panel when selected.
Tests & test setup
tests/App.test.tsx, tests/setup.ts
Tests updated to wrap App renders with BrowserRouter. tests/setup.ts adds a localStorage mock (getItem, setItem, removeItem, clear) assigned to window.localStorage alongside existing DOM/test mocks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Inspect route nesting in src/App.tsx and ensure state/handlers are correctly passed into the /* routed element.
  • Verify PrivacyPolicy uses useNavigate and side effects (title) safely.
  • Confirm UserSettings changes (type union and render path) don't break other categories.
  • Check tests for comprehensive BrowserRouter wrapping and that the localStorage mock doesn't clash with other test utilities.

Poem

🐰 I hopped through routes and hid a sign,
"Privacy" nestled near settings fine,
A wildcard path catches every trail,
Tests now wander with BrowserRouter's sail,
Thump-thump — cookies snug, and tail a-wagging.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'add privacy page' directly matches the main objective of the PR: adding a privacy policy page required for Google Play Store submission.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch add-privacy-policy-tmp

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

github-actions Bot commented Dec 5, 2025

Pages Preview
Preview URL: https://add-privacy-policy-tmp.obsidianirc.pages.dev

Automated deployment preview for the PR in the Cloudflare Pages.

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: 1

🧹 Nitpick comments (4)
privacy.html (4)

7-7: Consider using a built Tailwind CSS file for production.

Using the Tailwind CDN can impact performance as it includes all utility classes and requires runtime processing. For a production environment, consider generating a minimal CSS file containing only the classes used in this page.

This can be achieved by:

  1. Installing Tailwind CSS as a dependency
  2. Creating a build process that generates a minified CSS file
  3. Replacing the CDN script with a link to the generated CSS file

This would reduce the initial load size and improve page performance.


398-406: Dark mode script may be unnecessary.

The page uses dark theme colors by default (bg-base-900 text-base-100 on line 58), but the script adds a dark class based on system preference. Since there are no light mode color variants defined in the HTML, this script has no visual effect.

Consider either:

  1. Remove the script if the page should always be dark-themed
  2. Implement proper light/dark mode toggle with appropriate color classes (e.g., dark:bg-base-900 bg-white)

66-78: Add accessibility attributes to SVG icons.

The SVG icons throughout the page lack accessibility attributes. For better screen reader support, consider:

  • Adding aria-hidden="true" to decorative icons (like the checkmarks)
  • Adding role="img" and aria-label to meaningful icons (like the header logo)

Example for decorative icon:

 <svg
+  aria-hidden="true"
   class="w-5 h-5 text-green-500 mt-0.5 flex-shrink-0"
   fill="none"
   stroke="currentColor"
   viewBox="0 0 24 24"
 >

Example for meaningful icon:

 <svg
+  role="img"
+  aria-label="ObsidianIRC logo"
   class="w-6 h-6 text-white"
   fill="none"
   stroke="currentColor"
   viewBox="0 0 24 24"
 >

Also applies to: 160-172


360-365: Update contact email to project's organizational domain.

The contact email obsidian@gmail.com is a personal Gmail account. For a public project, use a domain-specific email address (e.g., contact@obsidianirc.dev or similar) to appear more professional and maintainable.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a1c0909 and 318ecd0.

📒 Files selected for processing (2)
  • docker/nginx.conf (1 hunks)
  • privacy.html (1 hunks)
🔇 Additional comments (1)
privacy.html (1)

86-377: Well-structured privacy policy content.

The privacy policy is comprehensive and well-organized with clear sections covering all essential aspects:

  • Data collection and usage
  • Data security measures
  • User rights
  • Legal compliance (children's privacy, international users)
  • Contact information

The semantic HTML structure and responsive design using Tailwind classes are appropriate for this use case.

Comment thread docker/nginx.conf Outdated
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: 0

Caution

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

⚠️ Outside diff range comments (1)
tests/App.test.tsx (1)

177-196: Duplicate test detected.

This test ("Shows error message when server connection fails") is an exact duplicate of the test at lines 156-175. Remove the duplicate or replace it with a different test case.

-    it("Shows error message when server connection fails", async () => {
-      render(
-        <BrowserRouter>
-          <App />
-        </BrowserRouter>,
-      );
-      const user = userEvent.setup();
-
-      // Mock failed connection
-      vi.mocked(ircClient.connect).mockRejectedValueOnce(
-        new Error("Connection failed"),
-      );
-
-      // Open modal
-      await user.click(screen.getByTestId("server-list-options-button"));
-      await user.click(screen.getByText(/Add Server/i));
-
-      // Check that toggleAddServerModal was called
-      expect(mockStoreState.toggleAddServerModal).toHaveBeenCalledWith(true);
-    });
🧹 Nitpick comments (3)
src/components/PrivacyPolicy.tsx (2)

32-34: Reminder: Keep the "Last updated" date current.

The hardcoded date should be updated whenever the privacy policy content is modified to maintain accuracy and user trust.


18-25: Consider a placeholder icon instead of hiding on error.

When the logo image fails to load, hiding it leaves an empty gradient container. A simple fallback icon or text would provide better UX.

 <img
   src="/images/obsidian-transparent.png"
   alt="ObsidianIRC"
   className="w-10 h-10"
   onError={(e) => {
-    e.currentTarget.style.display = "none";
+    e.currentTarget.outerHTML = '<span class="text-white text-2xl font-bold">O</span>';
   }}
 />

Alternatively, use a conditional render with a state variable for cleaner React patterns.

src/App.tsx (1)

173-212: Consider whether /privacy should share layout and connection behavior with the main app

The routing setup is valid and will correctly render PrivacyPolicy at /privacy and the main UI under /*. A couple of design points you may want to revisit:

  • /privacy currently renders only PrivacyPolicy, without AppLayout, so users won’t see the usual shell/navigation on that page. If you want a consistent frame (e.g., header/back navigation), consider wrapping PrivacyPolicy in the same layout or having AppLayout host nested routes (including privacy).
  • App-level effects (env initialization and connectToSavedServers) still run regardless of the current route. If /privacy is intended as a low-impact/static page (e.g., linked from outside the app before connecting anywhere), you might want to scope the connection/init logic so it only runs for the main app route (e.g., move into AppLayout or a route element).

Not blockers, but worth aligning with desired UX and privacy expectations.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 318ecd0 and f1d832a.

📒 Files selected for processing (6)
  • src/App.tsx (2 hunks)
  • src/components/PrivacyPolicy.tsx (1 hunks)
  • src/components/ui/UserSettings.tsx (5 hunks)
  • src/main.tsx (2 hunks)
  • tests/App.test.tsx (6 hunks)
  • tests/setup.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/components/ui/UserSettings.tsx (1)
src/components/ui/settings/SettingRenderer.tsx (1)
  • SettingField (240-299)
🔇 Additional comments (9)
tests/setup.ts (1)

20-32: LGTM! LocalStorage mock covers core functionality.

The mock provides the essential methods (getItem, setItem, removeItem, clear) needed for most test scenarios. If future tests require length or key() (for iteration), consider extending the mock to fully implement the Storage interface.

src/components/ui/UserSettings.tsx (3)

125-130: LGTM! Privacy category follows established patterns.

The new privacy category is well-integrated with consistent structure: icon, title, id, and description matching the existing categories.


752-758: Verify the contact email address.

The email obsidian@gmail.com appears to be a generic placeholder. Ensure this is the intended contact email for privacy inquiries, as it will be user-facing.


1145-1165: LGTM! Rendering logic correctly handles the new privacy category.

The conditional rendering properly routes the privacy category to its custom renderer while excluding it from the generic SettingField path, consistent with how profile and account categories are handled.

src/components/PrivacyPolicy.tsx (2)

7-9: LGTM! Document title setup is correct.

The useEffect with an empty dependency array properly sets the document title once on component mount.


533-551: Same email verification concern applies here.

The obsidian@gmail.com email appears here as well. Ensure this is a valid, monitored mailbox for handling privacy-related inquiries.

tests/App.test.tsx (1)

112-116: LGTM! Tests correctly wrap App with BrowserRouter.

The routing context is properly provided for all test renders, matching the production setup in main.tsx.

src/main.tsx (1)

12-17: LGTM! Router setup is correct.

BrowserRouter is properly placed inside StrictMode, providing routing context to the entire application.

Note: Ensure your web server is configured to serve index.html for all routes (e.g., /privacy) to support client-side routing in production. Without proper server configuration, direct navigation to /privacy will result in a 404.

src/App.tsx (1)

7-10: Routing imports and PrivacyPolicy wiring look correct

The new react-router-dom imports and PrivacyPolicy import are consistent with the routing usage below and look fine, assuming App is rendered within a <BrowserRouter> (or equivalent) at the root.

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: 0

🧹 Nitpick comments (2)
src/components/ui/UserSettings.tsx (1)

685-775: Verify privacy panel text matches actual behavior and update contact details if needed

The privacy panel UI itself is fine, but several statements here are policy/compliance-relevant and should be double‑checked:

  • “Local Storage: Your messages and settings are stored locally on your device”
  • “No Central Server: We don't store your IRC communications on our servers”
  • “Anonymous Analytics: Optional crash reports to improve the app”
  • The contact email obsidian@gmail.com

To avoid problems with Google Play and general privacy compliance, you’ll want to ensure:

  1. These bullets exactly match what the app and any backend actually do (e.g., what’s stored locally vs remotely, which analytics/crash services you use, what data they collect, whether they’re truly optional and opt‑in).
  2. The email address is a real, monitored contact for privacy inquiries (and ideally matches your project branding or domain).

If any of these are placeholders, consider tightening the wording and substituting real contact details before publishing.

If you’d like, I can help you draft more precise wording here based on what the app actually does (e.g., which services are used, what’s stored where).

src/App.tsx (1)

7-7: Routing structure and /privacy route integration look sound

Using <Routes> with a dedicated /privacy route and a catch‑all /* route for the main app UI is a clean approach:

  • /privacy renders PrivacyPolicy without the chat layout or modals, which is ideal for a standalone policy page you can link from the Play Store.
  • All existing UI (AppLayout, settings/modal stack, notices popup, etc.) now lives under /*, preserving behavior for normal usage.

From a react-router-dom perspective this is correct and idiomatic.

Two things to double‑check operationally:

  • Your hosting (e.g. Cloudflare Pages / any web deployment) should be configured as an SPA so that direct requests to /privacy serve your index.html and let the router render PrivacyPolicy.
  • If you expect /privacy to be opened from inside the app (e.g. via the new link in User Settings), confirm that the behavior is what you want on all targets (desktop/Tauri vs web/Android WebView) — opening in a new tab/window vs same view.

Also applies to: 10-10, 173-212

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1beab5b and 0848fb1.

📒 Files selected for processing (6)
  • src/App.tsx (2 hunks)
  • src/components/PrivacyPolicy.tsx (1 hunks)
  • src/components/ui/UserSettings.tsx (5 hunks)
  • src/main.tsx (2 hunks)
  • tests/App.test.tsx (6 hunks)
  • tests/setup.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/App.test.tsx
  • tests/setup.ts
  • src/components/PrivacyPolicy.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
src/components/ui/UserSettings.tsx (1)
src/components/ui/settings/SettingRenderer.tsx (1)
  • SettingField (240-299)
🔇 Additional comments (3)
src/main.tsx (1)

3-3: BrowserRouter integration at the entry point looks correct

Wrapping <App /> in <BrowserRouter> under React.StrictMode is the right way to supply routing context to the whole app, and it matches the new <Routes> usage inside App.tsx. No issues from a React/router perspective.

Please just confirm that your web hosting / Tauri setup is configured for SPA-style routing so direct hits to paths like /privacy still load index.html and let the router handle the route.

Also applies to: 14-16

src/components/ui/UserSettings.tsx (2)

13-16: Privacy category wiring and icon usage are consistent

Adding "privacy" to SettingsCategory, wiring it into categories, and using FaShieldAlt for the icon is type-safe and keeps the sidebar model consistent with existing categories. No functional issues here.

If settingsRegistry.getByCategory("privacy") isn’t backed by any definitions, just confirm that it safely returns an empty array rather than throwing, since it’s still being called even though the privacy category is custom-rendered.

Also applies to: 79-86, 94-131


1145-1165: Custom rendering for the privacy category is correctly excluded from the generic settings renderer

Conditionally rendering renderPrivacyFields() when activeCategory === "privacy" and excluding "profile", "account", and "privacy" from the generic SettingField loop keeps behavior clean: only real registry-backed categories hit the generic renderer.

Just ensure settingsRegistry.getByCategory doesn’t rely on "privacy" or "account" being present to avoid surprises if someone later adds registry entries for these categories.

@matheusfillipe
Copy link
Copy Markdown
Contributor Author

merging because I need this for testing other things.

@matheusfillipe matheusfillipe merged commit 9ae2ed2 into main Dec 20, 2025
4 checks passed
@matheusfillipe matheusfillipe deleted the add-privacy-policy-tmp branch December 20, 2025 11:15
zocram4cc pushed a commit to zocram4cc/ObsidianIRC that referenced this pull request Feb 17, 2026
* add privacy page

* Use react router instead
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.

1 participant