diff --git a/src/api/hooks/streaming/useCommunityStream.ts b/src/api/hooks/streaming/useCommunityStream.ts
index f0ccca5d6..5db097ae5 100644
--- a/src/api/hooks/streaming/useCommunityStream.ts
+++ b/src/api/hooks/streaming/useCommunityStream.ts
@@ -2,12 +2,16 @@ import { useTimelineStream } from './useTimelineStream';
interface UseCommunityStreamOpts {
onlyMedia?: boolean
+ enabled?: boolean
}
-function useCommunityStream({ onlyMedia }: UseCommunityStreamOpts = {}) {
+function useCommunityStream({ onlyMedia, enabled }: UseCommunityStreamOpts = {}) {
return useTimelineStream(
`community${onlyMedia ? ':media' : ''}`,
`public:local${onlyMedia ? ':media' : ''}`,
+ undefined,
+ undefined,
+ { enabled },
);
}
diff --git a/src/components/sidebar-navigation.tsx b/src/components/sidebar-navigation.tsx
index 3dadaeab1..095d2472a 100644
--- a/src/components/sidebar-navigation.tsx
+++ b/src/components/sidebar-navigation.tsx
@@ -4,7 +4,7 @@ import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { Stack } from 'soapbox/components/ui';
import { useStatContext } from 'soapbox/contexts/stat-context';
import ComposeButton from 'soapbox/features/ui/components/compose-button';
-import { useAppSelector, useGroupsPath, useFeatures, useOwnAccount, useSettings } from 'soapbox/hooks';
+import { useAppSelector, useGroupsPath, useFeatures, useOwnAccount, useSettings, useInstance } from 'soapbox/hooks';
import DropdownMenu, { Menu } from './dropdown-menu';
import SidebarNavigationLink from './sidebar-navigation-link';
@@ -22,6 +22,7 @@ const SidebarNavigation = () => {
const intl = useIntl();
const { unreadChatsCount } = useStatContext();
+ const instance = useInstance();
const features = useFeatures();
const settings = useSettings();
const { account } = useOwnAccount();
@@ -31,6 +32,8 @@ const SidebarNavigation = () => {
const followRequestsCount = useAppSelector((state) => state.user_lists.follow_requests.items.count());
const dashboardCount = useAppSelector((state) => state.admin.openReports.count() + state.admin.awaitingApproval.count());
+ const restrictUnauth = instance.pleroma.metadata.restrict_unauthenticated;
+
const makeMenu = (): Menu => {
const menu: Menu = [];
@@ -166,15 +169,17 @@ const SidebarNavigation = () => {
>
)}
- {features.publicTimeline && (
+ {(features.publicTimeline) && (
<>
- : }
- />
+ {(account || !restrictUnauth.timelines.local) && (
+ : }
+ />
+ )}
- {features.federating && (
+ {(features.federating && (account || !restrictUnauth.timelines.federated)) && (
{
const dispatch = useAppDispatch();
+ const instance = useInstance();
+
+ const timelineEnabled = !instance.pleroma.metadata.restrict_unauthenticated.timelines.local;
const next = useAppSelector(state => state.timelines.get('community')?.next);
const timelineId = 'community';
const handleLoadMore = (maxId: string) => {
- dispatch(expandCommunityTimeline({ url: next, maxId }));
+ if (timelineEnabled) {
+ dispatch(expandCommunityTimeline({ url: next, maxId }));
+ }
};
- const handleRefresh = () => {
- return dispatch(expandCommunityTimeline());
+ const handleRefresh = async () => {
+ if (timelineEnabled) {
+ return dispatch(expandCommunityTimeline());
+ }
};
- useCommunityStream();
+ useCommunityStream({ enabled: timelineEnabled });
useEffect(() => {
- dispatch(expandCommunityTimeline());
+ if (timelineEnabled) {
+ dispatch(expandCommunityTimeline());
+ }
}, []);
return (
@@ -37,16 +47,20 @@ const LandingTimeline = () => {
-
- }
- divideType='space'
- />
-
+ {timelineEnabled ? (
+
+ }
+ divideType='space'
+ />
+
+ ) : (
+
+ )}
);
};
diff --git a/src/schemas/instance.ts b/src/schemas/instance.ts
index c2f72b8ff..807d0c657 100644
--- a/src/schemas/instance.ts
+++ b/src/schemas/instance.ts
@@ -53,6 +53,20 @@ const pleromaSchema = coerceObject({
}),
fields_limits: z.any(),
migration_cooldown_period: z.number().optional().catch(undefined),
+ restrict_unauthenticated: coerceObject({
+ activities: coerceObject({
+ local: z.boolean().catch(false),
+ remote: z.boolean().catch(false),
+ }),
+ profiles: coerceObject({
+ local: z.boolean().catch(false),
+ remote: z.boolean().catch(false),
+ }),
+ timelines: coerceObject({
+ federated: z.boolean().catch(false),
+ local: z.boolean().catch(false),
+ }),
+ }),
translation: coerceObject({
allow_remote: z.boolean().catch(true),
allow_unauthenticated: z.boolean().catch(false),