Skip to content

Commit 03bae4d

Browse files
committed
use fire and forget
1 parent f5ade7a commit 03bae4d

File tree

2 files changed

+41
-87
lines changed

2 files changed

+41
-87
lines changed

windows/RNPrint/RNPrint.cpp

Lines changed: 40 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
#include "winrt/Windows.Foundation.h"
99
#include <winrt/Windows.System.h>
1010
#include <winrt/Windows.Web.Http.h>
11-
#include <winrt/Windows.Storage.h>
11+
#include <windows.h>
12+
#include <shellapi.h>
1213

1314
using namespace winrt;
1415
using namespace winrt::Microsoft::ReactNative;
@@ -23,13 +24,15 @@ void RNPrint::Initialize(React::ReactContext const &reactContext) noexcept {
2324
m_context = reactContext;
2425
}
2526

26-
void RNPrint::Print(RNPrintCodegen::RNPrintSpec_RNPrintOptions&& options, ::React::ReactPromise<::React::JSValue>&& promise) noexcept
27+
winrt::fire_and_forget RNPrint::Print(
28+
RNPrintCodegen::RNPrintSpec_RNPrintOptions options,
29+
::React::ReactPromise<::React::JSValue> promise) noexcept
2730
{
2831
try
2932
{
3033
if (!options.filePath.has_value()) {
3134
promise.Reject(L"Only filePath printing is supported without XAML controls.");
32-
return;
35+
co_return;
3336
}
3437

3538
std::string filePathStr = options.filePath.value();
@@ -38,7 +41,7 @@ void RNPrint::Print(RNPrintCodegen::RNPrintSpec_RNPrintOptions&& options, ::Reac
3841
// Check if the filePath is a URL (http/https)
3942
if (filePathStr.rfind("http://", 0) == 0 || filePathStr.rfind("https://", 0) == 0) {
4043
// Download the file to a temporary location first
41-
m_context.UIDispatcher().Post([filePathStr, promise = std::move(promise)]() mutable {
44+
m_context.UIDispatcher().Post([options, filePathStr, promise = std::move(promise)]() mutable -> winrt::fire_and_forget {
4245
using namespace winrt::Windows::Storage;
4346
using namespace winrt::Windows::Web::Http;
4447
using namespace winrt::Windows::Foundation;
@@ -48,103 +51,54 @@ void RNPrint::Print(RNPrintCodegen::RNPrintSpec_RNPrintOptions&& options, ::Reac
4851
auto uri = winrt::Windows::Foundation::Uri(winrt::to_hstring(filePathStr));
4952
HttpClient httpClient;
5053

51-
httpClient.GetBufferAsync(uri).Completed(
52-
[tempFolder, uri, promise = std::move(promise)](
53-
IAsyncOperationWithProgress<winrt::Windows::Storage::Streams::IBuffer, winrt::Windows::Web::Http::HttpProgress> op,
54-
AsyncStatus status) mutable
55-
{
56-
if (status != AsyncStatus::Completed) {
57-
promise.Reject(L"Failed to download file for printing.");
58-
return;
59-
}
60-
auto buffer = op.GetResults();
61-
auto path = uri.Path();
62-
std::wstring fileName = L"printfile";
63-
if (!path.empty()) {
64-
std::wstring wpath = path.c_str();
65-
size_t pos = wpath.find_last_of(L"/\\");
66-
if (pos != std::wstring::npos && pos + 1 < wpath.size()) {
67-
fileName = wpath.substr(pos + 1);
68-
}
69-
else {
70-
fileName = wpath;
71-
}
72-
}
73-
tempFolder.CreateFileAsync(fileName, CreationCollisionOption::GenerateUniqueName).Completed(
74-
[buffer, promise = std::move(promise)](IAsyncOperation<StorageFile> fileOp, AsyncStatus fileStatus) mutable {
75-
if (fileStatus != AsyncStatus::Completed) {
76-
promise.Reject(L"Failed to create temp file for printing.");
77-
return;
78-
}
79-
StorageFile file = fileOp.GetResults();
80-
FileIO::WriteBufferAsync(file, buffer).Completed(
81-
[file, promise = std::move(promise)](IAsyncAction /*writeOp*/, AsyncStatus writeStatus) mutable {
82-
if (writeStatus != AsyncStatus::Completed) {
83-
promise.Reject(L"Failed to write to temp file for printing.");
84-
return;
85-
}
86-
winrt::Windows::System::LauncherOptions options;
87-
options.DisplayApplicationPicker(false);
88-
options.PreferredApplicationDisplayName(L"Print");
89-
options.PreferredApplicationPackageFamilyName(L"");
90-
91-
winrt::Windows::System::Launcher::LaunchFileAsync(file, options).Completed(
92-
[promise = std::move(promise)](IAsyncOperation<bool> op, AsyncStatus status) mutable {
93-
if (status == AsyncStatus::Completed && op.GetResults()) {
94-
promise.Resolve(::React::JSValue(true));
95-
}
96-
else {
97-
promise.Reject(L"Failed to launch print handler for file.");
98-
}
99-
}
100-
);
101-
}
102-
);
103-
}
104-
);
54+
auto buffer = co_await httpClient.GetBufferAsync(uri);
55+
auto path = uri.Path();
56+
std::wstring fileName = L"printfile";
57+
if (!path.empty()) {
58+
std::wstring wpath = path.c_str();
59+
size_t pos = wpath.find_last_of(L"/\\");
60+
if (pos != std::wstring::npos && pos + 1 < wpath.size()) {
61+
fileName = wpath.substr(pos + 1);
10562
}
106-
);
63+
else {
64+
fileName = wpath;
65+
}
66+
}
67+
auto file = co_await tempFolder.CreateFileAsync(fileName, CreationCollisionOption::GenerateUniqueName);
68+
co_await FileIO::WriteBufferAsync(file, buffer);
69+
70+
std::wstring nativePath = file.Path().c_str(); // Get full native path
71+
ShellExecuteW(NULL, L"print", nativePath.c_str(), NULL, NULL, SW_SHOWNORMAL);
72+
promise.Resolve(options.jobName);
10773
}
10874
catch (...) {
109-
promise.Reject(L"Exception occurred while downloading file for printing.");
75+
promise.Reject(L"Exception occurred while downloading or printing file.");
11076
}
111-
});
77+
co_return;
78+
});
11279
} else {
11380
// Local file path
114-
m_context.UIDispatcher().Post([filePathHstring, promise = std::move(promise)]() mutable {
81+
m_context.UIDispatcher().Post([options, filePathHstring, promise = std::move(promise)]() mutable -> winrt::fire_and_forget {
11582
using namespace winrt::Windows::Storage;
11683
using namespace winrt::Windows::Foundation;
11784

118-
StorageFile::GetFileFromPathAsync(filePathHstring).Completed(
119-
[promise = std::move(promise)](IAsyncOperation<StorageFile> op, AsyncStatus status) mutable {
120-
if (status != AsyncStatus::Completed) {
121-
promise.Reject(L"Failed to open file for printing.");
122-
return;
123-
}
124-
StorageFile file = op.GetResults();
125-
126-
winrt::Windows::System::LauncherOptions options;
127-
options.DisplayApplicationPicker(false);
128-
options.PreferredApplicationDisplayName(L"Print");
129-
options.PreferredApplicationPackageFamilyName(L"");
130-
131-
winrt::Windows::System::Launcher::LaunchFileAsync(file, options).Completed(
132-
[promise = std::move(promise)](IAsyncOperation<bool> op, AsyncStatus status) mutable {
133-
if (status == AsyncStatus::Completed && op.GetResults()) {
134-
promise.Resolve(::React::JSValue(true));
135-
} else {
136-
promise.Reject(L"Failed to launch print handler for file.");
137-
}
138-
}
139-
);
140-
}
141-
);
85+
try {
86+
StorageFile file = co_await StorageFile::GetFileFromPathAsync(filePathHstring);
87+
std::wstring nativePath = file.Path().c_str(); // Get full native path
88+
ShellExecuteW(NULL, L"print", nativePath.c_str(), NULL, NULL, SW_SHOWNORMAL);
89+
promise.Resolve(options.jobName);
90+
}
91+
catch (...) {
92+
promise.Reject(L"Failed to open or print local file.");
93+
}
94+
co_return;
14295
});
14396
}
14497
}
14598
catch (...)
14699
{
147100
promise.Reject(L"Unknown error in Print function");
148101
}
102+
co_return;
149103
}
150104
} // namespace winrt::RNPrint

windows/RNPrint/RNPrint.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ struct RNPrint
3535
void Initialize(React::ReactContext const &reactContext) noexcept;
3636

3737
REACT_METHOD(Print, L"print");
38-
void Print(RNPrintCodegen::RNPrintSpec_RNPrintOptions && options, ::React::ReactPromise<::React::JSValue> && promise) noexcept;
38+
winrt::fire_and_forget Print(RNPrintCodegen::RNPrintSpec_RNPrintOptions options, ::React::ReactPromise<::React::JSValue> promise) noexcept;
3939

4040
private:
4141
React::ReactContext m_context;

0 commit comments

Comments
 (0)