Merge remote-tracking branch 'origin/main' into instance-hooks

This commit is contained in:
Alex Gleason 2024-10-11 01:49:35 -05:00
commit c5c38ed79c
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
52 changed files with 62 additions and 57 deletions

View File

@ -22,7 +22,7 @@ function getRandomNumber(min: number, max: number): number {
const useCaptcha = () => {
const api = useApi();
const instance = useInstance();
const { instance } = useInstance();
const dispatch = useAppDispatch();
const intl = useIntl();
const [captcha, setCaptcha] = useState<CaptchaData>();

View File

@ -10,7 +10,7 @@ function useTimelineStream(...args: Parameters<typeof connectTimelineStream>) {
const { enabled = true } = args[4] ?? {};
const dispatch = useAppDispatch();
const instance = useInstance();
const { instance } = useInstance();
const stream = useRef<(() => void) | null>(null);
const accessToken = useAppSelector(getAccessToken);

View File

@ -22,7 +22,7 @@ interface IBirthdayInput {
const BirthdayInput: React.FC<IBirthdayInput> = ({ value, onChange, required }) => {
const intl = useIntl();
const features = useFeatures();
const instance = useInstance();
const { instance } = useInstance();
const supportsBirthdays = features.birthdays;
const minAge = instance.pleroma.metadata.birthday_min_age;

View File

@ -13,7 +13,7 @@ const GdprBanner: React.FC = () => {
const [shown, setShown] = useState<boolean>(acceptedGdpr);
const [slideout, setSlideout] = useState(false);
const instance = useInstance();
const { instance } = useInstance();
const { gdprUrl } = useSoapboxConfig();
const handleAccept = () => {

View File

@ -20,7 +20,7 @@ interface IHelmet {
}
const Helmet: React.FC<IHelmet> = ({ children }) => {
const instance = useInstance();
const { instance } = useInstance();
const { unreadChatsCount } = useStatContext();
const unreadCount = useAppSelector((state) => getNotifTotals(state) + unreadChatsCount);
const { demetricator } = useSettings();

View File

@ -90,7 +90,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
const sidebarOpen = useAppSelector((state) => state.sidebar.sidebarOpen);
const settings = useAppSelector((state) => getSettings(state));
const followRequestsCount = useAppSelector((state) => state.user_lists.follow_requests.items.count());
const instance = useInstance();
const { instance } = useInstance();
const settingsNotifications = useSettingsNotifications();
const closeButtonRef = React.useRef(null);

View File

@ -23,7 +23,7 @@ const SidebarNavigation = () => {
const intl = useIntl();
const { unreadChatsCount } = useStatContext();
const instance = useInstance();
const { instance } = useInstance();
const features = useFeatures();
const { isDeveloper } = useSettings();
const { account } = useOwnAccount();

View File

@ -16,7 +16,7 @@ const TranslateButton: React.FC<ITranslateButton> = ({ status }) => {
const dispatch = useAppDispatch();
const intl = useIntl();
const features = useFeatures();
const instance = useInstance();
const { instance } = useInstance();
const me = useAppSelector((state) => state.me);

View File

@ -19,7 +19,7 @@ interface NostrProviderProps {
}
export const NostrProvider: React.FC<NostrProviderProps> = ({ children }) => {
const instance = useInstance();
const { instance } = useInstance();
const hasNostr = !!instance.nostr;
const [relay, setRelay] = useState<NRelay1>();

View File

@ -36,7 +36,7 @@ const modeFromInstance = ({ registrations }: Instance): RegistrationMode => {
const RegistrationModePicker: React.FC = () => {
const intl = useIntl();
const dispatch = useAppDispatch();
const instance = useInstance();
const { instance } = useInstance();
const mode = modeFromInstance(instance);

View File

@ -14,7 +14,7 @@ import RegistrationModePicker from '../components/registration-mode-picker';
const Dashboard: React.FC = () => {
const dispatch = useAppDispatch();
const instance = useInstance();
const { instance } = useInstance();
const features = useFeatures();
const { account } = useOwnAccount();

View File

@ -11,7 +11,7 @@ interface IConsumersList {
/** Displays OAuth consumers to log in with. */
const ConsumersList: React.FC<IConsumersList> = () => {
const instance = useInstance();
const { instance } = useInstance();
const providers = instance.pleroma.oauth_consumer_strategies;
if (providers.length > 0) {

View File

@ -42,7 +42,7 @@ const RegistrationForm: React.FC<IRegistrationForm> = ({ inviteToken }) => {
const { locale } = useSettings();
const features = useFeatures();
const instance = useInstance();
const { instance } = useInstance();
const needsConfirmation = instance.pleroma.metadata.account_activation_required;
const needsApproval = instance.registrations.approval_required;

View File

@ -10,7 +10,7 @@ import { useAppDispatch, useFeatures, useInstance, useRegistrationStatus } from
import RegistrationForm from './registration-form';
const RegistrationPage: React.FC = () => {
const instance = useInstance();
const { instance } = useInstance();
const { isOpen } = useRegistrationStatus();
const { nostrSignup } = useFeatures();
const dispatch = useAppDispatch();

View File

@ -13,7 +13,7 @@ import Timeline from '../ui/components/timeline';
const CommunityTimeline = () => {
const dispatch = useAppDispatch();
const theme = useTheme();
const instance = useInstance();
const { instance } = useInstance();
const settings = useSettings();
const onlyMedia = settings.community.other.onlyMedia;

View File

@ -68,11 +68,11 @@ const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickab
const history = useHistory();
const intl = useIntl();
const dispatch = useAppDispatch();
const { configuration } = useInstance();
const { instance } = useInstance();
const compose = useCompose(id);
const showSearch = useAppSelector((state) => state.search.submitted && !state.search.hidden);
const maxTootChars = configuration.statuses.max_characters;
const maxTootChars = instance.configuration.statuses.max_characters;
const scheduledStatusCount = useAppSelector((state) => state.scheduled_statuses.size);
const features = useFeatures();

View File

@ -110,7 +110,7 @@ interface IPollForm {
const PollForm: React.FC<IPollForm> = ({ composeId }) => {
const dispatch = useAppDispatch();
const intl = useIntl();
const { configuration } = useInstance();
const { instance } = useInstance();
const compose = useCompose(composeId);
@ -121,7 +121,7 @@ const PollForm: React.FC<IPollForm> = ({ composeId }) => {
const {
max_options: maxOptions,
max_characters_per_option: maxOptionChars,
} = configuration.polls;
} = instance.configuration.polls;
const onRemoveOption = (index: number) => dispatch(removePollOption(composeId, index));
const onChangeOption = (index: number, title: string) => dispatch(changePollOption(composeId, index, title));

View File

@ -33,10 +33,10 @@ const UploadButton: React.FC<IUploadButton> = ({
icon,
}) => {
const intl = useIntl();
const { configuration } = useInstance();
const { instance } = useInstance();
const fileElement = useRef<HTMLInputElement>(null);
const attachmentTypes = configuration.media_attachments.supported_mime_types;
const attachmentTypes = instance.configuration.media_attachments.supported_mime_types;
const handleChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
if (e.target.files?.length) {

View File

@ -15,7 +15,8 @@ interface IUploadCompose {
const UploadCompose: React.FC<IUploadCompose> = ({ composeId, id, onSubmit, onDragStart, onDragEnter, onDragEnd }) => {
const dispatch = useAppDispatch();
const { pleroma: { metadata: { description_limit: descriptionLimit } } } = useInstance();
const { instance } = useInstance();
const { pleroma: { metadata: { description_limit: descriptionLimit } } } = instance;
const media = useCompose(composeId).media_attachments.find(item => item.id === id)!;

View File

@ -18,7 +18,7 @@ interface ICryptoDonatePanel {
const CryptoDonatePanel: React.FC<ICryptoDonatePanel> = ({ limit = 3 }): JSX.Element | null => {
const intl = useIntl();
const history = useHistory();
const instance = useInstance();
const { instance } = useInstance();
const addresses = useSoapboxConfig().get('cryptoAddresses');

View File

@ -12,7 +12,7 @@ const messages = defineMessages({
const CryptoDonate: React.FC = (): JSX.Element => {
const intl = useIntl();
const instance = useInstance();
const { instance } = useInstance();
const [explanationBoxExpanded, toggleExplanationBox] = useState(true);

View File

@ -23,7 +23,7 @@ const Directory = () => {
const dispatch = useAppDispatch();
const { search } = useLocation();
const params = new URLSearchParams(search);
const instance = useInstance();
const { instance } = useInstance();
const features = useFeatures();
const accountIds = useAppSelector((state) => state.user_lists.directory.items);

View File

@ -27,7 +27,7 @@ const messages = defineMessages({
/** EditIdentity component. */
const EditIdentity: React.FC<IEditIdentity> = () => {
const intl = useIntl();
const instance = useInstance();
const { instance } = useInstance();
const dispatch = useAppDispatch();
const { account } = useOwnAccount();
const { mutate, isPending } = useRequestName();
@ -162,7 +162,7 @@ const EditIdentity: React.FC<IEditIdentity> = () => {
const UsernameInput: React.FC<React.ComponentProps<typeof Input>> = (props) => {
const intl = useIntl();
const instance = useInstance();
const { instance } = useInstance();
return (
<Input

View File

@ -194,7 +194,7 @@ const ProfileField: StreamfieldComponent<AccountCredentialsField> = ({ value, on
const EditProfile: React.FC = () => {
const intl = useIntl();
const dispatch = useAppDispatch();
const instance = useInstance();
const { instance } = useInstance();
const { account } = useOwnAccount();
const features = useFeatures();

View File

@ -34,7 +34,7 @@ interface IInstanceRestrictions {
}
const InstanceRestrictions: React.FC<IInstanceRestrictions> = ({ remoteInstance }) => {
const instance = useInstance();
const { instance } = useInstance();
const renderRestrictions = () => {
const items = [];

View File

@ -21,7 +21,7 @@ const messages = defineMessages({
const FederationRestrictions = () => {
const intl = useIntl();
const instance = useInstance();
const { instance } = useInstance();
const getHosts = useCallback(makeGetHosts(), []);

View File

@ -31,7 +31,7 @@ interface IEditGroup {
const EditGroup: React.FC<IEditGroup> = ({ params: { groupId } }) => {
const intl = useIntl();
const instance = useInstance();
const { instance } = useInstance();
const { group, isLoading } = useGroup(groupId);
const { updateGroup } = useUpdateGroup(groupId);

View File

@ -17,7 +17,7 @@ const HomeTimeline: React.FC = () => {
const intl = useIntl();
const dispatch = useAppDispatch();
const features = useFeatures();
const instance = useInstance();
const { instance } = useInstance();
const theme = useTheme();
const polling = useRef<NodeJS.Timeout | null>(null);

View File

@ -9,7 +9,7 @@ import { getTextDirection } from 'soapbox/utils/rtl';
import { LogoText } from './logo-text';
const SiteBanner: React.FC = () => {
const instance = useInstance();
const { instance } = useInstance();
const description = DOMPurify.sanitize(instance.description);
return (

View File

@ -15,7 +15,7 @@ import { SiteBanner } from './components/site-banner';
const LandingTimeline = () => {
const dispatch = useAppDispatch();
const instance = useInstance();
const { instance } = useInstance();
const theme = useTheme();
const isMobile = useIsMobile();

View File

@ -21,7 +21,7 @@ const messages = defineMessages({
const Migration = () => {
const intl = useIntl();
const dispatch = useAppDispatch();
const instance = useInstance();
const { instance } = useInstance();
const cooldownPeriod = instance.pleroma.metadata.migration_cooldown_period;

View File

@ -38,7 +38,7 @@ interface RelayData {
}
const RelayField: StreamfieldComponent<RelayData> = ({ value, onChange }) => {
const instance = useInstance();
const { instance } = useInstance();
const handleChange = (key: string): React.ChangeEventHandler<HTMLInputElement> => {
return e => {

View File

@ -198,7 +198,7 @@ const Notification: React.FC<INotification> = (props) => {
const history = useHistory();
const intl = useIntl();
const instance = useInstance();
const { instance } = useInstance();
const type = notification.type;
const { account, status } = notification;

View File

@ -27,7 +27,7 @@ const PublicTimeline = () => {
const [language, setLanguage] = useState<string>(localStorage.getItem('soapbox:global:language') || '');
const instance = useInstance();
const { instance } = useInstance();
const settings = useSettings();
const onlyMedia = settings.public.other.onlyMedia;
const next = useAppSelector(state => state.timelines.get('public')?.next);

View File

@ -12,7 +12,7 @@ interface RegisterInviteParams {
/** Page to register with an invitation. */
const RegisterInvite: React.FC = () => {
const instance = useInstance();
const { instance } = useInstance();
const { token } = useParams<RegisterInviteParams>();
const title = (

View File

@ -13,7 +13,7 @@ const messages = defineMessages({
const ServerInfo = () => {
const intl = useIntl();
const instance = useInstance();
const { instance } = useInstance();
return (
<Column label={intl.formatMessage(messages.heading)}>

View File

@ -46,7 +46,7 @@ const Settings = () => {
const mfa = useAppSelector((state) => state.security.get('mfa'));
const features = useFeatures();
const { account } = useOwnAccount();
const instance = useInstance();
const { instance } = useInstance();
const settingsNotifications = useSettingsNotifications();
const isMfaEnabled = mfa.getIn(['settings', 'totp']);

View File

@ -6,7 +6,7 @@ import { useInstance, useSoapboxConfig } from 'soapbox/hooks';
/** Prompts logged-out users to log in when viewing a thread. */
const ThreadLoginCta: React.FC = () => {
const instance = useInstance();
const { instance } = useInstance();
const { displayCta } = useSoapboxConfig();
if (!displayCta) return null;

View File

@ -5,7 +5,7 @@ import { Banner, Button, HStack, Stack, Text } from 'soapbox/components/ui';
import { useAppSelector, useInstance, useRegistrationStatus, useSoapboxConfig } from 'soapbox/hooks';
const CtaBanner = () => {
const instance = useInstance();
const { instance } = useInstance();
const { isOpen } = useRegistrationStatus();
const { displayCta } = useSoapboxConfig();
const me = useAppSelector((state) => state.me);

View File

@ -24,7 +24,7 @@ interface IDetailsStep {
const DetailsStep: React.FC<IDetailsStep> = ({ params, onChange }) => {
const intl = useIntl();
const debounce = useDebounce;
const instance = useInstance();
const { instance } = useInstance();
const {
display_name: displayName = '',

View File

@ -16,7 +16,7 @@ interface IExtensionStep {
const ExtensionStep: React.FC<IExtensionStep> = ({ isLogin, onClickAlt, onClose }) => {
const dispatch = useAppDispatch();
const instance = useInstance();
const { instance } = useInstance();
const { logo } = useSoapboxConfig();
const handleClose = () => {

View File

@ -20,7 +20,7 @@ interface IKeygenStep {
}
const KeygenStep: React.FC<IKeygenStep> = ({ onClose }) => {
const instance = useInstance();
const { instance } = useInstance();
const dispatch = useAppDispatch();
const isMobile = useIsMobile();
const { relay } = useNostr();

View File

@ -104,13 +104,13 @@ const ReportModal = ({ onClose }: IReportModal) => {
const entityType = useAppSelector((state) => state.reports.new.entityType);
const isBlocked = useAppSelector((state) => state.reports.new.block);
const isSubmitting = useAppSelector((state) => state.reports.new.isSubmitting);
const { rules } = useInstance();
const { instance } = useInstance();
const ruleIds = useAppSelector((state) => state.reports.new.rule_ids);
const selectedStatusIds = useAppSelector((state) => state.reports.new.status_ids);
const selectedChatMessage = useAppSelector((state) => state.reports.new.chat_message);
const selectedGroup = useAppSelector((state) => state.reports.new.group);
const shouldRequireRule = rules.length > 0;
const shouldRequireRule = instance.rules.length > 0;
const isReportingAccount = entityType === ReportableEntities.ACCOUNT;
const isReportingStatus = entityType === ReportableEntities.STATUS;

View File

@ -31,8 +31,11 @@ const ReasonStep: React.FC<IReasonStep> = () => {
const entityType = useAppSelector((state) => state.reports.new.entityType);
const comment = useAppSelector((state) => state.reports.new.comment);
const { rules } = useInstance();
const ruleIds = useAppSelector((state) => state.reports.new.rule_ids);
const { instance } = useInstance();
const { rules } = instance;
const shouldRequireRule = rules.length > 0;
const handleCommentChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {

View File

@ -29,7 +29,7 @@ const UnauthorizedModal: React.FC<IUnauthorizedModal> = ({ action, onClose, acco
const intl = useIntl();
const history = useHistory();
const dispatch = useAppDispatch();
const instance = useInstance();
const { instance } = useInstance();
const { isOpen } = useRegistrationStatus();
const username = useAppSelector(state => selectAccount(state, accountId!)?.display_name);

View File

@ -6,7 +6,7 @@ import { Button, Stack, Text } from 'soapbox/components/ui';
import { useAppDispatch, useAppSelector, useFeatures, useInstance, useRegistrationStatus } from 'soapbox/hooks';
const SignUpPanel = () => {
const instance = useInstance();
const { instance } = useInstance();
const { nostrSignup } = useFeatures();
const { isOpen } = useRegistrationStatus();
const me = useAppSelector((state) => state.me);

View File

@ -5,7 +5,7 @@ import { Widget, Stack, Text } from 'soapbox/components/ui';
import { useInstance, useSettings, useSoapboxConfig } from 'soapbox/hooks';
const PromoPanel: React.FC = () => {
const instance = useInstance();
const { instance } = useInstance();
const { promoPanel } = useSoapboxConfig();
const { locale } = useSettings();

View File

@ -157,7 +157,7 @@ interface ISwitchingColumnsArea {
}
const SwitchingColumnsArea: React.FC<ISwitchingColumnsArea> = ({ children }) => {
const instance = useInstance();
const { instance } = useInstance();
const features = useFeatures();
const { search } = useLocation();
const { isLoggedIn } = useLoggedIn();

View File

@ -8,7 +8,7 @@ import { useInstance } from './useInstance';
* @returns Backend
*/
const useBackend = () => {
const instance = useInstance();
const { instance } = useInstance();
return parseVersion(instance.version);
};

View File

@ -4,6 +4,6 @@ import { useInstance } from './useInstance';
/** Get features for the current instance. */
export const useFeatures = (): Features => {
const instance = useInstance();
const { instance } = useInstance();
return getFeatures(instance);
};

View File

@ -2,5 +2,6 @@ import { useAppSelector } from './useAppSelector';
/** Get the Instance for the current backend. */
export const useInstance = () => {
return useAppSelector((state) => state.instance);
const instance = useAppSelector((state) => state.instance);
return { instance };
};

View File

@ -2,7 +2,7 @@ import { useFeatures } from './useFeatures';
import { useInstance } from './useInstance';
export const useRegistrationStatus = () => {
const instance = useInstance();
const { instance } = useInstance();
const features = useFeatures();
return {