Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
code review comment fixes
  • Loading branch information
raydeStar committed Dec 11, 2025
commit f3c6c4f8f41094c1bc551099ae009a22e091f92b
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"next": "^15.2.2",
"next-themes": "^0.3.0",
"pdf-parse": "^1.1.1",
"psl": "^1.15.0",
"react": "^18",
"react-dom": "^18",
"react-text-to-speech": "^0.14.5",
Expand All @@ -56,6 +57,7 @@
"@types/jspdf": "^2.0.0",
"@types/node": "^24.8.1",
"@types/pdf-parse": "^1.1.4",
"@types/psl": "^1.1.3",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
Expand Down
9 changes: 8 additions & 1 deletion src/components/TriangulatedNews/TriangulatedNewsSources.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
TransitionChild,
} from '@headlessui/react';
import { ExternalLink } from 'lucide-react';
import { Fragment, useState } from 'react';
import { Fragment, useEffect, useState } from 'react';
import type { Lane, NewsSource } from '@/types/newsTriangulate';

interface TriangulatedNewsSourcesProps {
Expand Down Expand Up @@ -52,6 +52,13 @@ const TriangulatedNewsSources = ({
document.body.classList.add('overflow-hidden-scrollable');
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Dec 11, 2025

Choose a reason for hiding this comment

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

P1: The overflow-hidden-scrollable class added to document.body is not cleaned up if the component unmounts while the dialog is open. This can leave the page in a broken scrolling state. Use a useEffect cleanup to ensure the class is removed on unmount:

useEffect(() => {
  return () => {
    document.body.classList.remove('overflow-hidden-scrollable');
  };
}, []);
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/components/TriangulatedNews/TriangulatedNewsSources.tsx, line 52:

<comment>The `overflow-hidden-scrollable` class added to `document.body` is not cleaned up if the component unmounts while the dialog is open. This can leave the page in a broken scrolling state. Use a `useEffect` cleanup to ensure the class is removed on unmount:

```tsx
useEffect(() =&gt; {
  return () =&gt; {
    document.body.classList.remove(&#39;overflow-hidden-scrollable&#39;);
  };
}, []);
```</comment>

<file context>
@@ -0,0 +1,190 @@
+
+  const openModal = () =&gt; {
+    setIsDialogOpen(true);
+    document.body.classList.add(&#39;overflow-hidden-scrollable&#39;);
+  };
+
</file context>

✅ Addressed in f3c6c4f

};

// Cleanup: ensure body scroll class is removed if component unmounts while dialog is open
useEffect(() => {
return () => {
document.body.classList.remove('overflow-hidden-scrollable');
};
}, []);

const SourceCard = ({
source,
index,
Expand Down
29 changes: 16 additions & 13 deletions src/lib/biasLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
* - Press freedom: 25%
*/

import { readFileSync, appendFileSync, existsSync } from 'fs';
import { readFileSync, existsSync } from 'fs';
import { appendFile } from 'fs/promises';
import { join } from 'path';
import psl from 'psl';

export type Lane = 'LEFT' | 'RIGHT' | 'CENTER' | 'UNKNOWN';

Expand Down Expand Up @@ -357,18 +359,19 @@ const UNKNOWN_DOMAINS_LOG_PATH = join(
/**
* Logs an unknown domain to file for later research.
* Only logs each domain once per session.
* Uses async I/O to avoid blocking the event loop.
*/
const logUnknownDomain = (domain: string): void => {
if (unknownDomainsSet.has(domain)) return;
unknownDomainsSet.add(domain);

try {
const timestamp = new Date().toISOString().split('T')[0];
const logLine = `${timestamp}\t${domain}\n`;
appendFileSync(UNKNOWN_DOMAINS_LOG_PATH, logLine);
} catch {
const timestamp = new Date().toISOString().split('T')[0];
const logLine = `${timestamp}\t${domain}\n`;

// Fire-and-forget async write to avoid blocking the event loop
appendFile(UNKNOWN_DOMAINS_LOG_PATH, logLine).catch(() => {
// Silently fail if we can't write (e.g., permissions)
}
});
};

/**
Expand Down Expand Up @@ -425,6 +428,7 @@ const GOV_EDU_CREDIBILITY: SourceCredibility = {

/**
* Looks up a domain in the credibility map, handling subdomains.
* Uses psl (Public Suffix List) for proper TLD extraction (e.g., bbc.co.uk, not co.uk).
*/
const lookupDomain = (domain: string): SourceCredibility | null => {
const cleanDomain = domain.toLowerCase().replace(/^www\./, '');
Expand All @@ -435,12 +439,11 @@ const lookupDomain = (domain: string): SourceCredibility | null => {
return map.get(cleanDomain)!;
}

// Try without subdomains (e.g., news.bbc.com -> bbc.com)
const parts = cleanDomain.split('.');
if (parts.length > 2) {
const rootDomain = parts.slice(-2).join('.');
if (map.has(rootDomain)) {
return map.get(rootDomain)!;
// Extract root domain using psl for proper multi-part TLD handling
const parsed = psl.parse(cleanDomain);
if (parsed && 'domain' in parsed && parsed.domain) {
if (map.has(parsed.domain)) {
return map.get(parsed.domain)!;
}
}

Expand Down
Loading