diff --git a/change/react-native-windows-2020-04-22-15-02-43-stringviewmanagertemp.json b/change/react-native-windows-2020-04-22-15-02-43-stringviewmanagertemp.json new file mode 100644 index 00000000000..9470e6bc27a --- /dev/null +++ b/change/react-native-windows-2020-04-22-15-02-43-stringviewmanagertemp.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "Implement String ViewManager Command IDs", + "packageName": "react-native-windows", + "email": "ngerlem@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-04-22T22:02:43.043Z" +} diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/SampleAppCpp.vcxproj b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/SampleAppCpp.vcxproj index e11f22797a5..61c4965de7d 100644 --- a/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/SampleAppCpp.vcxproj +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleAppCPP/SampleAppCpp.vcxproj @@ -41,7 +41,6 @@ $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\ - Debug diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/CustomUserControlViewManagerCPP.cpp b/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/CustomUserControlViewManagerCPP.cpp index 8bc8dea706e..58ce16cc054 100644 --- a/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/CustomUserControlViewManagerCPP.cpp +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/CustomUserControlViewManagerCPP.cpp @@ -105,18 +105,18 @@ void CustomUserControlViewManagerCpp::UpdateProperties( } // IViewManagerWithCommands -IMapView CustomUserControlViewManagerCpp::Commands() noexcept { - auto commands = winrt::single_threaded_map(); - commands.Insert(L"CustomCommand", 0); +IVectorView CustomUserControlViewManagerCpp::Commands() noexcept { + auto commands = winrt::single_threaded_vector(); + commands.Append(L"CustomCommand"); return commands.GetView(); } void CustomUserControlViewManagerCpp::DispatchCommand( FrameworkElement const &view, - int64_t commandId, + winrt::hstring const &commandId, IJSValueReader const &commandArgsReader) noexcept { if (auto control = view.try_as()) { - if (commandId == 0) { + if (commandId == L"CustomCommand") { std::string arg = std::to_string(winrt::unbox_value(view.Tag())); arg.append(", \""); arg.append(winrt::to_string(commandArgsReader.GetString())); diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/CustomUserControlViewManagerCPP.h b/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/CustomUserControlViewManagerCPP.h index 8a07bb92ac4..d9e5775e011 100644 --- a/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/CustomUserControlViewManagerCPP.h +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/CustomUserControlViewManagerCPP.h @@ -38,11 +38,11 @@ struct CustomUserControlViewManagerCpp winrt::Microsoft::ReactNative::IJSValueReader const &propertyMapReader) noexcept; // IViewManagerWithCommands - winrt::Windows::Foundation::Collections::IMapView Commands() noexcept; + winrt::Windows::Foundation::Collections::IVectorView Commands() noexcept; void DispatchCommand( winrt::Windows::UI::Xaml::FrameworkElement const &view, - int64_t commandId, + winrt::hstring const &commandId, winrt::Microsoft::ReactNative::IJSValueReader const &commandArgsReader) noexcept; // IViewManagerWithExportedEventTypeConstants diff --git a/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/SampleLibraryCPP.vcxproj b/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/SampleLibraryCPP.vcxproj index 444db48e6bc..bb3b37cbd45 100644 --- a/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/SampleLibraryCPP.vcxproj +++ b/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/SampleLibraryCPP.vcxproj @@ -17,7 +17,6 @@ 10.0.16299.0 - Debug diff --git a/vnext/Desktop.DLL/react-native-win32.x64.def b/vnext/Desktop.DLL/react-native-win32.x64.def index 280de54d461..253bc9d1dfa 100644 --- a/vnext/Desktop.DLL/react-native-win32.x64.def +++ b/vnext/Desktop.DLL/react-native-win32.x64.def @@ -34,7 +34,7 @@ EXPORTS ?createIUIManager@react@facebook@@YA?AV?$shared_ptr@VIUIManager@react@facebook@@@std@@$$QEAV?$vector@V?$unique_ptr@VIViewManager@react@facebook@@U?$default_delete@VIViewManager@react@facebook@@@std@@@std@@V?$allocator@V?$unique_ptr@VIViewManager@react@facebook@@U?$default_delete@VIViewManager@react@facebook@@@std@@@std@@@2@@4@PEAUINativeUIManager@12@@Z ?createUIManagerModule@react@facebook@@YA?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@V?$shared_ptr@VIUIManager@react@facebook@@@4@@Z ?destroy@dynamic@folly@@AEAAXXZ -?dispatchCommand@ShadowNode@react@facebook@@UEAAX_JAEBUdynamic@folly@@@Z +?dispatchCommand@ShadowNode@react@facebook@@UEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBUdynamic@folly@@@Z ?getModuleRegistry@Instance@react@facebook@@QEAAAEAVModuleRegistry@23@XZ ?get_ptr@dynamic@folly@@QEGBAPEBU12@V?$Range@PEBD@2@@Z ?get_ptrImpl@dynamic@folly@@AEGBAPEBU12@AEBU12@@Z diff --git a/vnext/Desktop.DLL/react-native-win32.x86.def b/vnext/Desktop.DLL/react-native-win32.x86.def index 9ae703e4de2..8a299514bc9 100644 --- a/vnext/Desktop.DLL/react-native-win32.x86.def +++ b/vnext/Desktop.DLL/react-native-win32.x86.def @@ -35,7 +35,7 @@ EXPORTS ?createIUIManager@react@facebook@@YG?AV?$shared_ptr@VIUIManager@react@facebook@@@std@@$$QAV?$vector@V?$unique_ptr@VIViewManager@react@facebook@@U?$default_delete@VIViewManager@react@facebook@@@std@@@std@@V?$allocator@V?$unique_ptr@VIViewManager@react@facebook@@U?$default_delete@VIViewManager@react@facebook@@@std@@@std@@@2@@4@PAUINativeUIManager@12@@Z ?createUIManagerModule@react@facebook@@YG?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@V?$shared_ptr@VIUIManager@react@facebook@@@4@@Z ?destroy@dynamic@folly@@AAEXXZ -?dispatchCommand@ShadowNode@react@facebook@@UAEX_JABUdynamic@folly@@@Z +?dispatchCommand@ShadowNode@react@facebook@@UAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABUdynamic@folly@@@Z ?getModuleRegistry@Instance@react@facebook@@QAEAAVModuleRegistry@23@XZ ?get_ptr@dynamic@folly@@QGBEPBU12@V?$Range@PBD@2@@Z ?get_ptrImpl@dynamic@folly@@AGBEPBU12@ABU12@@Z diff --git a/vnext/Desktop.UnitTests/EmptyUIManagerModule.h b/vnext/Desktop.UnitTests/EmptyUIManagerModule.h index 6006bb2ca44..f8e333ea0bb 100644 --- a/vnext/Desktop.UnitTests/EmptyUIManagerModule.h +++ b/vnext/Desktop.UnitTests/EmptyUIManagerModule.h @@ -63,7 +63,10 @@ class EmptyUIManager { std::function /*final Callback*/ callback); void setJSResponder(int64_t reactTag, bool blockNativeResponder); void clearJSResponder(); - void dispatchViewManagerCommand(int64_t reactTag, int64_t commandId, folly::dynamic /*ReadableMap*/ commandArgs); + void dispatchViewManagerCommand( + int64_t reactTag, + const std::string &commandId, + folly::dynamic /*ReadableMap*/ commandArgs); void showPopupMenu( int64_t reactTag, folly::dynamic /*ReadableMap*/ items, diff --git a/vnext/Microsoft.ReactNative.SharedManaged/AttributedViewManager.cs b/vnext/Microsoft.ReactNative.SharedManaged/AttributedViewManager.cs index b590c2bfb96..56691b2be2f 100644 --- a/vnext/Microsoft.ReactNative.SharedManaged/AttributedViewManager.cs +++ b/vnext/Microsoft.ReactNative.SharedManaged/AttributedViewManager.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; using System.Reflection; using Windows.UI.Xaml; @@ -192,27 +193,21 @@ private static bool IsEnum(Type t) #region Commands - public virtual IReadOnlyDictionary Commands + public virtual IReadOnlyList Commands { get { if (null == _commands) { - var commands = new Dictionary(); + _commands = ViewManagerCommands.Keys.ToList(); - foreach (var kvp in ViewManagerCommands) - { - commands.Add(kvp.Value.CommandName, kvp.Value.CommandId); - } - - _commands = commands; } return _commands; } } - private IReadOnlyDictionary _commands; + private IReadOnlyList _commands; - public virtual void DispatchCommand(FrameworkElement view, long commandId, IJSValueReader commandArgsReader) + public virtual void DispatchCommand(FrameworkElement view, string commandId, IJSValueReader commandArgsReader) { if (view is TFrameworkElement viewAsT) { @@ -227,13 +222,13 @@ public virtual void DispatchCommand(FrameworkElement view, long commandId, IJSVa } } - internal Dictionary> ViewManagerCommands + internal Dictionary> ViewManagerCommands { get { if (null == _viewManagerCommands) { - var viewManagerCommands = new Dictionary>(); + var viewManagerCommands = new Dictionary>(); foreach (var methodInfo in GetType().GetTypeInfo().DeclaredMethods) { @@ -243,10 +238,9 @@ internal Dictionary> ViewManagerComm var command = new ViewManagerCommand { CommandName = commandAttribute.CommandName ?? methodInfo.Name, - CommandId = viewManagerCommands.Count, CommandMethod = MakeReaderMethod(methodInfo) }; - viewManagerCommands.Add(command.CommandId, command); + viewManagerCommands.Add(command.CommandName, command); } } @@ -255,12 +249,11 @@ internal Dictionary> ViewManagerComm return _viewManagerCommands; } } - private Dictionary> _viewManagerCommands; + private Dictionary> _viewManagerCommands; internal struct ViewManagerCommand where U : TFrameworkElement { public string CommandName; - public long CommandId; public Action CommandMethod; } diff --git a/vnext/Microsoft.ReactNative/ABIViewManager.cpp b/vnext/Microsoft.ReactNative/ABIViewManager.cpp index 0fd72679c1c..fc85aff39d0 100644 --- a/vnext/Microsoft.ReactNative/ABIViewManager.cpp +++ b/vnext/Microsoft.ReactNative/ABIViewManager.cpp @@ -115,29 +115,31 @@ void ABIViewManager::UpdateProperties(react::uwp::ShadowNodeBase *nodeToUpdate, } folly::dynamic ABIViewManager::GetCommands() const { - folly::dynamic innerParent = Super::GetCommands(); + folly::dynamic commandMap = folly::dynamic::object(); + // Why are we providing commands with the same key and value? React Native 0.61 internally introduced string command + // IDs which can be dispatched directly without querying the ViewManager for commands. Integer command IDs are + // internally deprecated, but querying for command ID is still the documented path. Returning constants as their + // string lets us internally only support the string path. if (m_viewManagerWithCommands) { - auto outerChild = m_viewManagerWithCommands.Commands(); - for (const auto &pair : outerChild) { - std::string key = to_string(pair.Key()); - folly::dynamic value{pair.Value()}; - innerParent.insert(key, value); + for (const auto &commandName : m_viewManagerWithCommands.Commands()) { + auto commandAsStr = to_string(commandName); + commandMap[commandAsStr] = commandAsStr; } } - return innerParent; + return commandMap; } void ABIViewManager::DispatchCommand( winrt::Windows::UI::Xaml::DependencyObject viewToUpdate, - int64_t commandId, + const std::string &commandId, const folly::dynamic &commandArgs) { if (m_viewManagerWithCommands) { auto view = viewToUpdate.as(); IJSValueReader argReader = winrt::make(commandArgs); - m_viewManagerWithCommands.DispatchCommand(view, commandId, argReader); + m_viewManagerWithCommands.DispatchCommand(view, to_hstring(commandId), argReader); } } diff --git a/vnext/Microsoft.ReactNative/ABIViewManager.h b/vnext/Microsoft.ReactNative/ABIViewManager.h index 4356f6dabeb..3b2e55ae57a 100644 --- a/vnext/Microsoft.ReactNative/ABIViewManager.h +++ b/vnext/Microsoft.ReactNative/ABIViewManager.h @@ -40,7 +40,7 @@ class ABIViewManager : public react::uwp::FrameworkElementViewManager { void DispatchCommand( winrt::Windows::UI::Xaml::DependencyObject viewToUpdate, - int64_t commandId, + const std::string &commandId, const folly::dynamic &commandArgs) override; folly::dynamic GetExportedCustomBubblingEventTypeConstants() const override; diff --git a/vnext/Microsoft.ReactNative/IViewManager.idl b/vnext/Microsoft.ReactNative/IViewManager.idl index 68598f48659..226bcf9703d 100644 --- a/vnext/Microsoft.ReactNative/IViewManager.idl +++ b/vnext/Microsoft.ReactNative/IViewManager.idl @@ -40,7 +40,7 @@ namespace Microsoft.ReactNative [webhosthidden] interface IViewManagerWithNativeProperties { - Windows.Foundation.Collections.IMapView NativeProps { get; }; + IMapView NativeProps { get; }; void UpdateProperties(Windows.UI.Xaml.FrameworkElement view, IJSValueReader propertyMapReader); } @@ -48,9 +48,9 @@ namespace Microsoft.ReactNative [webhosthidden] interface IViewManagerWithCommands { - Windows.Foundation.Collections.IMapView Commands { get; }; + IVectorView Commands { get; }; - void DispatchCommand(Windows.UI.Xaml.FrameworkElement view, Int64 commandId, IJSValueReader commandArgsReader); + void DispatchCommand(Windows.UI.Xaml.FrameworkElement view, String commandId, IJSValueReader commandArgsReader); } [webhosthidden] diff --git a/vnext/ReactUWP/Views/ScrollViewManager.cpp b/vnext/ReactUWP/Views/ScrollViewManager.cpp index 8e3a021ab84..bbe699e9e4b 100644 --- a/vnext/ReactUWP/Views/ScrollViewManager.cpp +++ b/vnext/ReactUWP/Views/ScrollViewManager.cpp @@ -11,10 +11,10 @@ namespace react { namespace uwp { -enum class ScrollViewCommands { - ScrollTo = 1, - ScrollToEnd, -}; +namespace ScrollViewCommands { +constexpr const char *ScrollTo = "scrollTo"; +constexpr const char *ScrollToEnd = "scrollToEnd"; +}; // namespace ScrollViewCommands class ScrollViewShadowNode : public ShadowNodeBase { using Super = ShadowNodeBase; @@ -22,7 +22,7 @@ class ScrollViewShadowNode : public ShadowNodeBase { public: ScrollViewShadowNode(); ~ScrollViewShadowNode(); - void dispatchCommand(int64_t commandId, const folly::dynamic &commandArgs) override; + void dispatchCommand(const std::string &commandId, const folly::dynamic &commandArgs) override; void createView() override; void updateProperties(const folly::dynamic &&props) override; @@ -65,28 +65,23 @@ ScrollViewShadowNode::~ScrollViewShadowNode() { m_SIPEventHandler.reset(); } -void ScrollViewShadowNode::dispatchCommand(int64_t commandId, const folly::dynamic &commandArgs) { +void ScrollViewShadowNode::dispatchCommand(const std::string &commandId, const folly::dynamic &commandArgs) { const auto scrollViewer = GetView().as(); if (scrollViewer == nullptr) return; - switch (commandId) { - case static_cast(ScrollViewCommands::ScrollTo): { - double x = commandArgs[0].asDouble(); - double y = commandArgs[1].asDouble(); - bool animated = commandArgs[2].asBool(); - scrollViewer.ChangeView(x, y, nullptr, !animated /*disableAnimation*/); - break; - } - case static_cast(ScrollViewCommands::ScrollToEnd): { - bool animated = commandArgs[0].asBool(); - bool horiz = scrollViewer.HorizontalScrollMode() == winrt::ScrollMode::Auto; - if (horiz) - scrollViewer.ChangeView(scrollViewer.ScrollableWidth(), nullptr, nullptr, !animated /*disableAnimation*/); - else - scrollViewer.ChangeView(nullptr, scrollViewer.ScrollableHeight(), nullptr, !animated /*disableAnimation*/); - break; - } + if (commandId == ScrollViewCommands::ScrollTo) { + double x = commandArgs[0].asDouble(); + double y = commandArgs[1].asDouble(); + bool animated = commandArgs[2].asBool(); + scrollViewer.ChangeView(x, y, nullptr, !animated /*disableAnimation*/); + } else if (commandId == ScrollViewCommands::ScrollToEnd) { + bool animated = commandArgs[0].asBool(); + bool horiz = scrollViewer.HorizontalScrollMode() == winrt::ScrollMode::Auto; + if (horiz) + scrollViewer.ChangeView(scrollViewer.ScrollableWidth(), nullptr, nullptr, !animated /*disableAnimation*/); + else + scrollViewer.ChangeView(nullptr, scrollViewer.ScrollableHeight(), nullptr, !animated /*disableAnimation*/); } } @@ -413,11 +408,10 @@ const char *ScrollViewManager::GetName() const { } folly::dynamic ScrollViewManager::GetCommands() const { - auto commands = Super::GetCommands(); - commands.update(folly::dynamic::object( - "scrollTo", static_cast>(ScrollViewCommands::ScrollTo))( - "scrollToEnd", static_cast>(ScrollViewCommands::ScrollToEnd))); - return commands; + // Upstream JS will dispatch the string directly instead of ever actually calling this, but providing a real + // implementation is simple enough in case anything changes. + return folly::dynamic::object(ScrollViewCommands::ScrollTo, ScrollViewCommands::ScrollTo)( + ScrollViewCommands::ScrollToEnd, ScrollViewCommands::ScrollToEnd); } folly::dynamic ScrollViewManager::GetNativeProps() const { diff --git a/vnext/ReactUWP/Views/ShadowNodeBase.cpp b/vnext/ReactUWP/Views/ShadowNodeBase.cpp index c03d97ed666..527c30e5a88 100644 --- a/vnext/ReactUWP/Views/ShadowNodeBase.cpp +++ b/vnext/ReactUWP/Views/ShadowNodeBase.cpp @@ -44,7 +44,7 @@ bool ShadowNodeBase::NeedsForceLayout() { return false; } -void ShadowNodeBase::dispatchCommand(int64_t commandId, const folly::dynamic &commandArgs) { +void ShadowNodeBase::dispatchCommand(const std::string &commandId, const folly::dynamic &commandArgs) { GetViewManager()->DispatchCommand(GetView(), commandId, commandArgs); } diff --git a/vnext/ReactUWP/Views/SwitchViewManager.cpp b/vnext/ReactUWP/Views/SwitchViewManager.cpp index e5ad8a0c5a5..93093cdf36e 100644 --- a/vnext/ReactUWP/Views/SwitchViewManager.cpp +++ b/vnext/ReactUWP/Views/SwitchViewManager.cpp @@ -160,5 +160,17 @@ bool SwitchViewManager::UpdateProperty( return true; } +void SwitchViewManager::DispatchCommand( + XamlView viewToUpdate, + const std::string &commandId, + const folly::dynamic &commandArgs) { + if (commandId == "setValue") { + auto value = commandArgs[0].asBool(); + viewToUpdate.as().IsEnabled(value); + } else { + Super::DispatchCommand(viewToUpdate, commandId, commandArgs); + } +} + } // namespace uwp } // namespace react diff --git a/vnext/ReactUWP/Views/SwitchViewManager.h b/vnext/ReactUWP/Views/SwitchViewManager.h index aaa6089c809..372163eb095 100644 --- a/vnext/ReactUWP/Views/SwitchViewManager.h +++ b/vnext/ReactUWP/Views/SwitchViewManager.h @@ -17,6 +17,7 @@ class SwitchViewManager : public ControlViewManager { const char *GetName() const override; folly::dynamic GetNativeProps() const override; facebook::react::ShadowNode *createShadow() const override; + void DispatchCommand(XamlView viewToUpdate, const std::string &commandId, const folly::dynamic &commandArgs) override; protected: bool UpdateProperty( diff --git a/vnext/ReactUWP/Views/ViewManagerBase.cpp b/vnext/ReactUWP/Views/ViewManagerBase.cpp index 38feb176955..86d1e61e084 100644 --- a/vnext/ReactUWP/Views/ViewManagerBase.cpp +++ b/vnext/ReactUWP/Views/ViewManagerBase.cpp @@ -255,7 +255,7 @@ void ViewManagerBase::TransferProperties(XamlView /*oldView*/, XamlView /*newVie void ViewManagerBase::DispatchCommand( XamlView /*viewToUpdate*/, - int64_t /*commandId*/, + const std::string & /*commandId*/, const folly::dynamic & /*commandArgs*/) { assert(false); // View did not handle its command } diff --git a/vnext/ReactWindowsCore/IUIManager.h b/vnext/ReactWindowsCore/IUIManager.h index 4cf28835a16..cb677aa75aa 100644 --- a/vnext/ReactWindowsCore/IUIManager.h +++ b/vnext/ReactWindowsCore/IUIManager.h @@ -44,7 +44,8 @@ class IUIManager { folly::dynamic &addChildTags, folly::dynamic &addAtIndices, folly::dynamic &removeFrom) = 0; - virtual void dispatchViewManagerCommand(int64_t reactTag, int64_t commandId, folly::dynamic &&commandArgs) = 0; + virtual void + dispatchViewManagerCommand(int64_t reactTag, const std::string &commandId, folly::dynamic &&commandArgs) = 0; virtual void replaceExistingNonRootView(int64_t oldTag, int64_t newTag) = 0; virtual void measure(int64_t reactTag, facebook::xplat::module::CxxModule::Callback callback) = 0; virtual void measureInWindow(int64_t reactTag, facebook::xplat::module::CxxModule::Callback callback) = 0; diff --git a/vnext/ReactWindowsCore/Modules/UIManagerModule.cpp b/vnext/ReactWindowsCore/Modules/UIManagerModule.cpp index b71f31bd556..7d72ac8d25a 100644 --- a/vnext/ReactWindowsCore/Modules/UIManagerModule.cpp +++ b/vnext/ReactWindowsCore/Modules/UIManagerModule.cpp @@ -320,7 +320,10 @@ void UIManager::replaceExistingNonRootView(int64_t oldTag, int64_t newTag) { manageChildren(parent.m_tag, emptyVec, emptyVec, tagToAdd, indicesToAdd, indicesToRemove); } -void UIManager::dispatchViewManagerCommand(int64_t reactTag, int64_t commandId, folly::dynamic &&commandArgs) { +void UIManager::dispatchViewManagerCommand( + int64_t reactTag, + const std::string &commandId, + folly::dynamic &&commandArgs) { m_nativeUIManager->ensureInBatch(); auto &node = m_nodeRegistry.getNode(reactTag); if (!node.m_zombie) @@ -507,8 +510,11 @@ std::vector UIManagerModule::getMeth Method( "dispatchViewManagerCommand", [manager](dynamic args) { + // 0.61 allows directly dispatching command names instead of querying the ViewManager for the command ID. + // In stock React Native, integer commands are deprecated but not yet removed. RNW APIs only allow strings, + // and provide command constants as their literal string. manager->dispatchViewManagerCommand( - jsArgAsInt(args, 0), jsArgAsInt(args, 1), std::move(jsArgAsDynamic(args, 2))); + jsArgAsInt(args, 0), jsArgAsString(args, 1), std::move(jsArgAsDynamic(args, 2))); }), Method("measure", [manager](dynamic args, Callback cb) { manager->measure(jsArgAsInt(args, 0), cb); }), Method( diff --git a/vnext/ReactWindowsCore/Modules/UIManagerModule.h b/vnext/ReactWindowsCore/Modules/UIManagerModule.h index cf79bb89346..e66f5d5e9ac 100644 --- a/vnext/ReactWindowsCore/Modules/UIManagerModule.h +++ b/vnext/ReactWindowsCore/Modules/UIManagerModule.h @@ -43,7 +43,9 @@ class UIManager : public IUIManager, INativeUIManagerHost { folly::dynamic &addChildTags, folly::dynamic &addAtIndices, folly::dynamic &removeFrom) override; - void dispatchViewManagerCommand(int64_t reactTag, int64_t commandId, folly::dynamic &&commandArgs) override; + + void dispatchViewManagerCommand(int64_t reactTag, const std::string &commandId, folly::dynamic &&commandArgs) + override; void replaceExistingNonRootView(int64_t oldTag, int64_t newTag) override; void onBatchComplete() override; void measure(int64_t reactTag, facebook::xplat::module::CxxModule::Callback callback) override; diff --git a/vnext/ReactWindowsCore/ShadowNode.cpp b/vnext/ReactWindowsCore/ShadowNode.cpp index 6bf17eb9261..626015b0423 100644 --- a/vnext/ReactWindowsCore/ShadowNode.cpp +++ b/vnext/ReactWindowsCore/ShadowNode.cpp @@ -8,7 +8,7 @@ namespace react { ShadowNode::~ShadowNode() {} -void ShadowNode::dispatchCommand(int64_t commandId, const folly::dynamic &commandArgs) {} +void ShadowNode::dispatchCommand(const std::string &commandId, const folly::dynamic &commandArgs) {} void ShadowNode::onDropViewInstance() {} diff --git a/vnext/ReactWindowsCore/ShadowNode.h b/vnext/ReactWindowsCore/ShadowNode.h index 4f986e2f108..ea10f0259db 100644 --- a/vnext/ReactWindowsCore/ShadowNode.h +++ b/vnext/ReactWindowsCore/ShadowNode.h @@ -20,7 +20,7 @@ struct ShadowNode { virtual void updateProperties(const folly::dynamic &&props); virtual void onDropViewInstance() = 0; - virtual void dispatchCommand(int64_t commandId, const folly::dynamic &commandArgs); + virtual void dispatchCommand(const std::string &commandId, const folly::dynamic &commandArgs); virtual void removeAllChildren() = 0; virtual void AddView(ShadowNode &child, int64_t index) = 0; virtual void RemoveChildAt(int64_t indexToRemove) = 0; diff --git a/vnext/include/ReactUWP/Views/ShadowNodeBase.h b/vnext/include/ReactUWP/Views/ShadowNodeBase.h index e8ec8da550f..2e008780943 100644 --- a/vnext/include/ReactUWP/Views/ShadowNodeBase.h +++ b/vnext/include/ReactUWP/Views/ShadowNodeBase.h @@ -54,7 +54,7 @@ struct REACTWINDOWS_EXPORT ShadowNodeBase : public facebook::react::ShadowNode { virtual ~ShadowNodeBase() {} virtual void onDropViewInstance() override; - virtual void dispatchCommand(int64_t commandId, const folly::dynamic &commandArgs) override; + virtual void dispatchCommand(const std::string &commandId, const folly::dynamic &commandArgs) override; virtual void removeAllChildren() override; virtual void AddView(ShadowNode &child, int64_t index) override; virtual void RemoveChildAt(int64_t indexToRemove) override; diff --git a/vnext/include/ReactUWP/Views/ViewManagerBase.h b/vnext/include/ReactUWP/Views/ViewManagerBase.h index 17f2e2ae6c0..b1ff720d35a 100644 --- a/vnext/include/ReactUWP/Views/ViewManagerBase.h +++ b/vnext/include/ReactUWP/Views/ViewManagerBase.h @@ -62,7 +62,7 @@ class REACTWINDOWS_EXPORT ViewManagerBase : public facebook::react::IViewManager virtual void UpdateProperties(ShadowNodeBase *nodeToUpdate, const folly::dynamic &reactDiffMap); - virtual void DispatchCommand(XamlView viewToUpdate, int64_t commandId, const folly::dynamic &commandArgs); + virtual void DispatchCommand(XamlView viewToUpdate, const std::string &commandId, const folly::dynamic &commandArgs); // Yoga Layout virtual void