Revert "pl-fe: migrate /api/v*/instance to tanstack query"
This reverts commit 1f8b79f309
.
This commit is contained in:
parent
76b8ff2819
commit
6472a5e4e2
79 changed files with 337 additions and 240 deletions
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,5 @@
|
||||||
import { fetchRelationships } from 'pl-fe/actions/accounts';
|
import { fetchRelationships } from 'pl-fe/actions/accounts';
|
||||||
import { importEntities } from 'pl-fe/actions/importer';
|
import { importEntities } from 'pl-fe/actions/importer';
|
||||||
import { queryClient } from 'pl-fe/queries/client';
|
|
||||||
import { filterBadges, getTagDiff } from 'pl-fe/utils/badges';
|
import { filterBadges, getTagDiff } from 'pl-fe/utils/badges';
|
||||||
|
|
||||||
import { getClient } from '../api';
|
import { getClient } from '../api';
|
||||||
|
@ -84,7 +83,6 @@ const updateConfig = (configs: PleromaConfig['configs']) =>
|
||||||
dispatch<AdminActions>({ type: ADMIN_CONFIG_UPDATE_REQUEST, configs });
|
dispatch<AdminActions>({ type: ADMIN_CONFIG_UPDATE_REQUEST, configs });
|
||||||
return getClient(getState).admin.config.updatePleromaConfig(configs)
|
return getClient(getState).admin.config.updatePleromaConfig(configs)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['instance', 'instanceInformation'] });
|
|
||||||
dispatch<AdminActions>({ type: ADMIN_CONFIG_UPDATE_SUCCESS, configs: data.configs, needsReboot: data.need_reboot });
|
dispatch<AdminActions>({ type: ADMIN_CONFIG_UPDATE_SUCCESS, configs: data.configs, needsReboot: data.need_reboot });
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch<AdminActions>({ type: ADMIN_CONFIG_UPDATE_FAIL, error, configs });
|
dispatch<AdminActions>({ type: ADMIN_CONFIG_UPDATE_FAIL, error, configs });
|
||||||
|
|
|
@ -93,7 +93,7 @@ const createAuthApp = () =>
|
||||||
const params = {
|
const params = {
|
||||||
client_name: `${sourceCode.displayName} (${new URL(window.origin).host})`,
|
client_name: `${sourceCode.displayName} (${new URL(window.origin).host})`,
|
||||||
redirect_uris: 'urn:ietf:wg:oauth:2.0:oob',
|
redirect_uris: 'urn:ietf:wg:oauth:2.0:oob',
|
||||||
scopes: getScopes(),
|
scopes: getScopes(getState()),
|
||||||
website: sourceCode.homepage,
|
website: sourceCode.homepage,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ const createAppToken = () =>
|
||||||
client_secret: app.client_secret!,
|
client_secret: app.client_secret!,
|
||||||
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
|
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
|
||||||
grant_type: 'client_credentials',
|
grant_type: 'client_credentials',
|
||||||
scope: getScopes(),
|
scope: getScopes(getState()),
|
||||||
};
|
};
|
||||||
|
|
||||||
return dispatch(obtainOAuthToken(params)).then((token) =>
|
return dispatch(obtainOAuthToken(params)).then((token) =>
|
||||||
|
@ -136,7 +136,7 @@ const createUserToken = (username: string, password: string) =>
|
||||||
grant_type: 'password',
|
grant_type: 'password',
|
||||||
username: username,
|
username: username,
|
||||||
password: password,
|
password: password,
|
||||||
scope: getScopes(),
|
scope: getScopes(getState()),
|
||||||
};
|
};
|
||||||
|
|
||||||
return dispatch(obtainOAuthToken(params))
|
return dispatch(obtainOAuthToken(params))
|
||||||
|
@ -156,7 +156,7 @@ const otpVerify = (code: string, mfa_token: string) =>
|
||||||
code: code,
|
code: code,
|
||||||
challenge_type: 'totp',
|
challenge_type: 'totp',
|
||||||
// redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
|
// redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
|
||||||
// scope: getScopes(),
|
// scope: getScopes(getState()),
|
||||||
}).then((token) => dispatch(authLoggedIn(token)));
|
}).then((token) => dispatch(authLoggedIn(token)));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ import { uploadFile, updateMedia } from './media';
|
||||||
import { createStatus } from './statuses';
|
import { createStatus } from './statuses';
|
||||||
|
|
||||||
import type { EditorState } from 'lexical';
|
import type { EditorState } from 'lexical';
|
||||||
import type { Account as BaseAccount, CreateStatusParams, Group, MediaAttachment, Status as BaseStatus, Tag, Poll, ScheduledStatus, Instance } from 'pl-api';
|
import type { Account as BaseAccount, CreateStatusParams, Group, MediaAttachment, Status as BaseStatus, Tag, Poll, ScheduledStatus } from 'pl-api';
|
||||||
import type { AutoSuggestion } from 'pl-fe/components/autosuggest-input';
|
import type { AutoSuggestion } from 'pl-fe/components/autosuggest-input';
|
||||||
import type { Emoji } from 'pl-fe/features/emoji';
|
import type { Emoji } from 'pl-fe/features/emoji';
|
||||||
import type { Account } from 'pl-fe/normalizers/account';
|
import type { Account } from 'pl-fe/normalizers/account';
|
||||||
|
@ -467,8 +467,7 @@ const submitComposeFail = (composeId: string, error: unknown) => ({
|
||||||
const uploadCompose = (composeId: string, files: FileList, intl: IntlShape) =>
|
const uploadCompose = (composeId: string, files: FileList, intl: IntlShape) =>
|
||||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||||
if (!isLoggedIn(getState)) return;
|
if (!isLoggedIn(getState)) return;
|
||||||
const instance = queryClient.getQueryData<Instance>(['instance', 'instanceInformation', getState().auth.client.baseURL]);
|
const attachmentLimit = getState().instance.configuration.statuses.max_media_attachments;
|
||||||
const attachmentLimit = instance!.configuration.statuses.max_media_attachments;
|
|
||||||
|
|
||||||
const media = getState().compose[composeId]?.media_attachments;
|
const media = getState().compose[composeId]?.media_attachments;
|
||||||
const progress = new Array(files.length).fill(0);
|
const progress = new Array(files.length).fill(0);
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
import { Instance } from 'pl-api';
|
|
||||||
import queryString from 'query-string';
|
import queryString from 'query-string';
|
||||||
|
|
||||||
import * as BuildConfig from 'pl-fe/build-config';
|
import * as BuildConfig from 'pl-fe/build-config';
|
||||||
import { queryClient } from 'pl-fe/queries/client';
|
|
||||||
import { isURL } from 'pl-fe/utils/auth';
|
import { isURL } from 'pl-fe/utils/auth';
|
||||||
import sourceCode from 'pl-fe/utils/code';
|
import sourceCode from 'pl-fe/utils/code';
|
||||||
import { getInstanceScopes } from 'pl-fe/utils/scopes';
|
import { getScopes } from 'pl-fe/utils/scopes';
|
||||||
|
|
||||||
import { createApp } from './apps';
|
import { createApp } from './apps';
|
||||||
|
|
||||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||||
|
|
||||||
const createProviderApp = (instance: Instance) =>
|
const createProviderApp = () =>
|
||||||
async(dispatch: AppDispatch, getState: () => RootState) => {
|
async(dispatch: AppDispatch, getState: () => RootState) => {
|
||||||
const scopes = getInstanceScopes(instance);
|
const scopes = getScopes(getState());
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
client_name: `${sourceCode.displayName} (${new URL(window.origin).host})`,
|
client_name: `${sourceCode.displayName} (${new URL(window.origin).host})`,
|
||||||
|
@ -29,9 +27,8 @@ const prepareRequest = (provider: string) =>
|
||||||
async(dispatch: AppDispatch, getState: () => RootState) => {
|
async(dispatch: AppDispatch, getState: () => RootState) => {
|
||||||
const baseURL = isURL(BuildConfig.BACKEND_URL) ? BuildConfig.BACKEND_URL : '';
|
const baseURL = isURL(BuildConfig.BACKEND_URL) ? BuildConfig.BACKEND_URL : '';
|
||||||
|
|
||||||
const instance = queryClient.getQueryData<Instance>(['instance', 'instanceInformation', baseURL])!;
|
const scopes = getScopes(getState());
|
||||||
const scopes = getInstanceScopes(instance);
|
const app = await dispatch(createProviderApp());
|
||||||
const app = await dispatch(createProviderApp(instance));
|
|
||||||
const { client_id, redirect_uri } = app;
|
const { client_id, redirect_uri } = app;
|
||||||
|
|
||||||
localStorage.setItem('plfe:external:app', JSON.stringify(app));
|
localStorage.setItem('plfe:external:app', JSON.stringify(app));
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
import { getAuthUserUrl, getMeUrl } from 'pl-fe/utils/auth';
|
import { getAuthUserUrl, getMeUrl } from 'pl-fe/utils/auth';
|
||||||
|
|
||||||
import type { RootState } from 'pl-fe/store';
|
import { getClient } from '../api';
|
||||||
|
|
||||||
|
import type { Instance } from 'pl-api';
|
||||||
|
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||||
|
|
||||||
|
const INSTANCE_FETCH_SUCCESS = 'INSTANCE_FETCH_SUCCESS' as const;
|
||||||
|
const INSTANCE_FETCH_FAIL = 'INSTANCE_FETCH_FAIL' as const;
|
||||||
|
|
||||||
/** Figure out the appropriate instance to fetch depending on the state */
|
/** Figure out the appropriate instance to fetch depending on the state */
|
||||||
const getHost = (state: RootState) => {
|
const getHost = (state: RootState) => {
|
||||||
|
@ -13,4 +19,34 @@ const getHost = (state: RootState) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export { getHost };
|
interface InstanceFetchSuccessAction {
|
||||||
|
type: typeof INSTANCE_FETCH_SUCCESS;
|
||||||
|
instance: Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface InstanceFetchFailAction {
|
||||||
|
type: typeof INSTANCE_FETCH_FAIL;
|
||||||
|
error: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchInstance = () => async (dispatch: AppDispatch, getState: () => RootState) => {
|
||||||
|
try {
|
||||||
|
const instance = await getClient(getState).instance.getInstance();
|
||||||
|
|
||||||
|
dispatch<InstanceFetchSuccessAction>({ type: INSTANCE_FETCH_SUCCESS, instance });
|
||||||
|
} catch (error) {
|
||||||
|
dispatch({ type: INSTANCE_FETCH_FAIL, error });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
type InstanceAction =
|
||||||
|
InstanceFetchSuccessAction
|
||||||
|
| InstanceFetchFailAction
|
||||||
|
|
||||||
|
export {
|
||||||
|
INSTANCE_FETCH_SUCCESS,
|
||||||
|
INSTANCE_FETCH_FAIL,
|
||||||
|
getHost,
|
||||||
|
fetchInstance,
|
||||||
|
type InstanceAction,
|
||||||
|
};
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { defineMessages, type IntlShape } from 'react-intl';
|
import { defineMessages, type IntlShape } from 'react-intl';
|
||||||
|
|
||||||
import { queryClient } from 'pl-fe/queries/client';
|
|
||||||
import toast from 'pl-fe/toast';
|
import toast from 'pl-fe/toast';
|
||||||
import { isLoggedIn } from 'pl-fe/utils/auth';
|
import { isLoggedIn } from 'pl-fe/utils/auth';
|
||||||
import { formatBytes, getVideoDuration } from 'pl-fe/utils/media';
|
import { formatBytes, getVideoDuration } from 'pl-fe/utils/media';
|
||||||
|
@ -8,7 +7,7 @@ import resizeImage from 'pl-fe/utils/resize-image';
|
||||||
|
|
||||||
import { getClient } from '../api';
|
import { getClient } from '../api';
|
||||||
|
|
||||||
import type { Instance, MediaAttachment, UploadMediaParams } from 'pl-api';
|
import type { MediaAttachment, UploadMediaParams } from 'pl-api';
|
||||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
@ -36,11 +35,9 @@ const uploadFile = (
|
||||||
changeTotal: (value: number) => void = () => {},
|
changeTotal: (value: number) => void = () => {},
|
||||||
) => async (dispatch: AppDispatch, getState: () => RootState) => {
|
) => async (dispatch: AppDispatch, getState: () => RootState) => {
|
||||||
if (!isLoggedIn(getState)) return;
|
if (!isLoggedIn(getState)) return;
|
||||||
const instance = queryClient.getQueryData<Instance>(['instance', 'instanceInformation', getState().auth.client.baseURL])!;
|
const maxImageSize = getState().instance.configuration.media_attachments.image_size_limit;
|
||||||
|
const maxVideoSize = getState().instance.configuration.media_attachments.video_size_limit;
|
||||||
const {
|
const maxVideoDuration = getState().instance.configuration.media_attachments.video_duration_limit;
|
||||||
image_size_limit: maxImageSize, video_size_limit: maxVideoSize, video_duration_limit: maxVideoDuration,
|
|
||||||
} = instance.configuration.media_attachments;
|
|
||||||
|
|
||||||
const isImage = file.type.match(/image.*/);
|
const isImage = file.type.match(/image.*/);
|
||||||
const isVideo = file.type.match(/video.*/);
|
const isVideo = file.type.match(/video.*/);
|
||||||
|
|
|
@ -67,8 +67,6 @@ interface PreloadAction {
|
||||||
export {
|
export {
|
||||||
PLEROMA_PRELOAD_IMPORT,
|
PLEROMA_PRELOAD_IMPORT,
|
||||||
MASTODON_PRELOAD_IMPORT,
|
MASTODON_PRELOAD_IMPORT,
|
||||||
decodeFromMarkup,
|
|
||||||
pleromaDecoder,
|
|
||||||
preload,
|
preload,
|
||||||
preloadMastodon,
|
preloadMastodon,
|
||||||
type PreloadAction,
|
type PreloadAction,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { createPushSubscription, updatePushSubscription } from 'pl-fe/actions/push-subscriptions';
|
import { createPushSubscription, updatePushSubscription } from 'pl-fe/actions/push-subscriptions';
|
||||||
import { pushNotificationsSetting } from 'pl-fe/settings';
|
import { pushNotificationsSetting } from 'pl-fe/settings';
|
||||||
|
import { getVapidKey } from 'pl-fe/utils/auth';
|
||||||
import { decode as decodeBase64 } from 'pl-fe/utils/base64';
|
import { decode as decodeBase64 } from 'pl-fe/utils/base64';
|
||||||
|
|
||||||
import { setBrowserSupport, setSubscription, clearSubscription } from './setter';
|
import { setBrowserSupport, setSubscription, clearSubscription } from './setter';
|
||||||
|
@ -29,10 +30,10 @@ const getPushSubscription = (registration: ServiceWorkerRegistration) =>
|
||||||
registration.pushManager.getSubscription()
|
registration.pushManager.getSubscription()
|
||||||
.then(subscription => ({ registration, subscription }));
|
.then(subscription => ({ registration, subscription }));
|
||||||
|
|
||||||
const subscribe = (registration: ServiceWorkerRegistration, vapidKey: string) =>
|
const subscribe = (registration: ServiceWorkerRegistration, getState: () => RootState) =>
|
||||||
registration.pushManager.subscribe({
|
registration.pushManager.subscribe({
|
||||||
userVisibleOnly: true,
|
userVisibleOnly: true,
|
||||||
applicationServerKey: urlBase64ToUint8Array(vapidKey),
|
applicationServerKey: urlBase64ToUint8Array(getVapidKey(getState())),
|
||||||
});
|
});
|
||||||
|
|
||||||
const unsubscribe = ({ registration, subscription }: {
|
const unsubscribe = ({ registration, subscription }: {
|
||||||
|
@ -60,9 +61,10 @@ const sendSubscriptionToBackend = (subscription: PushSubscription, me: Me) =>
|
||||||
// eslint-disable-next-line compat/compat
|
// eslint-disable-next-line compat/compat
|
||||||
const supportsPushNotifications = ('serviceWorker' in navigator && 'PushManager' in window && 'getKey' in PushSubscription.prototype);
|
const supportsPushNotifications = ('serviceWorker' in navigator && 'PushManager' in window && 'getKey' in PushSubscription.prototype);
|
||||||
|
|
||||||
const register = (vapidKey?: string) =>
|
const register = () =>
|
||||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||||
const me = getState().me;
|
const me = getState().me;
|
||||||
|
const vapidKey = getVapidKey(getState());
|
||||||
|
|
||||||
dispatch(setBrowserSupport(supportsPushNotifications));
|
dispatch(setBrowserSupport(supportsPushNotifications));
|
||||||
|
|
||||||
|
@ -93,13 +95,13 @@ const register = (vapidKey?: string) =>
|
||||||
} else {
|
} else {
|
||||||
// Something went wrong, try to subscribe again
|
// Something went wrong, try to subscribe again
|
||||||
return unsubscribe({ registration, subscription })
|
return unsubscribe({ registration, subscription })
|
||||||
.then((registration) => subscribe(registration, vapidKey))
|
.then((registration) => subscribe(registration, getState))
|
||||||
.then((pushSubscription) => dispatch(sendSubscriptionToBackend(pushSubscription, me)));
|
.then((pushSubscription) => dispatch(sendSubscriptionToBackend(pushSubscription, me)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No subscription, try to subscribe
|
// No subscription, try to subscribe
|
||||||
return subscribe(registration, vapidKey)
|
return subscribe(registration, getState)
|
||||||
.then((pushSubscription) => dispatch(sendSubscriptionToBackend(pushSubscription, me)));
|
.then((pushSubscription) => dispatch(sendSubscriptionToBackend(pushSubscription, me)));
|
||||||
})
|
})
|
||||||
.then((subscription) => {
|
.then((subscription) => {
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { useQuery } from '@tanstack/react-query';
|
|
||||||
import { instanceSchema } from 'pl-api';
|
|
||||||
import * as v from 'valibot';
|
|
||||||
|
|
||||||
import { useClient } from 'pl-fe/hooks/use-client';
|
|
||||||
import { initialState } from 'pl-fe/initial-state';
|
|
||||||
|
|
||||||
const placeholderData = v.parse(instanceSchema, {});
|
|
||||||
const initialData = initialState['/api/v1/instance'] ? v.parse(instanceSchema, initialState['/api/v1/instance']) : undefined;
|
|
||||||
|
|
||||||
const useInstance = () => {
|
|
||||||
const client = useClient();
|
|
||||||
|
|
||||||
const query = useQuery({
|
|
||||||
queryKey: ['instance', 'instanceInformation', client.baseURL],
|
|
||||||
queryFn: client.instance.getInstance,
|
|
||||||
initialData: client.baseURL === '' ? initialData : undefined,
|
|
||||||
});
|
|
||||||
|
|
||||||
return { ...query, data: query.data || placeholderData };
|
|
||||||
};
|
|
||||||
|
|
||||||
export { useInstance };
|
|
|
@ -1,15 +1,15 @@
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import { useClient } from 'pl-fe/hooks/use-client';
|
import { useClient } from 'pl-fe/hooks/use-client';
|
||||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useLoggedIn } from 'pl-fe/hooks/use-logged-in';
|
import { useLoggedIn } from 'pl-fe/hooks/use-logged-in';
|
||||||
|
|
||||||
const useTranslationLanguages = () => {
|
const useTranslationLanguages = () => {
|
||||||
const client = useClient();
|
const client = useClient();
|
||||||
const { isLoggedIn } = useLoggedIn();
|
const { isLoggedIn } = useLoggedIn();
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const getTranslationLanguages = async () => {
|
const getTranslationLanguages = async () => {
|
||||||
const metadata = instance.pleroma.metadata;
|
const metadata = instance.pleroma.metadata;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { useEffect, useRef } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
import { useClient } from 'pl-fe/hooks/use-client';
|
import { useClient } from 'pl-fe/hooks/use-client';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { getAccessToken } from 'pl-fe/utils/auth';
|
import { getAccessToken } from 'pl-fe/utils/auth';
|
||||||
|
|
||||||
import type { StreamingEvent } from 'pl-api';
|
import type { StreamingEvent } from 'pl-api';
|
||||||
|
@ -12,7 +12,7 @@ const useTimelineStream = (stream: string, params: { list?: string; tag?: string
|
||||||
|
|
||||||
const client = useClient();
|
const client = useClient();
|
||||||
|
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const socket = useRef<({
|
const socket = useRef<({
|
||||||
listen: (listener: any, stream?: string) => number;
|
listen: (listener: any, stream?: string) => number;
|
||||||
unlisten: (listener: any) => void;
|
unlisten: (listener: any) => void;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import IconButton from 'pl-fe/components/icon-button';
|
import IconButton from 'pl-fe/components/icon-button';
|
||||||
import { DatePicker } from 'pl-fe/features/ui/util/async-components';
|
import { DatePicker } from 'pl-fe/features/ui/util/async-components';
|
||||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
birthdayPlaceholder: { id: 'edit_profile.fields.birthday_placeholder', defaultMessage: 'Your birthday' },
|
birthdayPlaceholder: { id: 'edit_profile.fields.birthday_placeholder', defaultMessage: 'Your birthday' },
|
||||||
|
@ -23,7 +23,7 @@ interface IBirthdayInput {
|
||||||
const BirthdayInput: React.FC<IBirthdayInput> = ({ value, onChange, required }) => {
|
const BirthdayInput: React.FC<IBirthdayInput> = ({ value, onChange, required }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const supportsBirthdays = features.birthdays;
|
const supportsBirthdays = features.birthdays;
|
||||||
const minAge = instance.pleroma.metadata.birthday_min_age;
|
const minAge = instance.pleroma.metadata.birthday_min_age;
|
||||||
|
|
|
@ -2,12 +2,12 @@ import clsx from 'clsx';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Banner from 'pl-fe/components/ui/banner';
|
import Banner from 'pl-fe/components/ui/banner';
|
||||||
import Button from 'pl-fe/components/ui/button';
|
import Button from 'pl-fe/components/ui/button';
|
||||||
import HStack from 'pl-fe/components/ui/hstack';
|
import HStack from 'pl-fe/components/ui/hstack';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
import Text from 'pl-fe/components/ui/text';
|
import Text from 'pl-fe/components/ui/text';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { usePlFeConfig } from 'pl-fe/hooks/use-pl-fe-config';
|
import { usePlFeConfig } from 'pl-fe/hooks/use-pl-fe-config';
|
||||||
|
|
||||||
const acceptedGdpr = !!localStorage.getItem('plfe:gdpr');
|
const acceptedGdpr = !!localStorage.getItem('plfe:gdpr');
|
||||||
|
@ -18,7 +18,7 @@ const GdprBanner: React.FC = () => {
|
||||||
const [shown, setShown] = useState<boolean>(acceptedGdpr);
|
const [shown, setShown] = useState<boolean>(acceptedGdpr);
|
||||||
const [slideout, setSlideout] = useState(false);
|
const [slideout, setSlideout] = useState(false);
|
||||||
|
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const { gdprUrl } = usePlFeConfig();
|
const { gdprUrl } = usePlFeConfig();
|
||||||
|
|
||||||
const handleAccept = () => {
|
const handleAccept = () => {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Helmet as ReactHelmet } from 'react-helmet-async';
|
import { Helmet as ReactHelmet } from 'react-helmet-async';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import { useStatContext } from 'pl-fe/contexts/stat-context';
|
import { useStatContext } from 'pl-fe/contexts/stat-context';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useSettings } from 'pl-fe/hooks/use-settings';
|
import { useSettings } from 'pl-fe/hooks/use-settings';
|
||||||
import { RootState } from 'pl-fe/store';
|
import { RootState } from 'pl-fe/store';
|
||||||
import FaviconService from 'pl-fe/utils/favicon-service';
|
import FaviconService from 'pl-fe/utils/favicon-service';
|
||||||
|
@ -22,7 +22,7 @@ interface IHelmet {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Helmet: React.FC<IHelmet> = ({ children }) => {
|
const Helmet: React.FC<IHelmet> = ({ children }) => {
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const { unreadChatsCount } = useStatContext();
|
const { unreadChatsCount } = useStatContext();
|
||||||
const unreadCount = useAppSelector((state) => getNotifTotals(state) + unreadChatsCount);
|
const unreadCount = useAppSelector((state) => getNotifTotals(state) + unreadChatsCount);
|
||||||
const { demetricator } = useSettings();
|
const { demetricator } = useSettings();
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { Link, NavLink } from 'react-router-dom';
|
||||||
|
|
||||||
import { fetchOwnAccounts, logOut, switchAccount } from 'pl-fe/actions/auth';
|
import { fetchOwnAccounts, logOut, switchAccount } from 'pl-fe/actions/auth';
|
||||||
import { useAccount } from 'pl-fe/api/hooks/accounts/use-account';
|
import { useAccount } from 'pl-fe/api/hooks/accounts/use-account';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import { useInteractionRequestsCount } from 'pl-fe/api/hooks/statuses/use-interaction-requests';
|
import { useInteractionRequestsCount } from 'pl-fe/api/hooks/statuses/use-interaction-requests';
|
||||||
import Account from 'pl-fe/components/account';
|
import Account from 'pl-fe/components/account';
|
||||||
import Divider from 'pl-fe/components/ui/divider';
|
import Divider from 'pl-fe/components/ui/divider';
|
||||||
|
@ -18,6 +17,7 @@ import ProfileStats from 'pl-fe/features/ui/components/profile-stats';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useRegistrationStatus } from 'pl-fe/hooks/use-registration-status';
|
import { useRegistrationStatus } from 'pl-fe/hooks/use-registration-status';
|
||||||
import { makeGetOtherAccounts } from 'pl-fe/selectors';
|
import { makeGetOtherAccounts } from 'pl-fe/selectors';
|
||||||
import { useSettingsStore } from 'pl-fe/stores/settings';
|
import { useSettingsStore } from 'pl-fe/stores/settings';
|
||||||
|
@ -106,7 +106,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
const touchEnd = useRef<number | null>(null);
|
const touchEnd = useRef<number | null>(null);
|
||||||
const { isOpen } = useRegistrationStatus();
|
const { isOpen } = useRegistrationStatus();
|
||||||
|
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const restrictUnauth = instance.pleroma.metadata.restrict_unauthenticated;
|
const restrictUnauth = instance.pleroma.metadata.restrict_unauthenticated;
|
||||||
|
|
||||||
const containerRef = React.useRef<HTMLDivElement>(null);
|
const containerRef = React.useRef<HTMLDivElement>(null);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import { useInteractionRequestsCount } from 'pl-fe/api/hooks/statuses/use-interaction-requests';
|
import { useInteractionRequestsCount } from 'pl-fe/api/hooks/statuses/use-interaction-requests';
|
||||||
import Icon from 'pl-fe/components/ui/icon';
|
import Icon from 'pl-fe/components/ui/icon';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
|
@ -10,6 +9,7 @@ import ComposeButton from 'pl-fe/features/ui/components/compose-button';
|
||||||
import ProfileDropdown from 'pl-fe/features/ui/components/profile-dropdown';
|
import ProfileDropdown from 'pl-fe/features/ui/components/profile-dropdown';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useLogo } from 'pl-fe/hooks/use-logo';
|
import { useLogo } from 'pl-fe/hooks/use-logo';
|
||||||
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
|
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
|
||||||
import { useRegistrationStatus } from 'pl-fe/hooks/use-registration-status';
|
import { useRegistrationStatus } from 'pl-fe/hooks/use-registration-status';
|
||||||
|
@ -40,7 +40,7 @@ const SidebarNavigation = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { unreadChatsCount } = useStatContext();
|
const { unreadChatsCount } = useStatContext();
|
||||||
|
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const { isDeveloper } = useSettings();
|
const { isDeveloper } = useSettings();
|
||||||
const { account } = useOwnAccount();
|
const { account } = useOwnAccount();
|
||||||
|
|
|
@ -17,7 +17,6 @@ import { useBlockGroupMember } from 'pl-fe/api/hooks/groups/use-block-group-memb
|
||||||
import { useDeleteGroupStatus } from 'pl-fe/api/hooks/groups/use-delete-group-status';
|
import { useDeleteGroupStatus } from 'pl-fe/api/hooks/groups/use-delete-group-status';
|
||||||
import { useGroup } from 'pl-fe/api/hooks/groups/use-group';
|
import { useGroup } from 'pl-fe/api/hooks/groups/use-group';
|
||||||
import { useGroupRelationship } from 'pl-fe/api/hooks/groups/use-group-relationship';
|
import { useGroupRelationship } from 'pl-fe/api/hooks/groups/use-group-relationship';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import { useTranslationLanguages } from 'pl-fe/api/hooks/instance/use-translation-languages';
|
import { useTranslationLanguages } from 'pl-fe/api/hooks/instance/use-translation-languages';
|
||||||
import DropdownMenu from 'pl-fe/components/dropdown-menu';
|
import DropdownMenu from 'pl-fe/components/dropdown-menu';
|
||||||
import StatusActionButton from 'pl-fe/components/status-action-button';
|
import StatusActionButton from 'pl-fe/components/status-action-button';
|
||||||
|
@ -28,6 +27,7 @@ import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
import { useCanInteract } from 'pl-fe/hooks/use-can-interact';
|
import { useCanInteract } from 'pl-fe/hooks/use-can-interact';
|
||||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
|
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
|
||||||
import { useSettings } from 'pl-fe/hooks/use-settings';
|
import { useSettings } from 'pl-fe/hooks/use-settings';
|
||||||
import { useChats } from 'pl-fe/queries/chats';
|
import { useChats } from 'pl-fe/queries/chats';
|
||||||
|
@ -595,7 +595,7 @@ const MenuButton: React.FC<IMenuButton> = ({
|
||||||
|
|
||||||
const { groupRelationship } = useGroupRelationship(status.group_id || undefined);
|
const { groupRelationship } = useGroupRelationship(status.group_id || undefined);
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const { autoTranslate, deleteModal, knownLanguages } = useSettings();
|
const { autoTranslate, deleteModal, knownLanguages } = useSettings();
|
||||||
|
|
||||||
const { translationLanguages } = useTranslationLanguages();
|
const { translationLanguages } = useTranslationLanguages();
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { FormattedMessage, useIntl } from 'react-intl';
|
import { FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import { useTranslationLanguages } from 'pl-fe/api/hooks/instance/use-translation-languages';
|
import { useTranslationLanguages } from 'pl-fe/api/hooks/instance/use-translation-languages';
|
||||||
import { useStatusTranslation } from 'pl-fe/api/hooks/statuses/use-status-translation';
|
import { useStatusTranslation } from 'pl-fe/api/hooks/statuses/use-status-translation';
|
||||||
import HStack from 'pl-fe/components/ui/hstack';
|
import HStack from 'pl-fe/components/ui/hstack';
|
||||||
|
@ -10,6 +9,7 @@ import Stack from 'pl-fe/components/ui/stack';
|
||||||
import Text from 'pl-fe/components/ui/text';
|
import Text from 'pl-fe/components/ui/text';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useSettings } from 'pl-fe/hooks/use-settings';
|
import { useSettings } from 'pl-fe/hooks/use-settings';
|
||||||
import { useStatusMetaStore } from 'pl-fe/stores/status-meta';
|
import { useStatusMetaStore } from 'pl-fe/stores/status-meta';
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ interface ITranslateButton {
|
||||||
const TranslateButton: React.FC<ITranslateButton> = ({ status }) => {
|
const TranslateButton: React.FC<ITranslateButton> = ({ status }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const settings = useSettings();
|
const settings = useSettings();
|
||||||
const autoTranslate = settings.autoTranslate;
|
const autoTranslate = settings.autoTranslate;
|
||||||
const knownLanguages = autoTranslate ? [...settings.knownLanguages, intl.locale] : [intl.locale];
|
const knownLanguages = autoTranslate ? [...settings.knownLanguages, intl.locale] : [intl.locale];
|
||||||
|
|
|
@ -3,9 +3,9 @@ import React from 'react';
|
||||||
import { useIntl, defineMessages, FormattedMessage } from 'react-intl';
|
import { useIntl, defineMessages, FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { updateConfig } from 'pl-fe/actions/admin';
|
import { updateConfig } from 'pl-fe/actions/admin';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import { RadioGroup, RadioItem } from 'pl-fe/components/radio';
|
import { RadioGroup, RadioItem } from 'pl-fe/components/radio';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import toast from 'pl-fe/toast';
|
import toast from 'pl-fe/toast';
|
||||||
|
|
||||||
type RegistrationMode = 'open' | 'approval' | 'closed';
|
type RegistrationMode = 'open' | 'approval' | 'closed';
|
||||||
|
@ -37,7 +37,7 @@ const modeFromInstance = ({ registrations }: Instance): RegistrationMode => {
|
||||||
const RegistrationModePicker: React.FC = () => {
|
const RegistrationModePicker: React.FC = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const mode = modeFromInstance(instance);
|
const mode = modeFromInstance(instance);
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import List, { ListItem } from 'pl-fe/components/list';
|
import List, { ListItem } from 'pl-fe/components/list';
|
||||||
import { CardTitle } from 'pl-fe/components/ui/card';
|
import { CardTitle } from 'pl-fe/components/ui/card';
|
||||||
import Icon from 'pl-fe/components/ui/icon';
|
import Icon from 'pl-fe/components/ui/icon';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
|
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
|
||||||
import sourceCode from 'pl-fe/utils/code';
|
import sourceCode from 'pl-fe/utils/code';
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ import { DashCounter, DashCounters } from '../components/dashcounter';
|
||||||
import RegistrationModePicker from '../components/registration-mode-picker';
|
import RegistrationModePicker from '../components/registration-mode-picker';
|
||||||
|
|
||||||
const Dashboard: React.FC = () => {
|
const Dashboard: React.FC = () => {
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const { account } = useOwnAccount();
|
const { account } = useOwnAccount();
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Card from 'pl-fe/components/ui/card';
|
import Card from 'pl-fe/components/ui/card';
|
||||||
import HStack from 'pl-fe/components/ui/hstack';
|
import HStack from 'pl-fe/components/ui/hstack';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
import Text from 'pl-fe/components/ui/text';
|
import Text from 'pl-fe/components/ui/text';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
import ConsumerButton from './consumer-button';
|
import ConsumerButton from './consumer-button';
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ interface IConsumersList {
|
||||||
|
|
||||||
/** Displays OAuth consumers to log in with. */
|
/** Displays OAuth consumers to log in with. */
|
||||||
const ConsumersList: React.FC<IConsumersList> = () => {
|
const ConsumersList: React.FC<IConsumersList> = () => {
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const providers = instance.pleroma.oauth_consumer_strategies;
|
const providers = instance.pleroma.oauth_consumer_strategies;
|
||||||
|
|
||||||
if (providers.length > 0) {
|
if (providers.length > 0) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { FormattedMessage } from 'react-intl';
|
||||||
import { Redirect } from 'react-router-dom';
|
import { Redirect } from 'react-router-dom';
|
||||||
|
|
||||||
import { logIn, verifyCredentials, switchAccount } from 'pl-fe/actions/auth';
|
import { logIn, verifyCredentials, switchAccount } from 'pl-fe/actions/auth';
|
||||||
|
import { fetchInstance } from 'pl-fe/actions/instance';
|
||||||
import { BigCard } from 'pl-fe/components/big-card';
|
import { BigCard } from 'pl-fe/components/big-card';
|
||||||
import Button from 'pl-fe/components/ui/button';
|
import Button from 'pl-fe/components/ui/button';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
|
@ -42,6 +43,11 @@ const LoginPage = () => {
|
||||||
const { username, password } = getFormData(event.target as HTMLFormElement);
|
const { username, password } = getFormData(event.target as HTMLFormElement);
|
||||||
dispatch(logIn(username, password))
|
dispatch(logIn(username, password))
|
||||||
.then(({ access_token }) => dispatch(verifyCredentials(access_token)))
|
.then(({ access_token }) => dispatch(verifyCredentials(access_token)))
|
||||||
|
// Refetch the instance for authenticated fetch
|
||||||
|
.then(async (account) => {
|
||||||
|
await dispatch(fetchInstance());
|
||||||
|
return account;
|
||||||
|
})
|
||||||
.then((account: { id: string }) => {
|
.then((account: { id: string }) => {
|
||||||
closeModal();
|
closeModal();
|
||||||
if (typeof me === 'string') {
|
if (typeof me === 'string') {
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { Link, useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
import { accountLookup } from 'pl-fe/actions/accounts';
|
import { accountLookup } from 'pl-fe/actions/accounts';
|
||||||
import { register, verifyCredentials } from 'pl-fe/actions/auth';
|
import { register, verifyCredentials } from 'pl-fe/actions/auth';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import BirthdayInput from 'pl-fe/components/birthday-input';
|
import BirthdayInput from 'pl-fe/components/birthday-input';
|
||||||
import Button from 'pl-fe/components/ui/button';
|
import Button from 'pl-fe/components/ui/button';
|
||||||
import Checkbox from 'pl-fe/components/ui/checkbox';
|
import Checkbox from 'pl-fe/components/ui/checkbox';
|
||||||
|
@ -18,6 +17,7 @@ import Textarea from 'pl-fe/components/ui/textarea';
|
||||||
import CaptchaField from 'pl-fe/features/auth-login/components/captcha';
|
import CaptchaField from 'pl-fe/features/auth-login/components/captcha';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useSettings } from 'pl-fe/hooks/use-settings';
|
import { useSettings } from 'pl-fe/hooks/use-settings';
|
||||||
import { useModalsStore } from 'pl-fe/stores/modals';
|
import { useModalsStore } from 'pl-fe/stores/modals';
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ const RegistrationForm: React.FC<IRegistrationForm> = ({ inviteToken }) => {
|
||||||
|
|
||||||
const { locale } = useSettings();
|
const { locale } = useSettings();
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const { openModal } = useModalsStore();
|
const { openModal } = useModalsStore();
|
||||||
|
|
||||||
const needsConfirmation = instance.pleroma.metadata.account_activation_required;
|
const needsConfirmation = instance.pleroma.metadata.account_activation_required;
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import { BigCard } from 'pl-fe/components/big-card';
|
import { BigCard } from 'pl-fe/components/big-card';
|
||||||
import Text from 'pl-fe/components/ui/text';
|
import Text from 'pl-fe/components/ui/text';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useRegistrationStatus } from 'pl-fe/hooks/use-registration-status';
|
import { useRegistrationStatus } from 'pl-fe/hooks/use-registration-status';
|
||||||
|
|
||||||
import RegistrationForm from './registration-form';
|
import RegistrationForm from './registration-form';
|
||||||
|
|
||||||
const RegistrationPage: React.FC = () => {
|
const RegistrationPage: React.FC = () => {
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const { isOpen } = useRegistrationStatus();
|
const { isOpen } = useRegistrationStatus();
|
||||||
|
|
||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { defineMessages, IntlShape, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { unblockAccount } from 'pl-fe/actions/accounts';
|
import { unblockAccount } from 'pl-fe/actions/accounts';
|
||||||
import { useRelationship } from 'pl-fe/api/hooks/accounts/use-relationship';
|
import { useRelationship } from 'pl-fe/api/hooks/accounts/use-relationship';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Button from 'pl-fe/components/ui/button';
|
import Button from 'pl-fe/components/ui/button';
|
||||||
import Combobox, { ComboboxInput, ComboboxList, ComboboxOption, ComboboxPopover } from 'pl-fe/components/ui/combobox';
|
import Combobox, { ComboboxInput, ComboboxList, ComboboxOption, ComboboxPopover } from 'pl-fe/components/ui/combobox';
|
||||||
import HStack from 'pl-fe/components/ui/hstack';
|
import HStack from 'pl-fe/components/ui/hstack';
|
||||||
|
@ -14,6 +13,7 @@ import { useChatContext } from 'pl-fe/contexts/chat-context';
|
||||||
import UploadButton from 'pl-fe/features/compose/components/upload-button';
|
import UploadButton from 'pl-fe/features/compose/components/upload-button';
|
||||||
import emojiSearch from 'pl-fe/features/emoji/search';
|
import emojiSearch from 'pl-fe/features/emoji/search';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useModalsStore } from 'pl-fe/stores/modals';
|
import { useModalsStore } from 'pl-fe/stores/modals';
|
||||||
import { textAtCursorMatchesToken } from 'pl-fe/utils/suggestions';
|
import { textAtCursorMatchesToken } from 'pl-fe/utils/suggestions';
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ const ChatComposer = React.forwardRef<HTMLTextAreaElement | null, IChatComposer>
|
||||||
const isBlocked = relationship?.blocked_by && false;
|
const isBlocked = relationship?.blocked_by && false;
|
||||||
const isBlocking = relationship?.blocking && false;
|
const isBlocking = relationship?.blocking && false;
|
||||||
|
|
||||||
const maxCharacterCount = useInstance().data.configuration.chats.max_characters;
|
const maxCharacterCount = useInstance().configuration.chats.max_characters;
|
||||||
|
|
||||||
const [suggestions, setSuggestions] = useState<Suggestion>(initialSuggestionState);
|
const [suggestions, setSuggestions] = useState<Suggestion>(initialSuggestionState);
|
||||||
const isSuggestionsAvailable = suggestions.list.length > 0;
|
const isSuggestionsAvailable = suggestions.list.length > 0;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import React, { useRef } from 'react';
|
import React, { useRef } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Icon from 'pl-fe/components/icon';
|
import Icon from 'pl-fe/components/icon';
|
||||||
import HStack from 'pl-fe/components/ui/hstack';
|
import HStack from 'pl-fe/components/ui/hstack';
|
||||||
import Text from 'pl-fe/components/ui/text';
|
import Text from 'pl-fe/components/ui/text';
|
||||||
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
|
|
||||||
interface IUploadButton {
|
interface IUploadButton {
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
@ -14,7 +14,7 @@ interface IUploadButton {
|
||||||
const UploadButton: React.FC<IUploadButton> = ({ disabled, onSelectFile }) => {
|
const UploadButton: React.FC<IUploadButton> = ({ disabled, onSelectFile }) => {
|
||||||
const fileElement = useRef<HTMLInputElement>(null);
|
const fileElement = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const attachmentTypes = useInstance().data.configuration.media_attachments.supported_mime_types
|
const attachmentTypes = useAppSelector(state => state.instance.configuration.media_attachments.supported_mime_types)
|
||||||
?.filter((type) => type.startsWith('image/'));
|
?.filter((type) => type.startsWith('image/'));
|
||||||
|
|
||||||
let accept = attachmentTypes?.join(',');
|
let accept = attachmentTypes?.join(',');
|
||||||
|
|
|
@ -12,7 +12,6 @@ import {
|
||||||
selectComposeSuggestion,
|
selectComposeSuggestion,
|
||||||
uploadCompose,
|
uploadCompose,
|
||||||
} from 'pl-fe/actions/compose';
|
} from 'pl-fe/actions/compose';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Button from 'pl-fe/components/ui/button';
|
import Button from 'pl-fe/components/ui/button';
|
||||||
import HStack from 'pl-fe/components/ui/hstack';
|
import HStack from 'pl-fe/components/ui/hstack';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
|
@ -22,6 +21,7 @@ import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useCompose } from 'pl-fe/hooks/use-compose';
|
import { useCompose } from 'pl-fe/hooks/use-compose';
|
||||||
import { useDraggedFiles } from 'pl-fe/hooks/use-dragged-files';
|
import { useDraggedFiles } from 'pl-fe/hooks/use-dragged-files';
|
||||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
import QuotedStatusContainer from '../containers/quoted-status-container';
|
import QuotedStatusContainer from '../containers/quoted-status-container';
|
||||||
import ReplyIndicatorContainer from '../containers/reply-indicator-container';
|
import ReplyIndicatorContainer from '../containers/reply-indicator-container';
|
||||||
|
@ -75,7 +75,7 @@ const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickab
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { configuration } = useInstance().data;
|
const { configuration } = useInstance();
|
||||||
|
|
||||||
const compose = useCompose(id);
|
const compose = useCompose(id);
|
||||||
const maxTootChars = configuration.statuses.max_characters;
|
const maxTootChars = configuration.statuses.max_characters;
|
||||||
|
|
|
@ -2,11 +2,11 @@ import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { changeComposeContentType } from 'pl-fe/actions/compose';
|
import { changeComposeContentType } from 'pl-fe/actions/compose';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import DropdownMenu from 'pl-fe/components/dropdown-menu';
|
import DropdownMenu from 'pl-fe/components/dropdown-menu';
|
||||||
import Button from 'pl-fe/components/ui/button';
|
import Button from 'pl-fe/components/ui/button';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useCompose } from 'pl-fe/hooks/use-compose';
|
import { useCompose } from 'pl-fe/hooks/use-compose';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
content_type_plaintext: { id: 'preferences.options.content_type_plaintext', defaultMessage: 'Plain text' },
|
content_type_plaintext: { id: 'preferences.options.content_type_plaintext', defaultMessage: 'Plain text' },
|
||||||
|
@ -24,7 +24,7 @@ interface IContentTypeButton {
|
||||||
const ContentTypeButton: React.FC<IContentTypeButton> = ({ composeId }) => {
|
const ContentTypeButton: React.FC<IContentTypeButton> = ({ composeId }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const contentType = useCompose(composeId).content_type;
|
const contentType = useCompose(composeId).content_type;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import React from 'react';
|
||||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { addPollOption, changePollOption, changePollSettings, clearComposeSuggestions, fetchComposeSuggestions, removePoll, removePollOption, selectComposeSuggestion } from 'pl-fe/actions/compose';
|
import { addPollOption, changePollOption, changePollSettings, clearComposeSuggestions, fetchComposeSuggestions, removePoll, removePollOption, selectComposeSuggestion } from 'pl-fe/actions/compose';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import AutosuggestInput from 'pl-fe/components/autosuggest-input';
|
import AutosuggestInput from 'pl-fe/components/autosuggest-input';
|
||||||
import Button from 'pl-fe/components/ui/button';
|
import Button from 'pl-fe/components/ui/button';
|
||||||
import Divider from 'pl-fe/components/ui/divider';
|
import Divider from 'pl-fe/components/ui/divider';
|
||||||
|
@ -12,6 +11,7 @@ import Text from 'pl-fe/components/ui/text';
|
||||||
import Toggle from 'pl-fe/components/ui/toggle';
|
import Toggle from 'pl-fe/components/ui/toggle';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useCompose } from 'pl-fe/hooks/use-compose';
|
import { useCompose } from 'pl-fe/hooks/use-compose';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
import DurationSelector from './duration-selector';
|
import DurationSelector from './duration-selector';
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ interface IPollForm {
|
||||||
const PollForm: React.FC<IPollForm> = ({ composeId }) => {
|
const PollForm: React.FC<IPollForm> = ({ composeId }) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { configuration } = useInstance().data;
|
const { configuration } = useInstance();
|
||||||
|
|
||||||
const { poll, language, modified_language: modifiedLanguage } = useCompose(composeId);
|
const { poll, language, modified_language: modifiedLanguage } = useCompose(composeId);
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import React, { useRef } from 'react';
|
import React, { useRef } from 'react';
|
||||||
import { defineMessages, IntlShape, useIntl } from 'react-intl';
|
import { defineMessages, IntlShape, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import IconButton from 'pl-fe/components/ui/icon-button';
|
import IconButton from 'pl-fe/components/ui/icon-button';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
upload: { id: 'upload_button.label', defaultMessage: 'Add media attachment' },
|
upload: { id: 'upload_button.label', defaultMessage: 'Add media attachment' },
|
||||||
|
@ -32,7 +32,7 @@ const UploadButton: React.FC<IUploadButton> = ({
|
||||||
icon,
|
icon,
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { configuration } = useInstance().data;
|
const { configuration } = useInstance();
|
||||||
|
|
||||||
const fileElement = useRef<HTMLInputElement>(null);
|
const fileElement = useRef<HTMLInputElement>(null);
|
||||||
const attachmentTypes = configuration.media_attachments.supported_mime_types;
|
const attachmentTypes = configuration.media_attachments.supported_mime_types;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
|
|
||||||
import { undoUploadCompose, changeUploadCompose } from 'pl-fe/actions/compose';
|
import { undoUploadCompose, changeUploadCompose } from 'pl-fe/actions/compose';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Upload from 'pl-fe/components/upload';
|
import Upload from 'pl-fe/components/upload';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useCompose } from 'pl-fe/hooks/use-compose';
|
import { useCompose } from 'pl-fe/hooks/use-compose';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
interface IUploadCompose {
|
interface IUploadCompose {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -17,7 +17,7 @@ interface IUploadCompose {
|
||||||
|
|
||||||
const UploadCompose: React.FC<IUploadCompose> = ({ composeId, id, onSubmit, onDragStart, onDragEnter, onDragEnd }) => {
|
const UploadCompose: React.FC<IUploadCompose> = ({ composeId, id, onSubmit, onDragStart, onDragEnter, onDragEnd }) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { pleroma: { metadata: { description_limit: descriptionLimit } } } = useInstance().data;
|
const { pleroma: { metadata: { description_limit: descriptionLimit } } } = useInstance();
|
||||||
|
|
||||||
const media = useCompose(composeId).media_attachments.find(item => item.id === id)!;
|
const media = useCompose(composeId).media_attachments.find(item => item.id === id)!;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { ListItemNode, ListNode } from '@lexical/list';
|
||||||
import { HorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode';
|
import { HorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode';
|
||||||
import { HeadingNode, QuoteNode } from '@lexical/rich-text';
|
import { HeadingNode, QuoteNode } from '@lexical/rich-text';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
import { EmojiNode } from './emoji-node';
|
import { EmojiNode } from './emoji-node';
|
||||||
import { ImageNode } from './image-node';
|
import { ImageNode } from './image-node';
|
||||||
|
@ -20,7 +20,7 @@ import { MentionNode } from './mention-node';
|
||||||
import type { Klass, LexicalNode } from 'lexical';
|
import type { Klass, LexicalNode } from 'lexical';
|
||||||
|
|
||||||
const useNodes = (isWysiwyg?: boolean) => {
|
const useNodes = (isWysiwyg?: boolean) => {
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const nodes: Array<Klass<LexicalNode>> = [
|
const nodes: Array<Klass<LexicalNode>> = [
|
||||||
AutoLinkNode,
|
AutoLinkNode,
|
||||||
|
|
|
@ -23,8 +23,8 @@ import { createPortal } from 'react-dom';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { uploadFile } from 'pl-fe/actions/compose';
|
import { uploadFile } from 'pl-fe/actions/compose';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
import { $createImageNode } from '../nodes/image-node';
|
import { $createImageNode } from '../nodes/image-node';
|
||||||
import { setFloatingElemPosition } from '../utils/set-floating-elem-position';
|
import { setFloatingElemPosition } from '../utils/set-floating-elem-position';
|
||||||
|
@ -42,7 +42,7 @@ interface IUploadButton {
|
||||||
|
|
||||||
const UploadButton: React.FC<IUploadButton> = ({ onSelectFile }) => {
|
const UploadButton: React.FC<IUploadButton> = ({ onSelectFile }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { configuration } = useInstance().data;
|
const { configuration } = useInstance();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const [disabled, setDisabled] = useState(false);
|
const [disabled, setDisabled] = useState(false);
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ const BlockTypeFloatingToolbar = ({
|
||||||
}): JSX.Element => {
|
}): JSX.Element => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const popupCharStylesEditorRef = useRef<HTMLDivElement | null>(null);
|
const popupCharStylesEditorRef = useRef<HTMLDivElement | null>(null);
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const allowInlineImages = instance.pleroma.metadata.markup.allow_inline_images;
|
const allowInlineImages = instance.pleroma.metadata.markup.allow_inline_images;
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,8 @@ import * as React from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Icon from 'pl-fe/components/ui/icon';
|
import Icon from 'pl-fe/components/ui/icon';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
import { getDOMRangeRect } from '../utils/get-dom-range-rect';
|
import { getDOMRangeRect } from '../utils/get-dom-range-rect';
|
||||||
import { getSelectedNode } from '../utils/get-selected-node';
|
import { getSelectedNode } from '../utils/get-selected-node';
|
||||||
|
@ -109,7 +109,7 @@ const BlockTypeDropdown = ({ editor, anchorElem, blockType, icon }: {
|
||||||
blockType: keyof typeof blockTypeToBlockName;
|
blockType: keyof typeof blockTypeToBlockName;
|
||||||
icon: string;
|
icon: string;
|
||||||
}) => {
|
}) => {
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const [showDropDown, setShowDropDown] = useState(false);
|
const [showDropDown, setShowDropDown] = useState(false);
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,9 @@ import React from 'react';
|
||||||
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Text from 'pl-fe/components/ui/text';
|
import Text from 'pl-fe/components/ui/text';
|
||||||
import Widget from 'pl-fe/components/ui/widget';
|
import Widget from 'pl-fe/components/ui/widget';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { usePlFeConfig } from 'pl-fe/hooks/use-pl-fe-config';
|
import { usePlFeConfig } from 'pl-fe/hooks/use-pl-fe-config';
|
||||||
|
|
||||||
import SiteWallet from './site-wallet';
|
import SiteWallet from './site-wallet';
|
||||||
|
@ -20,7 +20,7 @@ interface ICryptoDonatePanel {
|
||||||
const CryptoDonatePanel: React.FC<ICryptoDonatePanel> = ({ limit = 3 }): JSX.Element | null => {
|
const CryptoDonatePanel: React.FC<ICryptoDonatePanel> = ({ limit = 3 }): JSX.Element | null => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const addresses = usePlFeConfig().cryptoAddresses;
|
const addresses = usePlFeConfig().cryptoAddresses;
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Accordion from 'pl-fe/components/ui/accordion';
|
import Accordion from 'pl-fe/components/ui/accordion';
|
||||||
import Column from 'pl-fe/components/ui/column';
|
import Column from 'pl-fe/components/ui/column';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
import SiteWallet from './components/site-wallet';
|
import SiteWallet from './components/site-wallet';
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ const messages = defineMessages({
|
||||||
|
|
||||||
const CryptoDonate: React.FC = (): JSX.Element => {
|
const CryptoDonate: React.FC = (): JSX.Element => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const [explanationBoxExpanded, toggleExplanationBox] = useState(true);
|
const [explanationBoxExpanded, toggleExplanationBox] = useState(true);
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,13 @@ import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||||
import { useSearchParams } from 'react-router-dom-v5-compat';
|
import { useSearchParams } from 'react-router-dom-v5-compat';
|
||||||
|
|
||||||
import { useDirectory } from 'pl-fe/api/hooks/account-lists/use-directory';
|
import { useDirectory } from 'pl-fe/api/hooks/account-lists/use-directory';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import LoadMore from 'pl-fe/components/load-more';
|
import LoadMore from 'pl-fe/components/load-more';
|
||||||
import { RadioGroup, RadioItem } from 'pl-fe/components/radio';
|
import { RadioGroup, RadioItem } from 'pl-fe/components/radio';
|
||||||
import { CardTitle } from 'pl-fe/components/ui/card';
|
import { CardTitle } from 'pl-fe/components/ui/card';
|
||||||
import Column from 'pl-fe/components/ui/column';
|
import Column from 'pl-fe/components/ui/column';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
import AccountCard from './components/account-card';
|
import AccountCard from './components/account-card';
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ const messages = defineMessages({
|
||||||
const Directory = () => {
|
const Directory = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const [params, setParams] = useSearchParams();
|
const [params, setParams] = useSearchParams();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
|
|
||||||
const order = (params.get('order') || 'active') as 'active' | 'new';
|
const order = (params.get('order') || 'active') as 'active' | 'new';
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { updateNotificationSettings } from 'pl-fe/actions/accounts';
|
import { updateNotificationSettings } from 'pl-fe/actions/accounts';
|
||||||
import { patchMe } from 'pl-fe/actions/me';
|
import { patchMe } from 'pl-fe/actions/me';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import BirthdayInput from 'pl-fe/components/birthday-input';
|
import BirthdayInput from 'pl-fe/components/birthday-input';
|
||||||
import List, { ListItem } from 'pl-fe/components/list';
|
import List, { ListItem } from 'pl-fe/components/list';
|
||||||
import Button from 'pl-fe/components/ui/button';
|
import Button from 'pl-fe/components/ui/button';
|
||||||
|
@ -22,6 +21,7 @@ import { useImageField } from 'pl-fe/hooks/forms/use-image-field';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
|
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
|
||||||
import toast from 'pl-fe/toast';
|
import toast from 'pl-fe/toast';
|
||||||
import { isDefaultAvatar, isDefaultHeader } from 'pl-fe/utils/accounts';
|
import { isDefaultAvatar, isDefaultHeader } from 'pl-fe/utils/accounts';
|
||||||
|
@ -173,7 +173,7 @@ const ProfileField: StreamfieldComponent<AccountCredentialsField> = ({ index, va
|
||||||
const EditProfile: React.FC = () => {
|
const EditProfile: React.FC = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const { account } = useOwnAccount();
|
const { account } = useOwnAccount();
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
|
@ -181,7 +181,8 @@ const EditProfile: React.FC = () => {
|
||||||
? instance.configuration.accounts.max_profile_fields
|
? instance.configuration.accounts.max_profile_fields
|
||||||
: instance.pleroma.metadata.fields_limits.max_fields;
|
: instance.pleroma.metadata.fields_limits.max_fields;
|
||||||
|
|
||||||
const attachmentTypes = useInstance().data.configuration.media_attachments.supported_mime_types
|
const attachmentTypes = useAppSelector(
|
||||||
|
state => state.instance.configuration.media_attachments.supported_mime_types)
|
||||||
?.filter(type => type.startsWith('image/'))
|
?.filter(type => type.startsWith('image/'))
|
||||||
.join(',');
|
.join(',');
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Icon from 'pl-fe/components/icon';
|
import Icon from 'pl-fe/components/icon';
|
||||||
import HStack from 'pl-fe/components/ui/hstack';
|
import HStack from 'pl-fe/components/ui/hstack';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
import Text from 'pl-fe/components/ui/text';
|
import Text from 'pl-fe/components/ui/text';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
import type { RemoteInstance } from 'pl-fe/selectors';
|
import type { RemoteInstance } from 'pl-fe/selectors';
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ interface IInstanceRestrictions {
|
||||||
}
|
}
|
||||||
|
|
||||||
const InstanceRestrictions: React.FC<IInstanceRestrictions> = ({ remoteInstance }) => {
|
const InstanceRestrictions: React.FC<IInstanceRestrictions> = ({ remoteInstance }) => {
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const renderRestrictions = () => {
|
const renderRestrictions = () => {
|
||||||
const items = [];
|
const items = [];
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Icon from 'pl-fe/components/icon';
|
import Icon from 'pl-fe/components/icon';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
import { makeGetRemoteInstance } from 'pl-fe/selectors';
|
import { makeGetRemoteInstance } from 'pl-fe/selectors';
|
||||||
|
@ -15,8 +14,7 @@ interface IRestrictedInstance {
|
||||||
}
|
}
|
||||||
|
|
||||||
const RestrictedInstance: React.FC<IRestrictedInstance> = ({ host }) => {
|
const RestrictedInstance: React.FC<IRestrictedInstance> = ({ host }) => {
|
||||||
const { data: instance } = useInstance();
|
const remoteInstance: any = useAppSelector((state) => getRemoteInstance(state, host));
|
||||||
const remoteInstance: any = useAppSelector((state) => getRemoteInstance(state, host, instance));
|
|
||||||
|
|
||||||
const [expanded, setExpanded] = useState(false);
|
const [expanded, setExpanded] = useState(false);
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import React, { useState, useCallback } from 'react';
|
import React, { useState, useCallback } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import ScrollableList from 'pl-fe/components/scrollable-list';
|
import ScrollableList from 'pl-fe/components/scrollable-list';
|
||||||
import Accordion from 'pl-fe/components/ui/accordion';
|
import Accordion from 'pl-fe/components/ui/accordion';
|
||||||
import Column from 'pl-fe/components/ui/column';
|
import Column from 'pl-fe/components/ui/column';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { makeGetHosts } from 'pl-fe/selectors';
|
import { makeGetHosts } from 'pl-fe/selectors';
|
||||||
import { federationRestrictionsDisclosed } from 'pl-fe/utils/state';
|
import { federationRestrictionsDisclosed } from 'pl-fe/utils/state';
|
||||||
|
|
||||||
|
@ -21,12 +21,12 @@ const messages = defineMessages({
|
||||||
|
|
||||||
const FederationRestrictions = () => {
|
const FederationRestrictions = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const getHosts = useCallback(makeGetHosts(), []);
|
const getHosts = useCallback(makeGetHosts(), []);
|
||||||
|
|
||||||
const hosts = useAppSelector((state) => getHosts(state, instance));
|
const hosts = useAppSelector((state) => getHosts(state));
|
||||||
const disclosed = federationRestrictionsDisclosed(instance);
|
const disclosed = useAppSelector((state) => federationRestrictionsDisclosed(state));
|
||||||
|
|
||||||
const [explanationBoxExpanded, setExplanationBoxExpanded] = useState(true);
|
const [explanationBoxExpanded, setExplanationBoxExpanded] = useState(true);
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { useGroup } from 'pl-fe/api/hooks/groups/use-group';
|
import { useGroup } from 'pl-fe/api/hooks/groups/use-group';
|
||||||
import { useUpdateGroup } from 'pl-fe/api/hooks/groups/use-update-group';
|
import { useUpdateGroup } from 'pl-fe/api/hooks/groups/use-update-group';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Button from 'pl-fe/components/ui/button';
|
import Button from 'pl-fe/components/ui/button';
|
||||||
import Column from 'pl-fe/components/ui/column';
|
import Column from 'pl-fe/components/ui/column';
|
||||||
import Form from 'pl-fe/components/ui/form';
|
import Form from 'pl-fe/components/ui/form';
|
||||||
|
@ -15,6 +14,8 @@ import Spinner from 'pl-fe/components/ui/spinner';
|
||||||
import Textarea from 'pl-fe/components/ui/textarea';
|
import Textarea from 'pl-fe/components/ui/textarea';
|
||||||
import { useImageField } from 'pl-fe/hooks/forms/use-image-field';
|
import { useImageField } from 'pl-fe/hooks/forms/use-image-field';
|
||||||
import { useTextField } from 'pl-fe/hooks/forms/use-text-field';
|
import { useTextField } from 'pl-fe/hooks/forms/use-text-field';
|
||||||
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import toast from 'pl-fe/toast';
|
import toast from 'pl-fe/toast';
|
||||||
import { isDefaultAvatar, isDefaultHeader } from 'pl-fe/utils/accounts';
|
import { isDefaultAvatar, isDefaultHeader } from 'pl-fe/utils/accounts';
|
||||||
import { unescapeHTML } from 'pl-fe/utils/html';
|
import { unescapeHTML } from 'pl-fe/utils/html';
|
||||||
|
@ -40,7 +41,7 @@ interface IEditGroup {
|
||||||
|
|
||||||
const EditGroup: React.FC<IEditGroup> = ({ params: { groupId } }) => {
|
const EditGroup: React.FC<IEditGroup> = ({ params: { groupId } }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const { group, isLoading } = useGroup(groupId);
|
const { group, isLoading } = useGroup(groupId);
|
||||||
const { updateGroup } = useUpdateGroup(groupId);
|
const { updateGroup } = useUpdateGroup(groupId);
|
||||||
|
@ -56,7 +57,7 @@ const EditGroup: React.FC<IEditGroup> = ({ params: { groupId } }) => {
|
||||||
const maxName = Number(instance.configuration.groups.max_characters_name);
|
const maxName = Number(instance.configuration.groups.max_characters_name);
|
||||||
const maxNote = Number(instance.configuration.groups.max_characters_description);
|
const maxNote = Number(instance.configuration.groups.max_characters_description);
|
||||||
|
|
||||||
const attachmentTypes = useInstance().data.configuration.media_attachments.supported_mime_types
|
const attachmentTypes = useAppSelector(state => state.instance.configuration.media_attachments.supported_mime_types)
|
||||||
?.filter((type) => type.startsWith('image/'))
|
?.filter((type) => type.startsWith('image/'))
|
||||||
.join(',');
|
.join(',');
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import { fetchHomeTimeline } from 'pl-fe/actions/timelines';
|
import { fetchHomeTimeline } from 'pl-fe/actions/timelines';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import PullToRefresh from 'pl-fe/components/pull-to-refresh';
|
import PullToRefresh from 'pl-fe/components/pull-to-refresh';
|
||||||
import Column from 'pl-fe/components/ui/column';
|
import Column from 'pl-fe/components/ui/column';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
|
@ -12,6 +11,7 @@ import Timeline from 'pl-fe/features/ui/components/timeline';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useIsMobile } from 'pl-fe/hooks/use-is-mobile';
|
import { useIsMobile } from 'pl-fe/hooks/use-is-mobile';
|
||||||
import { useTheme } from 'pl-fe/hooks/use-theme';
|
import { useTheme } from 'pl-fe/hooks/use-theme';
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ const HomeTimeline: React.FC = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const polling = useRef<NodeJS.Timeout | null>(null);
|
const polling = useRef<NodeJS.Timeout | null>(null);
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Markup from 'pl-fe/components/markup';
|
import Markup from 'pl-fe/components/markup';
|
||||||
import { ParsedContent } from 'pl-fe/components/parsed-content';
|
import { ParsedContent } from 'pl-fe/components/parsed-content';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { getTextDirection } from 'pl-fe/utils/rtl';
|
import { getTextDirection } from 'pl-fe/utils/rtl';
|
||||||
|
|
||||||
import { LogoText } from './logo-text';
|
import { LogoText } from './logo-text';
|
||||||
|
|
||||||
const SiteBanner: React.FC = () => {
|
const SiteBanner: React.FC = () => {
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack space={6}>
|
<Stack space={6}>
|
||||||
|
|
|
@ -2,11 +2,11 @@ import React, { useEffect } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { fetchPublicTimeline } from 'pl-fe/actions/timelines';
|
import { fetchPublicTimeline } from 'pl-fe/actions/timelines';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import { useCommunityStream } from 'pl-fe/api/hooks/streaming/use-community-stream';
|
import { useCommunityStream } from 'pl-fe/api/hooks/streaming/use-community-stream';
|
||||||
import PullToRefresh from 'pl-fe/components/pull-to-refresh';
|
import PullToRefresh from 'pl-fe/components/pull-to-refresh';
|
||||||
import Column from 'pl-fe/components/ui/column';
|
import Column from 'pl-fe/components/ui/column';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useIsMobile } from 'pl-fe/hooks/use-is-mobile';
|
import { useIsMobile } from 'pl-fe/hooks/use-is-mobile';
|
||||||
import { useTheme } from 'pl-fe/hooks/use-theme';
|
import { useTheme } from 'pl-fe/hooks/use-theme';
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ import { SiteBanner } from './components/site-banner';
|
||||||
|
|
||||||
const LandingTimeline = () => {
|
const LandingTimeline = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import { moveAccount } from 'pl-fe/actions/security';
|
import { moveAccount } from 'pl-fe/actions/security';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Button from 'pl-fe/components/ui/button';
|
import Button from 'pl-fe/components/ui/button';
|
||||||
import Column from 'pl-fe/components/ui/column';
|
import Column from 'pl-fe/components/ui/column';
|
||||||
import Form from 'pl-fe/components/ui/form';
|
import Form from 'pl-fe/components/ui/form';
|
||||||
|
@ -12,6 +11,7 @@ import FormGroup from 'pl-fe/components/ui/form-group';
|
||||||
import Input from 'pl-fe/components/ui/input';
|
import Input from 'pl-fe/components/ui/input';
|
||||||
import Text from 'pl-fe/components/ui/text';
|
import Text from 'pl-fe/components/ui/text';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import toast from 'pl-fe/toast';
|
import toast from 'pl-fe/toast';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
@ -28,7 +28,7 @@ const messages = defineMessages({
|
||||||
const Migration = () => {
|
const Migration = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const cooldownPeriod = instance.pleroma.metadata.migration_cooldown_period;
|
const cooldownPeriod = instance.pleroma.metadata.migration_cooldown_period;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { Link, useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
import { mentionCompose } from 'pl-fe/actions/compose';
|
import { mentionCompose } from 'pl-fe/actions/compose';
|
||||||
import { reblog, favourite, unreblog, unfavourite } from 'pl-fe/actions/interactions';
|
import { reblog, favourite, unreblog, unfavourite } from 'pl-fe/actions/interactions';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import HoverAccountWrapper from 'pl-fe/components/hover-account-wrapper';
|
import HoverAccountWrapper from 'pl-fe/components/hover-account-wrapper';
|
||||||
import Icon from 'pl-fe/components/icon';
|
import Icon from 'pl-fe/components/icon';
|
||||||
import RelativeTimestamp from 'pl-fe/components/relative-timestamp';
|
import RelativeTimestamp from 'pl-fe/components/relative-timestamp';
|
||||||
|
@ -17,6 +16,7 @@ import Emojify from 'pl-fe/features/emoji/emojify';
|
||||||
import { HotKeys } from 'pl-fe/features/ui/components/hotkeys';
|
import { HotKeys } from 'pl-fe/features/ui/components/hotkeys';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useLoggedIn } from 'pl-fe/hooks/use-logged-in';
|
import { useLoggedIn } from 'pl-fe/hooks/use-logged-in';
|
||||||
import { makeGetNotification } from 'pl-fe/selectors';
|
import { makeGetNotification } from 'pl-fe/selectors';
|
||||||
import { useModalsStore } from 'pl-fe/stores/modals';
|
import { useModalsStore } from 'pl-fe/stores/modals';
|
||||||
|
@ -212,7 +212,7 @@ const Notification: React.FC<INotification> = (props) => {
|
||||||
|
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const type = notification.type;
|
const type = notification.type;
|
||||||
const { accounts } = notification;
|
const { accounts } = notification;
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Account from 'pl-fe/components/account';
|
import Account from 'pl-fe/components/account';
|
||||||
import Button from 'pl-fe/components/ui/button';
|
import Button from 'pl-fe/components/ui/button';
|
||||||
import Card, { CardBody } from 'pl-fe/components/ui/card';
|
import Card, { CardBody } from 'pl-fe/components/ui/card';
|
||||||
import Icon from 'pl-fe/components/ui/icon';
|
import Icon from 'pl-fe/components/ui/icon';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
import Text from 'pl-fe/components/ui/text';
|
import Text from 'pl-fe/components/ui/text';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
|
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
|
||||||
|
|
||||||
const FediverseStep = ({ onNext }: { onNext: () => void }) => {
|
const FediverseStep = ({ onNext }: { onNext: () => void }) => {
|
||||||
const { account } = useOwnAccount();
|
const { account } = useOwnAccount();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card variant='rounded' size='xl'>
|
<Card variant='rounded' size='xl'>
|
||||||
|
|
|
@ -2,13 +2,13 @@ import React from 'react';
|
||||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { changeSetting } from 'pl-fe/actions/settings';
|
import { changeSetting } from 'pl-fe/actions/settings';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import List, { ListItem } from 'pl-fe/components/list';
|
import List, { ListItem } from 'pl-fe/components/list';
|
||||||
import Form from 'pl-fe/components/ui/form';
|
import Form from 'pl-fe/components/ui/form';
|
||||||
import { Mutliselect, SelectDropdown } from 'pl-fe/features/forms';
|
import { Mutliselect, SelectDropdown } from 'pl-fe/features/forms';
|
||||||
import SettingToggle from 'pl-fe/features/notifications/components/setting-toggle';
|
import SettingToggle from 'pl-fe/features/notifications/components/setting-toggle';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useSettings } from 'pl-fe/hooks/use-settings';
|
import { useSettings } from 'pl-fe/hooks/use-settings';
|
||||||
|
|
||||||
import ThemeToggle from '../ui/components/theme-toggle';
|
import ThemeToggle from '../ui/components/theme-toggle';
|
||||||
|
@ -98,7 +98,7 @@ const Preferences = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const settings = useSettings();
|
const settings = useSettings();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const onSelectChange = (event: React.ChangeEvent<HTMLSelectElement>, path: string[]) => {
|
const onSelectChange = (event: React.ChangeEvent<HTMLSelectElement>, path: string[]) => {
|
||||||
dispatch(changeSetting(path, event.target.value, { showAlert: true }));
|
dispatch(changeSetting(path, event.target.value, { showAlert: true }));
|
||||||
|
|
|
@ -4,12 +4,12 @@ import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import { changeSetting } from 'pl-fe/actions/settings';
|
import { changeSetting } from 'pl-fe/actions/settings';
|
||||||
import { fetchPublicTimeline } from 'pl-fe/actions/timelines';
|
import { fetchPublicTimeline } from 'pl-fe/actions/timelines';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import { usePublicStream } from 'pl-fe/api/hooks/streaming/use-public-stream';
|
import { usePublicStream } from 'pl-fe/api/hooks/streaming/use-public-stream';
|
||||||
import PullToRefresh from 'pl-fe/components/pull-to-refresh';
|
import PullToRefresh from 'pl-fe/components/pull-to-refresh';
|
||||||
import Accordion from 'pl-fe/components/ui/accordion';
|
import Accordion from 'pl-fe/components/ui/accordion';
|
||||||
import Column from 'pl-fe/components/ui/column';
|
import Column from 'pl-fe/components/ui/column';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useIsMobile } from 'pl-fe/hooks/use-is-mobile';
|
import { useIsMobile } from 'pl-fe/hooks/use-is-mobile';
|
||||||
import { useSettings } from 'pl-fe/hooks/use-settings';
|
import { useSettings } from 'pl-fe/hooks/use-settings';
|
||||||
import { useTheme } from 'pl-fe/hooks/use-theme';
|
import { useTheme } from 'pl-fe/hooks/use-theme';
|
||||||
|
@ -27,7 +27,7 @@ const CommunityTimeline = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const settings = useSettings();
|
const settings = useSettings();
|
||||||
const onlyMedia = settings.timelines.public?.other.onlyMedia ?? false;
|
const onlyMedia = settings.timelines.public?.other.onlyMedia ?? false;
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,9 @@ import React from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import { BigCard } from 'pl-fe/components/big-card';
|
import { BigCard } from 'pl-fe/components/big-card';
|
||||||
import RegistrationForm from 'pl-fe/features/auth-login/components/registration-form';
|
import RegistrationForm from 'pl-fe/features/auth-login/components/registration-form';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
interface RegisterInviteParams {
|
interface RegisterInviteParams {
|
||||||
token: string;
|
token: string;
|
||||||
|
@ -12,7 +12,7 @@ interface RegisterInviteParams {
|
||||||
|
|
||||||
/** Page to register with an invitation. */
|
/** Page to register with an invitation. */
|
||||||
const RegisterInvite: React.FC = () => {
|
const RegisterInvite: React.FC = () => {
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const { token } = useParams<RegisterInviteParams>();
|
const { token } = useParams<RegisterInviteParams>();
|
||||||
|
|
||||||
const title = (
|
const title = (
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Column from 'pl-fe/components/ui/column';
|
import Column from 'pl-fe/components/ui/column';
|
||||||
import Divider from 'pl-fe/components/ui/divider';
|
import Divider from 'pl-fe/components/ui/divider';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
import Text from 'pl-fe/components/ui/text';
|
import Text from 'pl-fe/components/ui/text';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
import LinkFooter from '../ui/components/link-footer';
|
import LinkFooter from '../ui/components/link-footer';
|
||||||
import PromoPanel from '../ui/components/panels/promo-panel';
|
import PromoPanel from '../ui/components/panels/promo-panel';
|
||||||
|
@ -16,7 +16,7 @@ const messages = defineMessages({
|
||||||
|
|
||||||
const ServerInfo = () => {
|
const ServerInfo = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column label={intl.formatMessage(messages.heading)}>
|
<Column label={intl.formatMessage(messages.heading)}>
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Button from 'pl-fe/components/ui/button';
|
import Button from 'pl-fe/components/ui/button';
|
||||||
import Card, { CardTitle } from 'pl-fe/components/ui/card';
|
import Card, { CardTitle } from 'pl-fe/components/ui/card';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
import Text from 'pl-fe/components/ui/text';
|
import Text from 'pl-fe/components/ui/text';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { usePlFeConfig } from 'pl-fe/hooks/use-pl-fe-config';
|
import { usePlFeConfig } from 'pl-fe/hooks/use-pl-fe-config';
|
||||||
|
|
||||||
/** Prompts logged-out users to log in when viewing a thread. */
|
/** Prompts logged-out users to log in when viewing a thread. */
|
||||||
const ThreadLoginCta: React.FC = () => {
|
const ThreadLoginCta: React.FC = () => {
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const { displayCta } = usePlFeConfig();
|
const { displayCta } = usePlFeConfig();
|
||||||
|
|
||||||
if (!displayCta) return null;
|
if (!displayCta) return null;
|
||||||
|
|
|
@ -2,7 +2,6 @@ import React, { useState, useEffect, useCallback } from 'react';
|
||||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { updateMrf } from 'pl-fe/actions/mrf';
|
import { updateMrf } from 'pl-fe/actions/mrf';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import List, { ListItem } from 'pl-fe/components/list';
|
import List, { ListItem } from 'pl-fe/components/list';
|
||||||
import Modal from 'pl-fe/components/ui/modal';
|
import Modal from 'pl-fe/components/ui/modal';
|
||||||
import Toggle from 'pl-fe/components/ui/toggle';
|
import Toggle from 'pl-fe/components/ui/toggle';
|
||||||
|
@ -31,9 +30,8 @@ const EditFederationModal: React.FC<BaseModalProps & EditFederationModalProps> =
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const { data: instance } = useInstance();
|
|
||||||
const getRemoteInstance = useCallback(makeGetRemoteInstance(), []);
|
const getRemoteInstance = useCallback(makeGetRemoteInstance(), []);
|
||||||
const remoteInstance = useAppSelector(state => getRemoteInstance(state, host, instance));
|
const remoteInstance = useAppSelector(state => getRemoteInstance(state, host));
|
||||||
|
|
||||||
const [data, setData] = useState<Record<string, any>>({});
|
const [data, setData] = useState<Record<string, any>>({});
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Form from 'pl-fe/components/ui/form';
|
import Form from 'pl-fe/components/ui/form';
|
||||||
import FormGroup from 'pl-fe/components/ui/form-group';
|
import FormGroup from 'pl-fe/components/ui/form-group';
|
||||||
import Input from 'pl-fe/components/ui/input';
|
import Input from 'pl-fe/components/ui/input';
|
||||||
|
@ -9,6 +8,8 @@ import Textarea from 'pl-fe/components/ui/textarea';
|
||||||
import AvatarPicker from 'pl-fe/features/edit-profile/components/avatar-picker';
|
import AvatarPicker from 'pl-fe/features/edit-profile/components/avatar-picker';
|
||||||
import HeaderPicker from 'pl-fe/features/edit-profile/components/header-picker';
|
import HeaderPicker from 'pl-fe/features/edit-profile/components/header-picker';
|
||||||
import { usePreview } from 'pl-fe/hooks/forms/use-preview';
|
import { usePreview } from 'pl-fe/hooks/forms/use-preview';
|
||||||
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import resizeImage from 'pl-fe/utils/resize-image';
|
import resizeImage from 'pl-fe/utils/resize-image';
|
||||||
|
|
||||||
import type { CreateGroupParams } from 'pl-api';
|
import type { CreateGroupParams } from 'pl-api';
|
||||||
|
@ -26,7 +27,7 @@ interface IDetailsStep {
|
||||||
|
|
||||||
const DetailsStep: React.FC<IDetailsStep> = ({ params, onChange }) => {
|
const DetailsStep: React.FC<IDetailsStep> = ({ params, onChange }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
display_name: displayName = '',
|
display_name: displayName = '',
|
||||||
|
@ -36,7 +37,7 @@ const DetailsStep: React.FC<IDetailsStep> = ({ params, onChange }) => {
|
||||||
const avatarSrc = usePreview(params.avatar);
|
const avatarSrc = usePreview(params.avatar);
|
||||||
const headerSrc = usePreview(params.header);
|
const headerSrc = usePreview(params.header);
|
||||||
|
|
||||||
const attachmentTypes = useInstance().data.configuration.media_attachments.supported_mime_types
|
const attachmentTypes = useAppSelector(state => state.instance.configuration.media_attachments.supported_mime_types)
|
||||||
?.filter((type) => type.startsWith('image/'))
|
?.filter((type) => type.startsWith('image/'))
|
||||||
.join(',');
|
.join(',');
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { blockAccount } from 'pl-fe/actions/accounts';
|
||||||
import { submitReport, ReportableEntities } from 'pl-fe/actions/reports';
|
import { submitReport, ReportableEntities } from 'pl-fe/actions/reports';
|
||||||
import { fetchAccountTimeline } from 'pl-fe/actions/timelines';
|
import { fetchAccountTimeline } from 'pl-fe/actions/timelines';
|
||||||
import { useAccount } from 'pl-fe/api/hooks/accounts/use-account';
|
import { useAccount } from 'pl-fe/api/hooks/accounts/use-account';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import AttachmentThumbs from 'pl-fe/components/attachment-thumbs';
|
import AttachmentThumbs from 'pl-fe/components/attachment-thumbs';
|
||||||
import StatusContent from 'pl-fe/components/status-content';
|
import StatusContent from 'pl-fe/components/status-content';
|
||||||
import Modal from 'pl-fe/components/ui/modal';
|
import Modal from 'pl-fe/components/ui/modal';
|
||||||
|
@ -15,6 +14,7 @@ import Text from 'pl-fe/components/ui/text';
|
||||||
import AccountContainer from 'pl-fe/containers/account-container';
|
import AccountContainer from 'pl-fe/containers/account-container';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
import ConfirmationStep from './steps/confirmation-step';
|
import ConfirmationStep from './steps/confirmation-step';
|
||||||
import OtherActionsStep from './steps/other-actions-step';
|
import OtherActionsStep from './steps/other-actions-step';
|
||||||
|
@ -83,7 +83,7 @@ const ReportModal: React.FC<BaseModalProps & ReportModalProps> = ({ onClose, acc
|
||||||
|
|
||||||
const [block, setBlock] = useState(false);
|
const [block, setBlock] = useState(false);
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
const { rules } = useInstance().data;
|
const { rules } = useInstance();
|
||||||
const [ruleIds, setRuleIds] = useState<Array<string>>([]);
|
const [ruleIds, setRuleIds] = useState<Array<string>>([]);
|
||||||
const [selectedStatusIds, setSelectedStatusIds] = useState(statusIds);
|
const [selectedStatusIds, setSelectedStatusIds] = useState(statusIds);
|
||||||
const [comment, setComment] = useState('');
|
const [comment, setComment] = useState('');
|
||||||
|
|
|
@ -2,11 +2,11 @@ import clsx from 'clsx';
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import FormGroup from 'pl-fe/components/ui/form-group';
|
import FormGroup from 'pl-fe/components/ui/form-group';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
import Text from 'pl-fe/components/ui/text';
|
import Text from 'pl-fe/components/ui/text';
|
||||||
import Textarea from 'pl-fe/components/ui/textarea';
|
import Textarea from 'pl-fe/components/ui/textarea';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
|
|
||||||
import type { Account } from 'pl-fe/normalizers/account';
|
import type { Account } from 'pl-fe/normalizers/account';
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ const ReasonStep: React.FC<IReasonStep> = ({ comment, setComment, ruleIds, setRu
|
||||||
const [isNearBottom, setNearBottom] = useState<boolean>(false);
|
const [isNearBottom, setNearBottom] = useState<boolean>(false);
|
||||||
const [isNearTop, setNearTop] = useState<boolean>(true);
|
const [isNearTop, setNearTop] = useState<boolean>(true);
|
||||||
|
|
||||||
const { rules } = useInstance().data;
|
const { rules } = useInstance();
|
||||||
const shouldRequireRule = rules.length > 0;
|
const shouldRequireRule = rules.length > 0;
|
||||||
|
|
||||||
const handleCommentChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
|
const handleCommentChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
import { remoteInteraction } from 'pl-fe/actions/interactions';
|
import { remoteInteraction } from 'pl-fe/actions/interactions';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Button from 'pl-fe/components/ui/button';
|
import Button from 'pl-fe/components/ui/button';
|
||||||
import Form from 'pl-fe/components/ui/form';
|
import Form from 'pl-fe/components/ui/form';
|
||||||
import Input from 'pl-fe/components/ui/input';
|
import Input from 'pl-fe/components/ui/input';
|
||||||
|
@ -13,6 +12,7 @@ import Text from 'pl-fe/components/ui/text';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useRegistrationStatus } from 'pl-fe/hooks/use-registration-status';
|
import { useRegistrationStatus } from 'pl-fe/hooks/use-registration-status';
|
||||||
import { selectAccount } from 'pl-fe/selectors';
|
import { selectAccount } from 'pl-fe/selectors';
|
||||||
import toast from 'pl-fe/toast';
|
import toast from 'pl-fe/toast';
|
||||||
|
@ -40,7 +40,7 @@ const UnauthorizedModal: React.FC<UnauthorizedModalProps & BaseModalProps> = ({
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const { isOpen } = useRegistrationStatus();
|
const { isOpen } = useRegistrationStatus();
|
||||||
|
|
||||||
const username = useAppSelector(state => selectAccount(state, accountId!)?.display_name);
|
const username = useAppSelector(state => selectAccount(state, accountId!)?.display_name);
|
||||||
|
|
|
@ -2,7 +2,6 @@ import React from 'react';
|
||||||
import { useIntl, defineMessages } from 'react-intl';
|
import { useIntl, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
import { pinHost, unpinHost } from 'pl-fe/actions/remote-timeline';
|
import { pinHost, unpinHost } from 'pl-fe/actions/remote-timeline';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import Widget from 'pl-fe/components/ui/widget';
|
import Widget from 'pl-fe/components/ui/widget';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
|
@ -27,9 +26,8 @@ const InstanceInfoPanel: React.FC<IInstanceInfoPanel> = ({ host }) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const settings = useSettings();
|
const settings = useSettings();
|
||||||
|
const remoteInstance: any = useAppSelector(state => getRemoteInstance(state, host));
|
||||||
const pinned = settings.remote_timeline.pinnedHosts.includes(host);
|
const pinned = settings.remote_timeline.pinnedHosts.includes(host);
|
||||||
const { data: instance } = useInstance();
|
|
||||||
const remoteInstance = useAppSelector(state => getRemoteInstance(state, host, instance));
|
|
||||||
|
|
||||||
const handlePinHost = () => {
|
const handlePinHost = () => {
|
||||||
if (!pinned) {
|
if (!pinned) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useIntl, defineMessages, FormattedMessage } from 'react-intl';
|
import { useIntl, defineMessages, FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import DropdownMenu from 'pl-fe/components/dropdown-menu';
|
import DropdownMenu from 'pl-fe/components/dropdown-menu';
|
||||||
import Widget from 'pl-fe/components/ui/widget';
|
import Widget from 'pl-fe/components/ui/widget';
|
||||||
import InstanceRestrictions from 'pl-fe/features/federation-restrictions/components/instance-restrictions';
|
import InstanceRestrictions from 'pl-fe/features/federation-restrictions/components/instance-restrictions';
|
||||||
|
@ -26,9 +25,8 @@ const InstanceModerationPanel: React.FC<IInstanceModerationPanel> = ({ host }) =
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { openModal } = useModalsStore();
|
const { openModal } = useModalsStore();
|
||||||
|
|
||||||
const { data: instance } = useInstance();
|
|
||||||
const { account } = useOwnAccount();
|
const { account } = useOwnAccount();
|
||||||
const remoteInstance = useAppSelector(state => getRemoteInstance(state, host, instance));
|
const remoteInstance = useAppSelector(state => getRemoteInstance(state, host));
|
||||||
|
|
||||||
const handleEditFederation = () => {
|
const handleEditFederation = () => {
|
||||||
openModal('EDIT_FEDERATION', { host });
|
openModal('EDIT_FEDERATION', { host });
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import ForkAwesomeIcon from 'pl-fe/components/fork-awesome-icon';
|
import ForkAwesomeIcon from 'pl-fe/components/fork-awesome-icon';
|
||||||
import List, { ListItem } from 'pl-fe/components/list';
|
import List, { ListItem } from 'pl-fe/components/list';
|
||||||
import HStack from 'pl-fe/components/ui/hstack';
|
import HStack from 'pl-fe/components/ui/hstack';
|
||||||
import Widget from 'pl-fe/components/ui/widget';
|
import Widget from 'pl-fe/components/ui/widget';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { usePlFeConfig } from 'pl-fe/hooks/use-pl-fe-config';
|
import { usePlFeConfig } from 'pl-fe/hooks/use-pl-fe-config';
|
||||||
import { useSettings } from 'pl-fe/hooks/use-settings';
|
import { useSettings } from 'pl-fe/hooks/use-settings';
|
||||||
|
|
||||||
const PromoPanel: React.FC = () => {
|
const PromoPanel: React.FC = () => {
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const { promoPanel } = usePlFeConfig();
|
const { promoPanel } = usePlFeConfig();
|
||||||
const { locale } = useSettings();
|
const { locale } = useSettings();
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { FormattedMessage } from 'react-intl';
|
||||||
import { Redirect } from 'react-router-dom';
|
import { Redirect } from 'react-router-dom';
|
||||||
|
|
||||||
import { logIn, switchAccount, verifyCredentials } from 'pl-fe/actions/auth';
|
import { logIn, switchAccount, verifyCredentials } from 'pl-fe/actions/auth';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
import { fetchInstance } from 'pl-fe/actions/instance';
|
||||||
import Button from 'pl-fe/components/ui/button';
|
import Button from 'pl-fe/components/ui/button';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
import Text from 'pl-fe/components/ui/text';
|
import Text from 'pl-fe/components/ui/text';
|
||||||
|
@ -12,6 +12,7 @@ import OtpAuthForm from 'pl-fe/features/auth-login/components/otp-auth-form';
|
||||||
import ExternalLoginForm from 'pl-fe/features/external-login/components/external-login-form';
|
import ExternalLoginForm from 'pl-fe/features/external-login/components/external-login-form';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useRegistrationStatus } from 'pl-fe/hooks/use-registration-status';
|
import { useRegistrationStatus } from 'pl-fe/hooks/use-registration-status';
|
||||||
import { getRedirectUrl } from 'pl-fe/utils/redirect';
|
import { getRedirectUrl } from 'pl-fe/utils/redirect';
|
||||||
import { isStandalone } from 'pl-fe/utils/state';
|
import { isStandalone } from 'pl-fe/utils/state';
|
||||||
|
@ -20,7 +21,7 @@ import type { PlfeResponse } from 'pl-fe/api';
|
||||||
|
|
||||||
const SignUpPanel = () => {
|
const SignUpPanel = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const { isOpen } = useRegistrationStatus();
|
const { isOpen } = useRegistrationStatus();
|
||||||
const me = useAppSelector((state) => state.me);
|
const me = useAppSelector((state) => state.me);
|
||||||
const standalone = useAppSelector(isStandalone);
|
const standalone = useAppSelector(isStandalone);
|
||||||
|
@ -41,6 +42,11 @@ const SignUpPanel = () => {
|
||||||
const { username, password } = getFormData(event.target as HTMLFormElement);
|
const { username, password } = getFormData(event.target as HTMLFormElement);
|
||||||
dispatch(logIn(username, password))
|
dispatch(logIn(username, password))
|
||||||
.then(({ access_token }) => dispatch(verifyCredentials(access_token as string)))
|
.then(({ access_token }) => dispatch(verifyCredentials(access_token as string)))
|
||||||
|
// Refetch the instance for authenticated fetch
|
||||||
|
.then(async (account) => {
|
||||||
|
await dispatch(fetchInstance());
|
||||||
|
return account;
|
||||||
|
})
|
||||||
.then((account: { id: string }) => {
|
.then((account: { id: string }) => {
|
||||||
if (typeof me === 'string') {
|
if (typeof me === 'string') {
|
||||||
dispatch(switchAccount(account.id));
|
dispatch(switchAccount(account.id));
|
||||||
|
|
|
@ -12,7 +12,6 @@ import { expandNotifications } from 'pl-fe/actions/notifications';
|
||||||
import { register as registerPushNotifications } from 'pl-fe/actions/push-notifications/registerer';
|
import { register as registerPushNotifications } from 'pl-fe/actions/push-notifications/registerer';
|
||||||
import { fetchScheduledStatuses } from 'pl-fe/actions/scheduled-statuses';
|
import { fetchScheduledStatuses } from 'pl-fe/actions/scheduled-statuses';
|
||||||
import { fetchHomeTimeline } from 'pl-fe/actions/timelines';
|
import { fetchHomeTimeline } from 'pl-fe/actions/timelines';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import { useUserStream } from 'pl-fe/api/hooks/streaming/use-user-stream';
|
import { useUserStream } from 'pl-fe/api/hooks/streaming/use-user-stream';
|
||||||
import SidebarNavigation from 'pl-fe/components/sidebar-navigation';
|
import SidebarNavigation from 'pl-fe/components/sidebar-navigation';
|
||||||
import ThumbNavigation from 'pl-fe/components/thumb-navigation';
|
import ThumbNavigation from 'pl-fe/components/thumb-navigation';
|
||||||
|
@ -21,6 +20,7 @@ import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
import { useDraggedFiles } from 'pl-fe/hooks/use-dragged-files';
|
import { useDraggedFiles } from 'pl-fe/hooks/use-dragged-files';
|
||||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||||
|
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||||
import { useLoggedIn } from 'pl-fe/hooks/use-logged-in';
|
import { useLoggedIn } from 'pl-fe/hooks/use-logged-in';
|
||||||
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
|
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
|
||||||
import { usePlFeConfig } from 'pl-fe/hooks/use-pl-fe-config';
|
import { usePlFeConfig } from 'pl-fe/hooks/use-pl-fe-config';
|
||||||
|
@ -41,6 +41,7 @@ import RemoteInstanceLayout from 'pl-fe/layouts/remote-instance-layout';
|
||||||
import SearchLayout from 'pl-fe/layouts/search-layout';
|
import SearchLayout from 'pl-fe/layouts/search-layout';
|
||||||
import StatusLayout from 'pl-fe/layouts/status-layout';
|
import StatusLayout from 'pl-fe/layouts/status-layout';
|
||||||
import { useUiStore } from 'pl-fe/stores/ui';
|
import { useUiStore } from 'pl-fe/stores/ui';
|
||||||
|
import { getVapidKey } from 'pl-fe/utils/auth';
|
||||||
import { isStandalone } from 'pl-fe/utils/state';
|
import { isStandalone } from 'pl-fe/utils/state';
|
||||||
|
|
||||||
import BackgroundShapes from './components/background-shapes';
|
import BackgroundShapes from './components/background-shapes';
|
||||||
|
@ -145,14 +146,13 @@ import { WrappedRoute } from './util/react-router-helpers';
|
||||||
// Dummy import, to make sure that <Status /> ends up in the application bundle.
|
// Dummy import, to make sure that <Status /> ends up in the application bundle.
|
||||||
// Without this it ends up in ~8 very commonly used bundles.
|
// Without this it ends up in ~8 very commonly used bundles.
|
||||||
import 'pl-fe/components/status';
|
import 'pl-fe/components/status';
|
||||||
import { useVapidKey } from 'pl-fe/hooks/use-vapid-key';
|
|
||||||
|
|
||||||
interface ISwitchingColumnsArea {
|
interface ISwitchingColumnsArea {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SwitchingColumnsArea: React.FC<ISwitchingColumnsArea> = ({ children }) => {
|
const SwitchingColumnsArea: React.FC<ISwitchingColumnsArea> = ({ children }) => {
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const { search } = useLocation();
|
const { search } = useLocation();
|
||||||
const { isLoggedIn } = useLoggedIn();
|
const { isLoggedIn } = useLoggedIn();
|
||||||
|
@ -361,7 +361,7 @@ const UI: React.FC<IUI> = ({ children }) => {
|
||||||
const me = useAppSelector(state => state.me);
|
const me = useAppSelector(state => state.me);
|
||||||
const { account } = useOwnAccount();
|
const { account } = useOwnAccount();
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const vapidKey = useVapidKey();
|
const vapidKey = useAppSelector(state => getVapidKey(state));
|
||||||
|
|
||||||
const { isDropdownMenuOpen } = useUiStore();
|
const { isDropdownMenuOpen } = useUiStore();
|
||||||
const standalone = useAppSelector(isStandalone);
|
const standalone = useAppSelector(isStandalone);
|
||||||
|
@ -447,7 +447,7 @@ const UI: React.FC<IUI> = ({ children }) => {
|
||||||
}, [!!account]);
|
}, [!!account]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(registerPushNotifications(vapidKey));
|
dispatch(registerPushNotifications());
|
||||||
}, [vapidKey]);
|
}, [vapidKey]);
|
||||||
|
|
||||||
// Wait for login to succeed or fail
|
// Wait for login to succeed or fail
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { Features } from 'pl-api';
|
import { Features } from 'pl-api';
|
||||||
|
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
|
|
||||||
import { useAppSelector } from './use-app-selector';
|
import { useAppSelector } from './use-app-selector';
|
||||||
|
import { useInstance } from './use-instance';
|
||||||
|
|
||||||
/** Get features for the current instance. */
|
/** Get features for the current instance. */
|
||||||
const useFeatures = (): Features => {
|
const useFeatures = (): Features => {
|
||||||
|
|
6
packages/pl-fe/src/hooks/use-instance.ts
Normal file
6
packages/pl-fe/src/hooks/use-instance.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { useAppSelector } from './use-app-selector';
|
||||||
|
|
||||||
|
/** Get the Instance for the current backend. */
|
||||||
|
const useInstance = () => useAppSelector((state) => state.instance);
|
||||||
|
|
||||||
|
export { useInstance };
|
|
@ -1,9 +1,8 @@
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
|
|
||||||
import { useFeatures } from './use-features';
|
import { useFeatures } from './use-features';
|
||||||
|
import { useInstance } from './use-instance';
|
||||||
|
|
||||||
const useRegistrationStatus = () => {
|
const useRegistrationStatus = () => {
|
||||||
const { data: instance } = useInstance();
|
const instance = useInstance();
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
|
|
||||||
import { useAppSelector } from './use-app-selector';
|
|
||||||
|
|
||||||
const useVapidKey = () => {
|
|
||||||
const { data: instance } = useInstance();
|
|
||||||
|
|
||||||
return useAppSelector((state) => instance.configuration.vapid.public_key || state.auth.app?.vapid_key);
|
|
||||||
};
|
|
||||||
|
|
||||||
export { useVapidKey };
|
|
|
@ -1,9 +1,9 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { IntlProvider } from 'react-intl';
|
import { IntlProvider } from 'react-intl';
|
||||||
|
|
||||||
|
import { fetchInstance } from 'pl-fe/actions/instance';
|
||||||
import { fetchMe } from 'pl-fe/actions/me';
|
import { fetchMe } from 'pl-fe/actions/me';
|
||||||
import { loadPlFeConfig } from 'pl-fe/actions/pl-fe';
|
import { loadPlFeConfig } from 'pl-fe/actions/pl-fe';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
import LoadingScreen from 'pl-fe/components/loading-screen';
|
import LoadingScreen from 'pl-fe/components/loading-screen';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
|
@ -17,6 +17,8 @@ const loadInitial = () => {
|
||||||
return async(dispatch, getState) => {
|
return async(dispatch, getState) => {
|
||||||
// Await for authenticated fetch
|
// Await for authenticated fetch
|
||||||
await dispatch(fetchMe());
|
await dispatch(fetchMe());
|
||||||
|
// Await for feature detection
|
||||||
|
await dispatch(fetchInstance());
|
||||||
// Await for configuration
|
// Await for configuration
|
||||||
await dispatch(loadPlFeConfig());
|
await dispatch(loadPlFeConfig());
|
||||||
};
|
};
|
||||||
|
@ -29,7 +31,6 @@ interface IPlFeLoad {
|
||||||
/** Initial data loader. */
|
/** Initial data loader. */
|
||||||
const PlFeLoad: React.FC<IPlFeLoad> = ({ children }) => {
|
const PlFeLoad: React.FC<IPlFeLoad> = ({ children }) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { isLoading: isLoadingInstance } = useInstance();
|
|
||||||
|
|
||||||
const me = useAppSelector(state => state.me);
|
const me = useAppSelector(state => state.me);
|
||||||
const { account } = useOwnAccount();
|
const { account } = useOwnAccount();
|
||||||
|
@ -45,7 +46,6 @@ const PlFeLoad: React.FC<IPlFeLoad> = ({ children }) => {
|
||||||
me && !account,
|
me && !account,
|
||||||
!isLoaded,
|
!isLoaded,
|
||||||
localeLoading,
|
localeLoading,
|
||||||
isLoadingInstance,
|
|
||||||
].some(Boolean);
|
].some(Boolean);
|
||||||
|
|
||||||
// Load the user's locale
|
// Load the user's locale
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
import { decodeFromMarkup, pleromaDecoder } from './actions/preload';
|
|
||||||
|
|
||||||
let initialState: Record<string, any> = {};
|
|
||||||
|
|
||||||
try {
|
|
||||||
initialState = decodeFromMarkup('initial-results', pleromaDecoder);
|
|
||||||
} catch (e) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
export { initialState };
|
|
|
@ -10,7 +10,6 @@ import {
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||||
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
|
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
|
||||||
import { federationRestrictionsDisclosed } from 'pl-fe/utils/state';
|
import { federationRestrictionsDisclosed } from 'pl-fe/utils/state';
|
||||||
import { useInstance } from 'pl-fe/api/hooks/instance/use-instance';
|
|
||||||
|
|
||||||
interface IRemoteInstanceLayout {
|
interface IRemoteInstanceLayout {
|
||||||
params?: {
|
params?: {
|
||||||
|
@ -24,8 +23,7 @@ const RemoteInstanceLayout: React.FC<IRemoteInstanceLayout> = ({ children, param
|
||||||
const host = params!.instance!;
|
const host = params!.instance!;
|
||||||
|
|
||||||
const { account } = useOwnAccount();
|
const { account } = useOwnAccount();
|
||||||
const { data: instance } = useInstance();
|
const disclosed = useAppSelector(federationRestrictionsDisclosed);
|
||||||
const disclosed = federationRestrictionsDisclosed(instance);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { create } from 'mutative';
|
import { create } from 'mutative';
|
||||||
|
import { type CredentialAccount, type Instance, type MediaAttachment, type Tag } from 'pl-api';
|
||||||
|
|
||||||
|
import { INSTANCE_FETCH_SUCCESS, type InstanceAction } from 'pl-fe/actions/instance';
|
||||||
import { isNativeEmoji, type Emoji } from 'pl-fe/features/emoji';
|
import { isNativeEmoji, type Emoji } from 'pl-fe/features/emoji';
|
||||||
import { tagHistory } from 'pl-fe/settings';
|
import { tagHistory } from 'pl-fe/settings';
|
||||||
|
|
||||||
|
@ -65,7 +67,6 @@ import { FE_NAME } from '../actions/settings';
|
||||||
import { TIMELINE_DELETE, type TimelineAction } from '../actions/timelines';
|
import { TIMELINE_DELETE, type TimelineAction } from '../actions/timelines';
|
||||||
import { unescapeHTML } from '../utils/html';
|
import { unescapeHTML } from '../utils/html';
|
||||||
|
|
||||||
import type { CredentialAccount, MediaAttachment, Tag } from 'pl-api';
|
|
||||||
import type { Language } from 'pl-fe/features/preferences';
|
import type { Language } from 'pl-fe/features/preferences';
|
||||||
import type { Account } from 'pl-fe/normalizers/account';
|
import type { Account } from 'pl-fe/normalizers/account';
|
||||||
import type { Status } from 'pl-fe/normalizers/status';
|
import type { Status } from 'pl-fe/normalizers/status';
|
||||||
|
@ -309,11 +310,11 @@ const importAccount = (compose: Compose, account: CredentialAccount) => {
|
||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
|
|
||||||
// const updateDefaultContentType = (compose: Compose, instance: Instance) => {
|
const updateDefaultContentType = (compose: Compose, instance: Instance) => {
|
||||||
// const postFormats = instance.pleroma.metadata.post_formats;
|
const postFormats = instance.pleroma.metadata.post_formats;
|
||||||
|
|
||||||
// compose.content_type = postFormats.includes(compose.content_type) ? compose.content_type : postFormats.includes('text/markdown') ? 'text/markdown' : postFormats[0];
|
compose.content_type = postFormats.includes(compose.content_type) ? compose.content_type : postFormats.includes('text/markdown') ? 'text/markdown' : postFormats[0];
|
||||||
// };
|
};
|
||||||
|
|
||||||
const updateCompose = (state: State, key: string, updater: (compose: Compose) => void) =>
|
const updateCompose = (state: State, key: string, updater: (compose: Compose) => void) =>
|
||||||
create(state, draft => {
|
create(state, draft => {
|
||||||
|
@ -326,7 +327,7 @@ const initialState: State = {
|
||||||
default: newCompose({ idempotencyKey: crypto.randomUUID(), resetFileKey: getResetFileKey() }),
|
default: newCompose({ idempotencyKey: crypto.randomUUID(), resetFileKey: getResetFileKey() }),
|
||||||
};
|
};
|
||||||
|
|
||||||
const compose = (state = initialState, action: ComposeAction | EventsAction | MeAction | TimelineAction): State => {
|
const compose = (state = initialState, action: ComposeAction | EventsAction | InstanceAction | MeAction | TimelineAction): State => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case COMPOSE_TYPE_CHANGE:
|
case COMPOSE_TYPE_CHANGE:
|
||||||
return updateCompose(state, action.composeId, compose => {
|
return updateCompose(state, action.composeId, compose => {
|
||||||
|
@ -687,6 +688,8 @@ const compose = (state = initialState, action: ComposeAction | EventsAction | Me
|
||||||
return updateCompose(state, action.composeId, compose => {
|
return updateCompose(state, action.composeId, compose => {
|
||||||
compose.federated = !compose.federated;
|
compose.federated = !compose.federated;
|
||||||
});
|
});
|
||||||
|
case INSTANCE_FETCH_SUCCESS:
|
||||||
|
return updateCompose(state, 'default', (compose) => updateDefaultContentType(compose, action.instance));
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import domain_lists from './domain-lists';
|
||||||
import draft_statuses from './draft-statuses';
|
import draft_statuses from './draft-statuses';
|
||||||
import filters from './filters';
|
import filters from './filters';
|
||||||
import followed_tags from './followed-tags';
|
import followed_tags from './followed-tags';
|
||||||
|
import instance from './instance';
|
||||||
import listAdder from './list-adder';
|
import listAdder from './list-adder';
|
||||||
import listEditor from './list-editor';
|
import listEditor from './list-editor';
|
||||||
import lists from './lists';
|
import lists from './lists';
|
||||||
|
@ -53,6 +54,7 @@ const reducers = {
|
||||||
entities,
|
entities,
|
||||||
filters,
|
filters,
|
||||||
followed_tags,
|
followed_tags,
|
||||||
|
instance,
|
||||||
listAdder,
|
listAdder,
|
||||||
listEditor,
|
listEditor,
|
||||||
lists,
|
lists,
|
||||||
|
@ -85,8 +87,8 @@ const logOut = (state: AppState): ReturnType<typeof appReducer> => {
|
||||||
|
|
||||||
const newState = rootReducer(undefined, { type: '' });
|
const newState = rootReducer(undefined, { type: '' });
|
||||||
|
|
||||||
const { plfe, custom_emojis, auth } = state;
|
const { instance, plfe, custom_emojis, auth } = state;
|
||||||
return { ...newState, plfe, custom_emojis, auth };
|
return { ...newState, instance, plfe, custom_emojis, auth };
|
||||||
};
|
};
|
||||||
|
|
||||||
const rootReducer: typeof appReducer = (state, action) => {
|
const rootReducer: typeof appReducer = (state, action) => {
|
||||||
|
|
|
@ -1,8 +1,102 @@
|
||||||
import { instanceSchema } from 'pl-api';
|
import { create } from 'mutative';
|
||||||
|
import { type Instance, instanceSchema, PleromaConfig } from 'pl-api';
|
||||||
import * as v from 'valibot';
|
import * as v from 'valibot';
|
||||||
|
|
||||||
const initialState = v.parse(instanceSchema, {});
|
import { ADMIN_CONFIG_UPDATE_REQUEST, ADMIN_CONFIG_UPDATE_SUCCESS, type AdminActions } from 'pl-fe/actions/admin';
|
||||||
|
import { INSTANCE_FETCH_FAIL, INSTANCE_FETCH_SUCCESS, type InstanceAction } from 'pl-fe/actions/instance';
|
||||||
|
import { PLEROMA_PRELOAD_IMPORT, type PreloadAction } from 'pl-fe/actions/preload';
|
||||||
|
import KVStore from 'pl-fe/storage/kv-store';
|
||||||
|
import ConfigDB from 'pl-fe/utils/config-db';
|
||||||
|
|
||||||
const instance = () => initialState;
|
const initialState: State = v.parse(instanceSchema, {});
|
||||||
|
|
||||||
|
type State = Instance;
|
||||||
|
|
||||||
|
const preloadImport = (state: State, action: Record<string, any>, path: string) => {
|
||||||
|
const instance = action.data[path];
|
||||||
|
return instance ? v.parse(instanceSchema, instance) : state;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getConfigValue = (instanceConfig: Array<any>, key: string) => {
|
||||||
|
const v = instanceConfig
|
||||||
|
.find(value => value?.tuple?.[0] === key);
|
||||||
|
|
||||||
|
return v ? v?.tuple?.[1] : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const importConfigs = (state: State, configs: PleromaConfig['configs']) => {
|
||||||
|
// FIXME: This is pretty hacked together. Need to make a cleaner map.
|
||||||
|
const config = ConfigDB.find(configs, ':pleroma', ':instance');
|
||||||
|
const simplePolicy = ConfigDB.toSimplePolicy(configs);
|
||||||
|
|
||||||
|
if (!config && !simplePolicy) return state;
|
||||||
|
|
||||||
|
if (config) {
|
||||||
|
const value = config.value || [];
|
||||||
|
const registrationsOpen = getConfigValue(value, ':registrations_open') as boolean | undefined;
|
||||||
|
const approvalRequired = getConfigValue(value, ':account_approval_required') as boolean | undefined;
|
||||||
|
|
||||||
|
state.registrations = {
|
||||||
|
enabled: registrationsOpen ?? state.registrations.enabled,
|
||||||
|
approval_required: approvalRequired ?? state.registrations.approval_required,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (simplePolicy) {
|
||||||
|
state.pleroma.metadata.federation.mrf_simple = simplePolicy;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAuthFetch = (state: State) => {
|
||||||
|
// Authenticated fetch is enabled, so make the instance appear censored
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
title: state.title || '██████',
|
||||||
|
description: state.description || '████████████',
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const getHost = (instance: { domain: string }) => {
|
||||||
|
const domain = instance.domain;
|
||||||
|
try {
|
||||||
|
return new URL(domain).host;
|
||||||
|
} catch {
|
||||||
|
try {
|
||||||
|
return new URL(`https://${domain}`).host;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const persistInstance = (instance: { domain: string }, host: string | null = getHost(instance)) => {
|
||||||
|
if (host) {
|
||||||
|
KVStore.setItem(`instance:${host}`, instance).catch(console.error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleInstanceFetchFail = (state: State, error: any) => {
|
||||||
|
if (error.response?.status === 401) {
|
||||||
|
return handleAuthFetch(state);
|
||||||
|
} else {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const instance = (state = initialState, action: AdminActions | InstanceAction | PreloadAction): State => {
|
||||||
|
switch (action.type) {
|
||||||
|
case PLEROMA_PRELOAD_IMPORT:
|
||||||
|
return create(state, (draft) => preloadImport(draft, action, '/api/v1/instance'));
|
||||||
|
case INSTANCE_FETCH_SUCCESS:
|
||||||
|
persistInstance(action.instance);
|
||||||
|
return action.instance;
|
||||||
|
case INSTANCE_FETCH_FAIL:
|
||||||
|
return handleInstanceFetchFail(state, action.error);
|
||||||
|
case ADMIN_CONFIG_UPDATE_REQUEST:
|
||||||
|
case ADMIN_CONFIG_UPDATE_SUCCESS:
|
||||||
|
return create(state, (draft) => importConfigs(draft, action.configs));
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
export { instance as default };
|
export { instance as default };
|
||||||
|
|
|
@ -1,10 +1,20 @@
|
||||||
import type { AnyAction } from 'redux';
|
import { INSTANCE_FETCH_FAIL, type InstanceAction } from 'pl-fe/actions/instance';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
/** Whether /api/v1/instance 404'd (and we should display the external auth form). */
|
/** Whether /api/v1/instance 404'd (and we should display the external auth form). */
|
||||||
instance_fetch_failed: false,
|
instance_fetch_failed: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const meta = (state = initialState, action: AnyAction): typeof initialState => state;
|
const meta = (state = initialState, action: InstanceAction): typeof initialState => {
|
||||||
|
switch (action.type) {
|
||||||
|
case INSTANCE_FETCH_FAIL:
|
||||||
|
if ((action.error as any)?.response?.status === 404) {
|
||||||
|
return { instance_fetch_failed: true };
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export { meta as default };
|
export { meta as default };
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { validId } from 'pl-fe/utils/auth';
|
||||||
import ConfigDB from 'pl-fe/utils/config-db';
|
import ConfigDB from 'pl-fe/utils/config-db';
|
||||||
import { shouldFilter } from 'pl-fe/utils/timelines';
|
import { shouldFilter } from 'pl-fe/utils/timelines';
|
||||||
|
|
||||||
import type { Account as BaseAccount, Filter, Instance, MediaAttachment, NotificationGroup, Relationship } from 'pl-api';
|
import type { Account as BaseAccount, Filter, MediaAttachment, NotificationGroup, Relationship } from 'pl-api';
|
||||||
import type { EntityStore } from 'pl-fe/entity-store/types';
|
import type { EntityStore } from 'pl-fe/entity-store/types';
|
||||||
import type { Account } from 'pl-fe/normalizers/account';
|
import type { Account } from 'pl-fe/normalizers/account';
|
||||||
import type { Group } from 'pl-fe/normalizers/group';
|
import type { Group } from 'pl-fe/normalizers/group';
|
||||||
|
@ -275,7 +275,7 @@ const makeGetOtherAccounts = () => createSelector([
|
||||||
|
|
||||||
const getSimplePolicy = createSelector([
|
const getSimplePolicy = createSelector([
|
||||||
(state: RootState) => state.admin.configs,
|
(state: RootState) => state.admin.configs,
|
||||||
(_state: RootState, instance: Instance) => instance.pleroma.metadata.federation.mrf_simple,
|
(state: RootState) => state.instance.pleroma.metadata.federation.mrf_simple,
|
||||||
], (configs, instancePolicy) => ({
|
], (configs, instancePolicy) => ({
|
||||||
...instancePolicy,
|
...instancePolicy,
|
||||||
...ConfigDB.toSimplePolicy(configs),
|
...ConfigDB.toSimplePolicy(configs),
|
||||||
|
@ -291,8 +291,8 @@ type HostFederation = {
|
||||||
[key in keyof MRFSimple]: boolean;
|
[key in keyof MRFSimple]: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getRemoteInstanceFederation = (state: RootState, host: string, instance: Instance): HostFederation => {
|
const getRemoteInstanceFederation = (state: RootState, host: string): HostFederation => {
|
||||||
const simplePolicy = getSimplePolicy(state, instance);
|
const simplePolicy = getSimplePolicy(state);
|
||||||
|
|
||||||
return Object.fromEntries(
|
return Object.fromEntries(
|
||||||
Object.entries(simplePolicy).map(([key, hosts]) => [key, hosts.includes(host)]),
|
Object.entries(simplePolicy).map(([key, hosts]) => [key, hosts.includes(host)]),
|
||||||
|
|
|
@ -56,6 +56,10 @@ const getAuthUserUrl = (state: RootState) => {
|
||||||
].filter(url => url).find(isURL);
|
].filter(url => url).find(isURL);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Get the VAPID public key. */
|
||||||
|
const getVapidKey = (state: RootState) =>
|
||||||
|
state.auth.app?.vapid_key || state.instance.configuration.vapid.public_key;
|
||||||
|
|
||||||
const getMeUrl = (state: RootState) => selectOwnAccount(state)?.url;
|
const getMeUrl = (state: RootState) => selectOwnAccount(state)?.url;
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
@ -67,5 +71,6 @@ export {
|
||||||
getAccessToken,
|
getAccessToken,
|
||||||
getAuthUserId,
|
getAuthUserId,
|
||||||
getAuthUserUrl,
|
getAuthUserUrl,
|
||||||
|
getVapidKey,
|
||||||
getMeUrl,
|
getMeUrl,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
import { getFeatures, PLEROMA, TOKI, type Instance } from 'pl-api';
|
import { getFeatures, PLEROMA, TOKI, type Instance } from 'pl-api';
|
||||||
|
|
||||||
import * as BuildConfig from 'pl-fe/build-config';
|
import type { RootState } from 'pl-fe/store';
|
||||||
import { queryClient } from 'pl-fe/queries/client';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the OAuth scopes to use for login & signup.
|
* Get the OAuth scopes to use for login & signup.
|
||||||
* Mastodon will refuse scopes it doesn't know, so care is needed.
|
* Mastodon will refuse scopes it doesn't know, so care is needed.
|
||||||
*/
|
*/
|
||||||
const getInstanceScopes = (instance?: Instance) => {
|
const getInstanceScopes = (instance: Instance) => {
|
||||||
const software = instance ? getFeatures(instance).version.software : null;
|
const v = getFeatures(instance).version;
|
||||||
|
|
||||||
switch (software) {
|
switch (v.software) {
|
||||||
case TOKI:
|
case TOKI:
|
||||||
return 'read write follow push write:bites';
|
return 'read write follow push write:bites';
|
||||||
case PLEROMA:
|
case PLEROMA:
|
||||||
|
@ -21,11 +20,7 @@ const getInstanceScopes = (instance?: Instance) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Convenience function to get scopes from instance in store. */
|
/** Convenience function to get scopes from instance in store. */
|
||||||
const getScopes = (baseURL = BuildConfig.BACKEND_URL || '') => {
|
const getScopes = (state: RootState) => getInstanceScopes(state.instance);
|
||||||
const instance = queryClient.getQueryData<Instance>(['instance', 'instanceInformation', baseURL]);
|
|
||||||
|
|
||||||
return getInstanceScopes(instance);
|
|
||||||
};
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getInstanceScopes,
|
getInstanceScopes,
|
||||||
|
|
|
@ -9,15 +9,14 @@ import { isPrerendered } from 'pl-fe/precheck';
|
||||||
import { selectOwnAccount } from 'pl-fe/selectors';
|
import { selectOwnAccount } from 'pl-fe/selectors';
|
||||||
import { isURL } from 'pl-fe/utils/auth';
|
import { isURL } from 'pl-fe/utils/auth';
|
||||||
|
|
||||||
import type { Instance } from 'pl-api';
|
|
||||||
import type { RootState } from 'pl-fe/store';
|
import type { RootState } from 'pl-fe/store';
|
||||||
|
|
||||||
/** Whether to display the fqn instead of the acct. */
|
/** Whether to display the fqn instead of the acct. */
|
||||||
const displayFqn = (state: RootState): boolean => getPlFeConfig(state).displayFqn;
|
const displayFqn = (state: RootState): boolean => getPlFeConfig(state).displayFqn;
|
||||||
|
|
||||||
/** Whether the instance exposes instance blocks through the API. */
|
/** Whether the instance exposes instance blocks through the API. */
|
||||||
const federationRestrictionsDisclosed = (instance: Instance): boolean =>
|
const federationRestrictionsDisclosed = (state: RootState): boolean =>
|
||||||
!!instance.pleroma.metadata.federation.mrf_policies;
|
!!state.instance.pleroma.metadata.federation.mrf_policies;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether pl-fe is running in standalone mode.
|
* Determine whether pl-fe is running in standalone mode.
|
||||||
|
|
Loading…
Reference in a new issue