Allow displaying RSS button to unauthenticated users
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
parent
84ff4d928d
commit
5d10324127
7 changed files with 71 additions and 8 deletions
|
@ -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()}
|
||||||
|
|
|
@ -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)}
|
||||||
|
|
50
app/soapbox/features/ui/components/feed-button.tsx
Normal file
50
app/soapbox/features/ui/components/feed-button.tsx
Normal 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;
|
|
@ -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)));
|
||||||
|
|
|
@ -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}",
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue