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.
- package/Libraries/ReactNative/AppContainer-dev.js +3 -2
- package/Libraries/ReactNative/AppContainer-prod.js +2 -1
- package/Libraries/ReactNative/AppContainer.js +2 -0
- package/Libraries/ReactNative/AppRegistry.d.ts +7 -0
- package/Libraries/ReactNative/AppRegistry.js +8 -0
- package/Libraries/ReactNative/renderApplication.js +3 -0
- package/Microsoft.ReactNative/AsynchronousEventBeat.cpp +1 -2
- package/Microsoft.ReactNative/CompositionHwndHost.idl +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +18 -18
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +2 -2
- package/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.cpp +4 -4
- package/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.h +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +3 -3
- package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.h +3 -3
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +5 -5
- package/Microsoft.ReactNative/Fabric/Composition/{CompositionRootView.cpp → ReactNativeIsland.cpp} +59 -51
- package/Microsoft.ReactNative/Fabric/Composition/{CompositionRootView.h → ReactNativeIsland.h} +8 -8
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +7 -8
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +2 -2
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +2 -2
- package/Microsoft.ReactNative/Fabric/Composition/UriImageManager.cpp +82 -17
- package/Microsoft.ReactNative/Fabric/Composition/UriImageManager.h +79 -0
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +2 -2
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +3 -3
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +191 -119
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.h +11 -0
- package/Microsoft.ReactNative/HttpSettings.idl +19 -0
- package/Microsoft.ReactNative/Modules/ImageViewManagerModule.cpp +15 -11
- package/Microsoft.ReactNative/{CompositionRootView.idl → ReactNativeIsland.idl} +10 -10
- package/Microsoft.ReactNative/UriImageManager.idl +35 -17
- package/Microsoft.ReactNative/Utils/ImageUtils.cpp +22 -3
- package/Microsoft.ReactNative/Utils/ImageUtils.h +3 -1
- package/Microsoft.ReactNative/Views/Image/ImageViewManager.cpp +1 -1
- package/Microsoft.ReactNative/Views/Image/ReactImage.cpp +13 -4
- package/Microsoft.ReactNative/Views/Image/ReactImage.h +4 -2
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/Shared/Modules/FileReaderModule.cpp +3 -4
- package/Shared/Modules/WebSocketModule.cpp +14 -16
- package/Shared/Networking/DefaultBlobResource.cpp +6 -14
- package/Shared/Networking/NetworkPropertyIds.cpp +60 -0
- package/Shared/Networking/NetworkPropertyIds.h +41 -0
- package/Shared/Networking/RedirectHttpFilter.cpp +18 -9
- package/Shared/Networking/RedirectHttpFilter.h +6 -3
- package/Shared/Networking/WinRTHttpResource.cpp +36 -8
- package/Shared/Networking/WinRTHttpResource.h +17 -0
- package/Shared/Shared.vcxitems +6 -4
- package/Shared/Shared.vcxitems.filters +5 -3
- package/package.json +1 -1
- 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 &
|
|
28
|
-
|
|
29
|
-
|
|
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::
|
|
33
|
-
|
|
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
|
-
|
|
36
|
-
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
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 (!
|
|
55
|
-
|
|
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::
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
|
94
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
121
|
-
imageRequest.getSharedObserverCoordinator();
|
|
193
|
+
namespace winrt::Microsoft::ReactNative::Composition::implementation {
|
|
122
194
|
|
|
123
|
-
|
|
124
|
-
|
|
195
|
+
ImageResponseOrImageErrorInfo StreamImageResponse::ResolveImage() {
|
|
196
|
+
ImageResponseOrImageErrorInfo imageOrError;
|
|
197
|
+
try {
|
|
198
|
+
auto result = ::Microsoft::ReactNative::wicBitmapSourceFromStream(m_stream);
|
|
125
199
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
84
|
-
auto
|
|
85
|
-
if (
|
|
86
|
-
|
|
87
|
-
|
|
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 @
|
|
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 @
|
|
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 @
|
|
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 @
|
|
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
|
|
76
|
+
runtimeclass ReactNativeIsland
|
|
77
77
|
{
|
|
78
|
-
DOC_STRING("Creates a new instance of @
|
|
79
|
-
|
|
78
|
+
DOC_STRING("Creates a new instance of @ReactNativeIsland.")
|
|
79
|
+
ReactNativeIsland();
|
|
80
80
|
|
|
81
81
|
#ifdef USE_WINUI3
|
|
82
|
-
|
|
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 @
|
|
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 @
|
|
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
|
-
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
|
|
40
|
-
|
|
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
|
-
|
|
60
|
+
runtimeclass UriBrushFactoryImageResponse : ImageResponse
|
|
54
61
|
{
|
|
55
|
-
|
|
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
|
-
|
|
76
|
+
runtimeclass UriBrushFactoryImageResponse : Microsoft.ReactNative.Composition.ImageResponse
|
|
71
77
|
{
|
|
72
|
-
|
|
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
|