Allow displaying RSS button to unauthenticated users

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2022-11-11 00:11:19 +01:00
parent 84ff4d928d
commit 5d10324127
7 changed files with 71 additions and 8 deletions

View file

@ -21,6 +21,7 @@ import { HStack, IconButton, Menu, MenuButton, MenuItem, MenuList, MenuLink, Men
import SvgIcon from 'soapbox/components/ui/icon/svg-icon'; import SvgIcon from 'soapbox/components/ui/icon/svg-icon';
import MovedNote from 'soapbox/features/account_timeline/components/moved_note'; import MovedNote from 'soapbox/features/account_timeline/components/moved_note';
import ActionButton from 'soapbox/features/ui/components/action-button'; import ActionButton from 'soapbox/features/ui/components/action-button';
import FeedButton from 'soapbox/features/ui/components/feed-button';
import SubscriptionButton from 'soapbox/features/ui/components/subscription-button'; import SubscriptionButton from 'soapbox/features/ui/components/subscription-button';
import { useAppDispatch, useFeatures, useOwnAccount } from 'soapbox/hooks'; import { useAppDispatch, useFeatures, useOwnAccount } from 'soapbox/hooks';
import { normalizeAttachment } from 'soapbox/normalizers'; import { normalizeAttachment } from 'soapbox/normalizers';
@ -573,7 +574,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
<div className='mt-10 flex flex-row space-y-0 space-x-2'> <div className='mt-10 flex flex-row space-y-0 space-x-2'>
<SubscriptionButton account={account} /> <SubscriptionButton account={account} />
{ownAccount && ( {ownAccount ? (
<Menu> <Menu>
<MenuButton <MenuButton
as={IconButton} as={IconButton}
@ -607,6 +608,8 @@ const Header: React.FC<IHeader> = ({ account }) => {
})} })}
</MenuList> </MenuList>
</Menu> </Menu>
) : (
<FeedButton account={account} />
)} )}
{renderShareButton()} {renderShareButton()}

View file

@ -49,6 +49,7 @@ const messages = defineMessages({
authenticatedProfileLabel: { id: 'soapbox_config.authenticated_profile_label', defaultMessage: 'Profiles require authentication' }, authenticatedProfileLabel: { id: 'soapbox_config.authenticated_profile_label', defaultMessage: 'Profiles require authentication' },
authenticatedProfileHint: { id: 'soapbox_config.authenticated_profile_hint', defaultMessage: 'Users must be logged-in to view replies and media on user profiles.' }, authenticatedProfileHint: { id: 'soapbox_config.authenticated_profile_hint', defaultMessage: 'Users must be logged-in to view replies and media on user profiles.' },
displayCtaLabel: { id: 'soapbox_config.cta_label', defaultMessage: 'Display call to action panels if not authenticated' }, displayCtaLabel: { id: 'soapbox_config.cta_label', defaultMessage: 'Display call to action panels if not authenticated' },
featureFeedsLabel: { id: 'soapbox_config.feature_feeds_label', defaultMessage: 'Feature RSS feeds to unauthenticated users' },
singleUserModeLabel: { id: 'soapbox_config.single_user_mode_label', defaultMessage: 'Single user mode' }, singleUserModeLabel: { id: 'soapbox_config.single_user_mode_label', defaultMessage: 'Single user mode' },
singleUserModeHint: { id: 'soapbox_config.single_user_mode_hint', defaultMessage: 'Front page will redirect to a given user profile.' }, singleUserModeHint: { id: 'soapbox_config.single_user_mode_hint', defaultMessage: 'Front page will redirect to a given user profile.' },
singleUserModeProfileLabel: { id: 'soapbox_config.single_user_mode_profile_label', defaultMessage: 'Main user handle' }, singleUserModeProfileLabel: { id: 'soapbox_config.single_user_mode_profile_label', defaultMessage: 'Main user handle' },
@ -269,6 +270,13 @@ const SoapboxConfig: React.FC = () => {
/> />
</ListItem> </ListItem>
<ListItem label={intl.formatMessage(messages.featureFeedsLabel)}>
<Toggle
checked={soapbox.featureFeeds === true}
onChange={handleChange(['featureFeeds'], (e) => e.target.checked)}
/>
</ListItem>
<ListItem <ListItem
label={intl.formatMessage(messages.authenticatedProfileLabel)} label={intl.formatMessage(messages.authenticatedProfileLabel)}
hint={intl.formatMessage(messages.authenticatedProfileHint)} hint={intl.formatMessage(messages.authenticatedProfileHint)}

View file

@ -0,0 +1,50 @@
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { IconButton } from 'soapbox/components/ui';
import { useAppSelector, useSoapboxConfig } from 'soapbox/hooks';
import { isLocal } from 'soapbox/utils/accounts';
import { parseVersion, MASTODON, PLEROMA } from 'soapbox/utils/features';
import type { Account as AccountEntity } from 'soapbox/types/entities';
const messages = defineMessages({
subscribeFeed: { id: 'account.rss_feed', defaultMessage: 'Subscribe to RSS feed' },
});
interface IFeedButton {
account: AccountEntity
}
const FeedButton = ({ account }: IFeedButton) => {
const intl = useIntl();
const { featureFeeds } = useSoapboxConfig();
const { software } = useAppSelector((state) => parseVersion(state.instance.version));
let feedUrl: string | undefined;
switch (software) {
case MASTODON:
feedUrl = `${account.url}.rss`;
break;
case PLEROMA:
feedUrl = `${account.url}/feed.rss`;
break;
}
if (!featureFeeds || !feedUrl || !isLocal(account)) return null;
return (
<IconButton
src={require('@tabler/icons/rss.svg')}
onClick={() => window.open(feedUrl, '_blank')}
title={intl.formatMessage(messages.subscribeFeed)}
theme='outlined'
className='px-[10px]'
iconClassName='w-4 h-4'
/>
);
};
export default FeedButton;

View file

@ -32,12 +32,12 @@ const SubscriptionButton = ({ account }: ISubscriptionButton) => {
const isFollowing = account.relationship?.following; const isFollowing = account.relationship?.following;
const isRequested = account.relationship?.requested; const isRequested = account.relationship?.requested;
const isSubscribed = features.accountNotifies ? const isSubscribed = features.accountNotifies
account.relationship?.notifying : ? account.relationship?.notifying
account.relationship?.subscribing; : account.relationship?.subscribing;
const title = isSubscribed ? const title = isSubscribed
intl.formatMessage(messages.unsubscribe, { name: account.get('username') }) : ? intl.formatMessage(messages.unsubscribe, { name: account.get('username') })
intl.formatMessage(messages.subscribe, { name: account.get('username') }); : intl.formatMessage(messages.subscribe, { name: account.get('username') });
const onSubscribeSuccess = () => const onSubscribeSuccess = () =>
dispatch(snackbar.success(intl.formatMessage(messages.subscribeSuccess))); dispatch(snackbar.success(intl.formatMessage(messages.subscribeSuccess)));

View file

@ -48,6 +48,7 @@
"account.report": "Zgłoś @{name}", "account.report": "Zgłoś @{name}",
"account.requested": "Oczekująca prośba, kliknij aby anulować", "account.requested": "Oczekująca prośba, kliknij aby anulować",
"account.requested_small": "Oczekująca prośba", "account.requested_small": "Oczekująca prośba",
"account.rss_feed": "Subskrybuj kanał RSS",
"account.search": "Szukaj wpisów @{name}", "account.search": "Szukaj wpisów @{name}",
"account.search_self": "Szukaj własnych wpisów", "account.search_self": "Szukaj własnych wpisów",
"account.share": "Udostępnij profil @{name}", "account.share": "Udostępnij profil @{name}",

View file

@ -112,6 +112,7 @@ export const SoapboxConfigRecord = ImmutableRecord({
linkFooterMessage: '', linkFooterMessage: '',
links: ImmutableMap<string, string>(), links: ImmutableMap<string, string>(),
displayCta: true, displayCta: true,
featureFeeds: false,
}, 'SoapboxConfig'); }, 'SoapboxConfig');
type SoapboxConfigMap = ImmutableMap<string, any>; type SoapboxConfigMap = ImmutableMap<string, any>;

View file

@ -133,7 +133,7 @@ const configuration: Configuration = {
'/unsubscribe', '/unsubscribe',
]; ];
if (backendRoutes.some(path => pathname.startsWith(path)) || pathname.endsWith('/embed')) { if (backendRoutes.some(path => pathname.startsWith(path)) || pathname.endsWith('/embed') || pathname.endsWith('.rss')) {
return url; return url;
} }
}, },