sidebar: better headlines

No tooltip, instead show title when expand
Sort articles by source priority
Also allow excluding domains and exclude google news by default (its just an aggregator so it causes lots of duplicates)
This commit is contained in:
2 * r + 2 * t 2025-04-10 19:56:40 +10:00
parent fc3ea04ee5
commit 6f62023574
5 changed files with 21 additions and 5 deletions

View file

@ -849,6 +849,14 @@
& > :last-child { & > :last-child {
margin-top: lib.s(8); margin-top: lib.s(8);
} }
.title {
@include font.title;
font-size: lib.s(18);
font-weight: 500;
margin-bottom: lib.s(3);
}
} }
button:hover .article-body, button:hover .article-body,

View file

@ -175,6 +175,7 @@ export default {
categories: ["business", "top", "technology", "world"], // A list of news categories to filter by categories: ["business", "top", "technology", "world"], // A list of news categories to filter by
languages: ["en"], // A list of languages codes to filter by languages: ["en"], // A list of languages codes to filter by
domains: [] as string[], // A list of news domains to pull from, see https://newsdata.io/news-sources for available domains domains: [] as string[], // A list of news domains to pull from, see https://newsdata.io/news-sources for available domains
excludeDomains: ["news.google.com"], // A list of news domains to exclude, e.g. bbc.co.uk
timezone: "", // A timezone to filter by, e.g. "America/New_York", see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones timezone: "", // A timezone to filter by, e.g. "America/New_York", see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
pages: 3, // Number of pages to pull (each page is 10 articles) pages: 3, // Number of pages to pull (each page is 10 articles)
}, },

View file

@ -86,6 +86,7 @@ export default {
"news.categories": ARR(NEWS_CATEGORIES), "news.categories": ARR(NEWS_CATEGORIES),
"news.languages": ARR(NEWS_LANGUAGES), "news.languages": ARR(NEWS_LANGUAGES),
"news.domains": ARR(STR), "news.domains": ARR(STR),
"news.excludeDomains": ARR(STR),
"news.timezone": STR, "news.timezone": STR,
"news.pages": NUM, "news.pages": NUM,
} as { [k: string]: string | string[] | number[] }; } as { [k: string]: string | string[] | number[] };

View file

@ -2,7 +2,6 @@ import type { Monitor } from "@/services/monitors";
import News, { type IArticle } from "@/services/news"; import News, { type IArticle } from "@/services/news";
import Palette, { type IPalette } from "@/services/palette"; import Palette, { type IPalette } from "@/services/palette";
import { capitalize } from "@/utils/strings"; import { capitalize } from "@/utils/strings";
import { setupCustomTooltip } from "@/utils/widgets";
import { bind, execAsync, Variable } from "astal"; import { bind, execAsync, Variable } from "astal";
import { Gtk } from "astal/gtk3"; import { Gtk } from "astal/gtk3";
import { sidebar } from "config"; import { sidebar } from "config";
@ -56,7 +55,7 @@ const Article = ({ title, description, creator, pubDate, source_name, link }: IA
<button className="wrapper" cursor="pointer" onClicked={() => expanded.set(!expanded.get())}> <button className="wrapper" cursor="pointer" onClicked={() => expanded.set(!expanded.get())}>
<box hexpand className="header"> <box hexpand className="header">
<box vertical> <box vertical>
<label truncate xalign={0} label={title} setup={self => setupCustomTooltip(self, title)} /> <label truncate xalign={0} label={title} />
<label <label
truncate truncate
xalign={0} xalign={0}
@ -73,6 +72,7 @@ const Article = ({ title, description, creator, pubDate, source_name, link }: IA
> >
<button onClicked={() => execAsync(`app2unit -O -- ${link}`)}> <button onClicked={() => execAsync(`app2unit -O -- ${link}`)}>
<box vertical className="article-body"> <box vertical className="article-body">
<label wrap className="title" xalign={0} label={title} />
<label wrap xalign={0} label={`Published on ${new Date(pubDate).toLocaleString()}`} /> <label wrap xalign={0} label={`Published on ${new Date(pubDate).toLocaleString()}`} />
<label <label
wrap wrap
@ -119,7 +119,9 @@ const Category = ({ title, articles }: { title: string; articles: IArticle[] })
transitionDuration={200} transitionDuration={200}
> >
<box vertical className="body"> <box vertical className="body">
{articles.map(a => ( {articles
.sort((a, b) => a.source_priority - b.source_priority)
.map(a => (
<Article {...a} /> <Article {...a} />
))} ))}
</box> </box>

View file

@ -10,6 +10,7 @@ export interface IArticle {
description: string | null; description: string | null;
pubDate: string; pubDate: string;
source_name: string; source_name: string;
source_priority: number;
category: string[]; category: string[];
} }
@ -68,6 +69,7 @@ export default class News extends GObject.Object {
const categories = config.categories.get().join(","); const categories = config.categories.get().join(",");
const languages = config.languages.get().join(","); const languages = config.languages.get().join(",");
const domains = config.domains.get().join(","); const domains = config.domains.get().join(",");
const excludeDomains = config.excludeDomains.get().join(",");
const timezone = config.timezone.get(); const timezone = config.timezone.get();
if (countries.includes("current")) { if (countries.includes("current")) {
@ -80,6 +82,7 @@ export default class News extends GObject.Object {
if (categories) args += `&category=${categories}`; if (categories) args += `&category=${categories}`;
if (languages) args += `&language=${languages}`; if (languages) args += `&language=${languages}`;
if (domains) args += `&domain=${domains}`; if (domains) args += `&domain=${domains}`;
if (excludeDomains) args += `&excludedomain=${excludeDomains}`;
if (timezone) args += `&timezone=${timezone}`; if (timezone) args += `&timezone=${timezone}`;
const url = `https://newsdata.io/api/1/latest?apikey=${config.apiKey.get()}&${args}`; const url = `https://newsdata.io/api/1/latest?apikey=${config.apiKey.get()}&${args}`;
@ -141,6 +144,7 @@ export default class News extends GObject.Object {
config.categories.subscribe(() => this.getNews().catch(console.error)); config.categories.subscribe(() => this.getNews().catch(console.error));
config.languages.subscribe(() => this.getNews().catch(console.error)); config.languages.subscribe(() => this.getNews().catch(console.error));
config.domains.subscribe(() => this.getNews().catch(console.error)); config.domains.subscribe(() => this.getNews().catch(console.error));
config.excludeDomains.subscribe(() => this.getNews().catch(console.error));
config.timezone.subscribe(() => this.getNews().catch(console.error)); config.timezone.subscribe(() => this.getNews().catch(console.error));
config.pages.subscribe(() => this.getNews().catch(console.error)); config.pages.subscribe(() => this.getNews().catch(console.error));
} }