react-native-windows 0.74.7 → 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 (49) 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 +18 -18
  10. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +2 -2
  11. package/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.cpp +4 -4
  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 +5 -5
  16. package/Microsoft.ReactNative/Fabric/Composition/{CompositionRootView.cpp → ReactNativeIsland.cpp} +59 -51
  17. package/Microsoft.ReactNative/Fabric/Composition/{CompositionRootView.h → ReactNativeIsland.h} +8 -8
  18. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +7 -8
  19. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +2 -2
  20. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +2 -2
  21. package/Microsoft.ReactNative/Fabric/Composition/UriImageManager.cpp +82 -17
  22. package/Microsoft.ReactNative/Fabric/Composition/UriImageManager.h +79 -0
  23. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +2 -2
  24. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +3 -3
  25. package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +191 -119
  26. package/Microsoft.ReactNative/Fabric/WindowsImageManager.h +11 -0
  27. package/Microsoft.ReactNative/HttpSettings.idl +19 -0
  28. package/Microsoft.ReactNative/Modules/ImageViewManagerModule.cpp +15 -11
  29. package/Microsoft.ReactNative/{CompositionRootView.idl → ReactNativeIsland.idl} +10 -10
  30. package/Microsoft.ReactNative/UriImageManager.idl +35 -17
  31. package/Microsoft.ReactNative/Utils/ImageUtils.cpp +22 -3
  32. package/Microsoft.ReactNative/Utils/ImageUtils.h +3 -1
  33. package/Microsoft.ReactNative/Views/Image/ImageViewManager.cpp +1 -1
  34. package/Microsoft.ReactNative/Views/Image/ReactImage.cpp +13 -4
  35. package/Microsoft.ReactNative/Views/Image/ReactImage.h +4 -2
  36. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  37. package/Shared/Modules/FileReaderModule.cpp +3 -4
  38. package/Shared/Modules/WebSocketModule.cpp +14 -16
  39. package/Shared/Networking/DefaultBlobResource.cpp +6 -14
  40. package/Shared/Networking/NetworkPropertyIds.cpp +60 -0
  41. package/Shared/Networking/NetworkPropertyIds.h +41 -0
  42. package/Shared/Networking/RedirectHttpFilter.cpp +18 -9
  43. package/Shared/Networking/RedirectHttpFilter.h +6 -3
  44. package/Shared/Networking/WinRTHttpResource.cpp +36 -8
  45. package/Shared/Networking/WinRTHttpResource.h +17 -0
  46. package/Shared/Shared.vcxitems +6 -4
  47. package/Shared/Shared.vcxitems.filters +5 -3
  48. package/package.json +1 -1
  49. package/templates/cpp-app/windows/MyApp/MyApp.cpp +2 -2
@@ -5,84 +5,152 @@
5
5
 
6
6
  #include "WindowsImageManager.h"
7
7
 
8
+ #include <CppRuntimeOptions.h>
8
9
  #include <Fabric/Composition/CompositionContextHelper.h>
9
10
  #include <Fabric/Composition/ImageResponseImage.h>
10
11
  #include <Fabric/Composition/UriImageManager.h>
12
+ #include <Networking/NetworkPropertyIds.h>
11
13
  #include <Utils/ImageUtils.h>
14
+ #include <fmt/format.h>
12
15
  #include <functional/functor.h>
13
16
  #include <shcore.h>
14
17
  #include <wincodec.h>
18
+ #include <winrt/Microsoft.ReactNative.Composition.h>
19
+ #include <winrt/Windows.Web.Http.Headers.h>
20
+ #include <winrt/Windows.Web.Http.h>
15
21
 
16
22
  extern "C" HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT SDKVersion, IWICImagingFactory **ppIWICImagingFactory);
17
23
 
18
24
  namespace Microsoft::ReactNative {
19
25
 
26
+ std::string FormatHResultError(winrt::hresult_error const &ex) {
27
+ return fmt::format("[0x{:0>8x}] {}", static_cast<uint32_t>(ex.code()), winrt::to_string(ex.message()));
28
+ }
29
+
20
30
  WindowsImageManager::WindowsImageManager(winrt::Microsoft::ReactNative::ReactContext reactContext)
21
31
  : m_reactContext(reactContext) {
22
32
  m_uriImageManager =
23
33
  winrt::Microsoft::ReactNative::Composition::implementation::UriImageManager::Get(reactContext.Properties());
34
+
35
+ // Ideally we'd just set m_httpClient.DefaultRequestHeaders().UserAgent().ParseAdd(m_defaultUserAgent), but when we do
36
+ // we start hitting E_STATE_CHANGED errors. Which appears to be this issue
37
+ // https://github.com/MicrosoftDocs/winrt-api/issues/2410 So instead we apply the header to each request
38
+ auto userAgent = Microsoft::React::GetRuntimeOptionString("Http.UserAgent");
39
+ if (userAgent.size() > 0) {
40
+ m_defaultUserAgent = winrt::to_hstring(userAgent);
41
+ } else if (auto userAgentProp = reactContext.Properties().Get(::Microsoft::React::DefaultUserAgentPropertyId())) {
42
+ m_defaultUserAgent = *userAgentProp;
43
+ }
24
44
  }
25
45
 
26
- winrt::com_ptr<IWICBitmapSource> wicBitmapSourceFromStream(
27
- const winrt::Windows::Storage::Streams::IRandomAccessStream &results) noexcept {
28
- if (!results) {
29
- return nullptr;
46
+ std::tuple<winrt::com_ptr<IWICBitmapSource>, winrt::com_ptr<IWICImagingFactory>, std::string> wicBitmapSourceFromStream(
47
+ const winrt::Windows::Storage::Streams::IRandomAccessStream &stream) noexcept {
48
+ try {
49
+ winrt::com_ptr<IWICImagingFactory> imagingFactory;
50
+ winrt::check_hresult(WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, imagingFactory.put()));
51
+
52
+ winrt::com_ptr<IStream> istream;
53
+ winrt::check_hresult(
54
+ CreateStreamOverRandomAccessStream(stream.as<IUnknown>().get(), __uuidof(IStream), istream.put_void()));
55
+
56
+ winrt::com_ptr<IWICBitmapDecoder> bitmapDecoder;
57
+ winrt::check_hresult(imagingFactory->CreateDecoderFromStream(
58
+ istream.get(), nullptr, WICDecodeMetadataCacheOnDemand, bitmapDecoder.put()));
59
+
60
+ if (!bitmapDecoder) {
61
+ return {nullptr, nullptr, "Failed to decode the image."};
62
+ }
63
+
64
+ winrt::com_ptr<IWICBitmapFrameDecode> decodedFrame;
65
+ winrt::check_hresult(bitmapDecoder->GetFrame(0, decodedFrame.put()));
66
+ return {decodedFrame, imagingFactory, {}};
67
+ } catch (winrt::hresult_error const &ex) {
68
+ return {nullptr, nullptr, ::Microsoft::ReactNative::FormatHResultError(winrt::hresult_error(ex))};
30
69
  }
70
+ }
71
+
72
+ winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::ReactNative::Composition::ImageResponse>
73
+ WindowsImageManager::GetImageRandomAccessStreamAsync(ReactImageSource source) const {
74
+ co_await winrt::resume_background();
31
75
 
32
- winrt::com_ptr<IWICImagingFactory> imagingFactory;
33
- winrt::check_hresult(WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, imagingFactory.put()));
76
+ winrt::Windows::Foundation::Uri uri(winrt::to_hstring(source.uri));
77
+ bool isFile = (uri.SchemeName() == L"file");
78
+ bool isAppx = (uri.SchemeName() == L"ms-appx");
34
79
 
35
- winrt::com_ptr<IStream> istream;
36
- winrt::check_hresult(
37
- CreateStreamOverRandomAccessStream(results.as<IUnknown>().get(), __uuidof(IStream), istream.put_void()));
80
+ if (isFile || isAppx) {
81
+ winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::StorageFile> getFileSync{nullptr};
38
82
 
39
- winrt::com_ptr<IWICBitmapDecoder> bitmapDecoder;
40
- if (imagingFactory->CreateDecoderFromStream(
41
- istream.get(), nullptr, WICDecodeMetadataCacheOnDemand, bitmapDecoder.put()) < 0) {
42
- return nullptr;
83
+ if (isFile) {
84
+ getFileSync = winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(uri.AbsoluteCanonicalUri());
85
+ } else {
86
+ getFileSync = winrt::Windows::Storage::StorageFile::GetFileFromApplicationUriAsync(uri);
87
+ }
88
+
89
+ winrt::Windows::Storage::StorageFile file(co_await getFileSync);
90
+ co_return winrt::Microsoft::ReactNative::Composition::StreamImageResponse(co_await file.OpenReadAsync());
43
91
  }
44
92
 
45
- winrt::com_ptr<IWICBitmapFrameDecode> decodedFrame;
46
- winrt::check_hresult(bitmapDecoder->GetFrame(0, decodedFrame.put()));
47
- return decodedFrame;
48
- }
93
+ auto httpMethod{
94
+ source.method.empty() ? winrt::Windows::Web::Http::HttpMethod::Get()
95
+ : winrt::Windows::Web::Http::HttpMethod{winrt::to_hstring(source.method)}};
49
96
 
50
- std::shared_ptr<winrt::Microsoft::ReactNative::Composition::implementation::ImageResponseImage> generateBitmap(
51
- const winrt::Windows::Storage::Streams::IRandomAccessStream &results) noexcept {
52
- winrt::com_ptr<IWICBitmapSource> decodedFrame = wicBitmapSourceFromStream(results);
97
+ winrt::Windows::Web::Http::HttpRequestMessage request{httpMethod, uri};
53
98
 
54
- if (!decodedFrame) {
55
- return nullptr;
99
+ if (!m_defaultUserAgent.empty()) {
100
+ request.Headers().Append(L"User-Agent", m_defaultUserAgent);
101
+ }
102
+
103
+ if (!source.headers.empty()) {
104
+ for (auto &header : source.headers) {
105
+ if (_stricmp(header.first.c_str(), "authorization") == 0) {
106
+ request.Headers().TryAppendWithoutValidation(winrt::to_hstring(header.first), winrt::to_hstring(header.second));
107
+ } else {
108
+ request.Headers().Append(winrt::to_hstring(header.first), winrt::to_hstring(header.second));
109
+ }
110
+ }
56
111
  }
57
112
 
58
- winrt::com_ptr<IWICImagingFactory> imagingFactory;
59
- winrt::check_hresult(WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, imagingFactory.put()));
60
- winrt::com_ptr<IWICFormatConverter> converter;
61
- winrt::check_hresult(imagingFactory->CreateFormatConverter(converter.put()));
62
-
63
- winrt::check_hresult(converter->Initialize(
64
- decodedFrame.get(),
65
- GUID_WICPixelFormat32bppPBGRA,
66
- WICBitmapDitherTypeNone,
67
- nullptr,
68
- 0.0f,
69
- WICBitmapPaletteTypeMedianCut));
70
-
71
- winrt::com_ptr<IWICBitmap> wicbmp;
72
- winrt::check_hresult(imagingFactory->CreateBitmapFromSource(converter.get(), WICBitmapCacheOnLoad, wicbmp.put()));
73
-
74
- auto image = std::make_shared<winrt::Microsoft::ReactNative::Composition::implementation::ImageResponseImage>();
75
- image->m_wicbmp = wicbmp;
76
- return image;
113
+ winrt::Windows::Web::Http::HttpResponseMessage response(co_await m_httpClient.SendRequestAsync(request));
114
+
115
+ if (!response.IsSuccessStatusCode()) {
116
+ co_return winrt::Microsoft::ReactNative::Composition::ImageFailedResponse(
117
+ response.ReasonPhrase(), response.StatusCode(), response.Headers());
118
+ }
119
+
120
+ winrt::Windows::Storage::Streams::InMemoryRandomAccessStream memoryStream;
121
+ co_await response.Content().WriteToStreamAsync(memoryStream);
122
+ memoryStream.Seek(0);
123
+
124
+ co_return winrt::Microsoft::ReactNative::Composition::StreamImageResponse(memoryStream.CloneStream());
77
125
  }
78
126
 
79
- template <typename T>
80
- void ProcessImageRequestTask(
81
- std::weak_ptr<const facebook::react::ImageResponseObserverCoordinator> &weakObserverCoordinator,
82
- const winrt::Windows::Foundation::IAsyncOperation<T> &task,
83
- Mso::Functor<std::shared_ptr<winrt::Microsoft::ReactNative::Composition::implementation::ImageResponseImage>(
84
- const T &result)> &&onSuccess) {
85
- task.Completed([weakObserverCoordinator, onSuccess = std::move(onSuccess)](auto asyncOp, auto status) {
127
+ facebook::react::ImageRequest WindowsImageManager::requestImage(
128
+ const facebook::react::ImageSource &imageSource,
129
+ facebook::react::SurfaceId surfaceId) const {
130
+ auto imageRequest = facebook::react::ImageRequest(imageSource, nullptr, {});
131
+
132
+ auto weakObserverCoordinator = (std::weak_ptr<const facebook::react::ImageResponseObserverCoordinator>)
133
+ imageRequest.getSharedObserverCoordinator();
134
+
135
+ auto rnImageSource = winrt::Microsoft::ReactNative::Composition::implementation::MakeImageSource(imageSource);
136
+ auto provider = m_uriImageManager->TryGetUriImageProvider(m_reactContext.Handle(), rnImageSource);
137
+
138
+ winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::ReactNative::Composition::ImageResponse>
139
+ imageResponseTask{nullptr};
140
+
141
+ if (provider) {
142
+ imageResponseTask = provider.GetImageResponseAsync(m_reactContext.Handle(), rnImageSource);
143
+ } else {
144
+ ReactImageSource source;
145
+ source.uri = imageSource.uri;
146
+ source.height = imageSource.size.height;
147
+ source.width = imageSource.size.width;
148
+ source.sourceType = ImageSourceType::Download;
149
+
150
+ imageResponseTask = GetImageRandomAccessStreamAsync(source);
151
+ }
152
+
153
+ imageResponseTask.Completed([weakObserverCoordinator](auto asyncOp, auto status) {
86
154
  auto observerCoordinator = weakObserverCoordinator.lock();
87
155
  if (!observerCoordinator) {
88
156
  return;
@@ -90,12 +158,16 @@ void ProcessImageRequestTask(
90
158
 
91
159
  switch (status) {
92
160
  case winrt::Windows::Foundation::AsyncStatus::Completed: {
93
- auto imageResponseImage = onSuccess(asyncOp.GetResults());
94
- if (imageResponseImage)
161
+ auto imageResponse = asyncOp.GetResults();
162
+ auto selfImageResponse =
163
+ winrt::get_self<winrt::Microsoft::ReactNative::Composition::implementation::ImageResponse>(imageResponse);
164
+ auto imageResultOrError = selfImageResponse->ResolveImage();
165
+ if (imageResultOrError.image) {
95
166
  observerCoordinator->nativeImageResponseComplete(
96
- facebook::react::ImageResponse(imageResponseImage, nullptr /*metadata*/));
97
- else
167
+ facebook::react::ImageResponse(imageResultOrError.image, nullptr /*metadata*/));
168
+ } else {
98
169
  observerCoordinator->nativeImageResponseFailed();
170
+ }
99
171
  break;
100
172
  }
101
173
  case winrt::Windows::Foundation::AsyncStatus::Canceled: {
@@ -107,86 +179,86 @@ void ProcessImageRequestTask(
107
179
  break;
108
180
  }
109
181
  case winrt::Windows::Foundation::AsyncStatus::Started: {
182
+ // TODO progress? - Can we register for progress off the download task?
183
+ // observerCoordinator->nativeImageResponseProgress(0.0/*progress*/, 0/*completed*/, 0/*total*/);
184
+ break;
110
185
  }
111
186
  }
112
187
  });
188
+ return imageRequest;
113
189
  }
114
190
 
115
- facebook::react::ImageRequest WindowsImageManager::requestImage(
116
- const facebook::react::ImageSource &imageSource,
117
- facebook::react::SurfaceId surfaceId) const {
118
- auto imageRequest = facebook::react::ImageRequest(imageSource, nullptr, {});
191
+ } // namespace Microsoft::ReactNative
119
192
 
120
- auto weakObserverCoordinator = (std::weak_ptr<const facebook::react::ImageResponseObserverCoordinator>)
121
- imageRequest.getSharedObserverCoordinator();
193
+ namespace winrt::Microsoft::ReactNative::Composition::implementation {
122
194
 
123
- auto rnImageSource = winrt::Microsoft::ReactNative::Composition::implementation::MakeImageSource(imageSource);
124
- auto provider = m_uriImageManager->TryGetUriImageProvider(m_reactContext.Handle(), rnImageSource);
195
+ ImageResponseOrImageErrorInfo StreamImageResponse::ResolveImage() {
196
+ ImageResponseOrImageErrorInfo imageOrError;
197
+ try {
198
+ auto result = ::Microsoft::ReactNative::wicBitmapSourceFromStream(m_stream);
125
199
 
126
- if (auto bProvider = provider.try_as<winrt::Microsoft::ReactNative::Composition::IUriBrushProvider>()) {
127
- ProcessImageRequestTask<winrt::Microsoft::ReactNative::Composition::UriBrushFactory>(
128
- weakObserverCoordinator,
129
- bProvider.GetSourceAsync(m_reactContext.Handle(), rnImageSource),
130
- [](const winrt::Microsoft::ReactNative::Composition::UriBrushFactory &factory) noexcept {
131
- auto image =
132
- std::make_shared<winrt::Microsoft::ReactNative::Composition::implementation::ImageResponseImage>();
133
-
134
- // Wrap the UriBrushFactory to provide the internal CompositionContext types
135
- image->m_brushFactory =
136
- [factory](
137
- const winrt::Microsoft::ReactNative::IReactContext &context,
138
- const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext
139
- &compositionContext) {
140
- auto compositor = winrt::Microsoft::ReactNative::Composition::Experimental::
141
- MicrosoftCompositionContextHelper::InnerCompositor(compositionContext);
142
- auto brush = factory(context, compositor);
143
- return winrt::Microsoft::ReactNative::Composition::Experimental::implementation::
144
- MicrosoftCompositionContextHelper::WrapBrush(brush);
145
- };
146
- return image;
147
- });
148
-
149
- return imageRequest;
200
+ auto &errorInfo = std::get<std::string>(result);
201
+ if (!errorInfo.empty()) {
202
+ imageOrError.errorInfo = errorInfo;
203
+ return imageOrError;
204
+ }
205
+
206
+ auto imagingFactory = std::get<winrt::com_ptr<IWICImagingFactory>>(result);
207
+ auto decodedFrame = std::get<winrt::com_ptr<IWICBitmapSource>>(result);
208
+
209
+ winrt::com_ptr<IWICFormatConverter> converter;
210
+ winrt::check_hresult(imagingFactory->CreateFormatConverter(converter.put()));
211
+
212
+ winrt::check_hresult(converter->Initialize(
213
+ decodedFrame.get(),
214
+ GUID_WICPixelFormat32bppPBGRA,
215
+ WICBitmapDitherTypeNone,
216
+ nullptr,
217
+ 0.0f,
218
+ WICBitmapPaletteTypeMedianCut));
219
+
220
+ imageOrError.image =
221
+ std::make_shared<winrt::Microsoft::ReactNative::Composition::implementation::ImageResponseImage>();
222
+ winrt::check_hresult(imagingFactory->CreateBitmapFromSource(
223
+ converter.get(), WICBitmapCacheOnLoad, imageOrError.image->m_wicbmp.put()));
224
+ } catch (winrt::hresult_error const &ex) {
225
+ imageOrError.errorInfo = ::Microsoft::ReactNative::FormatHResultError(winrt::hresult_error(ex));
150
226
  }
227
+ return imageOrError;
228
+ }
151
229
 
152
- if (auto brushProvider =
153
- provider.try_as<winrt::Microsoft::ReactNative::Composition::Experimental::IUriBrushProvider>()) {
154
- ProcessImageRequestTask<winrt::Microsoft::ReactNative::Composition::Experimental::UriBrushFactory>(
155
- weakObserverCoordinator,
156
- brushProvider.GetSourceAsync(m_reactContext.Handle(), rnImageSource),
157
- [](const winrt::Microsoft::ReactNative::Composition::Experimental::UriBrushFactory &factory) noexcept {
158
- auto image =
159
- std::make_shared<winrt::Microsoft::ReactNative::Composition::implementation::ImageResponseImage>();
160
- image->m_brushFactory = factory;
161
- return image;
162
- });
163
-
164
- return imageRequest;
230
+ ImageResponseOrImageErrorInfo UriBrushFactoryImageResponse::ResolveImage() {
231
+ ImageResponseOrImageErrorInfo imageOrError;
232
+ imageOrError.image =
233
+ std::make_shared<winrt::Microsoft::ReactNative::Composition::implementation::ImageResponseImage>();
234
+
235
+ // Wrap the UriBrushFactory to provide the internal CompositionContext types
236
+ imageOrError.image
237
+ ->m_brushFactory = [factory = m_factory](
238
+ const winrt::Microsoft::ReactNative::IReactContext &context,
239
+ const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext
240
+ &compositionContext) {
241
+ auto compositor =
242
+ winrt::Microsoft::ReactNative::Composition::Experimental::MicrosoftCompositionContextHelper::InnerCompositor(
243
+ compositionContext);
244
+ auto brush = factory(context, compositor);
245
+ return winrt::Microsoft::ReactNative::Composition::Experimental::implementation::MicrosoftCompositionContextHelper::
246
+ WrapBrush(brush);
165
247
  };
248
+ return imageOrError;
249
+ }
166
250
 
167
- winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::Streams::IRandomAccessStream> task;
168
- if (auto imageStreamProvider =
169
- provider.try_as<winrt::Microsoft::ReactNative::Composition::IUriImageStreamProvider>()) {
170
- task = imageStreamProvider.GetSourceAsync(m_reactContext.Handle(), rnImageSource);
171
- } else {
172
- ReactImageSource source;
173
- source.uri = imageSource.uri;
174
- source.height = imageSource.size.height;
175
- source.width = imageSource.size.width;
176
- source.sourceType = ImageSourceType::Download;
177
-
178
- task = GetImageStreamAsync(source);
179
- }
180
-
181
- // TODO progress? - Can we register for progress off the download task?
182
- // observerCoordinator->nativeImageResponseProgress((float)progress / (float)total);
251
+ } // namespace winrt::Microsoft::ReactNative::Composition::implementation
183
252
 
184
- ProcessImageRequestTask<winrt::Windows::Storage::Streams::IRandomAccessStream>(
185
- weakObserverCoordinator, task, [](const winrt::Windows::Storage::Streams::IRandomAccessStream &stream) {
186
- return generateBitmap(stream);
187
- });
253
+ namespace winrt::Microsoft::ReactNative::Composition::Experimental::implementation {
188
254
 
189
- return imageRequest;
255
+ winrt::Microsoft::ReactNative::Composition::implementation::ImageResponseOrImageErrorInfo
256
+ UriBrushFactoryImageResponse::ResolveImage() {
257
+ winrt::Microsoft::ReactNative::Composition::implementation::ImageResponseOrImageErrorInfo imageOrError;
258
+ imageOrError.image =
259
+ std::make_shared<winrt::Microsoft::ReactNative::Composition::implementation::ImageResponseImage>();
260
+ imageOrError.image->m_brushFactory = m_factory;
261
+ return imageOrError;
190
262
  }
191
263
 
192
- } // namespace Microsoft::ReactNative
264
+ } // namespace winrt::Microsoft::ReactNative::Composition::Experimental::implementation
@@ -7,6 +7,9 @@
7
7
 
8
8
  #include <Fabric/Composition/UriImageManager.h>
9
9
  #include <ReactContext.h>
10
+ #include <Utils/ImageUtils.h>
11
+ #include <winrt/Microsoft.ReactNative.Composition.h>
12
+ #include <winrt/Windows.Web.Http.h>
10
13
 
11
14
  namespace Microsoft::ReactNative {
12
15
 
@@ -18,8 +21,16 @@ struct WindowsImageManager {
18
21
  facebook::react::SurfaceId surfaceId) const;
19
22
 
20
23
  private:
24
+ winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::ReactNative::Composition::ImageResponse>
25
+ GetImageRandomAccessStreamAsync(ReactImageSource source) const;
26
+
27
+ winrt::Windows::Web::Http::HttpClient m_httpClient;
21
28
  winrt::Microsoft::ReactNative::ReactContext m_reactContext;
29
+ winrt::hstring m_defaultUserAgent;
22
30
  std::shared_ptr<winrt::Microsoft::ReactNative::Composition::implementation::UriImageManager> m_uriImageManager;
23
31
  };
24
32
 
33
+ std::tuple<winrt::com_ptr<IWICBitmapSource>, winrt::com_ptr<IWICImagingFactory>, std::string> wicBitmapSourceFromStream(
34
+ const winrt::Windows::Storage::Streams::IRandomAccessStream &stream) noexcept;
35
+
25
36
  } // namespace Microsoft::ReactNative
@@ -0,0 +1,19 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ import "ReactInstanceSettings.idl";
5
+
6
+ #include "DocString.h"
7
+
8
+ namespace Microsoft.ReactNative
9
+ {
10
+ [webhosthidden]
11
+ DOC_STRING(
12
+ "Provides settings for Http functionality. ")
13
+ runtimeclass HttpSettings
14
+ {
15
+ DOC_STRING(
16
+ "Configures the react instance to use a user-agent header by default on http requests.")
17
+ static void SetDefaultUserAgent(Microsoft.ReactNative.ReactInstanceSettings settings, String userAgent);
18
+ }
19
+ } // namespace Microsoft.ReactNative
@@ -14,6 +14,7 @@
14
14
  #include <Views/Image/ReactImage.h>
15
15
  #include <cxxreact/JsArgumentHelpers.h>
16
16
  #ifdef USE_FABRIC
17
+ #include <Fabric/WindowsImageManager.h>
17
18
  #include <Utils/Helpers.h>
18
19
  #include <wincodec.h>
19
20
  #include "XamlUtils.h"
@@ -29,12 +30,8 @@ using namespace xaml::Media::Imaging;
29
30
 
30
31
  namespace Microsoft::ReactNative {
31
32
 
32
- #ifdef USE_FABRIC
33
- winrt::com_ptr<IWICBitmapSource> wicBitmapSourceFromStream(
34
- const winrt::Windows::Storage::Streams::IRandomAccessStream &results) noexcept;
35
- #endif // USE_FABRIC
36
-
37
33
  winrt::fire_and_forget GetImageSizeAsync(
34
+ const winrt::Microsoft::ReactNative::IReactPropertyBag &properties,
38
35
  std::string uriString,
39
36
  winrt::Microsoft::ReactNative::JSValue &&headers,
40
37
  Mso::Functor<void(int32_t width, int32_t height)> successCallback,
@@ -62,7 +59,7 @@ winrt::fire_and_forget GetImageSizeAsync(
62
59
 
63
60
  winrt::IRandomAccessStream memoryStream;
64
61
  if (needsDownload) {
65
- memoryStream = co_await GetImageStreamAsync(source);
62
+ memoryStream = co_await GetImageStreamAsync(properties, source);
66
63
  } else if (inlineData) {
67
64
  memoryStream = co_await GetImageInlineDataAsync(source);
68
65
  }
@@ -80,11 +77,16 @@ winrt::fire_and_forget GetImageSizeAsync(
80
77
  }
81
78
  #ifdef USE_FABRIC
82
79
  } else {
83
- UINT width, height;
84
- auto wicBmpSource = wicBitmapSourceFromStream(memoryStream);
85
- if (SUCCEEDED(wicBmpSource->GetSize(&width, &height))) {
86
- successCallback(width, height);
87
- succeeded = true;
80
+ auto result = wicBitmapSourceFromStream(memoryStream);
81
+ auto &errorInfo = std::get<std::string>(result);
82
+ if (errorInfo.empty()) {
83
+ auto imagingFactory = std::get<winrt::com_ptr<IWICImagingFactory>>(result);
84
+ auto wicBmpSource = std::get<winrt::com_ptr<IWICBitmapSource>>(result);
85
+ UINT width, height;
86
+ if (SUCCEEDED(wicBmpSource->GetSize(&width, &height))) {
87
+ successCallback(width, height);
88
+ succeeded = true;
89
+ }
88
90
  }
89
91
  }
90
92
  #endif // USE_FABRIC
@@ -105,6 +107,7 @@ void ImageLoader::getSize(std::string uri, React::ReactPromise<std::vector<doubl
105
107
  m_context.UIDispatcher().Post(
106
108
  [context = m_context, uri = std::move(uri), result = std::move(result)]() mutable noexcept {
107
109
  GetImageSizeAsync(
110
+ context.Properties().Handle(),
108
111
  std::move(uri),
109
112
  {},
110
113
  [result, context](double width, double height) noexcept {
@@ -133,6 +136,7 @@ void ImageLoader::getSizeWithHeaders(
133
136
  headers = std::move(headers),
134
137
  result = std::move(result)]() mutable noexcept {
135
138
  GetImageSizeAsync(
139
+ context.Properties().Handle(),
136
140
  std::move(uri),
137
141
  std::move(headers),
138
142
  [result, context](double width, double height) noexcept {
@@ -23,19 +23,19 @@ namespace Microsoft.ReactNative
23
23
  [default_interface]
24
24
  [webhosthidden]
25
25
  [experimental]
26
- DOC_STRING("Argument type for @CompositionRootView.NavigateFocus.")
26
+ DOC_STRING("Argument type for @ReactNativeIsland.NavigateFocus.")
27
27
  runtimeclass FocusNavigationRequest {
28
28
  DOC_STRING("Creates new instance of @FocusNavigationRequest")
29
29
  FocusNavigationRequest(FocusNavigationReason reason);
30
30
 
31
- DOC_STRING("The reason the @CompositionRootView is getting focus.")
31
+ DOC_STRING("The reason the @ReactNativeIsland is getting focus.")
32
32
  FocusNavigationReason Reason {get;set;};
33
33
  };
34
34
 
35
35
  [default_interface]
36
36
  [webhosthidden]
37
37
  [experimental]
38
- DOC_STRING("Provides result from a @CompositionRootView.NavigateFocus method call.")
38
+ DOC_STRING("Provides result from a @ReactNativeIsland.NavigateFocus method call.")
39
39
  runtimeclass FocusNavigationResult {
40
40
  DOC_STRING("Gets a value that indicates whether the focus successfully moved.")
41
41
  Boolean WasFocusMoved {get;};
@@ -51,7 +51,7 @@ namespace Microsoft.ReactNative
51
51
  " in future versions")
52
52
  interface IInternalCompositionRootView
53
53
  {
54
- DOC_STRING("The RootVisual associated with the @CompositionRootView. It must be set to show any React UI elements.")
54
+ DOC_STRING("The RootVisual associated with the @ReactNativeIsland. It must be set to show any React UI elements.")
55
55
  Microsoft.ReactNative.Composition.Experimental.IVisual InternalRootVisual { get; set; };
56
56
 
57
57
  DOC_STRING("Hosting Window that input is coming from. Only required when not using ContentIslands")
@@ -73,13 +73,13 @@ namespace Microsoft.ReactNative
73
73
  [webhosthidden]
74
74
  [experimental]
75
75
  DOC_STRING("A windows composition component that hosts React Native UI elements.")
76
- runtimeclass CompositionRootView
76
+ runtimeclass ReactNativeIsland
77
77
  {
78
- DOC_STRING("Creates a new instance of @CompositionRootView.")
79
- CompositionRootView();
78
+ DOC_STRING("Creates a new instance of @ReactNativeIsland.")
79
+ ReactNativeIsland();
80
80
 
81
81
  #ifdef USE_WINUI3
82
- CompositionRootView(Microsoft.UI.Composition.Compositor compositor);
82
+ ReactNativeIsland(Microsoft.UI.Composition.Compositor compositor);
83
83
  #endif
84
84
 
85
85
  DOC_STRING(
@@ -87,7 +87,7 @@ namespace Microsoft.ReactNative
87
87
  "It must be set to show any React UI elements.")
88
88
  IReactViewHost ReactViewHost { get; set; };
89
89
 
90
- DOC_STRING("The RootVisual associated with the @CompositionRootView. It must be set to show any React UI elements.")
90
+ DOC_STRING("The RootVisual associated with the @ReactNativeIsland. It must be set to show any React UI elements.")
91
91
  Microsoft.UI.Composition.Visual RootVisual { get; };
92
92
 
93
93
  Windows.Foundation.Size Size { get; };
@@ -95,7 +95,7 @@ namespace Microsoft.ReactNative
95
95
  DOC_STRING("ScaleFactor for this windows (DPI/96)")
96
96
  Single ScaleFactor {get; set;};
97
97
 
98
- DOC_STRING("Move focus to this @CompositionRootView")
98
+ DOC_STRING("Move focus to this @ReactNativeIsland")
99
99
  FocusNavigationResult NavigateFocus(FocusNavigationRequest request);
100
100
 
101
101
  Windows.Foundation.Size Measure(LayoutConstraints layoutConstraints, Windows.Foundation.Point viewportOffset);
@@ -20,27 +20,33 @@ namespace Microsoft.ReactNative.Composition
20
20
  Single Scale { get; };
21
21
  };
22
22
 
23
-
24
23
  [webhosthidden]
25
24
  [experimental]
26
- interface IUriImageProvider
25
+ [default_interface]
26
+ unsealed runtimeclass ImageResponse
27
27
  {
28
- DOC_STRING(
29
- "This should return true if this provider will provide an image for the provided uri.")
30
- Boolean CanLoadImageUri(Microsoft.ReactNative.IReactContext context, Windows.Foundation.Uri uri);
31
28
  }
32
29
 
33
30
  [webhosthidden]
34
31
  [experimental]
35
- DOC_STRING(
36
- "This allows applications to provide their own image caching / storage pipelines. Or to generate images on the fly based on uri.")
37
- interface IUriImageStreamProvider requires IUriImageProvider
32
+ [default_interface]
33
+ DOC_STRING(
34
+ "Use this as a return value from @IUriImageProvider.GetImageResponseAsync to provide information about why the image load failed.")
35
+ runtimeclass ImageFailedResponse : ImageResponse
38
36
  {
39
- DOC_STRING(
40
- "Returns a stream of an image file that can be decoded by Windows Imaging Component - https://learn.microsoft.com/en-us/windows/win32/api/_wic/ ")
41
- Windows.Foundation.IAsyncOperation<Windows.Storage.Streams.IRandomAccessStream> GetSourceAsync(Microsoft.ReactNative.IReactContext context, ImageSource imageSource);
37
+ ImageFailedResponse(String errorMessage);
38
+ ImageFailedResponse(String errorMessage, Windows.Web.Http.HttpStatusCode responseCode, Windows.Web.Http.Headers.HttpResponseHeaderCollection responseHeaders);
42
39
  }
43
40
 
41
+ [webhosthidden]
42
+ [experimental]
43
+ [default_interface]
44
+ runtimeclass StreamImageResponse : ImageResponse
45
+ {
46
+ DOC_STRING(
47
+ "Takes a stream of an image file that can be decoded by Windows Imaging Component - https://learn.microsoft.com/en-us/windows/win32/api/_wic/ ")
48
+ StreamImageResponse(Windows.Storage.Streams.IRandomAccessStream stream);
49
+ }
44
50
 
45
51
  [webhosthidden]
46
52
  [experimental]
@@ -48,13 +54,12 @@ namespace Microsoft.ReactNative.Composition
48
54
 
49
55
  [webhosthidden]
50
56
  [experimental]
57
+ [default_interface]
51
58
  DOC_STRING(
52
59
  "This allows applications to provide their own image rendering pipeline. Or to generate graphics on the fly based on uri.")
53
- interface IUriBrushProvider requires IUriImageProvider
60
+ runtimeclass UriBrushFactoryImageResponse : ImageResponse
54
61
  {
55
- DOC_STRING(
56
- "This allows applications to provide their own image rendering pipeline. Or to generate graphics on the fly based on uri.")
57
- Windows.Foundation.IAsyncOperation<UriBrushFactory> GetSourceAsync(Microsoft.ReactNative.IReactContext context, Microsoft.ReactNative.Composition.ImageSource imageSource);
62
+ UriBrushFactoryImageResponse(UriBrushFactory factory);
58
63
  }
59
64
 
60
65
  namespace Experimental {
@@ -65,11 +70,24 @@ namespace Microsoft.ReactNative.Composition
65
70
 
66
71
  [webhosthidden]
67
72
  [experimental]
73
+ [default_interface]
68
74
  DOC_STRING(
69
75
  "This allows applications to provide their own image rendering pipeline. Or to generate graphics on the fly based on uri.")
70
- interface IUriBrushProvider requires Microsoft.ReactNative.Composition.IUriImageProvider
76
+ runtimeclass UriBrushFactoryImageResponse : Microsoft.ReactNative.Composition.ImageResponse
71
77
  {
72
- Windows.Foundation.IAsyncOperation<UriBrushFactory> GetSourceAsync(Microsoft.ReactNative.IReactContext context, Microsoft.ReactNative.Composition.ImageSource imageSource);
78
+ UriBrushFactoryImageResponse(UriBrushFactory factory);
73
79
  }
80
+ } // namespace Experimental
81
+
82
+ [webhosthidden]
83
+ [experimental]
84
+ DOC_STRING(
85
+ "This allows applications to provide their own image caching / storage pipelines. Or to generate images on the fly based on uri.")
86
+ interface IUriImageProvider
87
+ {
88
+ DOC_STRING(
89
+ "This should return true if this provider will provide an image for the provided uri.")
90
+ Boolean CanLoadImageUri(Microsoft.ReactNative.IReactContext context, Windows.Foundation.Uri uri);
91
+ Windows.Foundation.IAsyncOperation<ImageResponse> GetImageResponseAsync(Microsoft.ReactNative.IReactContext context, ImageSource imageSource);
74
92
  }
75
93
  } // namespace Microsoft.ReactNative.Composition