2025-03-19 13:37:54 +05:30
|
|
|
import { searchSearxng } from '@/lib/searxng';
|
2025-08-17 22:53:19 +08:00
|
|
|
import { DEFAULT_LOCALE } from '@/i18n/locales';
|
2025-03-19 13:37:54 +05:30
|
|
|
|
2025-07-29 13:17:07 +05:30
|
|
|
const websitesForTopic = {
|
|
|
|
|
tech: {
|
|
|
|
|
query: ['technology news', 'latest tech', 'AI', 'science and innovation'],
|
|
|
|
|
links: ['techcrunch.com', 'wired.com', 'theverge.com'],
|
|
|
|
|
},
|
|
|
|
|
finance: {
|
|
|
|
|
query: ['finance news', 'economy', 'stock market', 'investing'],
|
|
|
|
|
links: ['bloomberg.com', 'cnbc.com', 'marketwatch.com'],
|
|
|
|
|
},
|
|
|
|
|
art: {
|
|
|
|
|
query: ['art news', 'culture', 'modern art', 'cultural events'],
|
|
|
|
|
links: ['artnews.com', 'hyperallergic.com', 'theartnewspaper.com'],
|
|
|
|
|
},
|
|
|
|
|
sports: {
|
|
|
|
|
query: ['sports news', 'latest sports', 'cricket football tennis'],
|
|
|
|
|
links: ['espn.com', 'bbc.com/sport', 'skysports.com'],
|
|
|
|
|
},
|
|
|
|
|
entertainment: {
|
|
|
|
|
query: ['entertainment news', 'movies', 'TV shows', 'celebrities'],
|
|
|
|
|
links: ['hollywoodreporter.com', 'variety.com', 'deadline.com'],
|
|
|
|
|
},
|
|
|
|
|
};
|
2025-03-19 13:37:54 +05:30
|
|
|
|
2025-07-29 13:17:07 +05:30
|
|
|
type Topic = keyof typeof websitesForTopic;
|
2025-03-19 13:37:54 +05:30
|
|
|
|
|
|
|
|
export const GET = async (req: Request) => {
|
|
|
|
|
try {
|
2025-05-30 08:35:15 +05:30
|
|
|
const params = new URL(req.url).searchParams;
|
2025-07-29 13:17:07 +05:30
|
|
|
|
2025-05-30 08:35:15 +05:30
|
|
|
const mode: 'normal' | 'preview' =
|
|
|
|
|
(params.get('mode') as 'normal' | 'preview') || 'normal';
|
2025-07-29 13:17:07 +05:30
|
|
|
const topic: Topic = (params.get('topic') as Topic) || 'tech';
|
|
|
|
|
|
|
|
|
|
const selectedTopic = websitesForTopic[topic];
|
2025-05-30 08:35:15 +05:30
|
|
|
|
|
|
|
|
let data = [];
|
|
|
|
|
|
|
|
|
|
if (mode === 'normal') {
|
2025-08-01 20:41:07 +05:30
|
|
|
const seenUrls = new Set();
|
|
|
|
|
|
2025-05-30 08:35:15 +05:30
|
|
|
data = (
|
2025-08-01 20:41:07 +05:30
|
|
|
await Promise.all(
|
|
|
|
|
selectedTopic.links.flatMap((link) =>
|
|
|
|
|
selectedTopic.query.map(async (query) => {
|
2025-05-30 08:35:15 +05:30
|
|
|
return (
|
2025-08-01 20:41:07 +05:30
|
|
|
await searchSearxng(`site:${link} ${query}`, {
|
feat(i18n): Integrate next-intl, localize core UI, add regional locales and zh-TW Discover sources
**Overview**
- Integrates next-intl (App Router, no i18n routing) with cookie-based locale and Accept-Language fallback.
- Adds message bundles and regional variants; sets en-US as the default.
**Key changes**
- i18n foundation
- Adds request-scoped config to load messages per locale and injects NextIntlClientProvider in [layout.tsx]
- Adds/updates messages for: en-US, en-GB, zh-TW, zh-HK, zh-CN, ja, ko, fr-FR, fr-CA, de.
Centralizes LOCALES, LOCALE_LABELS, and DEFAULT_LOCALE in [locales.ts]
- Adds LocaleSwitcher (cookie-based) and [LocaleBootstrap]
- Pages and components
- Localizes Sidebar, Home (including metadata/manifest), Settings, Discover, Library.
- Localizes common components: MessageInput, Attach, Focus, Optimization, MessageBox, MessageSources, SearchImages, SearchVideos, EmptyChat, NewsArticleWidget, WeatherWidget.
- APIs
- Weather API returns localized condition strings server-side.
- UX and quality
- Converts all remaining <img> to Next Image.
- Updates browserslist/caniuse DB to silence warnings.
- Security: Settings API Key inputs are now password fields and placeholders were removed.
2025-08-16 12:27:18 +08:00
|
|
|
engines: ['google news', 'bing news'],
|
2025-08-01 20:41:07 +05:30
|
|
|
pageno: 1,
|
2025-08-17 22:53:19 +08:00
|
|
|
language: DEFAULT_LOCALE,
|
2025-08-01 20:41:07 +05:30
|
|
|
})
|
2025-05-30 08:35:15 +05:30
|
|
|
).results;
|
|
|
|
|
}),
|
2025-08-01 20:41:07 +05:30
|
|
|
),
|
|
|
|
|
)
|
2025-05-30 08:35:15 +05:30
|
|
|
)
|
|
|
|
|
.flat()
|
2025-08-01 20:41:07 +05:30
|
|
|
.filter((item) => {
|
|
|
|
|
const url = item.url?.toLowerCase().trim();
|
|
|
|
|
if (seenUrls.has(url)) return false;
|
|
|
|
|
seenUrls.add(url);
|
|
|
|
|
return true;
|
|
|
|
|
})
|
2025-07-29 13:18:36 +05:30
|
|
|
.sort(() => Math.random() - 0.5);
|
2025-05-30 08:35:15 +05:30
|
|
|
} else {
|
|
|
|
|
data = (
|
|
|
|
|
await searchSearxng(
|
2025-07-29 13:17:07 +05:30
|
|
|
`site:${selectedTopic.links[Math.floor(Math.random() * selectedTopic.links.length)]} ${selectedTopic.query[Math.floor(Math.random() * selectedTopic.query.length)]}`,
|
2025-07-17 02:01:45 +08:00
|
|
|
{
|
feat(i18n): Integrate next-intl, localize core UI, add regional locales and zh-TW Discover sources
**Overview**
- Integrates next-intl (App Router, no i18n routing) with cookie-based locale and Accept-Language fallback.
- Adds message bundles and regional variants; sets en-US as the default.
**Key changes**
- i18n foundation
- Adds request-scoped config to load messages per locale and injects NextIntlClientProvider in [layout.tsx]
- Adds/updates messages for: en-US, en-GB, zh-TW, zh-HK, zh-CN, ja, ko, fr-FR, fr-CA, de.
Centralizes LOCALES, LOCALE_LABELS, and DEFAULT_LOCALE in [locales.ts]
- Adds LocaleSwitcher (cookie-based) and [LocaleBootstrap]
- Pages and components
- Localizes Sidebar, Home (including metadata/manifest), Settings, Discover, Library.
- Localizes common components: MessageInput, Attach, Focus, Optimization, MessageBox, MessageSources, SearchImages, SearchVideos, EmptyChat, NewsArticleWidget, WeatherWidget.
- APIs
- Weather API returns localized condition strings server-side.
- UX and quality
- Converts all remaining <img> to Next Image.
- Updates browserslist/caniuse DB to silence warnings.
- Security: Settings API Key inputs are now password fields and placeholders were removed.
2025-08-16 12:27:18 +08:00
|
|
|
engines: ['google news', 'bing news'],
|
2025-07-17 02:01:45 +08:00
|
|
|
pageno: 1,
|
2025-08-17 22:53:19 +08:00
|
|
|
language: DEFAULT_LOCALE,
|
2025-07-17 02:01:45 +08:00
|
|
|
},
|
2025-05-30 08:35:15 +05:30
|
|
|
)
|
|
|
|
|
).results;
|
|
|
|
|
}
|
2025-03-19 13:37:54 +05:30
|
|
|
|
|
|
|
|
return Response.json(
|
|
|
|
|
{
|
|
|
|
|
blogs: data,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
status: 200,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
} catch (err) {
|
2025-03-27 11:36:58 +05:30
|
|
|
console.error(`An error occurred in discover route: ${err}`);
|
2025-03-19 13:37:54 +05:30
|
|
|
return Response.json(
|
|
|
|
|
{
|
|
|
|
|
message: 'An error has occurred',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
status: 500,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
};
|