Convert to Shared Preference Plugin to Sandy
Summary: per title In addition, this diff adds `startUnactivated` option to allow setting up `onSend` mock implementation. Reviewed By: mweststrate Differential Revision: D24477989 fbshipit-source-id: f913574ebacdd436e8511baa43744249a014e90b
This commit is contained in:
committed by
Facebook GitHub Bot
parent
467a6b16fb
commit
402ea2fc14
235
desktop/plugins/shared_preferences/src/index.tsx
Normal file
235
desktop/plugins/shared_preferences/src/index.tsx
Normal file
@@ -0,0 +1,235 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {
|
||||
ManagedTable,
|
||||
Text,
|
||||
Heading,
|
||||
FlexColumn,
|
||||
colors,
|
||||
FlexRow,
|
||||
ManagedDataInspector,
|
||||
styled,
|
||||
Select,
|
||||
} from 'flipper';
|
||||
import {PluginClient, createState, usePlugin, useValue} from 'flipper-plugin';
|
||||
import {clone} from 'lodash';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
type SharedPreferencesChangeEvent = {
|
||||
preferences: string;
|
||||
name: string;
|
||||
time: number;
|
||||
deleted: boolean;
|
||||
value?: any;
|
||||
};
|
||||
type SharedPreferences = Record<string, any>;
|
||||
type SharedPreferencesEntry = {
|
||||
preferences: SharedPreferences;
|
||||
changesList: Array<SharedPreferencesChangeEvent>;
|
||||
};
|
||||
|
||||
export type SetSharedPreferenceParams = {
|
||||
sharedPreferencesName: string;
|
||||
preferenceName: string;
|
||||
preferenceValue: any;
|
||||
};
|
||||
type DeleteSharedPreferenceParams = {
|
||||
sharedPreferencesName: string;
|
||||
preferenceName: string;
|
||||
};
|
||||
|
||||
type Events = {sharedPreferencesChange: SharedPreferencesChangeEvent};
|
||||
type Methods = {
|
||||
getAllSharedPreferences: (params: {}) => Promise<
|
||||
Record<string, SharedPreferences>
|
||||
>;
|
||||
setSharedPreference: (
|
||||
params: SetSharedPreferenceParams,
|
||||
) => Promise<SharedPreferences>;
|
||||
deleteSharedPreference: (
|
||||
params: DeleteSharedPreferenceParams,
|
||||
) => Promise<SharedPreferences>;
|
||||
};
|
||||
|
||||
export function plugin(client: PluginClient<Events, Methods>) {
|
||||
const selectedPreferences = createState<string | null>(null, {
|
||||
persist: 'selectedPreferences',
|
||||
});
|
||||
const setSelectedPreferences = (value: string) =>
|
||||
selectedPreferences.set(value);
|
||||
const sharedPreferences = createState<Record<string, SharedPreferencesEntry>>(
|
||||
{},
|
||||
{persist: 'sharedPreferences'},
|
||||
);
|
||||
|
||||
function updateSharedPreferences(update: {name: string; preferences: any}) {
|
||||
if (selectedPreferences.get() == null) {
|
||||
selectedPreferences.set(update.name);
|
||||
}
|
||||
sharedPreferences.update((draft) => {
|
||||
const entry = draft[update.name] || {changesList: []};
|
||||
entry.preferences = update.preferences;
|
||||
draft[update.name] = entry;
|
||||
});
|
||||
}
|
||||
|
||||
async function setSharedPreference(params: SetSharedPreferenceParams) {
|
||||
const results = await client.send('setSharedPreference', params);
|
||||
updateSharedPreferences({
|
||||
name: params.sharedPreferencesName,
|
||||
preferences: results,
|
||||
});
|
||||
}
|
||||
async function deleteSharedPreference(params: DeleteSharedPreferenceParams) {
|
||||
const results = await client.send('deleteSharedPreference', params);
|
||||
updateSharedPreferences({
|
||||
name: params.sharedPreferencesName,
|
||||
preferences: results,
|
||||
});
|
||||
}
|
||||
|
||||
client.onMessage('sharedPreferencesChange', (change) =>
|
||||
sharedPreferences.update((draft) => {
|
||||
const entry = draft[change.preferences];
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
if (change.deleted) {
|
||||
delete entry.preferences[change.name];
|
||||
} else {
|
||||
entry.preferences[change.name] = change.value;
|
||||
}
|
||||
entry.changesList.unshift(change);
|
||||
draft[change.preferences] = entry;
|
||||
}),
|
||||
);
|
||||
client.onConnect(async () => {
|
||||
const results = await client.send('getAllSharedPreferences', {});
|
||||
Object.entries(results).forEach(([name, prefs]) =>
|
||||
updateSharedPreferences({name: name, preferences: prefs}),
|
||||
);
|
||||
});
|
||||
|
||||
return {
|
||||
selectedPreferences,
|
||||
sharedPreferences,
|
||||
setSelectedPreferences,
|
||||
setSharedPreference,
|
||||
deleteSharedPreference,
|
||||
};
|
||||
}
|
||||
|
||||
const CHANGELOG_COLUMNS = {
|
||||
event: {value: 'Event'},
|
||||
name: {value: 'Name'},
|
||||
value: {value: 'Value'},
|
||||
};
|
||||
const CHANGELOG_COLUMN_SIZES = {
|
||||
event: '30%',
|
||||
name: '30%',
|
||||
value: '30%',
|
||||
};
|
||||
|
||||
const UPDATED_LABEL = <Text color={colors.lime}>Updated</Text>;
|
||||
const DELETED_LABEL = <Text color={colors.cherry}>Deleted</Text>;
|
||||
|
||||
const InspectorColumn = styled(FlexColumn)({flexGrow: 0.2});
|
||||
const ChangelogColumn = styled(FlexColumn)({
|
||||
flexGrow: 0.8,
|
||||
paddingLeft: '16px',
|
||||
});
|
||||
const RootColumn = styled(FlexColumn)({
|
||||
paddingLeft: '16px',
|
||||
paddingRight: '16px',
|
||||
paddingTop: '16px',
|
||||
});
|
||||
|
||||
export function Component() {
|
||||
const instance = usePlugin(plugin);
|
||||
const selectedPreferences = useValue(instance.selectedPreferences);
|
||||
const sharedPreferences = useValue(instance.sharedPreferences);
|
||||
|
||||
if (selectedPreferences == null) {
|
||||
return null;
|
||||
}
|
||||
const entry = sharedPreferences[selectedPreferences];
|
||||
if (entry == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<RootColumn grow={true}>
|
||||
<Heading>
|
||||
<span style={{marginRight: '16px'}}>Preference File</span>
|
||||
<Select
|
||||
options={Object.keys(sharedPreferences)
|
||||
.sort((a, b) => (a.toLowerCase() > b.toLowerCase() ? 1 : -1))
|
||||
.reduce((obj, item) => {
|
||||
obj[item] = item;
|
||||
return obj;
|
||||
}, {} as Record<string, string>)}
|
||||
selected={selectedPreferences}
|
||||
onChange={instance.setSelectedPreferences}
|
||||
/>
|
||||
</Heading>
|
||||
<FlexRow grow={true} scrollable={true}>
|
||||
<InspectorColumn>
|
||||
<Heading>Inspector</Heading>
|
||||
<ManagedDataInspector
|
||||
data={entry.preferences}
|
||||
setValue={async (path: Array<string>, value: any) => {
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
const values = entry.preferences;
|
||||
let newValue = value;
|
||||
if (path.length === 2 && values) {
|
||||
newValue = clone(values[path[0]]);
|
||||
newValue[path[1]] = value;
|
||||
}
|
||||
await instance.setSharedPreference({
|
||||
sharedPreferencesName: selectedPreferences,
|
||||
preferenceName: path[0],
|
||||
preferenceValue: newValue,
|
||||
});
|
||||
}}
|
||||
onDelete={async (path: Array<string>) =>
|
||||
await instance.deleteSharedPreference({
|
||||
sharedPreferencesName: selectedPreferences,
|
||||
preferenceName: path[0],
|
||||
})
|
||||
}
|
||||
/>
|
||||
</InspectorColumn>
|
||||
<ChangelogColumn>
|
||||
<Heading>Changelog</Heading>
|
||||
<ManagedTable
|
||||
columnSizes={CHANGELOG_COLUMN_SIZES}
|
||||
columns={CHANGELOG_COLUMNS}
|
||||
rowLineHeight={26}
|
||||
rows={entry.changesList.map((element, index) => {
|
||||
return {
|
||||
columns: {
|
||||
event: {
|
||||
value: element.deleted ? DELETED_LABEL : UPDATED_LABEL,
|
||||
},
|
||||
name: {value: element.name},
|
||||
value: {value: String(element.value)},
|
||||
},
|
||||
key: String(index),
|
||||
};
|
||||
})}
|
||||
/>
|
||||
</ChangelogColumn>
|
||||
</FlexRow>
|
||||
</RootColumn>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user