pl-fe: allow to force implicit addressing

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2024-11-25 13:13:00 +01:00
parent 6a9921a409
commit 11d9d844bd
8 changed files with 30 additions and 20 deletions

View file

@ -29,6 +29,7 @@ Changes made since the project forked from Soapbox in April 2024.
- Language detection is done client-side for composed posts, utilizing `fasttext.wasm.js`.
- Draft posts. They are stored locally only and work with any backend.
- New visibility scopes are supported local-only and list-only for Pleroma. Local-only is a separate switch on GoToSocial.
- On backends that support explicit mentioning, you can choose to include mentions in your replies body.
**Features:**
- The most recent scrobble is displayed on user profile/card.

View file

@ -20,7 +20,7 @@ import { uploadFile, updateMedia } from './media';
import { createStatus } from './statuses';
import type { EditorState } from 'lexical';
import type { Account as BaseAccount, BackendVersion, CreateStatusParams, Group, MediaAttachment, Status as BaseStatus, Tag, Poll, ScheduledStatus } 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 { Emoji } from 'pl-fe/features/emoji';
import type { Account } from 'pl-fe/normalizers/account';
@ -118,7 +118,6 @@ interface ComposeSetStatusAction {
explicitAddressing: boolean;
spoilerText?: string;
contentType?: string | false;
v: BackendVersion;
withRedraft?: boolean;
draftId?: string;
editorState?: string | null;
@ -135,8 +134,8 @@ const setComposeToStatus = (
editorState?: string | null,
) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const client = getClient(getState);
const { createStatusExplicitAddressing: explicitAddressing, version: v } = client.features;
const { features } = getClient(getState);
const explicitAddressing = features.createStatusExplicitAddressing && !useSettingsStore.getState().settings.forceImplicitAddressing;
dispatch<ComposeSetStatusAction>({
type: COMPOSE_SET_STATUS,
@ -147,7 +146,6 @@ const setComposeToStatus = (
explicitAddressing,
spoilerText,
contentType,
v,
withRedraft,
draftId,
editorState,
@ -178,9 +176,9 @@ const replyCompose = (
) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const client = getClient(state);
const { createStatusExplicitAddressing: explicitAddressing } = client.features;
const preserveSpoilers = useSettingsStore.getState().settings.preserveSpoilers;
const { features } = getClient(getState);
const { forceImplicitAddressing, preserveSpoilers } = useSettingsStore.getState().settings;
const explicitAddressing = features.createStatusExplicitAddressing && !forceImplicitAddressing;
const account = selectOwnAccount(state);
if (!account) return;
@ -214,7 +212,8 @@ interface ComposeQuoteAction {
const quoteCompose = (status: ComposeQuoteAction['status']) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const { createStatusExplicitAddressing: explicitAddressing } = state.auth.client.features;
const { forceImplicitAddressing } = useSettingsStore.getState().settings;
const explicitAddressing = state.auth.client.features.createStatusExplicitAddressing && !forceImplicitAddressing;
dispatch<ComposeQuoteAction>({
type: COMPOSE_QUOTE,
@ -347,10 +346,13 @@ const submitCompose = (composeId: string, opts: SubmitComposeOpts = {}) =>
const compose = state.compose[composeId]!;
const status = compose.text;
const media = compose.media_attachments;
const statusId = compose.id;
let to = compose.to;
const { forceImplicitAddressing } = useSettingsStore.getState().settings;
const explicitAddressing = state.auth.client.features.createStatusExplicitAddressing && !forceImplicitAddressing;
if (!validateSchedule(state, composeId)) {
toast.error(messages.scheduleError);
@ -399,7 +401,7 @@ const submitCompose = (composeId: string, opts: SubmitComposeOpts = {}) =>
content_type: contentType,
scheduled_at: compose.schedule?.toISOString(),
language: compose.language || compose.suggested_language || undefined,
to: to.length ? to : undefined,
to: explicitAddressing && to.length ? to : undefined,
local_only: !compose.federated,
};
@ -897,7 +899,8 @@ interface ComposeEventReplyAction {
const eventDiscussionCompose = (composeId: string, status: ComposeEventReplyAction['status']) =>
(dispatch: AppDispatch, getState: () => RootState) => {
const state = getState();
const { createStatusExplicitAddressing: explicitAddressing } = state.auth.client.features;
const { forceImplicitAddressing } = useSettingsStore.getState().settings;
const explicitAddressing = state.auth.client.features.createStatusExplicitAddressing && !forceImplicitAddressing;
return dispatch({
type: COMPOSE_EVENT_REPLY,

View file

@ -4,6 +4,7 @@ import { FormattedList, FormattedMessage } from 'react-intl';
import { useCompose } from 'pl-fe/hooks/use-compose';
import { useFeatures } from 'pl-fe/hooks/use-features';
import { useModalsStore } from 'pl-fe/stores/modals';
import { useSettingsStore } from 'pl-fe/stores/settings';
interface IReplyMentions {
composeId: string;
@ -15,7 +16,10 @@ const ReplyMentions: React.FC<IReplyMentions> = ({ composeId }) => {
const compose = useCompose(composeId);
const to = compose.to;
if (!features.createStatusExplicitAddressing || !compose.in_reply_to || !to) {
const { forceImplicitAddressing } = useSettingsStore().settings;
const explicitAddressing = features.createStatusExplicitAddressing && !forceImplicitAddressing;
if (!explicitAddressing || !compose.in_reply_to || !to) {
return null;
}

View file

@ -203,6 +203,12 @@ const Preferences = () => {
</ListItem>
)}
{features.createStatusExplicitAddressing && (
<ListItem label={<FormattedMessage id='preferences.fields.implicit_addressing_label' defaultMessage='Include mentions in post content when replying' />}>
<SettingToggle settings={settings} settingPath={['forceImplicitAddressing']} onChange={onToggleChange} />
</ListItem>
)}
<ListItem label={<FormattedMessage id='preferences.notifications.advanced' defaultMessage='Show all notification categories' />}>
<SettingToggle settings={settings} settingPath={['notifications', 'quickFilter', 'advanced']} onChange={onToggleChange} />
</ListItem>

View file

@ -1253,6 +1253,7 @@
"preferences.fields.display_media.default": "Hide posts marked as sensitive",
"preferences.fields.display_media.hide_all": "Always hide media posts",
"preferences.fields.display_media.show_all": "Always show posts",
"preferences.fields.implicit_addressing_label": "Include mentions in post content when replying",
"preferences.fields.known_languages_label": "Languages you know",
"preferences.fields.language_label": "Display language",
"preferences.fields.media_display_label": "Sensitive content",

View file

@ -1,10 +1,9 @@
import { create } from 'mutative';
import { PLEROMA, type CredentialAccount, type Instance, type MediaAttachment, type Tag } from 'pl-api';
import { type CredentialAccount, type Instance, type MediaAttachment, type Tag } from 'pl-api';
import { INSTANCE_FETCH_SUCCESS, InstanceAction } from 'pl-fe/actions/instance';
import { isNativeEmoji, type Emoji } from 'pl-fe/features/emoji';
import { tagHistory } from 'pl-fe/settings';
import { hasIntegerMediaIds } from 'pl-fe/utils/status';
import {
COMPOSE_CHANGE,
@ -546,11 +545,7 @@ const compose = (state = initialState, action: ComposeAction | EventsAction | In
compose.quote = action.status.quote_id;
compose.group_id = action.status.group_id;
if (action.v?.software === PLEROMA && action.withRedraft && hasIntegerMediaIds(action.status)) {
compose.media_attachments = [];
} else {
compose.media_attachments = action.status.media_attachments;
}
compose.media_attachments = action.status.media_attachments;
if (action.status.spoiler_text.length > 0) {
compose.spoiler_text = action.status.spoiler_text;

View file

@ -33,6 +33,7 @@ const settingsSchema = v.object({
autoloadTimelines: v.fallback(v.boolean(), true),
autoloadMore: v.fallback(v.boolean(), true),
preserveSpoilers: v.fallback(v.boolean(), false),
forceImplicitAddressing: v.fallback(v.boolean(), false),
autoTranslate: v.fallback(v.boolean(), false),
knownLanguages: v.fallback(v.array(v.string()), []),
showWrenchButton: v.fallback(v.boolean(), false),

View file

@ -65,7 +65,6 @@ const useSettingsStore = create<State>()(mutative((set) => ({
changeSetting(state.userSettings, path, value);
mergeSettings(state);
console.log(JSON.parse(JSON.stringify(state.userSettings)));
}),
rememberEmojiUse: (emoji: Emoji) => set((state: State) => {