feat: integrate zitat-service.de API for DE/EN/ES quotes
- Add zitat-service.de as built-in multilingual fallback in goal API:
tries the user's preferred language (de/en/es) automatically before
falling back to ZenQuotes (EN) and then local curated quotes
- Parser now also handles {quote, authorName} response format from
zitat-service.de alongside all previously supported formats
- Preset source pills in settings: add Zitat-Service (DE), (EN), (ES)
(supports de, en, es — no fr/it available from that API)
- Remove Forismatic from presets (unreliable, often returns empty)
- Update hint text to reflect DE/EN/ES API availability vs FR/IT local
v1.84.1
This commit is contained in:
parent
2ec1278b19
commit
04b72a326a
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "my-weekly-todo-list",
|
||||
"version": "1.84.0",
|
||||
"version": "1.84.1",
|
||||
"description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@ -111,14 +111,16 @@ export async function GET(req: Request) {
|
||||
// Quotable: {content, author}
|
||||
if (data.content && data.author) return `${data.content} — ${data.author}`;
|
||||
// Forismatic: {quoteText, quoteAuthor}
|
||||
if (data.quoteText) return data.quoteAuthor ? `${data.quoteText.trim()} — ${data.quoteAuthor.trim()}` : data.quoteText.trim();
|
||||
// Common: {text, author} or {quote, author}
|
||||
if (data.quoteText) return data.quoteAuthor?.trim() ? `${data.quoteText.trim()} — ${data.quoteAuthor.trim()}` : data.quoteText.trim();
|
||||
// zitat-service.de: {quote, authorName}
|
||||
if (data.quote && data.authorName) return `${data.quote} — ${data.authorName}`;
|
||||
// Common: {text, author} or {quote, author} or {body, ...}
|
||||
const text = data.text || data.quote || data.body || data.sentence;
|
||||
const author = data.author || data.by || data.from || data.speaker;
|
||||
const author = data.author || data.authorName || data.by || data.from || data.speaker;
|
||||
if (text) return author ? `${text} — ${author}` : text;
|
||||
// Nested: {data: {quote, author}}
|
||||
// Nested: {data: {...}}
|
||||
if (data.data) return parseQuoteResponse(data.data);
|
||||
// Nested: {slip: {advice}}
|
||||
// Advice Slip: {slip: {advice}}
|
||||
if (data.slip?.advice) return data.slip.advice;
|
||||
} catch { /* ignore */ }
|
||||
return null;
|
||||
@ -139,7 +141,23 @@ export async function GET(req: Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// ZenQuotes as built-in English fallback
|
||||
// Built-in multilingual fallbacks via zitat-service.de (de, en, es) + ZenQuotes (en)
|
||||
const zitatLangMap: Record<string, string> = { de: 'de', en: 'en', es: 'es' };
|
||||
const zitatLang = quoteLangs.find(l => zitatLangMap[l]);
|
||||
if (zitatLang) {
|
||||
try {
|
||||
const res = await fetch(`https://api.zitat-service.de/v1/quote?language=${zitatLangMap[zitatLang]}`, { signal: AbortSignal.timeout(4000) });
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
const parsed = parseQuoteResponse(data);
|
||||
if (parsed) return NextResponse.json({ goal: parsed, isQuote: true });
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch from zitat-service.de:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// ZenQuotes as English fallback
|
||||
if (quoteLangs.includes('en')) {
|
||||
try {
|
||||
const res = await fetch('https://zenquotes.io/api/random', { signal: AbortSignal.timeout(3000) });
|
||||
|
||||
@ -3782,8 +3782,10 @@ function SettingsSidebar({
|
||||
{ label: "ZenQuotes (EN)", url: "https://zenquotes.io/api/random" },
|
||||
{ label: "Stoic Quotes (EN)", url: "https://stoic.tekloon.net/stoic-quote" },
|
||||
{ label: "Quotable (EN)", url: "https://api.quotable.io/quotes/random" },
|
||||
{ label: "Forismatic (EN)", url: "https://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=en" },
|
||||
{ label: "Advice Slip (EN)", url: "https://api.adviceslip.com/advice" },
|
||||
{ label: "Zitat-Service (DE)", url: "https://api.zitat-service.de/v1/quote?language=de" },
|
||||
{ label: "Zitat-Service (EN)", url: "https://api.zitat-service.de/v1/quote?language=en" },
|
||||
{ label: "Zitat-Service (ES)", url: "https://api.zitat-service.de/v1/quote?language=es" },
|
||||
].map(({ label, url }) => {
|
||||
const current: string[] = profile.quoteSourceUrls || [];
|
||||
const already = current.includes(url);
|
||||
@ -3815,8 +3817,8 @@ function SettingsSidebar({
|
||||
</div>
|
||||
<p style={{ fontSize: "0.72rem", color: "var(--weekly-text-light)", marginTop: "6px", fontStyle: "italic" }}>
|
||||
{profile.language === "de"
|
||||
? "Für DE, FR, IT, ES werden kuratierte lokale Zitate verwendet."
|
||||
: "For DE, FR, IT, ES, curated local quotes are used automatically."}
|
||||
? "DE/EN/ES: auch über Zitat-Service API verfügbar. FR/IT: kuratierte lokale Sammlung."
|
||||
: "DE/EN/ES: also available via Zitat-Service API. FR/IT: curated local collection."}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user