diff --git a/android/src/main/java/com/facebook/flipper/plugins/sharedpreferences/SharedPreferencesFlipperPlugin.java b/android/src/main/java/com/facebook/flipper/plugins/sharedpreferences/SharedPreferencesFlipperPlugin.java index 9ccc26da8..e46f7772d 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/sharedpreferences/SharedPreferencesFlipperPlugin.java +++ b/android/src/main/java/com/facebook/flipper/plugins/sharedpreferences/SharedPreferencesFlipperPlugin.java @@ -229,6 +229,22 @@ public class SharedPreferencesFlipperPlugin implements FlipperPlugin { 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 diff --git a/desktop/app/src/ui/components/data-inspector/DataInspector.tsx b/desktop/app/src/ui/components/data-inspector/DataInspector.tsx index 2801d561b..cf642cccb 100644 --- a/desktop/app/src/ui/components/data-inspector/DataInspector.tsx +++ b/desktop/app/src/ui/components/data-inspector/DataInspector.tsx @@ -69,6 +69,8 @@ const nameTooltipOptions: TooltipOptions = { export type DataInspectorSetValue = (path: Array, val: any) => void; +export type DataInspectorDeleteValue = (path: Array) => void; + export type DataInspectorExpanded = { [key: string]: boolean; }; @@ -122,6 +124,10 @@ type DataInspectorProps = { * Callback whenever the current expanded paths is changed. */ 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. */ @@ -351,6 +357,7 @@ export default class DataInspector extends Component { nextProps.depth !== props.depth || !deepEqual(nextProps.path, props.path) || nextProps.onExpanded !== props.onExpanded || + nextProps.onDelete !== props.onDelete || nextProps.setValue !== props.setValue ); } @@ -399,6 +406,15 @@ export default class DataInspector extends Component { this.setExpanded(this.props.path, !isExpanded); }; + handleDelete = (path: Array) => { + const onDelete = this.props.onDelete; + if (!onDelete) { + return; + } + + onDelete(path); + }; + extractValue = (data: any, depth: number) => { let res; @@ -424,6 +440,7 @@ export default class DataInspector extends Component { extractValue, name, onExpanded, + onDelete, path, ancestry, collapsed, @@ -508,6 +525,7 @@ export default class DataInspector extends Component { expanded={expandedPaths} collapsed={collapsed} onExpanded={onExpanded} + onDelete={onDelete} path={path.concat(key)} depth={depth + 1} key={key} @@ -628,6 +646,13 @@ export default class DataInspector extends Component { }, ); + if (!isExpandable && onDelete) { + contextMenuItems.push({ + label: 'Delete', + click: () => this.handleDelete(this.props.path), + }); + } + return ( , val: any) => void; + /** + * Callback when a delete action is invoked. + */ + onDelete?: (path: Array) => void; /** * Whether all objects and arrays should be collapsed by default. */ @@ -80,6 +84,7 @@ export default class ManagedDataInspector extends PureComponent< setValue={this.props.setValue} expanded={this.state.expanded} onExpanded={this.onExpanded} + onDelete={this.props.onDelete} expandRoot={this.props.expandRoot} collapsed={this.props.collapsed} tooltips={this.props.tooltips} diff --git a/desktop/plugins/shared_preferences/index.js b/desktop/plugins/shared_preferences/index.js index fe3b66790..fc993b29a 100644 --- a/desktop/plugins/shared_preferences/index.js +++ b/desktop/plugins/shared_preferences/index.js @@ -209,6 +209,21 @@ export default class extends FlipperPlugin { }); }; + onSharedPreferencesDeleted = (path: Array) => { + 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() { const selectedPreferences = this.state.selectedPreferences; if (selectedPreferences == null) { @@ -241,6 +256,7 @@ export default class extends FlipperPlugin { diff --git a/iOS/Plugins/FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.m b/iOS/Plugins/FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.m index ced17e17a..d995fb874 100644 --- a/iOS/Plugins/FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.m +++ b/iOS/Plugins/FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.m @@ -82,6 +82,15 @@ static NSString* const kAppSuiteUserDefaultsName = @"App Suite UserDefaults"; forKey:preferenceName]; [responder success:[sharedPreferences dictionaryRepresentation]]; }]; + + [connection receive:@"deleteSharedPreference" + withBlock:^(NSDictionary* params, id responder) { + NSUserDefaults* sharedPreferences = + [self sharedPreferencesForParams:params]; + NSString* preferenceName = params[@"preferenceName"]; + [sharedPreferences removeObjectForKey:preferenceName]; + [responder success:[sharedPreferences dictionaryRepresentation]]; + }]; } - (void)didDisconnect {