diff --git a/src/components/settings/services/EditServiceForm.tsx b/src/components/settings/services/EditServiceForm.tsx index 69893c16c8..00629b6b69 100644 --- a/src/components/settings/services/EditServiceForm.tsx +++ b/src/components/settings/services/EditServiceForm.tsx @@ -396,6 +396,7 @@ class EditServiceForm extends Component {

{intl.formatMessage(messages.headlineAppearance)}

+ {form.$('isDarkModeEnabled').value && ( <> diff --git a/src/config.ts b/src/config.ts index 612aa68710..348b4b85d6 100644 --- a/src/config.ts +++ b/src/config.ts @@ -443,6 +443,7 @@ export const DEFAULT_SERVICE_SETTINGS = { isBadgeEnabled: true, isMediaBadgeEnabled: false, trapLinkClicks: false, + useFavicon: false, isMuted: false, customIcon: false, isDarkModeEnabled: false, diff --git a/src/containers/settings/EditServiceScreen.tsx b/src/containers/settings/EditServiceScreen.tsx index f3b9b08572..e890e86952 100644 --- a/src/containers/settings/EditServiceScreen.tsx +++ b/src/containers/settings/EditServiceScreen.tsx @@ -96,6 +96,10 @@ const messages = defineMessages({ id: 'settings.service.form.trapLinkClicks', defaultMessage: 'Open URLs within Ferdium', }, + useFavicon: { + id: 'settings.service.form.useFavicon', + defaultMessage: 'Use service favicon instead of default or custom icon', + }, onlyShowFavoritesInUnreadCount: { id: 'settings.service.form.onlyShowFavoritesInUnreadCount', defaultMessage: 'Only show Favorites in unread count', @@ -258,6 +262,15 @@ class EditServiceScreen extends Component { default: DEFAULT_SERVICE_SETTINGS.trapLinkClicks, type: 'checkbox', }, + useFavicon: { + label: intl.formatMessage(messages.useFavicon), + value: ifUndefined( + service?.useFavicon, + DEFAULT_SERVICE_SETTINGS.useFavicon, + ), + default: DEFAULT_SERVICE_SETTINGS.useFavicon, + type: 'checkbox', + }, isMuted: { label: intl.formatMessage(messages.enableAudio), value: !ifUndefined( diff --git a/src/helpers/favicon-helpers.ts b/src/helpers/favicon-helpers.ts new file mode 100644 index 0000000000..5743d938fb --- /dev/null +++ b/src/helpers/favicon-helpers.ts @@ -0,0 +1,3 @@ +export function getFaviconUrl(url: string, size: number = 128): string { + return `https://www.google.com/s2/favicons?sz=${size}&domain_url=${url}`; +} diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 1941ecd867..1835854e1b 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -394,6 +394,7 @@ "settings.service.form.tabOnPremise": "Self hosted ⭐️", "settings.service.form.team": "Team", "settings.service.form.trapLinkClicks": "Open URLs within Ferdium", + "settings.service.form.useFavicon": "Use service favicon instead of default or custom icon", "settings.service.form.useHostedService": "Use the hosted {name} service.", "settings.service.form.yourServices": "Your services", "settings.service.reloadRequired": "Changes require reload of the service", diff --git a/src/internal-server/app/Controllers/Http/ServiceController.js b/src/internal-server/app/Controllers/Http/ServiceController.js index 8e8aa97a8d..4e3c63515c 100644 --- a/src/internal-server/app/Controllers/Http/ServiceController.js +++ b/src/internal-server/app/Controllers/Http/ServiceController.js @@ -53,6 +53,7 @@ class ServiceController { isNotificationEnabled: DEFAULT_SERVICE_SETTINGS.isNotificationEnabled, isBadgeEnabled: DEFAULT_SERVICE_SETTINGS.isBadgeEnabled, trapLinkClicks: DEFAULT_SERVICE_SETTINGS.trapLinkClicks, + useFavicon: DEFAULT_SERVICE_SETTINGS.useFavicon, isMuted: DEFAULT_SERVICE_SETTINGS.isMuted, isDarkModeEnabled: '', // TODO: This should ideally be a boolean (false). But, changing it caused the sidebar toggle to not work. isProgressbarEnabled: DEFAULT_SERVICE_SETTINGS.isProgressbarEnabled, @@ -83,6 +84,7 @@ class ServiceController { hasCustomIcon: DEFAULT_SERVICE_SETTINGS.hasCustomIcon, isBadgeEnabled: DEFAULT_SERVICE_SETTINGS.isBadgeEnabled, trapLinkClicks: DEFAULT_SERVICE_SETTINGS.trapLinkClicks, + useFavicon: DEFAULT_SERVICE_SETTINGS.useFavicon, isDarkModeEnabled: '', // TODO: This should ideally be a boolean (false). But, changing it caused the sidebar toggle to not work. isProgressbarEnabled: DEFAULT_SERVICE_SETTINGS.isProgressbarEnabled, isEnabled: DEFAULT_SERVICE_SETTINGS.isEnabled, @@ -232,6 +234,7 @@ class ServiceController { hasCustomIcon: DEFAULT_SERVICE_SETTINGS.customIcon, isBadgeEnabled: DEFAULT_SERVICE_SETTINGS.isBadgeEnabled, trapLinkClicks: DEFAULT_SERVICE_SETTINGS.trapLinkClicks, + useFavicon: DEFAULT_SERVICE_SETTINGS.useFavicon, isDarkModeEnabled: '', // TODO: This should ideally be a boolean (false). But, changing it caused the sidebar toggle to not work. isProgressbarEnabled: DEFAULT_SERVICE_SETTINGS.isProgressbarEnabled, isEnabled: DEFAULT_SERVICE_SETTINGS.isEnabled, diff --git a/src/models/Service.ts b/src/models/Service.ts index 6d19f44f1a..5256611724 100644 --- a/src/models/Service.ts +++ b/src/models/Service.ts @@ -8,6 +8,7 @@ import { v4 as uuidV4 } from 'uuid'; import { needsToken } from '../api/apiBase'; import { DEFAULT_SERVICE_ORDER, DEFAULT_SERVICE_SETTINGS } from '../config'; import { todosStore } from '../features/todos'; +import { getFaviconUrl } from '../helpers/favicon-helpers'; import { isValidExternalURL, normalizedUrl } from '../helpers/url-helpers'; import { ifUndefined } from '../jsUtils'; import type { IRecipe } from './Recipe'; @@ -134,6 +135,8 @@ export default class Service { @observable isMediaPlaying: boolean = false; + @observable useFavicon: boolean = DEFAULT_SERVICE_SETTINGS.useFavicon; + @action _setAutoRun() { if (!this.isEnabled) { this.webview = null; @@ -167,6 +170,7 @@ export default class Service { this.team = ifUndefined(data.team, this.team); this.customUrl = ifUndefined(data.customUrl, this.customUrl); this.iconUrl = ifUndefined(data.iconUrl, this.iconUrl); + this.useFavicon = ifUndefined(data.useFavicon, this.useFavicon); this.order = ifUndefined(data.order, this.order); this.isEnabled = ifUndefined(data.isEnabled, this.isEnabled); this.isNotificationEnabled = ifUndefined( @@ -350,6 +354,10 @@ export default class Service { } @computed get icon(): string { + if (this.useFavicon) { + return getFaviconUrl(this.url); + } + if (this.iconUrl) { if (needsToken()) { let url: URL; diff --git a/src/stores/ServicesStore.ts b/src/stores/ServicesStore.ts index fd74140041..9f2cfeca3b 100644 --- a/src/stores/ServicesStore.ts +++ b/src/stores/ServicesStore.ts @@ -472,6 +472,7 @@ export default class ServicesStore extends TypedStore { isBadgeEnabled: DEFAULT_SERVICE_SETTINGS.isBadgeEnabled, isMediaBadgeEnabled: DEFAULT_SERVICE_SETTINGS.isMediaBadgeEnabled, trapLinkClicks: DEFAULT_SERVICE_SETTINGS.trapLinkClicks, + useFavicon: DEFAULT_SERVICE_SETTINGS.useFavicon, isMuted: DEFAULT_SERVICE_SETTINGS.isMuted, customIcon: DEFAULT_SERVICE_SETTINGS.customIcon, isDarkModeEnabled: DEFAULT_SERVICE_SETTINGS.isDarkModeEnabled,