diff --git a/package.json b/package.json index bdbb577554..68cce9d60b 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,7 @@ "multiselect-react-dropdown": "^2.0.25", "object-to-formdata": "^4.5.1", "path-browserify": "^1.0.1", - "pl-api": "^0.0.17", + "pl-api": "^0.0.18", "postcss": "^8.4.29", "process": "^0.11.10", "punycode": "^2.1.1", diff --git a/src/actions/me.ts b/src/actions/me.ts index 912144caf6..769a0936f8 100644 --- a/src/actions/me.ts +++ b/src/actions/me.ts @@ -8,7 +8,7 @@ import { getClient } from '../api'; import { loadCredentials } from './auth'; import { importFetchedAccount } from './importer'; -import type { CredentialAccount } from 'pl-api'; +import type { CredentialAccount, UpdateCredentialsParams } from 'pl-api'; import type { AppDispatch, RootState } from 'soapbox/store'; const ME_FETCH_REQUEST = 'ME_FETCH_REQUEST' as const; @@ -55,6 +55,17 @@ const fetchMe = () => /** Update the auth account in IndexedDB for Mastodon, etc. */ const persistAuthAccount = (account: CredentialAccount, params: Record) => { + if (account && account.url) { + const key = `authAccount:${account.url}`; + KVStore.getItem(key).then((oldAccount: any) => { + const settings = oldAccount?.settings_store || {}; + if (!account.settings_store) { + account.settings_store = settings; + } + KVStore.setItem(key, account); + }) + .catch(console.error); + } if (account && account.url) { if (!account.settings_store) { account.settings_store = params.pleroma_settings_store || {}; @@ -63,7 +74,7 @@ const persistAuthAccount = (account: CredentialAccount, params: Record) => +const patchMe = (params: UpdateCredentialsParams) => (dispatch: AppDispatch, getState: () => RootState) => { dispatch(patchMeRequest()); diff --git a/src/actions/settings.ts b/src/actions/settings.ts index a3025ee1d5..66fd197697 100644 --- a/src/actions/settings.ts +++ b/src/actions/settings.ts @@ -3,7 +3,10 @@ import { defineMessage } from 'react-intl'; import { createSelector } from 'reselect'; import { patchMe } from 'soapbox/actions/me'; +import { getClient } from 'soapbox/api'; import messages from 'soapbox/messages'; +import { makeGetAccount } from 'soapbox/selectors'; +import KVStore from 'soapbox/storage/kv-store'; import toast from 'soapbox/toast'; import { isLoggedIn } from 'soapbox/utils/auth'; @@ -15,6 +18,8 @@ const SETTINGS_UPDATE = 'SETTINGS_UPDATE' as const; const FE_NAME = 'pl_fe'; +const getAccount = makeGetAccount(); + /** Options when changing/saving settings. */ type SettingOpts = { /** Whether to display an alert when settings are saved. */ @@ -171,11 +176,7 @@ const saveSettings = (opts?: SettingOpts) => const data = state.settings.delete('saved').toJS(); - dispatch(patchMe({ - pleroma_settings_store: { - [FE_NAME]: data, - }, - })).then(() => { + dispatch(updateSettingsStore(data)).then(() => { dispatch({ type: SETTING_SAVE }); if (opts?.showAlert) { @@ -186,6 +187,39 @@ const saveSettings = (opts?: SettingOpts) => }); }; +/** Update settings store for Mastodon, etc. */ +const updateAuthAccount = (url: string, settings: any) => { + const key = `authAccount:${url}`; + return KVStore.getItem(key).then((oldAccount: any) => { + if (!oldAccount) return; + if (!oldAccount.__meta) oldAccount.__meta = { pleroma: { settings_store: {} } }; + else if (!oldAccount.__meta.pleroma) oldAccount.__meta.pleroma = { settings_store: {} }; + else if (!oldAccount.__meta.pleroma.settings_store) oldAccount.__meta.pleroma.settings_store = {}; + oldAccount.__meta.pleroma.settings_store[FE_NAME] = settings; + // const settingsStore = oldAccount?.__meta || {}; + // settingsStore[FE_NAME] = settings; + KVStore.setItem(key, oldAccount); + }).catch(console.error); +}; + +const updateSettingsStore = (settings: any) => + (dispatch: AppDispatch, getState: () => RootState) => { + const state = getState(); + const client = getClient(state); + + if (client.features.settingsStore) { + return dispatch(patchMe({ + settings_store: { + [FE_NAME]: settings, + }, + })); + } else { + const accountUrl = getAccount(state, state.me as string)!.url; + + return updateAuthAccount(accountUrl, settings); + } + }; + const getLocale = (state: RootState, fallback = 'en') => { const localeWithVariant = (getSettings(state).get('locale') as string).replace('_', '-'); const locale = localeWithVariant.split('-')[0]; @@ -206,6 +240,7 @@ export { changeSettingImmediate, changeSetting, saveSettings, + updateSettingsStore, getLocale, type SettingsAction, }; diff --git a/src/features/developers/settings-store.tsx b/src/features/developers/settings-store.tsx index a212ceab32..15c7280f61 100644 --- a/src/features/developers/settings-store.tsx +++ b/src/features/developers/settings-store.tsx @@ -1,8 +1,7 @@ import React, { useState, useEffect } from 'react'; import { useIntl, FormattedMessage, defineMessages } from 'react-intl'; -import { patchMe } from 'soapbox/actions/me'; -import { FE_NAME, SETTINGS_UPDATE, changeSetting } from 'soapbox/actions/settings'; +import { SETTINGS_UPDATE, changeSetting, updateSettingsStore } from 'soapbox/actions/settings'; import List, { ListItem } from 'soapbox/components/list'; import { CardHeader, @@ -57,11 +56,7 @@ const SettingsStore: React.FC = () => { const settings = JSON.parse(rawJSON); setLoading(true); - dispatch(patchMe({ - pleroma_settings_store: { - [FE_NAME]: settings, - }, - })).then(response => { + dispatch(updateSettingsStore(settings)).then(() => { dispatch({ type: SETTINGS_UPDATE, settings }); setLoading(false); }).catch(error => { diff --git a/src/features/edit-profile/index.tsx b/src/features/edit-profile/index.tsx index 0efb36c492..eb6c2e07ef 100644 --- a/src/features/edit-profile/index.tsx +++ b/src/features/edit-profile/index.tsx @@ -215,7 +215,7 @@ const EditProfile: React.FC = () => { if (header.file !== undefined) params.header = header.file || ''; if (avatar.file !== undefined) params.avatar = avatar.file || ''; - promises.push(dispatch(patchMe(params))); + promises.push(dispatch(patchMe(params as any))); if (features.muteStrangers) { promises.push( diff --git a/src/features/onboarding/steps/avatar-selection-step.tsx b/src/features/onboarding/steps/avatar-selection-step.tsx index 23994ab7b4..e0b4051e4f 100644 --- a/src/features/onboarding/steps/avatar-selection-step.tsx +++ b/src/features/onboarding/steps/avatar-selection-step.tsx @@ -42,9 +42,7 @@ const AvatarSelectionStep = ({ onNext }: { onNext: () => void }) => { setSelectedFile(url); setSubmitting(true); - const formData = new FormData(); - formData.append('avatar', rawFile); - const credentials = dispatch(patchMe(formData)); + const credentials = dispatch(patchMe({ avatar: rawFile })); return Promise.all([credentials]).then(() => { setDisabled(false); diff --git a/src/features/onboarding/steps/cover-photo-selection-step.tsx b/src/features/onboarding/steps/cover-photo-selection-step.tsx index d3c1609554..f6347e8ccb 100644 --- a/src/features/onboarding/steps/cover-photo-selection-step.tsx +++ b/src/features/onboarding/steps/cover-photo-selection-step.tsx @@ -45,9 +45,7 @@ const CoverPhotoSelectionStep = ({ onNext }: { onNext: () => void }) => { setSelectedFile(url); setSubmitting(true); - const formData = new FormData(); - formData.append('header', file); - const credentials = dispatch(patchMe(formData)); + const credentials = dispatch(patchMe({ header: file })); Promise.all([credentials]).then(() => { setDisabled(false); diff --git a/src/reducers/settings.ts b/src/reducers/settings.ts index 1934fd34ac..17e810e81f 100644 --- a/src/reducers/settings.ts +++ b/src/reducers/settings.ts @@ -41,6 +41,7 @@ const settings = ( ): State => { switch (action.type) { case ME_FETCH_SUCCESS: + console.log('importing', action.me); return importSettings(state, action.me); case NOTIFICATIONS_FILTER_SET: case SEARCH_FILTER_SET: diff --git a/yarn.lock b/yarn.lock index efed0b7d93..311565f705 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8385,10 +8385,10 @@ pkg-types@^1.0.3: mlly "^1.2.0" pathe "^1.1.0" -pl-api@^0.0.17: - version "0.0.17" - resolved "https://registry.yarnpkg.com/pl-api/-/pl-api-0.0.17.tgz#4659be98c65bcf1cebab43b38b28a1f306c1eef4" - integrity sha512-qD/Qn+FGM5LX8y7Ud9mfnNMj8ZbXPGWs3Y2J3vVBAOxhkpIdhHX2JwETx08kPu1Mq7Kt3yTWDxREHSQc3XR10A== +pl-api@^0.0.18: + version "0.0.18" + resolved "https://registry.yarnpkg.com/pl-api/-/pl-api-0.0.18.tgz#23542323cb9450e4c084a38e411a8dc5f3e806f5" + integrity sha512-JYNR3hKO8bHUOnMNERCXwYj6PMNToY9uqPC5lFbe0vQry77ioHzaqiGzA4F1cK1nSSYZhDR41psuBqisvIp9kg== dependencies: blurhash "^2.0.5" http-link-header "^1.1.3"