react-native-windows 0.74.6 → 0.74.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/Libraries/ReactNative/AppContainer-dev.js +3 -2
  2. package/Libraries/ReactNative/AppContainer-prod.js +2 -1
  3. package/Libraries/ReactNative/AppContainer.js +2 -0
  4. package/Libraries/ReactNative/AppRegistry.d.ts +7 -0
  5. package/Libraries/ReactNative/AppRegistry.js +8 -0
  6. package/Libraries/ReactNative/renderApplication.js +3 -0
  7. package/Microsoft.ReactNative/AsynchronousEventBeat.cpp +1 -2
  8. package/Microsoft.ReactNative/CompositionHwndHost.idl +1 -1
  9. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +21 -21
  10. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +2 -2
  11. package/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.cpp +7 -6
  12. package/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.h +1 -1
  13. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +3 -3
  14. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.h +3 -3
  15. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +9 -5
  16. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +2 -0
  17. package/Microsoft.ReactNative/Fabric/Composition/{CompositionRootView.cpp → ReactNativeIsland.cpp} +160 -115
  18. package/Microsoft.ReactNative/Fabric/Composition/{CompositionRootView.h → ReactNativeIsland.h} +25 -20
  19. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +19 -6
  20. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +6 -2
  21. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +2 -2
  22. package/Microsoft.ReactNative/Fabric/Composition/UriImageManager.cpp +82 -17
  23. package/Microsoft.ReactNative/Fabric/Composition/UriImageManager.h +79 -0
  24. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +8 -14
  25. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +4 -3
  26. package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +191 -119
  27. package/Microsoft.ReactNative/Fabric/WindowsImageManager.h +11 -0
  28. package/Microsoft.ReactNative/HttpSettings.idl +19 -0
  29. package/Microsoft.ReactNative/Modules/ImageViewManagerModule.cpp +15 -11
  30. package/Microsoft.ReactNative/{CompositionRootView.idl → ReactNativeIsland.idl} +23 -13
  31. package/Microsoft.ReactNative/UriImageManager.idl +35 -17
  32. package/Microsoft.ReactNative/Utils/ImageUtils.cpp +22 -3
  33. package/Microsoft.ReactNative/Utils/ImageUtils.h +3 -1
  34. package/Microsoft.ReactNative/Views/Image/ImageViewManager.cpp +1 -1
  35. package/Microsoft.ReactNative/Views/Image/ReactImage.cpp +13 -4
  36. package/Microsoft.ReactNative/Views/Image/ReactImage.h +4 -2
  37. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  38. package/Shared/Modules/FileReaderModule.cpp +3 -4
  39. package/Shared/Modules/WebSocketModule.cpp +14 -16
  40. package/Shared/Networking/DefaultBlobResource.cpp +6 -14
  41. package/Shared/Networking/NetworkPropertyIds.cpp +60 -0
  42. package/Shared/Networking/NetworkPropertyIds.h +41 -0
  43. package/Shared/Networking/RedirectHttpFilter.cpp +18 -9
  44. package/Shared/Networking/RedirectHttpFilter.h +6 -3
  45. package/Shared/Networking/WinRTHttpResource.cpp +36 -8
  46. package/Shared/Networking/WinRTHttpResource.h +17 -0
  47. package/Shared/Shared.vcxitems +6 -9
  48. package/Shared/Shared.vcxitems.filters +5 -3
  49. package/package.json +1 -1
  50. package/templates/cpp-app/windows/MyApp/MyApp.cpp +5 -4
  51. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootView_emptyimpl.cpp +0 -149
  52. package/Microsoft.ReactNative/Views/ICompositionRootView.h +0 -18
@@ -2,16 +2,16 @@
2
2
  // Licensed under the MIT License.
3
3
  #pragma once
4
4
 
5
- #include "CompositionRootView.g.h"
5
+ #include "ReactNativeIsland.g.h"
6
6
  #include <FocusNavigationRequest.g.h>
7
7
  #include <FocusNavigationResult.g.h>
8
8
 
9
9
  #include <ReactContext.h>
10
+ #include <react/renderer/core/LayoutConstraints.h>
10
11
  #include <winrt/Microsoft.ReactNative.Composition.Experimental.h>
11
12
  #include <winrt/Microsoft.ReactNative.h>
12
13
  #include "CompositionEventHandler.h"
13
14
  #include "ReactHost/React.h"
14
- #include "Views/ICompositionRootView.h"
15
15
 
16
16
  namespace winrt::Microsoft::ReactNative::implementation {
17
17
 
@@ -41,15 +41,14 @@ struct FocusNavigationResult : FocusNavigationResultT<FocusNavigationResult> {
41
41
  const bool m_wasFocusMoved;
42
42
  };
43
43
 
44
- struct CompositionRootView
45
- : CompositionRootViewT<CompositionRootView, Composition::Experimental::IInternalCompositionRootView>,
46
- ::Microsoft::ReactNative::ICompositionRootView {
47
- CompositionRootView() noexcept;
48
- ~CompositionRootView() noexcept;
44
+ struct ReactNativeIsland
45
+ : ReactNativeIslandT<ReactNativeIsland, Composition::Experimental::IInternalCompositionRootView> {
46
+ ReactNativeIsland() noexcept;
47
+ ~ReactNativeIsland() noexcept;
49
48
 
50
49
  #ifdef USE_WINUI3
51
- CompositionRootView(const winrt::Microsoft::UI::Composition::Compositor &compositor) noexcept;
52
- winrt::Microsoft::UI::Content::ContentIsland Island() noexcept;
50
+ ReactNativeIsland(const winrt::Microsoft::UI::Composition::Compositor &compositor) noexcept;
51
+ winrt::Microsoft::UI::Content::ContentIsland Island();
53
52
  #endif
54
53
 
55
54
  // property ReactViewHost
@@ -70,6 +69,12 @@ struct CompositionRootView
70
69
  float ScaleFactor() noexcept;
71
70
  void ScaleFactor(float value) noexcept;
72
71
 
72
+ winrt::event_token SizeChanged(
73
+ winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::RootViewSizeChangedEventArgs> const
74
+ &handler) noexcept;
75
+ void SizeChanged(winrt::event_token const &token) noexcept;
76
+ void NotifySizeChanged() noexcept;
77
+
73
78
  void AddRenderedVisual(const winrt::Microsoft::ReactNative::Composition::Experimental::IVisual &visual) noexcept;
74
79
  void RemoveRenderedVisual(const winrt::Microsoft::ReactNative::Composition::Experimental::IVisual &visual) noexcept;
75
80
  bool TrySetFocus() noexcept;
@@ -80,8 +85,12 @@ struct CompositionRootView
80
85
  winrt::Microsoft::ReactNative::Composition::Theme Theme() noexcept;
81
86
  void Theme(const winrt::Microsoft::ReactNative::Composition::Theme &value) noexcept;
82
87
 
83
- winrt::Windows::Foundation::Size Measure(winrt::Windows::Foundation::Size const &availableSize) const;
84
- winrt::Windows::Foundation::Size Arrange(winrt::Windows::Foundation::Size finalSize) const;
88
+ winrt::Windows::Foundation::Size Measure(
89
+ const winrt::Microsoft::ReactNative::LayoutConstraints &layoutConstraints,
90
+ const winrt::Windows::Foundation::Point &viewportOffset) const noexcept;
91
+ void Arrange(
92
+ const winrt::Microsoft::ReactNative::LayoutConstraints &layoutConstraints,
93
+ const winrt::Windows::Foundation::Point &viewportOffset) noexcept;
85
94
 
86
95
  winrt::Microsoft::ReactNative::FocusNavigationResult NavigateFocus(
87
96
  const winrt::Microsoft::ReactNative::FocusNavigationRequest &request) noexcept;
@@ -103,13 +112,6 @@ struct CompositionRootView
103
112
  const winrt::Microsoft::ReactNative::Composition::Input::Pointer &pointer,
104
113
  facebook::react::Tag tag) noexcept;
105
114
 
106
- public: // IReactRootView
107
- std::string JSComponentName() const noexcept override;
108
- int64_t GetActualHeight() const noexcept override;
109
- int64_t GetActualWidth() const noexcept override;
110
- int64_t GetTag() const noexcept override;
111
- void SetTag(int64_t tag) noexcept override;
112
-
113
115
  public: // IReactViewInstance UI-thread implementation
114
116
  void InitRootView(
115
117
  winrt::Microsoft::ReactNative::IReactContext &&context,
@@ -134,7 +136,7 @@ struct CompositionRootView
134
136
  winrt::IInspectable m_uiaProvider{nullptr};
135
137
  int64_t m_rootTag{-1};
136
138
  float m_scaleFactor{1.0};
137
- winrt::Windows::Foundation::Size m_size;
139
+ winrt::Windows::Foundation::Size m_size{0, 0};
138
140
  winrt::Microsoft::ReactNative::ReactContext m_context;
139
141
  winrt::Microsoft::ReactNative::IReactViewHost m_reactViewHost;
140
142
  winrt::Microsoft::ReactNative::ReactViewOptions m_reactViewOptions;
@@ -145,6 +147,9 @@ struct CompositionRootView
145
147
  winrt::Microsoft::ReactNative::Composition::ICustomResourceLoader m_resources{nullptr};
146
148
  winrt::Microsoft::ReactNative::Composition::Theme m_theme{nullptr};
147
149
  winrt::Microsoft::ReactNative::Composition::Theme::ThemeChanged_revoker m_themeChangedRevoker;
150
+ facebook::react::LayoutConstraints m_layoutConstraints;
151
+ winrt::event<winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::RootViewSizeChangedEventArgs>>
152
+ m_sizeChangedEvent;
148
153
 
149
154
  void UpdateRootViewInternal() noexcept;
150
155
  void ClearLoadingUI() noexcept;
@@ -160,7 +165,7 @@ struct CompositionRootView
160
165
  } // namespace winrt::Microsoft::ReactNative::implementation
161
166
 
162
167
  namespace winrt::Microsoft::ReactNative::factory_implementation {
163
- struct CompositionRootView : CompositionRootViewT<CompositionRootView, implementation::CompositionRootView> {};
168
+ struct ReactNativeIsland : ReactNativeIslandT<ReactNativeIsland, implementation::ReactNativeIsland> {};
164
169
  struct FocusNavigationRequest
165
170
  : FocusNavigationRequestT<FocusNavigationRequest, implementation::FocusNavigationRequest> {};
166
171
  } // namespace winrt::Microsoft::ReactNative::factory_implementation
@@ -8,7 +8,7 @@
8
8
 
9
9
  #include <Fabric/FabricUIManagerModule.h>
10
10
  #include "CompositionRootAutomationProvider.h"
11
- #include "CompositionRootView.h"
11
+ #include "ReactNativeIsland.h"
12
12
  #include "Theme.h"
13
13
 
14
14
  namespace winrt::Microsoft::ReactNative::Composition::implementation {
@@ -29,7 +29,7 @@ RootComponentView::RootComponentView(
29
29
 
30
30
  RootComponentView::~RootComponentView() {
31
31
  if (auto rootView = m_wkRootView.get()) {
32
- winrt::get_self<winrt::Microsoft::ReactNative::implementation::CompositionRootView>(rootView)->RemoveRenderedVisual(
32
+ winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(rootView)->RemoveRenderedVisual(
33
33
  OuterVisual());
34
34
  }
35
35
  }
@@ -45,6 +45,19 @@ RootComponentView *RootComponentView::rootComponentView() noexcept {
45
45
  return this;
46
46
  }
47
47
 
48
+ void RootComponentView::updateLayoutMetrics(
49
+ facebook::react::LayoutMetrics const &layoutMetrics,
50
+ facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept {
51
+ base_type::updateLayoutMetrics(layoutMetrics, oldLayoutMetrics);
52
+
53
+ if (oldLayoutMetrics.frame != layoutMetrics.frame ||
54
+ oldLayoutMetrics.pointScaleFactor != layoutMetrics.pointScaleFactor) {
55
+ if (auto rootView = m_wkRootView.get()) {
56
+ winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(rootView)->NotifySizeChanged();
57
+ }
58
+ }
59
+ }
60
+
48
61
  winrt::Microsoft::ReactNative::ComponentView RootComponentView::GetFocusedComponent() noexcept {
49
62
  return m_focusedComponent;
50
63
  }
@@ -60,7 +73,7 @@ void RootComponentView::SetFocusedComponent(const winrt::Microsoft::ReactNative:
60
73
 
61
74
  if (value) {
62
75
  if (auto rootView = m_wkRootView.get()) {
63
- winrt::get_self<winrt::Microsoft::ReactNative::implementation::CompositionRootView>(rootView)->TrySetFocus();
76
+ winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(rootView)->TrySetFocus();
64
77
  }
65
78
  auto args = winrt::make<winrt::Microsoft::ReactNative::implementation::GotFocusEventArgs>(value);
66
79
  winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(value)->onGotFocus(args);
@@ -148,7 +161,7 @@ HRESULT RootComponentView::GetFragmentRoot(IRawElementProviderFragmentRoot **pRe
148
161
  if (uiManager == nullptr)
149
162
  return UIA_E_ELEMENTNOTAVAILABLE;
150
163
 
151
- auto rootView = uiManager->GetCompositionRootView(Tag());
164
+ auto rootView{uiManager->GetReactNativeIsland(Tag())};
152
165
  if (!rootView) {
153
166
  return UIA_E_ELEMENTNOTAVAILABLE;
154
167
  }
@@ -165,8 +178,8 @@ uint32_t RootComponentView::overlayIndex() noexcept {
165
178
  return 1;
166
179
  }
167
180
 
168
- void RootComponentView::start(const winrt::Microsoft::ReactNative::CompositionRootView &rootView) noexcept {
169
- winrt::get_self<winrt::Microsoft::ReactNative::implementation::CompositionRootView>(rootView)->AddRenderedVisual(
181
+ void RootComponentView::start(const winrt::Microsoft::ReactNative::ReactNativeIsland &rootView) noexcept {
182
+ winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(rootView)->AddRenderedVisual(
170
183
  OuterVisual());
171
184
  m_wkRootView = rootView;
172
185
  }
@@ -38,11 +38,15 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
38
38
 
39
39
  // Index that visuals can be inserted into OuterVisual for debugging UI
40
40
  uint32_t overlayIndex() noexcept;
41
- void start(const winrt::Microsoft::ReactNative::CompositionRootView &rootView) noexcept;
41
+ void start(const winrt::Microsoft::ReactNative::ReactNativeIsland &rootView) noexcept;
42
42
 
43
43
  HRESULT GetFragmentRoot(IRawElementProviderFragmentRoot **pRetVal) noexcept;
44
44
  winrt::Microsoft::ReactNative::implementation::ClipState getClipState() noexcept override;
45
45
 
46
+ void updateLayoutMetrics(
47
+ facebook::react::LayoutMetrics const &layoutMetrics,
48
+ facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept override;
49
+
46
50
  winrt::IInspectable UiaProviderFromPoint(const POINT &ptPixels) noexcept;
47
51
 
48
52
  RootComponentView(
@@ -60,7 +64,7 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
60
64
  // be clearing its focus But being a reactTaggedView might make it easier to identify cases where that isn't
61
65
  // happening.
62
66
  winrt::Microsoft::ReactNative::ComponentView m_focusedComponent{nullptr};
63
- winrt::weak_ref<winrt::Microsoft::ReactNative::CompositionRootView> m_wkRootView{nullptr};
67
+ winrt::weak_ref<winrt::Microsoft::ReactNative::ReactNativeIsland> m_wkRootView{nullptr};
64
68
  };
65
69
 
66
70
  } // namespace winrt::Microsoft::ReactNative::Composition::implementation
@@ -736,7 +736,7 @@ void WindowsTextInputComponentView::OnPointerMoved(
736
736
  msg = WM_MOUSEMOVE;
737
737
  wParam = PointerRoutedEventArgsToMouseWParam(args);
738
738
  } else {
739
- msg = WM_POINTERUP;
739
+ msg = WM_POINTERUPDATE;
740
740
  wParam = PointerPointToPointerWParam(pp);
741
741
  }
742
742
 
@@ -1411,7 +1411,7 @@ winrt::com_ptr<::IDWriteTextLayout> WindowsTextInputComponentView::CreatePlaceho
1411
1411
 
1412
1412
  void WindowsTextInputComponentView::DrawText() noexcept {
1413
1413
  m_needsRedraw = true;
1414
- if (m_cDrawBlock || theme()->IsEmpty()) {
1414
+ if (m_cDrawBlock || theme()->IsEmpty() || !m_textServices) {
1415
1415
  return;
1416
1416
  }
1417
1417
 
@@ -5,11 +5,19 @@
5
5
  #include "UriImageManager.h"
6
6
 
7
7
  #include "Composition.ImageSource.g.h"
8
+ #include <Composition.Experimental.UriBrushFactoryImageResponse.g.cpp>
9
+ #include <Composition.ImageFailedResponse.g.cpp>
10
+ #include <Composition.ImageResponse.g.cpp>
11
+ #include <Composition.StreamImageResponse.g.cpp>
12
+ #include <Composition.UriBrushFactoryImageResponse.g.cpp>
8
13
  #include <AutoDraw.h>
14
+ #include <IBlobPersistor.h>
15
+ #include <Networking/NetworkPropertyIds.h>
9
16
  #include <ReactPropertyBag.h>
10
17
  #include <d2d1_3.h>
11
18
  #include <shcore.h>
12
19
  #include <winrt/Microsoft.ReactNative.Composition.Experimental.h>
20
+ #include <winrt/Microsoft.ReactNative.Composition.h>
13
21
  #include <winrt/Windows.Security.Cryptography.h>
14
22
  #include <winrt/Windows.Storage.Streams.h>
15
23
 
@@ -54,16 +62,14 @@ winrt::Microsoft::ReactNative::Composition::ImageSource MakeImageSource(
54
62
  * />
55
63
  *
56
64
  */
57
- struct SvgDataImageHandler : winrt::implements<
58
- SvgDataImageHandler,
59
- winrt::Microsoft::ReactNative::Composition::Experimental::IUriBrushProvider,
60
- winrt::Microsoft::ReactNative::Composition::IUriImageProvider> {
65
+ struct SvgDataImageHandler
66
+ : winrt::implements<SvgDataImageHandler, winrt::Microsoft::ReactNative::Composition::IUriImageProvider> {
61
67
  bool CanLoadImageUri(winrt::Microsoft::ReactNative::IReactContext context, winrt::Windows::Foundation::Uri uri) {
62
68
  return uri.SchemeName() == L"data" && std::wstring_view(uri.Path()).starts_with(L"image/svg+xml;base64,");
63
69
  }
64
70
 
65
- winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::ReactNative::Composition::Experimental::UriBrushFactory>
66
- GetSourceAsync(
71
+ winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::ReactNative::Composition::ImageResponse>
72
+ GetImageResponseAsync(
67
73
  const winrt::Microsoft::ReactNative::IReactContext &context,
68
74
  const winrt::Microsoft::ReactNative::Composition::ImageSource &imageSource) {
69
75
  auto path = winrt::to_string(imageSource.Uri().Path());
@@ -85,7 +91,7 @@ struct SvgDataImageHandler : winrt::implements<
85
91
  co_await memoryStream.WriteAsync(buffer);
86
92
  memoryStream.Seek(0);
87
93
 
88
- co_return
94
+ co_return winrt::Microsoft::ReactNative::Composition::Experimental::UriBrushFactoryImageResponse(
89
95
  [memoryStream, size, scale](
90
96
  const winrt::Microsoft::ReactNative::IReactContext &reactContext,
91
97
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compositionContext)
@@ -126,12 +132,13 @@ struct SvgDataImageHandler : winrt::implements<
126
132
  renderTarget->SetTransform(originalTransform);
127
133
 
128
134
  return drawingBrush;
129
- };
135
+ });
130
136
 
131
- } catch (winrt::hresult_error const &) {
137
+ } catch (winrt::hresult_error const &ex) {
138
+ co_return winrt::Microsoft::ReactNative::Composition::ImageFailedResponse(ex.message());
132
139
  }
133
140
 
134
- co_return nullptr;
141
+ winrt::throw_hresult(E_UNEXPECTED);
135
142
  }
136
143
  };
137
144
 
@@ -145,15 +152,14 @@ struct SvgDataImageHandler : winrt::implements<
145
152
  * />
146
153
  *
147
154
  */
148
- struct DataImageHandler : winrt::implements<
149
- DataImageHandler,
150
- winrt::Microsoft::ReactNative::Composition::IUriImageStreamProvider,
151
- winrt::Microsoft::ReactNative::Composition::IUriImageProvider> {
155
+ struct DataImageHandler
156
+ : winrt::implements<DataImageHandler, winrt::Microsoft::ReactNative::Composition::IUriImageProvider> {
152
157
  bool CanLoadImageUri(winrt::Microsoft::ReactNative::IReactContext context, winrt::Windows::Foundation::Uri uri) {
153
158
  return uri.SchemeName() == L"data";
154
159
  }
155
160
 
156
- winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::Streams::IRandomAccessStream> GetSourceAsync(
161
+ winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::ReactNative::Composition::ImageResponse>
162
+ GetImageResponseAsync(
157
163
  const winrt::Microsoft::ReactNative::IReactContext &context,
158
164
  const winrt::Microsoft::ReactNative::Composition::ImageSource &imageSource) {
159
165
  auto path = winrt::to_string(imageSource.Uri().Path());
@@ -173,12 +179,57 @@ struct DataImageHandler : winrt::implements<
173
179
  co_await memoryStream.WriteAsync(buffer);
174
180
  memoryStream.Seek(0);
175
181
 
176
- co_return memoryStream;
182
+ co_return winrt::Microsoft::ReactNative::Composition::StreamImageResponse(memoryStream);
177
183
  } catch (winrt::hresult_error const &) {
178
184
  // Base64 decode failed
185
+ co_return winrt::Microsoft::ReactNative::Composition::ImageFailedResponse(
186
+ L"Invalid base64 encoding in inline image data");
179
187
  }
180
188
 
181
- co_return nullptr;
189
+ winrt::throw_hresult(E_UNEXPECTED);
190
+ }
191
+ };
192
+
193
+ /**
194
+ * This ImageHandler will handle uri loading data from blobs
195
+ *
196
+ * <Image
197
+ * style={{width: 400, height: 200}}
198
+ * source={{uri:'blob:<guid>?offset=<offset>&size=<size>'}}
199
+ * />
200
+ *
201
+ */
202
+ struct BlobImageHandler
203
+ : winrt::implements<BlobImageHandler, winrt::Microsoft::ReactNative::Composition::IUriImageProvider> {
204
+ bool CanLoadImageUri(winrt::Microsoft::ReactNative::IReactContext context, winrt::Windows::Foundation::Uri uri) {
205
+ return uri.SchemeName() == L"blob";
206
+ }
207
+
208
+ winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::ReactNative::Composition::ImageResponse>
209
+ GetImageResponseAsync(
210
+ const winrt::Microsoft::ReactNative::IReactContext &context,
211
+ const winrt::Microsoft::ReactNative::Composition::ImageSource &imageSource) {
212
+ if (auto prop = winrt::Microsoft::ReactNative::ReactPropertyBag(context.Properties())
213
+ .Get(::Microsoft::React::BlobModulePersistorPropertyId())) {
214
+ auto weakBlobPersistor = prop.Value();
215
+ if (auto persistor = weakBlobPersistor.lock()) {
216
+ auto queryParsed = imageSource.Uri().QueryParsed();
217
+ auto guid = winrt::to_string(imageSource.Uri().Path());
218
+ int64_t offset = _atoi64(winrt::to_string(queryParsed.GetFirstValueByName(L"offset")).c_str());
219
+ int64_t size = _atoi64(winrt::to_string(queryParsed.GetFirstValueByName(L"size")).c_str());
220
+
221
+ auto arr = persistor->ResolveMessage(std::move(guid), offset, size);
222
+ winrt::Windows::Storage::Streams::InMemoryRandomAccessStream memoryStream;
223
+ winrt::Windows::Storage::Streams::DataWriter dataWriter{memoryStream};
224
+ dataWriter.WriteBytes(arr);
225
+ co_await dataWriter.StoreAsync();
226
+ memoryStream.Seek(0);
227
+
228
+ co_return winrt::Microsoft::ReactNative::Composition::StreamImageResponse(memoryStream.CloneStream());
229
+ }
230
+ }
231
+
232
+ co_return winrt::Microsoft::ReactNative::Composition::ImageFailedResponse(L"Failed to load image from blob");
182
233
  }
183
234
  };
184
235
 
@@ -191,6 +242,7 @@ static const ReactPropertyId<ReactNonAbiValue<std::shared_ptr<UriImageManager>>>
191
242
  UriImageManager::UriImageManager() {
192
243
  m_providers.push_back(winrt::make<SvgDataImageHandler>());
193
244
  m_providers.push_back(winrt::make<DataImageHandler>());
245
+ m_providers.push_back(winrt::make<BlobImageHandler>());
194
246
  }
195
247
 
196
248
  void UriImageManager::Install(
@@ -227,4 +279,17 @@ IUriImageProvider UriImageManager::TryGetUriImageProvider(
227
279
  return nullptr;
228
280
  }
229
281
 
282
+ ImageResponseOrImageErrorInfo ImageResponse::ResolveImage() {
283
+ winrt::throw_hresult(E_NOTIMPL);
284
+ }
285
+
286
+ ImageResponseOrImageErrorInfo ImageFailedResponse::ResolveImage() {
287
+ ImageResponseOrImageErrorInfo imageOrError;
288
+ imageOrError.errorInfo = winrt::to_string(m_errorMessage);
289
+ if (imageOrError.errorInfo.empty()) {
290
+ imageOrError.errorInfo = "Failed to load image.";
291
+ }
292
+ return imageOrError;
293
+ }
294
+
230
295
  } // namespace winrt::Microsoft::ReactNative::Composition::implementation
@@ -3,10 +3,16 @@
3
3
 
4
4
  #pragma once
5
5
 
6
+ #include <Composition.Experimental.UriBrushFactoryImageResponse.g.h>
7
+ #include <Composition.ImageFailedResponse.g.h>
8
+ #include <Composition.ImageResponse.g.h>
9
+ #include <Composition.StreamImageResponse.g.h>
10
+ #include <Composition.UriBrushFactoryImageResponse.g.h>
6
11
  #include <ReactPropertyBag.h>
7
12
  #include <Utils/ImageUtils.h>
8
13
  #include <react/renderer/imagemanager/primitives.h>
9
14
  #include <winrt/Microsoft.ReactNative.Composition.h>
15
+ #include "ImageResponseImage.h"
10
16
 
11
17
  namespace winrt::Microsoft::ReactNative::Composition::implementation {
12
18
 
@@ -33,4 +39,77 @@ struct UriImageManager {
33
39
  winrt::Microsoft::ReactNative::Composition::ImageSource MakeImageSource(
34
40
  const facebook::react::ImageSource &source) noexcept;
35
41
 
42
+ struct ImageResponseOrImageErrorInfo {
43
+ std::shared_ptr<winrt::Microsoft::ReactNative::Composition::implementation::ImageResponseImage> image;
44
+ std::string errorInfo;
45
+ };
46
+
47
+ struct ImageResponse : ImageResponseT<ImageResponse /*, IResolveImage*/> {
48
+ ImageResponse() noexcept = default;
49
+ virtual ImageResponseOrImageErrorInfo ResolveImage();
50
+ };
51
+
52
+ struct ImageFailedResponse : ImageFailedResponseT<ImageFailedResponse, ImageResponse /*, IResolveImage*/> {
53
+ ImageFailedResponse(winrt::hstring errorMessage) noexcept : base_type(), m_errorMessage(errorMessage) {}
54
+ ImageFailedResponse(
55
+ winrt::hstring errorMessage,
56
+ winrt::Windows::Web::Http::HttpStatusCode statusCode,
57
+ const winrt::Windows::Web::Http::Headers::HttpResponseHeaderCollection &responseHeaders) noexcept
58
+ : base_type(), m_errorMessage(errorMessage), m_statusCode(statusCode), m_responseHeaders(responseHeaders) {}
59
+
60
+ virtual ImageResponseOrImageErrorInfo ResolveImage();
61
+
62
+ private:
63
+ const winrt::hstring m_errorMessage;
64
+ const winrt::Windows::Web::Http::HttpStatusCode m_statusCode{winrt::Windows::Web::Http::HttpStatusCode::None};
65
+ const winrt::Windows::Web::Http::Headers::HttpResponseHeaderCollection m_responseHeaders{nullptr};
66
+ };
67
+
68
+ struct StreamImageResponse : StreamImageResponseT<StreamImageResponse, ImageResponse /*, IResolveImage*/> {
69
+ StreamImageResponse(const winrt::Windows::Storage::Streams::IRandomAccessStream &stream) noexcept
70
+ : base_type(), m_stream(stream) {}
71
+ virtual ImageResponseOrImageErrorInfo ResolveImage();
72
+
73
+ private:
74
+ const winrt::Windows::Storage::Streams::IRandomAccessStream m_stream;
75
+ };
76
+
77
+ struct UriBrushFactoryImageResponse
78
+ : UriBrushFactoryImageResponseT<UriBrushFactoryImageResponse, ImageResponse /*, IResolveImage*/> {
79
+ UriBrushFactoryImageResponse(const winrt::Microsoft::ReactNative::Composition::UriBrushFactory &factory) noexcept
80
+ : base_type(), m_factory(factory) {}
81
+ virtual ImageResponseOrImageErrorInfo ResolveImage();
82
+
83
+ private:
84
+ const winrt::Microsoft::ReactNative::Composition::UriBrushFactory m_factory;
85
+ };
86
+
36
87
  } // namespace winrt::Microsoft::ReactNative::Composition::implementation
88
+
89
+ namespace winrt::Microsoft::ReactNative::Composition::Experimental::implementation {
90
+ struct UriBrushFactoryImageResponse
91
+ : UriBrushFactoryImageResponseT<
92
+ UriBrushFactoryImageResponse,
93
+ winrt::Microsoft::ReactNative::Composition::implementation::
94
+ ImageResponse /*, winrt::Microsoft::ReactNative::Composition::implementation::IResolveImage*/> {
95
+ UriBrushFactoryImageResponse(
96
+ const winrt::Microsoft::ReactNative::Composition::Experimental::UriBrushFactory &factory) noexcept
97
+ : base_type(), m_factory(factory) {}
98
+ virtual winrt::Microsoft::ReactNative::Composition::implementation::ImageResponseOrImageErrorInfo ResolveImage();
99
+
100
+ private:
101
+ const winrt::Microsoft::ReactNative::Composition::Experimental::UriBrushFactory m_factory;
102
+ };
103
+ } // namespace winrt::Microsoft::ReactNative::Composition::Experimental::implementation
104
+
105
+ namespace winrt::Microsoft::ReactNative::Composition::factory_implementation {
106
+ struct ImageFailedResponse : ImageFailedResponseT<ImageFailedResponse, implementation::ImageFailedResponse> {};
107
+ struct StreamImageResponse : StreamImageResponseT<StreamImageResponse, implementation::StreamImageResponse> {};
108
+ struct UriBrushFactoryImageResponse
109
+ : UriBrushFactoryImageResponseT<UriBrushFactoryImageResponse, implementation::UriBrushFactoryImageResponse> {};
110
+ } // namespace winrt::Microsoft::ReactNative::Composition::factory_implementation
111
+
112
+ namespace winrt::Microsoft::ReactNative::Composition::Experimental::factory_implementation {
113
+ struct UriBrushFactoryImageResponse
114
+ : UriBrushFactoryImageResponseT<UriBrushFactoryImageResponse, implementation::UriBrushFactoryImageResponse> {};
115
+ } // namespace winrt::Microsoft::ReactNative::Composition::Experimental::factory_implementation
@@ -12,7 +12,6 @@
12
12
  #include <Fabric/FabricUIManagerModule.h>
13
13
  #include <Fabric/ReactNativeConfigProperties.h>
14
14
  #include <Fabric/WindowsComponentDescriptorRegistry.h>
15
- #include <ICompositionRootView.h>
16
15
  #include <IReactContext.h>
17
16
  #include <IReactRootView.h>
18
17
  #include <JSI/jsi.h>
@@ -142,8 +141,9 @@ const IComponentViewRegistry &FabricUIManager::GetViewRegistry() const noexcept
142
141
  }
143
142
 
144
143
  void FabricUIManager::startSurface(
145
- const winrt::Microsoft::ReactNative::CompositionRootView &rootView,
144
+ const winrt::Microsoft::ReactNative::ReactNativeIsland &rootView,
146
145
  facebook::react::SurfaceId surfaceId,
146
+ const facebook::react::LayoutConstraints &layoutConstraints,
147
147
  const std::string &moduleName,
148
148
  const folly::dynamic &initialProps) noexcept {
149
149
  m_surfaceRegistry.insert({surfaceId, {rootView}});
@@ -158,22 +158,16 @@ void FabricUIManager::startSurface(
158
158
  root->start(rootView);
159
159
  });
160
160
 
161
- facebook::react::LayoutContext context;
162
- facebook::react::LayoutConstraints constraints;
163
- context.pointScaleFactor = rootView.ScaleFactor();
164
- context.fontSizeMultiplier = rootView.ScaleFactor();
165
- constraints.minimumSize.height = rootView.Size().Height;
166
- constraints.minimumSize.width = rootView.Size().Width;
167
- constraints.maximumSize.height = rootView.Size().Height;
168
- constraints.maximumSize.width = rootView.Size().Width;
169
- constraints.layoutDirection = facebook::react::LayoutDirection::LeftToRight;
161
+ facebook::react::LayoutContext layoutContext;
162
+ layoutContext.pointScaleFactor = rootView.ScaleFactor();
163
+ layoutContext.fontSizeMultiplier = rootView.ScaleFactor();
170
164
 
171
165
  m_surfaceManager->startSurface(
172
166
  surfaceId,
173
167
  moduleName,
174
168
  initialProps,
175
- constraints, // layout constraints
176
- context // layout context
169
+ layoutConstraints,
170
+ layoutContext // layout context
177
171
  );
178
172
  }
179
173
 
@@ -181,7 +175,7 @@ void FabricUIManager::stopSurface(facebook::react::SurfaceId surfaceId) noexcept
181
175
  m_surfaceManager->stopSurface(surfaceId);
182
176
  }
183
177
 
184
- winrt::Microsoft::ReactNative::CompositionRootView FabricUIManager::GetCompositionRootView(
178
+ winrt::Microsoft::ReactNative::ReactNativeIsland FabricUIManager::GetReactNativeIsland(
185
179
  facebook::react::SurfaceId surfaceId) const noexcept {
186
180
  return m_surfaceRegistry.at(surfaceId).wkRootView.get();
187
181
  }
@@ -29,8 +29,9 @@ struct FabricUIManager final : public std::enable_shared_from_this<FabricUIManag
29
29
  void Initialize(winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept;
30
30
 
31
31
  void startSurface(
32
- const winrt::Microsoft::ReactNative::CompositionRootView &rootView,
32
+ const winrt::Microsoft::ReactNative::ReactNativeIsland &rootView,
33
33
  facebook::react::SurfaceId surfaceId,
34
+ const facebook::react::LayoutConstraints &layoutConstraints,
34
35
  const std::string &moduleName,
35
36
  const folly::dynamic &initialProps) noexcept;
36
37
 
@@ -48,7 +49,7 @@ struct FabricUIManager final : public std::enable_shared_from_this<FabricUIManag
48
49
 
49
50
  const IComponentViewRegistry &GetViewRegistry() const noexcept;
50
51
 
51
- winrt::Microsoft::ReactNative::CompositionRootView GetCompositionRootView(
52
+ winrt::Microsoft::ReactNative::ReactNativeIsland GetReactNativeIsland(
52
53
  facebook::react::SurfaceId surfaceId) const noexcept;
53
54
 
54
55
  private:
@@ -72,7 +73,7 @@ struct FabricUIManager final : public std::enable_shared_from_this<FabricUIManag
72
73
 
73
74
  ComponentViewRegistry m_registry;
74
75
  struct SurfaceInfo {
75
- winrt::weak_ref<winrt::Microsoft::ReactNative::CompositionRootView> wkRootView{nullptr};
76
+ winrt::weak_ref<winrt::Microsoft::ReactNative::ReactNativeIsland> wkRootView{nullptr};
76
77
  };
77
78
 
78
79
  std::unordered_map<facebook::react::SurfaceId, SurfaceInfo> m_surfaceRegistry;