Add support for deleting a shared preference (#1018)

Summary:
This change makes it possible to remove preferences. I also added a `Delete` context menu option to `DataInspector` because I needed it to implement this feature. passy confirmed that it makes sense to add this because delete is a common action.

Fixes https://github.com/facebook/flipper/issues/451
Pull Request resolved: https://github.com/facebook/flipper/pull/1018

Reviewed By: jknoxville

Differential Revision: D21086308

Pulled By: passy

fbshipit-source-id: 551ff0908d5e6c93f58d6012b42e1ee3531de997
This commit is contained in:
Michal Zielinski
2020-04-17 08:58:14 -07:00
committed by Facebook GitHub Bot
parent 9b8974eeb3
commit 2d1870cf7d
5 changed files with 71 additions and 0 deletions

View File

@@ -229,6 +229,22 @@ public class SharedPreferencesFlipperPlugin implements FlipperPlugin {
responder.success(getFlipperObjectFor(sharedPreferencesName)); responder.success(getFlipperObjectFor(sharedPreferencesName));
} }
}); });
connection.receive(
"deleteSharedPreference",
new FlipperReceiver() {
@Override
public void onReceive(FlipperObject params, FlipperResponder responder)
throws IllegalArgumentException {
String sharedPreferencesName = params.getString("sharedPreferencesName");
String preferenceName = params.getString("preferenceName");
SharedPreferences sharedPrefs = getSharedPreferencesFor(sharedPreferencesName);
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.remove(preferenceName);
editor.apply();
responder.success(getFlipperObjectFor(sharedPreferencesName));
}
});
} }
@Override @Override

View File

@@ -69,6 +69,8 @@ const nameTooltipOptions: TooltipOptions = {
export type DataInspectorSetValue = (path: Array<string>, val: any) => void; export type DataInspectorSetValue = (path: Array<string>, val: any) => void;
export type DataInspectorDeleteValue = (path: Array<string>) => void;
export type DataInspectorExpanded = { export type DataInspectorExpanded = {
[key: string]: boolean; [key: string]: boolean;
}; };
@@ -122,6 +124,10 @@ type DataInspectorProps = {
* Callback whenever the current expanded paths is changed. * Callback whenever the current expanded paths is changed.
*/ */
onExpanded?: ((expanded: DataInspectorExpanded) => void) | undefined | null; onExpanded?: ((expanded: DataInspectorExpanded) => void) | undefined | null;
/**
* Callback whenever delete action is invoked on current path.
*/
onDelete?: DataInspectorDeleteValue | undefined | null;
/** /**
* Callback when a value is edited. * Callback when a value is edited.
*/ */
@@ -351,6 +357,7 @@ export default class DataInspector extends Component<DataInspectorProps> {
nextProps.depth !== props.depth || nextProps.depth !== props.depth ||
!deepEqual(nextProps.path, props.path) || !deepEqual(nextProps.path, props.path) ||
nextProps.onExpanded !== props.onExpanded || nextProps.onExpanded !== props.onExpanded ||
nextProps.onDelete !== props.onDelete ||
nextProps.setValue !== props.setValue nextProps.setValue !== props.setValue
); );
} }
@@ -399,6 +406,15 @@ export default class DataInspector extends Component<DataInspectorProps> {
this.setExpanded(this.props.path, !isExpanded); this.setExpanded(this.props.path, !isExpanded);
}; };
handleDelete = (path: Array<string>) => {
const onDelete = this.props.onDelete;
if (!onDelete) {
return;
}
onDelete(path);
};
extractValue = (data: any, depth: number) => { extractValue = (data: any, depth: number) => {
let res; let res;
@@ -424,6 +440,7 @@ export default class DataInspector extends Component<DataInspectorProps> {
extractValue, extractValue,
name, name,
onExpanded, onExpanded,
onDelete,
path, path,
ancestry, ancestry,
collapsed, collapsed,
@@ -508,6 +525,7 @@ export default class DataInspector extends Component<DataInspectorProps> {
expanded={expandedPaths} expanded={expandedPaths}
collapsed={collapsed} collapsed={collapsed}
onExpanded={onExpanded} onExpanded={onExpanded}
onDelete={onDelete}
path={path.concat(key)} path={path.concat(key)}
depth={depth + 1} depth={depth + 1}
key={key} key={key}
@@ -628,6 +646,13 @@ export default class DataInspector extends Component<DataInspectorProps> {
}, },
); );
if (!isExpandable && onDelete) {
contextMenuItems.push({
label: 'Delete',
click: () => this.handleDelete(this.props.path),
});
}
return ( return (
<BaseContainer <BaseContainer
depth={depth} depth={depth}

View File

@@ -36,6 +36,10 @@ type ManagedDataInspectorProps = {
* Callback when a value is edited. * Callback when a value is edited.
*/ */
setValue?: (path: Array<string>, val: any) => void; setValue?: (path: Array<string>, val: any) => void;
/**
* Callback when a delete action is invoked.
*/
onDelete?: (path: Array<string>) => void;
/** /**
* Whether all objects and arrays should be collapsed by default. * Whether all objects and arrays should be collapsed by default.
*/ */
@@ -80,6 +84,7 @@ export default class ManagedDataInspector extends PureComponent<
setValue={this.props.setValue} setValue={this.props.setValue}
expanded={this.state.expanded} expanded={this.state.expanded}
onExpanded={this.onExpanded} onExpanded={this.onExpanded}
onDelete={this.props.onDelete}
expandRoot={this.props.expandRoot} expandRoot={this.props.expandRoot}
collapsed={this.props.collapsed} collapsed={this.props.collapsed}
tooltips={this.props.tooltips} tooltips={this.props.tooltips}

View File

@@ -209,6 +209,21 @@ export default class extends FlipperPlugin<SharedPreferencesState> {
}); });
}; };
onSharedPreferencesDeleted = (path: Array<string>) => {
this.client
.call('deleteSharedPreference', {
sharedPreferencesName: this.state.selectedPreferences,
preferenceName: path[0],
})
.then((results: SharedPreferences) => {
const update = {
name: this.state.selectedPreferences,
preferences: results,
};
this.dispatchAction({update, type: 'UpdateSharedPreferences'});
});
};
render() { render() {
const selectedPreferences = this.state.selectedPreferences; const selectedPreferences = this.state.selectedPreferences;
if (selectedPreferences == null) { if (selectedPreferences == null) {
@@ -241,6 +256,7 @@ export default class extends FlipperPlugin<SharedPreferencesState> {
<ManagedDataInspector <ManagedDataInspector
data={entry.preferences} data={entry.preferences}
setValue={this.onSharedPreferencesChanged} setValue={this.onSharedPreferencesChanged}
onDelete={this.onSharedPreferencesDeleted}
/> />
</InspectorColumn> </InspectorColumn>
<ChangelogColumn> <ChangelogColumn>

View File

@@ -82,6 +82,15 @@ static NSString* const kAppSuiteUserDefaultsName = @"App Suite UserDefaults";
forKey:preferenceName]; forKey:preferenceName];
[responder success:[sharedPreferences dictionaryRepresentation]]; [responder success:[sharedPreferences dictionaryRepresentation]];
}]; }];
[connection receive:@"deleteSharedPreference"
withBlock:^(NSDictionary* params, id<FlipperResponder> responder) {
NSUserDefaults* sharedPreferences =
[self sharedPreferencesForParams:params];
NSString* preferenceName = params[@"preferenceName"];
[sharedPreferences removeObjectForKey:preferenceName];
[responder success:[sharedPreferences dictionaryRepresentation]];
}];
} }
- (void)didDisconnect { - (void)didDisconnect {