react-native-ios-context-menu/docs/TODO.md
Dominic Go e87901f363 📝 Update TODO
2021-11-21 06:18:26 +08:00

15 KiB
Raw Blame History

TODO

Unsorted/Misc

  • Implement: ContextMenu — Add support for UIDefferedElement.

  • Refactor: Use structs instead of classes for holding configuration for making the menu items.`

  • Cleanup: Remove print logs.


  • Refactor: Update logic for handling images.
    • Copy over RNIImageItem impl. from react-native-ios-navigator.
    • Rename IconConfig type to IconConfigDeprecated.
    • Make the icon property accept both IconConfigDeprecated and ImageItemConfig.
    • Then in native, map IconConfigDeprecated to ImageItemConfig.
    • Then use RNIImageItem to create the icon images for the context menu.

  • Refactor: Refactor to use typescript + add type annotations.
  • Refactor: Refactor example to use typescript.

  • Docs: Update documentation sections

    • Remove numbered subsections.

    • Move links to files out of the section title.

    • Temporarily strip out links to section (i.e. replace with PLACEHOLDER_LINK).

    • Add versions table.

    • Remove collapsable sections.


  • Sync: Import the core libraries in react-native-ios-context-menu.
    • Import RNIImageItem and update RCTMenuIcon to use it.

  • Implement: Add support for targeted previews on text (i.e. similar to safari).
  • Implement: Control ContextMenuView via context and create useContextMenuViewContext hook.
  • Implement: Subscribe to ContextMenuView events via event emitter from context.
  • Implement: Implement ContextMenuView event hook (i.e. useContextMenuViewEvents hook).

  • Read apple documentation to find any new changes added.


For Next Major Version

  • Cleanup: Breaking Change — Remove legacy support for icon config shorthand/shortcut that was added temporarily when migrating between an older version of this library.


Completed

Version: next

  • Bugfix: Fix memory leak
    • (Commit: 6ddabae) Partially fix memory leak by performing cleanup during reload + when the view is unmounted.
    • (Commit: 19533b2) Use RNIWrapperView for the menu preview.
    • (Commit: c45c576) Fix menu preview memory leak,

  • (Commit: 4c75563) Bugfix: Fix menu action subtitles no longer working on iOS 15.

    • Example #13 — Setting discoverabilityTitle no longer does anything.
    • In iOS 13, this used to show a subtitle blurb below the menu item title. In iOS 15, it no longer displays the subtitle.
    • In iOS 15, there's a new property added called UIMenuElement.subtitle.

  • Refactor: Update to use RNIImageItem for the menu icons.
    • (Commit: 836f0a3) Copy over RNIImageItem impl. from react-native-ios-navigator.
    • (Commit: 97fa40c) Refactor to use RNIImageItem for menu item icon.
    • (Commit: e02d96e) Copy over ImageItemConfig types from react-native-ios-navigator.
    • (Commit: e176438) Update types for menu config to accept ImageItemConfig.

Version: 1.4.0

  • (Commit: a0b008c) Migrate project to use the new template generated by create-react-native-library and react-native-builder-bob.
    • Example app no longer builds, but the library still works when installed on a newly created react-native app. The example project may be incompatible with Xcode 13.1.
    • After migrating the project to the new template, the example app now builds + run on iOS 15.

  • (Commit: d1c8277) Sync: Update UIColor+Helpers.swift to use the newer code in react-native-ios-context-menu.
  • (Commit: 59d4faf) Refactor: Migrate Extension+Init-related types to use failable initializers instead of static functions.
  • (Commit: 7bb8148) Cleanup: Update MARK comments in native code.
  • (Commit: 873b61a) Cleanup: Cleanup swift types (e.g. NSString -> String).
  • (Commit: ebfa1cc) Cleanup: Remove RCTSwiftLog + usage.
  • (Commit: 3702dfc) Refactor: Replace RCT prefix with RNI.
  • (Commit: 2102840) Refactor: Extract RNIContextMenuView native component to its own separate file.
  • (Commit: 3fb4faa) Refactor: Extract RNIContextMenuButton native component to its own separate file.
  • (Commit: 023f8e7) Implement: Types — Add type declaration for MenuConfig and related types.
  • (Commit: 6768b32) Implement: Types — Add type declaration for MenuPreviewConfig and related types.
  • (Commit: 01089f0) Implement: Types — Add type declaration for IconConfig and related types.
  • (Commit: 0d71080) Refactor: Extract constants (e.g. isContextMenuButtonSupported, isContextMenuViewSupported) to their own separate file.

  • Implement: Types — Add type declaration for ContextMenuView
    • (Commit: 8c72054) Implement: Types — Migrate ContextMenuView component to use typescript and partially added type declarations.
    • (Commit: 348d2f9) Implement: Types — Add type declaration for ContextMenuView events.

  • (Commit: e0bc64f) Implement: Types — Add type declaration for ContextMenuButton
  • (Commit: 25bf0b2) Implement: Types — Partially add type declaration for ActionSheetFallback
  • (Commit: 47a97bc) Implement: Types — Add type declaration for Helpers


Archived/Abandoned

  • Docs: In the MenuAction Object section, add example object with comments.
  • Docs: In the MenuConfig Object section, add example object with comments.
  • Docs: Create collapsable "Table of Contents"
  • Docs: Add README.md in example directory

  • ContextMenuButton: Add SystemImage component for creating a UIImage that uses SF Icons (Research first if the built-in image component already supports this).
  • ContextMenuButton: Add example for wrapNativeComponent prop, i.e. example for using a different "button" component.

  • ContextMenuView: Custom Preview - Add support for setting an image as the custom preview. Use the built-in Image react native component to handle setting the image source + sizing. Receive the image as a child from RCTContextMenuView and cast it to RCTImage if necessary. The image will then be wrapped inside a view controller and is set as the UIMenu's preview target. The view should be resized to fit the screen.

  • Test: ContextMenuView and ContextMenuButton on different react native versions
    • Test on 0.60
    • Test on 0.61
    • Test on 0.62
    • Test on 0.63.3
    • Test on 0.63.4
  • Test: react-native-context-menu uses autolinking for installation. Check if this library will work on older react-native versions prior to 0.60 i.e test ContextMenuView and ContextMenuButton on react native versions older than 0.60
    • Test on 0.59
    • Test on 0.58

  • Submit a PR to the RN repo — Update RN template to fix Undefined Symbol
  • Update PreviewConfig.previewSize to support passing in a size object, e.g. {width: 100, height: 100}
  • Docs: Fix grammar/spelling errors
  • Docs: Test/Fix jump links
  • Attach RN touch handler to context menu
  • Impl. support for icon weight

  • Implement: ActionSheetModule to display an "Action Sheet" menu via UIAlertController.

    • Reference: Article in the apple developer about "Alerts and Action Sheets"

    • Reference: ActionSheetIOS JS code. The native module is called RCTActionSheetManager (link to JS native module, and link to native code)

    • Reference: @react-native-menu/menu library has a very good looking ActionSheet fallback with icons and disabled menu actions.


  • ContextMenu : Add support for UIDefferedElement

    • In MenuConfig.menuItems property or in the menuConfig prop, if an object has a property called defferedKey, then it means we want to create a UIDefferedElement element.

    • Impl. onRequestDefferedElement function. This function is called whenever a UIDefferedElement item needs to be loaded.

      • This function will receive a defferedKey. This function must return a promise, i.e. either a MenuConfig or MenuAction object.
      • If the returned promise is a MenuAction object, it will use defferedKey for the actionKey property.
      • In this function, based on the defferedKey it must return a corresponding MenuConfig/MenuAction object. If null is returned, then it means it failed.
      • This function is invoked from the native side. Native UI component NativeCommands don't natively support promises, so a workaround must be used based on request callbacks (like the one i used on react-native-ios-modal). But NativeModule functions has support for promises built in.
        • We can use findNodeHandle(this.nativeCompRef) to get a node handle. Then we can use self.bridge.uiManager.view(forReactTag: node) to get a ref to the component. Then we cast it to the correct type: component as? RCTContextMenuView and then call the completion function for the corresponding UIDefferedElement, something like: contextMenuView.resolveDefferedMenuElement(for: defferedKey, item: menuElementDict)
      • We need to create a class to create a UIDeferredMenuElement. It will extend RNIMenuElement and can be init from a dictionary. Probably name it something like: RCTMenuDefferedItem. It will have one property: defferedKey
        • RNIMenuItem.createMenu function must be updated to also handle creating a RCTMenuDefferedItem item.
      • On the native side when we create a UIDeferredMenuElement we do this: UIDeferredMenuElement { completion in self.completionDict[defferedKey] = completion }, and then invoke a RN event: self.onRequestDefferedElement([defferedKey: defferedKey]).
        • onRequestDefferedElement event prop will be invoked. We wait for the promise to return some value and then call a NativeModule function.
        • The NativeModule function will probably look like this: ContextMenuViewModule.resolveDefferedMenuElement({nodeHandle, defferedKey, menuItem});
        • Completion handlers will be stored in a dictionary. I'm not sure if I can use NSMapTable. I can use a plain NSDictionary but if I accidentally forget to cleanup (i.e. remove the completion handler from the dict) then that completion handler will be retained, causing a memory leak.
          • Completion handlers, i.e. closures, are reference types. If I assign it to NSMapTable with valueOptions: .weakMemory, will it be automatically be released when it's no longer used? Will it be retained while it's in use or will it be released the moment i add it to NSMapTable because nothing is using it? Technically, it is in use because it's in UIDeferredMenuElement argument (so the ref count should increase?)


Completed Archive

  • Docs: First remove all the links that point to the examples directory or links to different section. Highlight them in yellow then replace the highlighted text in the documentation with the new/updated section/examples links.
    • Move ContextMenuView examples + tests in examples/src to examples/src/ContextMenuView then update documentation links
    • In the "Examples" section add section for ContextMenuView and ContextMenuButton, then update the documentation "jump to" heading links
    • Update and rename Images/Gifs
      • Move gifs for ContextMenuView in /assets to assets/ContextMenuView/
      • Rename ContextMenuView gifs i.e. prefix them with "ContextMenuView" e.g. SimpleExample-1-2-3-4.gif becomes ContextMenuView-SimpleExample-1-2-3-4.gif, etc.
      • In the /assets/example-screenshots folder, prefix images with "ContextMenuView", e.g. SimpleExample01.png becomes ContextMenuView-SimpleExample01.png, etc.
  • Docs: Add images to steps: Undefined Symbol
  • Docs: Make sections collapsabe
  • Docs: Fix table layout
  • In the "Documentation" section, add ContextMenuButton props.
  • Finish onPressMenuItem nativeEvent Object section.
  • Add section for useActionSheetFallback prop.

  • ContextMenuView: Export ActionSheetFallback function and add it to the docs.

  • ContextMenuView: Rename RCTContextMenuManager to RCTContextMenuViewManager and update corresponding js native component

  • ContextMenuView: Impl. iOS 14 specific feature: UpdateVisibleMenu

  • ContextMenuView: Impl. iOS 14 specific feature: dismissMenu

    • Try implementing this via NativeModule
  • ContextMenuView: Custom Preview - Add support for custom previews, i.e by passing a child component to RCTContextMenuView, and wrapping that child inside a view controller and passing it as the preview target in UIMenu config. The first child of the RCTContextMenuView will be reserved for the custom menu preview. If no child is passed, i.e no custom preview is configured, then the preview target is not set for the UIMenu. The preview view should only be mounted when the menu is visible, and thus, it should support setting the preferred size of the preview target. Test if the preview target can be changed when it's already visible.


  • ContextMenuButton: Finish initial impl. with 1 working simple example
  • ContextMenuButton: Add documentation for ContextMenuButton

  • General: Implement targeted previews
  • General: Implement tinted/colored menu icons + config for line weight etc.
  • Refactor: Change "ImageType" to "IconType", and "imageValue" to "imageType"
  • General: Move menu icon related properties to "icon": { icon: { iconType: '', iconValue: '', tint: ''} }
  • ContextMenu — Add discoverabilityTitle to UIAction

  • Implement ImageType.ASSET to support: "create an image from an image asset or image file located in your apps main bundle"
    • The imageValue string from MenuAction/MenuConfig will be used to init a UIImage, like: UIImage(named: imageValue)

  • Implement ImageType.REQUIRE to support using images via require(path/to/image)

    • One way to implement is to use Image.resolveAssetSource(source); from the RN docs. So we have something like: { imageType: 'REQUIRE', imageValue: require('path/to/image.png') }.

      • Reference: Medium Article. Explains how Image.resolveAssetSource works.
    • Attempted to impl. this but ran into problems: when in debug mode, assets are provided via a local URL via the metro bundler.