diff --git a/packages/pl-api/lib/features.ts b/packages/pl-api/lib/features.ts index fcce14ae0..ff822d53a 100644 --- a/packages/pl-api/lib/features.ts +++ b/packages/pl-api/lib/features.ts @@ -205,6 +205,18 @@ const getFeatures = (instance: Instance) => { */ accountCreation: true, + /** + * Ability to control account discoverability. + * @see PATCH /api/v1/accounts/update_credentials + */ + accountDiscoverability: any([ + v.software === FRIENDICA, + v.software === GOTOSOCIAL, + v.software === MASTODON, + v.software === MITRA, + instance.api_versions['profile_directory.pleroma.pl-api'] >= 1, + ]), + /** * @see PATCH /api/v1/accounts/update_credentials */ @@ -279,6 +291,20 @@ const getFeatures = (instance: Instance) => { v.software === GOTOSOCIAL, ]), + /** + * @see PATCH /api/v1/accounts/update_credentials + */ + accountWebLayout: any([ + v.software === GOTOSOCIAL && gte(v.version, '0.19.0'), + ]), + + /** + * @see PATCH /api/v1/accounts/update_credentials + */ + accountWebVisibility: any([ + v.software === GOTOSOCIAL && gte(v.version, '0.17.0'), + ]), + /** * Ability to address a status to a list of users. * @see POST /api/v1/statuses diff --git a/packages/pl-api/lib/params/settings.ts b/packages/pl-api/lib/params/settings.ts index cdc6d5fad..437f1f0ea 100644 --- a/packages/pl-api/lib/params/settings.ts +++ b/packages/pl-api/lib/params/settings.ts @@ -1,3 +1,6 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import type { Features } from '../features'; + /** * @category Request params */ @@ -57,7 +60,10 @@ interface UpdateCredentialsParams { locked?: boolean; /** Boolean. Whether the account has a bot flag. */ bot?: boolean; - /** Boolean. Whether the account should be shown in the profile directory. */ + /** + * Boolean. Whether the account should be shown in the profile directory. + * Requires features{@link Features.accountDiscoverability} + */ discoverable?: boolean; /** Boolean. Whether to hide followers and followed accounts. */ hide_collections?: boolean; @@ -115,19 +121,39 @@ interface UpdateCredentialsParams { /** * Description of avatar image, for alt-text. * - * Requires features{@link Features['accountAvatarDescription']}. + * Requires features{@link Features.accountAvatarDescription}. */ avatar_description?: boolean; /** * Description of header image, for alt-text. - * Requires features{@link Features['accountAvatarDescription']}. + * Requires features{@link Features.accountAvatarDescription}. */ header_description?: boolean; + /** + * Custom CSS to use when rendering this account's profile or statuses. String must be no more than 5,000 characters (~5kb). + * Requires `instance.configuration.accounts.allow_custom_css`. + */ + custom_css?: string; /** * Enable RSS feed for this account's Public posts at `/[username]/feed.rss` - * Requires features{@link Features['accountEnableRss']}. + * Requires features{@link Features.accountEnableRss}. */ enable_rss?: boolean; + /** + * Layout to use for the web view of the account. + * - `microblog`: default, classic microblog layout. + * - `gallery`: gallery layout with media only. + * Requires features{@link Features.accountWebLayout}. + */ + web_layout?: 'microblog' | 'gallery'; + /** + * Posts to show on the web view of the account. + * - `public`: default, show only Public visibility posts on the web. + * - `unlisted`: show Public and Unlisted visibility posts on the web. + * - `none`: show no posts on the web, not even Public ones. + * Requires features{@link Features.accountWebVisibility}. + */ + web_visibility?: 'public' | 'unlisted' | 'none'; /** Whether the user is a cat */ is_cat?: boolean; @@ -136,7 +162,7 @@ interface UpdateCredentialsParams { /** * Mention policy - * Required features{@link Features['accountMentionPolicy']}. + * Required features{@link Features.accountMentionPolicy}. */ mention_policy?: 'none' | 'only_known' | 'only_contacts'; } diff --git a/packages/pl-api/package.json b/packages/pl-api/package.json index 8dc34e37f..d55919b71 100644 --- a/packages/pl-api/package.json +++ b/packages/pl-api/package.json @@ -1,6 +1,6 @@ { "name": "pl-api", - "version": "1.0.0-rc.54", + "version": "1.0.0-rc.55", "type": "module", "homepage": "https://github.com/mkljczk/pl-fe/tree/develop/packages/pl-api", "repository": { diff --git a/packages/pl-fe/package.json b/packages/pl-fe/package.json index c5272bcfb..d3da67d92 100644 --- a/packages/pl-fe/package.json +++ b/packages/pl-fe/package.json @@ -104,7 +104,7 @@ "multiselect-react-dropdown": "^2.0.25", "mutative": "^1.1.0", "path-browserify": "^1.0.1", - "pl-api": "^1.0.0-rc.54", + "pl-api": "^1.0.0-rc.55", "postcss": "^8.5.3", "process": "^0.11.10", "punycode": "^2.1.1", diff --git a/packages/pl-fe/src/features/edit-profile/index.tsx b/packages/pl-fe/src/features/edit-profile/index.tsx index 6c4573400..14b19f960 100644 --- a/packages/pl-fe/src/features/edit-profile/index.tsx +++ b/packages/pl-fe/src/features/edit-profile/index.tsx @@ -7,6 +7,7 @@ import { updateNotificationSettings } from 'pl-fe/actions/accounts'; import { patchMe } from 'pl-fe/actions/me'; import BirthdayInput from 'pl-fe/components/birthday-input'; import List, { ListItem } from 'pl-fe/components/list'; +import Accordion from 'pl-fe/components/ui/accordion'; import Button from 'pl-fe/components/ui/button'; import Column from 'pl-fe/components/ui/column'; import Form from 'pl-fe/components/ui/form'; @@ -60,6 +61,12 @@ const messages = defineMessages({ mentionPolicyNone: { id: 'edit_profile.fields.mention_policy.none', defaultMessage: 'Everybody' }, mentionPolicyOnlyKnown: { id: 'edit_profile.fields.mention_policy.only_known', defaultMessage: 'Everybody except new accounts' }, mentionPolicyOnlyContacts: { id: 'edit_profile.fields.mention_policy.only_contacts', defaultMessage: 'People I follow and my followers' }, + webLayoutMicroblog: { id: 'edit_profile.fields.web_layout.microblog', defaultMessage: 'Classic microblog layout' }, + webLayoutGallery: { id: 'edit_profile.fields.web_layout.gallery', defaultMessage: 'Media-only gallery layout' }, + webVisibilityPublic: { id: 'edit_profile.fields.web_visibility.public', defaultMessage: 'Show public posts only' }, + webVisibilityUnlisted: { id: 'edit_profile.fields.web_visibility.unlisted', defaultMessage: 'Show public and unlisted posts' }, + webVisibilityNone: { id: 'edit_profile.fields.web_visibility.none', defaultMessage: 'Show no posts' }, + customCSSLabel: { id: 'edit_profile.fields.custom_css_label', defaultMessage: 'Custom CSS' }, }); /** @@ -134,6 +141,9 @@ interface AccountCredentials { speak_as_cat?: boolean; /** Mention policy */ mention_policy?: string; + web_layout?: string; + web_visibility?: string; + custom_css?: string; } /** Convert an account into an update_credentials request object. */ @@ -141,7 +151,7 @@ const accountToCredentials = (account: Account): AccountCredentials => { const hideNetwork = hidesNetwork(account); return { - ...(pick(account, ['discoverable', 'bot', 'display_name', 'locked', 'location', 'avatar_description', 'header_description', 'enable_rss', 'hide_collections', 'is_cat', 'speak_as_cat', 'mention_policy'])), + ...(pick(account, ['discoverable', 'bot', 'display_name', 'locked', 'location', 'avatar_description', 'header_description', 'enable_rss', 'hide_collections', 'is_cat', 'speak_as_cat', 'mention_policy', 'web_visibility', 'web_layout'])), note: account.__meta.source?.note ?? '', fields_attributes: [...account.__meta.source?.fields ?? []], stranger_notifications: account.__meta.pleroma?.notification_settings?.block_from_strangers === true, @@ -200,6 +210,7 @@ const EditProfile: React.FC = () => { const [isLoading, setLoading] = useState(false); const [data, setData] = useState({}); const [muteStrangers, setMuteStrangers] = useState(false); + const [customCSSEditorExpanded, setCustomCSSEditorExpanded] = useState(false); const avatar = useImageField({ maxPixels: 400 * 400, preview: nonDefaultAvatar(account?.avatar) }); const header = useImageField({ maxPixels: 1920 * 1080, preview: nonDefaultHeader(account?.header) }); @@ -416,7 +427,7 @@ const EditProfile: React.FC = () => { )} - {features.profileDirectory && ( + {features.accountDiscoverability && ( } hint={} @@ -463,6 +474,39 @@ const EditProfile: React.FC = () => { )} + {features.accountWebLayout && ( + } + > + ) => handleFieldChange('web_layout')(event.target.value)} + /> + + )} + + {features.accountWebVisibility && ( + } + > + ) => handleFieldChange('web_visibility')(event.target.value)} + /> + + )} + {features.accountMentionPolicy && ( } @@ -497,6 +541,30 @@ const EditProfile: React.FC = () => { /> )} + {instance.configuration.accounts?.allow_custom_css && ( + + +