Offline: persist Soapbox config (eg frontend_configurations or soapbox.json)
This commit is contained in:
parent
615cdc5c66
commit
7259ed58fb
5 changed files with 67 additions and 13 deletions
|
@ -22,7 +22,7 @@ const getMeUrl = state => {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Figure out the appropriate instance to fetch depending on the state
|
// Figure out the appropriate instance to fetch depending on the state
|
||||||
const getHost = state => {
|
export const getHost = state => {
|
||||||
const accountUrl = getMeUrl(state) || getAuthUserUrl(state);
|
const accountUrl = getMeUrl(state) || getAuthUserUrl(state);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -2,10 +2,16 @@ import api, { staticClient } from '../api';
|
||||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
||||||
import { getFeatures } from 'soapbox/utils/features';
|
import { getFeatures } from 'soapbox/utils/features';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
|
import { getHost } from 'soapbox/actions/instance';
|
||||||
|
import KVStore from 'soapbox/storage/kv_store';
|
||||||
|
|
||||||
export const SOAPBOX_CONFIG_REQUEST_SUCCESS = 'SOAPBOX_CONFIG_REQUEST_SUCCESS';
|
export const SOAPBOX_CONFIG_REQUEST_SUCCESS = 'SOAPBOX_CONFIG_REQUEST_SUCCESS';
|
||||||
export const SOAPBOX_CONFIG_REQUEST_FAIL = 'SOAPBOX_CONFIG_REQUEST_FAIL';
|
export const SOAPBOX_CONFIG_REQUEST_FAIL = 'SOAPBOX_CONFIG_REQUEST_FAIL';
|
||||||
|
|
||||||
|
export const SOAPBOX_CONFIG_REMEMBER_REQUEST = 'SOAPBOX_CONFIG_REMEMBER_REQUEST';
|
||||||
|
export const SOAPBOX_CONFIG_REMEMBER_SUCCESS = 'SOAPBOX_CONFIG_REMEMBER_SUCCESS';
|
||||||
|
export const SOAPBOX_CONFIG_REMEMBER_FAIL = 'SOAPBOX_CONFIG_REMEMBER_FAIL';
|
||||||
|
|
||||||
const allowedEmoji = ImmutableList([
|
const allowedEmoji = ImmutableList([
|
||||||
'👍',
|
'👍',
|
||||||
'❤',
|
'❤',
|
||||||
|
@ -61,46 +67,71 @@ export const getSoapboxConfig = createSelector([
|
||||||
return makeDefaultConfig(features).merge(soapbox);
|
return makeDefaultConfig(features).merge(soapbox);
|
||||||
});
|
});
|
||||||
|
|
||||||
export function fetchSoapboxConfig() {
|
export function rememberSoapboxConfig(host) {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
dispatch({ type: SOAPBOX_CONFIG_REMEMBER_REQUEST, host });
|
||||||
|
return KVStore.getItemOrError(`soapbox_config:${host}`).then(soapboxConfig => {
|
||||||
|
dispatch({ type: SOAPBOX_CONFIG_REMEMBER_SUCCESS, host, soapboxConfig });
|
||||||
|
return soapboxConfig;
|
||||||
|
}).catch(error => {
|
||||||
|
dispatch({ type: SOAPBOX_CONFIG_REMEMBER_FAIL, host, error, skipAlert: true });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchSoapboxConfig(host) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
api(getState).get('/api/pleroma/frontend_configurations').then(response => {
|
api(getState).get('/api/pleroma/frontend_configurations').then(response => {
|
||||||
if (response.data.soapbox_fe) {
|
if (response.data.soapbox_fe) {
|
||||||
dispatch(importSoapboxConfig(response.data.soapbox_fe));
|
dispatch(importSoapboxConfig(response.data.soapbox_fe, host));
|
||||||
} else {
|
} else {
|
||||||
dispatch(fetchSoapboxJson());
|
dispatch(fetchSoapboxJson(host));
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(fetchSoapboxJson());
|
dispatch(fetchSoapboxJson(host));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchSoapboxJson() {
|
// Tries to remember the config from browser storage before fetching it
|
||||||
|
export function loadSoapboxConfig() {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
const host = getHost(getState());
|
||||||
|
|
||||||
|
return dispatch(rememberSoapboxConfig(host)).finally(() => {
|
||||||
|
return dispatch(fetchSoapboxConfig(host));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchSoapboxJson(host) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
staticClient.get('/instance/soapbox.json').then(({ data }) => {
|
staticClient.get('/instance/soapbox.json').then(({ data }) => {
|
||||||
if (!isObject(data)) throw 'soapbox.json failed';
|
if (!isObject(data)) throw 'soapbox.json failed';
|
||||||
dispatch(importSoapboxConfig(data));
|
dispatch(importSoapboxConfig(data, host));
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(soapboxConfigFail(error));
|
dispatch(soapboxConfigFail(error, host));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function importSoapboxConfig(soapboxConfig) {
|
export function importSoapboxConfig(soapboxConfig, host) {
|
||||||
if (!soapboxConfig.brandColor) {
|
if (!soapboxConfig.brandColor) {
|
||||||
soapboxConfig.brandColor = '#0482d8';
|
soapboxConfig.brandColor = '#0482d8';
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
type: SOAPBOX_CONFIG_REQUEST_SUCCESS,
|
type: SOAPBOX_CONFIG_REQUEST_SUCCESS,
|
||||||
soapboxConfig,
|
soapboxConfig,
|
||||||
|
host,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function soapboxConfigFail(error) {
|
export function soapboxConfigFail(error, host) {
|
||||||
return {
|
return {
|
||||||
type: SOAPBOX_CONFIG_REQUEST_FAIL,
|
type: SOAPBOX_CONFIG_REQUEST_FAIL,
|
||||||
error,
|
error,
|
||||||
skipAlert: true,
|
skipAlert: true,
|
||||||
|
host,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { preload } from '../actions/preload';
|
||||||
import { IntlProvider } from 'react-intl';
|
import { IntlProvider } from 'react-intl';
|
||||||
import ErrorBoundary from '../components/error_boundary';
|
import ErrorBoundary from '../components/error_boundary';
|
||||||
import { loadInstance } from 'soapbox/actions/instance';
|
import { loadInstance } from 'soapbox/actions/instance';
|
||||||
import { fetchSoapboxConfig } from 'soapbox/actions/soapbox';
|
import { loadSoapboxConfig } from 'soapbox/actions/soapbox';
|
||||||
import { fetchMe } from 'soapbox/actions/me';
|
import { fetchMe } from 'soapbox/actions/me';
|
||||||
import PublicLayout from 'soapbox/features/public_layout';
|
import PublicLayout from 'soapbox/features/public_layout';
|
||||||
import { getSettings } from 'soapbox/actions/settings';
|
import { getSettings } from 'soapbox/actions/settings';
|
||||||
|
@ -43,7 +43,7 @@ store.dispatch(fetchMe())
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// Postpone for authenticated fetch
|
// Postpone for authenticated fetch
|
||||||
store.dispatch(loadInstance());
|
store.dispatch(loadInstance());
|
||||||
store.dispatch(fetchSoapboxConfig());
|
store.dispatch(loadSoapboxConfig());
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
import { PLEROMA_PRELOAD_IMPORT } from 'soapbox/actions/preload';
|
import { PLEROMA_PRELOAD_IMPORT } from 'soapbox/actions/preload';
|
||||||
import { Map as ImmutableMap, fromJS } from 'immutable';
|
import { Map as ImmutableMap, fromJS } from 'immutable';
|
||||||
import { ConfigDB } from 'soapbox/utils/config_db';
|
import { ConfigDB } from 'soapbox/utils/config_db';
|
||||||
|
import KVStore from 'soapbox/storage/kv_store';
|
||||||
|
|
||||||
const initialState = ImmutableMap();
|
const initialState = ImmutableMap();
|
||||||
|
|
||||||
|
@ -36,12 +37,23 @@ const preloadImport = (state, action) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const persistSoapboxConfig = (soapboxConfig, host) => {
|
||||||
|
if (host) {
|
||||||
|
KVStore.setItem(`soapbox_config:${host}`, soapboxConfig.toJS()).catch(console.error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const importSoapboxConfig = (state, soapboxConfig, host) => {
|
||||||
|
persistSoapboxConfig(soapboxConfig, host);
|
||||||
|
return soapboxConfig;
|
||||||
|
};
|
||||||
|
|
||||||
export default function soapbox(state = initialState, action) {
|
export default function soapbox(state = initialState, action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case PLEROMA_PRELOAD_IMPORT:
|
case PLEROMA_PRELOAD_IMPORT:
|
||||||
return preloadImport(state, action);
|
return preloadImport(state, action);
|
||||||
case SOAPBOX_CONFIG_REQUEST_SUCCESS:
|
case SOAPBOX_CONFIG_REQUEST_SUCCESS:
|
||||||
return fromJS(action.soapboxConfig);
|
return importSoapboxConfig(state, fromJS(action.soapboxConfig), action.host);
|
||||||
case SOAPBOX_CONFIG_REQUEST_FAIL:
|
case SOAPBOX_CONFIG_REQUEST_FAIL:
|
||||||
return fallbackState.mergeDeep(state);
|
return fallbackState.mergeDeep(state);
|
||||||
case ADMIN_CONFIG_UPDATE_SUCCESS:
|
case ADMIN_CONFIG_UPDATE_SUCCESS:
|
||||||
|
|
11
app/soapbox/utils/instance.js
Normal file
11
app/soapbox/utils/instance.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
export const getHost = instance => {
|
||||||
|
try {
|
||||||
|
return new URL(instance.get('uri')).host;
|
||||||
|
} catch {
|
||||||
|
try {
|
||||||
|
return new URL(`https://${instance.get('uri')}`).host;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in a new issue