/* GoToSocial Copyright (C) GoToSocial Authors admin@gotosocial.org SPDX-License-Identifier: AGPL-3.0-or-later This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ import React, { useCallback, useMemo } from "react"; import { useDefaultInteractionPoliciesQuery, useResetDefaultInteractionPoliciesMutation, useUpdateDefaultInteractionPoliciesMutation, } from "../../../../lib/query/user"; import Loading from "../../../../components/loading"; import { Error } from "../../../../components/error"; import MutationButton from "../../../../components/form/mutation-button"; import { DefaultInteractionPolicies, InteractionPolicy, InteractionPolicyEntry, InteractionPolicyValue, PolicyValueAuthor, PolicyValueFollowers, PolicyValueFollowing, PolicyValueMentioned, PolicyValuePublic, } from "../../../../lib/types/interaction"; import { useTextInput } from "../../../../lib/form"; import { Select } from "../../../../components/form/inputs"; import { TextFormInputHook } from "../../../../lib/form/types"; import { useBasicFor } from "./basic"; import { PolicyFormSomethingElse, useSomethingElseFor } from "./something-else"; import { Action, PolicyFormSub, SomethingElseValue, Visibility } from "./types"; export default function InteractionPolicySettings() { const { data: defaultPolicies, isLoading, isFetching, isError, error, } = useDefaultInteractionPoliciesQuery(); if (isLoading || isFetching) { return ; } if (isError) { return ; } if (!defaultPolicies) { throw "default policies undefined"; } return ( ); } interface InteractionPoliciesFormProps { defaultPolicies: DefaultInteractionPolicies; } function InteractionPoliciesForm({ defaultPolicies }: InteractionPoliciesFormProps) { // Sub-form for visibility "public". const formPublic = useFormForVis(defaultPolicies.public, "public"); const assemblePublic = useCallback(() => { return { can_favourite: assemblePolicyEntry("public", "favourite", formPublic), can_reply: assemblePolicyEntry("public", "reply", formPublic), can_reblog: assemblePolicyEntry("public", "reblog", formPublic), }; }, [formPublic]); // Sub-form for visibility "unlisted". const formUnlisted = useFormForVis(defaultPolicies.unlisted, "unlisted"); const assembleUnlisted = useCallback(() => { return { can_favourite: assemblePolicyEntry("unlisted", "favourite", formUnlisted), can_reply: assemblePolicyEntry("unlisted", "reply", formUnlisted), can_reblog: assemblePolicyEntry("unlisted", "reblog", formUnlisted), }; }, [formUnlisted]); // Sub-form for visibility "private". const formPrivate = useFormForVis(defaultPolicies.private, "private"); const assemblePrivate = useCallback(() => { return { can_favourite: assemblePolicyEntry("private", "favourite", formPrivate), can_reply: assemblePolicyEntry("private", "reply", formPrivate), can_reblog: assemblePolicyEntry("private", "reblog", formPrivate), }; }, [formPrivate]); const selectedVis = useTextInput("selectedVis", { defaultValue: "public" }); const [updatePolicies, updateResult] = useUpdateDefaultInteractionPoliciesMutation(); const [resetPolicies, resetResult] = useResetDefaultInteractionPoliciesMutation(); const onSubmit = (e) => { e.preventDefault(); updatePolicies({ public: assemblePublic(), unlisted: assembleUnlisted(), private: assemblePrivate(), // Always use the // default for direct. direct: null, }); }; return (

Default Interaction Policies

You can use this section to customize the default interaction policy for posts created by you, per visibility setting.
These settings apply only for new posts created by you after applying these settings; they do not apply retroactively.
The word "anyone" in the below options means anyone with permission to see the post, taking account of blocks.
Bear in mind that no matter what you set below, you will always be able to like, reply-to, and boost your own posts.

Learn more about these settings (opens in a new tab)
resetPolicies()} label="Reset to defaults" result={resetResult} className="button danger" showError={false} />
); } // A tablist of tab buttons, one for each visibility. function PolicyPanelsTablist({ selectedVis }: { selectedVis: TextFormInputHook}) { return (
); } interface TabProps { thisVisibility: string; label: string, selectedVis: TextFormInputHook } // One tab in a tablist, corresponding to the given thisVisibility. function Tab({ thisVisibility, label, selectedVis }: TabProps) { const selected = useMemo(() => { return selectedVis.value === thisVisibility; }, [selectedVis, thisVisibility]); return ( ); } interface PolicyPanelProps { policyForm: PolicyForm; forVis: Visibility; isActive: boolean; } // Tab panel for one policy form of the given visibility. function PolicyPanel({ policyForm, forVis, isActive }: PolicyPanelProps) { return ( ); } interface PolicyComponentProps { form: { basic: PolicyFormSub; somethingElse: PolicyFormSomethingElse; }; forAction: Action; } // A component of one policy of the given // visibility, corresponding to the given action. function PolicyComponent({ form, forAction }: PolicyComponentProps) { const legend = useLegend(forAction); return (
{legend} { forAction === "reply" &&
Mentioned accounts can always reply.
} }