From c87ab9460f7a8f3309508499ffeb9c17ffe59e88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Dr=C3=B3=C5=BCd=C5=BC?= <31368152+behenate@users.noreply.github.com> Date: Tue, 27 Jun 2023 18:50:10 +0200 Subject: [PATCH] [expo-print][ios] Added constants, added prevention of starting multiple print requests (#23128) # Why While migrating `expo-print` to the new Modules API I forgot to add constants to native swift code of the module. This causes `Print.Orientation.landscape/portrait` to return null. I also noticed that it is possible to start multiple print requests, which launches multiple UIPrintInteractionController print interfaces, which causes the app to crash. # How Added the constants to iOS module, added a check on JS side that checks if another print request is being processed (it's still possible to add multiple documents to the iOS print queue, it's just not possible to launch multiple iOS print bottom sheets at once). Ideally this would be added on native side, but it would add a lot more complexity to the code than a simple check on JS side. # Test Plan Tested on Android emulator and iOS simulator. --- ios/Podfile.lock | 8 ++++---- ios/versioned/sdk49/Expo/ABI49_0_0Expo.podspec.json | 2 +- .../sdk49/ExpoPrint/ABI49_0_0ExpoPrint.podspec.json | 2 +- ios/versioned/sdk49/ExpoPrint/ExpoPrintModule.swift | 9 +++++++++ ios/versioned/sdk49/ExpoPrint/PrintOptions.swift | 9 ++++++--- packages/expo-print/CHANGELOG.md | 2 ++ packages/expo-print/build/Print.d.ts.map | 2 +- packages/expo-print/build/Print.js | 12 +++++++++++- packages/expo-print/build/Print.js.map | 2 +- packages/expo-print/ios/ExpoPrintModule.swift | 9 +++++++++ packages/expo-print/ios/PrintOptions.swift | 9 ++++++--- packages/expo-print/src/Print.ts | 12 +++++++++++- 12 files changed, 62 insertions(+), 16 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index c462d49f6ec7ad..f07fb7399c2d15 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1425,7 +1425,7 @@ PODS: - ABI49_0_0ExpoModulesCore - ABI49_0_0EXPermissions (14.2.0): - ABI49_0_0ExpoModulesCore - - ABI49_0_0Expo (49.0.0-alpha.9): + - ABI49_0_0Expo (49.0.0-alpha.10): - ABI49_0_0ExpoModulesCore - ABI49_0_0ExpoAppleAuthentication (6.1.0): - ABI49_0_0ExpoModulesCore @@ -1611,7 +1611,7 @@ PODS: - ABI49_0_0EXUpdates - ABI49_0_0ExpoNetwork (5.4.0): - ABI49_0_0ExpoModulesCore - - ABI49_0_0ExpoPrint (12.4.0): + - ABI49_0_0ExpoPrint (12.4.1): - ABI49_0_0ExpoModulesCore - ABI49_0_0ExpoRandom (13.2.0): - ABI49_0_0ExpoModulesCore @@ -4784,7 +4784,7 @@ SPEC CHECKSUMS: ABI49_0_0EXMediaLibrary: 0e0e244712394523c90e1bda78127d8c76814434 ABI49_0_0EXNotifications: b8a6fdc20a5c93452177fb980d07d8c1ca73138c ABI49_0_0EXPermissions: f43bc5235e58a3bc698d3fadd6aa1ecb27020b05 - ABI49_0_0Expo: b71ccedd80113fe654059abb8a0cf99a2646c7a8 + ABI49_0_0Expo: 110e062a5a397647d2f71eaa3e438d82ce636bec ABI49_0_0ExpoAppleAuthentication: af85867e111a296a561ddf9d3f659728ee8675d0 ABI49_0_0ExpoBattery: 9417f9897691a8af49a93047d99b27c2c6c13528 ABI49_0_0ExpoBlur: 9293857092c742630ef6dadbbd6378c0965cb317 @@ -4810,7 +4810,7 @@ SPEC CHECKSUMS: ABI49_0_0ExpoModulesCore: 4f3ca2d3439d9c6293a036f0f731d858a3c100bf ABI49_0_0ExpoModulesProvider: 6d5f656e0e7f821ae6aae15fd02290c88c45feab ABI49_0_0ExpoNetwork: 028f02f5d15379f89e529b37982559e445f86ab9 - ABI49_0_0ExpoPrint: 33aeee5e8b7464c77657b2c59218c9ea9542554c + ABI49_0_0ExpoPrint: 8065c3f088efcad86befd6ead6c2bc8adb425f24 ABI49_0_0ExpoRandom: 83829ccecffd4afbdd4f711e053639e2109df0b6 ABI49_0_0ExpoScreenOrientation: 246531771c12e546098bfbac9fb44b0efc174830 ABI49_0_0ExpoSecureStore: 05b26374e173878efda9267822d64825c80f652e diff --git a/ios/versioned/sdk49/Expo/ABI49_0_0Expo.podspec.json b/ios/versioned/sdk49/Expo/ABI49_0_0Expo.podspec.json index 565caededde70e..b64ee407056906 100644 --- a/ios/versioned/sdk49/Expo/ABI49_0_0Expo.podspec.json +++ b/ios/versioned/sdk49/Expo/ABI49_0_0Expo.podspec.json @@ -1,6 +1,6 @@ { "name": "ABI49_0_0Expo", - "version": "49.0.0-alpha.9", + "version": "49.0.0-alpha.10", "summary": "The Expo SDK", "description": "The Expo SDK", "license": "MIT", diff --git a/ios/versioned/sdk49/ExpoPrint/ABI49_0_0ExpoPrint.podspec.json b/ios/versioned/sdk49/ExpoPrint/ABI49_0_0ExpoPrint.podspec.json index dedd5712c08070..20b4b3f7c3845f 100644 --- a/ios/versioned/sdk49/ExpoPrint/ABI49_0_0ExpoPrint.podspec.json +++ b/ios/versioned/sdk49/ExpoPrint/ABI49_0_0ExpoPrint.podspec.json @@ -1,6 +1,6 @@ { "name": "ABI49_0_0ExpoPrint", - "version": "12.4.0", + "version": "12.4.1", "summary": "Provides an API for iOS (AirPrint) and Android printing functionality.", "description": "Provides an API for iOS (AirPrint) and Android printing functionality.", "license": "MIT", diff --git a/ios/versioned/sdk49/ExpoPrint/ExpoPrintModule.swift b/ios/versioned/sdk49/ExpoPrint/ExpoPrintModule.swift index af92fa45b892ad..99269b403a4eb4 100644 --- a/ios/versioned/sdk49/ExpoPrint/ExpoPrintModule.swift +++ b/ios/versioned/sdk49/ExpoPrint/ExpoPrintModule.swift @@ -21,6 +21,15 @@ public class ExpoPrintModule: Module { public func definition() -> ModuleDefinition { Name("ExpoPrint") + Constants { + [ + "Orientation": [ + "portrait": PrintOrientation.portrait.rawValue, + "landscape": PrintOrientation.landscape.rawValue + ] + ] + } + AsyncFunction("print") { (options: PrintOptions, promise: Promise) in printWithPrinter.startPrint(options: options, promise: promise) } diff --git a/ios/versioned/sdk49/ExpoPrint/PrintOptions.swift b/ios/versioned/sdk49/ExpoPrint/PrintOptions.swift index 5943b338ddd8f8..6fae285bdee8a4 100644 --- a/ios/versioned/sdk49/ExpoPrint/PrintOptions.swift +++ b/ios/versioned/sdk49/ExpoPrint/PrintOptions.swift @@ -1,5 +1,10 @@ import ABI49_0_0ExpoModulesCore +enum PrintOrientation: String { + case portrait + case landscape +} + internal struct PrintOptions: Record { @Field var html: String? @@ -35,8 +40,6 @@ internal struct PrintOptions: Record { var markupFormatterIOS: String? let kLetterPaperSize = CGSize(width: 612, height: 792) - let kExpoPrintOrientationLandscape = "landscape" - let kExpoPrintOrientationPortrait = "portrait" func toPageSize() -> CGSize { // defaults to pixel size for A4 paper format with 72 PPI @@ -81,6 +84,6 @@ internal struct PrintOptions: Record { } func toUIPrintInfoOrientation() -> UIPrintInfo.Orientation { - orientation == kExpoPrintOrientationLandscape ? UIPrintInfo.Orientation.landscape : UIPrintInfo.Orientation.portrait + orientation == PrintOrientation.landscape.rawValue ? UIPrintInfo.Orientation.landscape : UIPrintInfo.Orientation.portrait } } diff --git a/packages/expo-print/CHANGELOG.md b/packages/expo-print/CHANGELOG.md index ae2d0de1017652..64b4956b2cb86f 100644 --- a/packages/expo-print/CHANGELOG.md +++ b/packages/expo-print/CHANGELOG.md @@ -8,6 +8,8 @@ ### 🐛 Bug fixes +- Fixed missing constants on iOS, restricted possibility of starting multiple print jobs at once, which would lead to crashes. ([#23128](https://github.com/expo/expo/pull/23128) by [@behenate](https://github.com/behenate)) + ### 💡 Others ## 12.4.1 — 2023-06-27 diff --git a/packages/expo-print/build/Print.d.ts.map b/packages/expo-print/build/Print.d.ts.map index d00eb6ac729c59..8b5e2368617d49 100644 --- a/packages/expo-print/build/Print.d.ts.map +++ b/packages/expo-print/build/Print.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"Print.d.ts","sourceRoot":"","sources":["../src/Print.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,OAAO,EACR,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;AAGrF;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,eAA2C,CAAC;AAGtE;;;;;;;;;;;;GAYG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAcrE;AAGD;;;;GAIG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAM3D;AAGD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAE/F"} \ No newline at end of file +{"version":3,"file":"Print.d.ts","sourceRoot":"","sources":["../src/Print.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,OAAO,EACR,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;AAIrF;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,eAA2C,CAAC;AAGtE;;;;;;;;;;;;GAYG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBrE;AAGD;;;;GAIG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAM3D;AAGD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAE/F"} \ No newline at end of file diff --git a/packages/expo-print/build/Print.js b/packages/expo-print/build/Print.js index 44cc9064a75d3a..652c8d588e0ba1 100644 --- a/packages/expo-print/build/Print.js +++ b/packages/expo-print/build/Print.js @@ -1,6 +1,7 @@ import { UnavailabilityError } from 'expo-modules-core'; import { Platform } from 'react-native'; import ExponentPrint from './ExponentPrint'; +let isPrinting = false; // @needsAudit @docsMissing /** * The orientation of the printed content. @@ -33,7 +34,16 @@ export async function printAsync(options) { if (options.markupFormatterIOS !== undefined) { console.warn('The markupFormatterIOS option is deprecated. Use useMarkupFormatter instead.'); } - return await ExponentPrint.print(options); + if (isPrinting) { + throw new Error('Another print request is already in progress'); + } + isPrinting = true; + try { + return await ExponentPrint.print(options); + } + finally { + isPrinting = false; + } } // @needsAudit /** diff --git a/packages/expo-print/build/Print.js.map b/packages/expo-print/build/Print.js.map index 9a91741325137a..b9a3951ed744bb 100644 --- a/packages/expo-print/build/Print.js.map +++ b/packages/expo-print/build/Print.js.map @@ -1 +1 @@ -{"version":3,"file":"Print.js","sourceRoot":"","sources":["../src/Print.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAW5C,2BAA2B;AAC3B;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAoB,aAAa,CAAC,WAAW,CAAC;AAEtE,cAAc;AACd;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAqB;IACpD,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE;QACzB,OAAO,MAAM,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;KAC3C;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE;QACzF,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;KACjE;IACD,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE;QAC/B,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;KACzF;IACD,IAAI,OAAO,CAAC,kBAAkB,KAAK,SAAS,EAAE;QAC5C,OAAO,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAC;KAC9F;IACD,OAAO,MAAM,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,cAAc;AACd;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,IAAI,aAAa,CAAC,aAAa,EAAE;QAC/B,OAAO,MAAM,aAAa,CAAC,aAAa,EAAE,CAAC;KAC5C;IAED,MAAM,IAAI,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;AAC/D,CAAC;AAED,cAAc;AACd;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,UAA4B,EAAE;IACnE,OAAO,MAAM,aAAa,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AACvD,CAAC","sourcesContent":["import { UnavailabilityError } from 'expo-modules-core';\nimport { Platform } from 'react-native';\n\nimport ExponentPrint from './ExponentPrint';\nimport {\n FilePrintOptions,\n FilePrintResult,\n OrientationType,\n PrintOptions,\n Printer,\n} from './Print.types';\n\nexport { FilePrintOptions, FilePrintResult, OrientationType, PrintOptions, Printer };\n\n// @needsAudit @docsMissing\n/**\n * The orientation of the printed content.\n */\nexport const Orientation: OrientationType = ExponentPrint.Orientation;\n\n// @needsAudit\n/**\n * Prints a document or HTML, on web this prints the HTML from the page.\n * > Note: On iOS, printing from HTML source doesn't support local asset URLs (due to `WKWebView`\n * > limitations). As a workaround you can use inlined base64-encoded strings.\n * > See [this comment](https://github.com/expo/expo/issues/7940#issuecomment-657111033) for more details.\n *\n * > Note: on iOS, when printing without providing a `PrintOptions.printerUrl` the `Promise` will be\n * > resolved once printing is started in the native print window and rejected if the window is closed without\n * > starting the print. On Android the `Promise` will be resolved immediately after displaying the native print window\n * > and won't be rejected if the window is closed without starting the print.\n * @param options A map defining what should be printed.\n * @return Resolves to an empty `Promise` if printing started.\n */\nexport async function printAsync(options: PrintOptions): Promise {\n if (Platform.OS === 'web') {\n return await ExponentPrint.print(options);\n }\n if (!options.uri && !options.html && Platform.OS === 'ios' && !options.markupFormatterIOS) {\n throw new Error('Must provide either `html` or `uri` to print');\n }\n if (options.uri && options.html) {\n throw new Error('Must provide exactly one of `html` and `uri` but both were specified');\n }\n if (options.markupFormatterIOS !== undefined) {\n console.warn('The markupFormatterIOS option is deprecated. Use useMarkupFormatter instead.');\n }\n return await ExponentPrint.print(options);\n}\n\n// @needsAudit\n/**\n * Chooses a printer that can be later used in `printAsync`\n * @return A promise which fulfils with an object containing `name` and `url` of the selected printer.\n * @platform ios\n */\nexport async function selectPrinterAsync(): Promise {\n if (ExponentPrint.selectPrinter) {\n return await ExponentPrint.selectPrinter();\n }\n\n throw new UnavailabilityError('Print', 'selectPrinterAsync');\n}\n\n// @needsAudit\n/**\n * Prints HTML to PDF file and saves it to [app's cache directory](./filesystem/#filesystemcachedirectory).\n * On Web this method opens the print dialog.\n * @param options A map of print options.\n */\nexport async function printToFileAsync(options: FilePrintOptions = {}): Promise {\n return await ExponentPrint.printToFileAsync(options);\n}\n"]} \ No newline at end of file +{"version":3,"file":"Print.js","sourceRoot":"","sources":["../src/Print.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAW5C,IAAI,UAAU,GAAG,KAAK,CAAC;AACvB,2BAA2B;AAC3B;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAoB,aAAa,CAAC,WAAW,CAAC;AAEtE,cAAc;AACd;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAqB;IACpD,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE;QACzB,OAAO,MAAM,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;KAC3C;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE;QACzF,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;KACjE;IACD,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE;QAC/B,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;KACzF;IACD,IAAI,OAAO,CAAC,kBAAkB,KAAK,SAAS,EAAE;QAC5C,OAAO,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAC;KAC9F;IACD,IAAI,UAAU,EAAE;QACd,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;KACjE;IAED,UAAU,GAAG,IAAI,CAAC;IAClB,IAAI;QACF,OAAO,MAAM,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;KAC3C;YAAS;QACR,UAAU,GAAG,KAAK,CAAC;KACpB;AACH,CAAC;AAED,cAAc;AACd;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,IAAI,aAAa,CAAC,aAAa,EAAE;QAC/B,OAAO,MAAM,aAAa,CAAC,aAAa,EAAE,CAAC;KAC5C;IAED,MAAM,IAAI,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;AAC/D,CAAC;AAED,cAAc;AACd;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,UAA4B,EAAE;IACnE,OAAO,MAAM,aAAa,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AACvD,CAAC","sourcesContent":["import { UnavailabilityError } from 'expo-modules-core';\nimport { Platform } from 'react-native';\n\nimport ExponentPrint from './ExponentPrint';\nimport {\n FilePrintOptions,\n FilePrintResult,\n OrientationType,\n PrintOptions,\n Printer,\n} from './Print.types';\n\nexport { FilePrintOptions, FilePrintResult, OrientationType, PrintOptions, Printer };\n\nlet isPrinting = false;\n// @needsAudit @docsMissing\n/**\n * The orientation of the printed content.\n */\nexport const Orientation: OrientationType = ExponentPrint.Orientation;\n\n// @needsAudit\n/**\n * Prints a document or HTML, on web this prints the HTML from the page.\n * > Note: On iOS, printing from HTML source doesn't support local asset URLs (due to `WKWebView`\n * > limitations). As a workaround you can use inlined base64-encoded strings.\n * > See [this comment](https://github.com/expo/expo/issues/7940#issuecomment-657111033) for more details.\n *\n * > Note: on iOS, when printing without providing a `PrintOptions.printerUrl` the `Promise` will be\n * > resolved once printing is started in the native print window and rejected if the window is closed without\n * > starting the print. On Android the `Promise` will be resolved immediately after displaying the native print window\n * > and won't be rejected if the window is closed without starting the print.\n * @param options A map defining what should be printed.\n * @return Resolves to an empty `Promise` if printing started.\n */\nexport async function printAsync(options: PrintOptions): Promise {\n if (Platform.OS === 'web') {\n return await ExponentPrint.print(options);\n }\n if (!options.uri && !options.html && Platform.OS === 'ios' && !options.markupFormatterIOS) {\n throw new Error('Must provide either `html` or `uri` to print');\n }\n if (options.uri && options.html) {\n throw new Error('Must provide exactly one of `html` and `uri` but both were specified');\n }\n if (options.markupFormatterIOS !== undefined) {\n console.warn('The markupFormatterIOS option is deprecated. Use useMarkupFormatter instead.');\n }\n if (isPrinting) {\n throw new Error('Another print request is already in progress');\n }\n\n isPrinting = true;\n try {\n return await ExponentPrint.print(options);\n } finally {\n isPrinting = false;\n }\n}\n\n// @needsAudit\n/**\n * Chooses a printer that can be later used in `printAsync`\n * @return A promise which fulfils with an object containing `name` and `url` of the selected printer.\n * @platform ios\n */\nexport async function selectPrinterAsync(): Promise {\n if (ExponentPrint.selectPrinter) {\n return await ExponentPrint.selectPrinter();\n }\n\n throw new UnavailabilityError('Print', 'selectPrinterAsync');\n}\n\n// @needsAudit\n/**\n * Prints HTML to PDF file and saves it to [app's cache directory](./filesystem/#filesystemcachedirectory).\n * On Web this method opens the print dialog.\n * @param options A map of print options.\n */\nexport async function printToFileAsync(options: FilePrintOptions = {}): Promise {\n return await ExponentPrint.printToFileAsync(options);\n}\n"]} \ No newline at end of file diff --git a/packages/expo-print/ios/ExpoPrintModule.swift b/packages/expo-print/ios/ExpoPrintModule.swift index fa00dd3df65d08..225ce194f61284 100644 --- a/packages/expo-print/ios/ExpoPrintModule.swift +++ b/packages/expo-print/ios/ExpoPrintModule.swift @@ -21,6 +21,15 @@ public class ExpoPrintModule: Module { public func definition() -> ModuleDefinition { Name("ExpoPrint") + Constants { + [ + "Orientation": [ + "portrait": PrintOrientation.portrait.rawValue, + "landscape": PrintOrientation.landscape.rawValue + ] + ] + } + AsyncFunction("print") { (options: PrintOptions, promise: Promise) in printWithPrinter.startPrint(options: options, promise: promise) } diff --git a/packages/expo-print/ios/PrintOptions.swift b/packages/expo-print/ios/PrintOptions.swift index a83cbbbef9bfca..340e9b0c4e384f 100644 --- a/packages/expo-print/ios/PrintOptions.swift +++ b/packages/expo-print/ios/PrintOptions.swift @@ -1,5 +1,10 @@ import ExpoModulesCore +enum PrintOrientation: String { + case portrait + case landscape +} + internal struct PrintOptions: Record { @Field var html: String? @@ -35,8 +40,6 @@ internal struct PrintOptions: Record { var markupFormatterIOS: String? let kLetterPaperSize = CGSize(width: 612, height: 792) - let kExpoPrintOrientationLandscape = "landscape" - let kExpoPrintOrientationPortrait = "portrait" func toPageSize() -> CGSize { // defaults to pixel size for A4 paper format with 72 PPI @@ -81,6 +84,6 @@ internal struct PrintOptions: Record { } func toUIPrintInfoOrientation() -> UIPrintInfo.Orientation { - orientation == kExpoPrintOrientationLandscape ? UIPrintInfo.Orientation.landscape : UIPrintInfo.Orientation.portrait + orientation == PrintOrientation.landscape.rawValue ? UIPrintInfo.Orientation.landscape : UIPrintInfo.Orientation.portrait } } diff --git a/packages/expo-print/src/Print.ts b/packages/expo-print/src/Print.ts index 1c51ce67d45dc7..8d814310bd44a5 100644 --- a/packages/expo-print/src/Print.ts +++ b/packages/expo-print/src/Print.ts @@ -12,6 +12,7 @@ import { export { FilePrintOptions, FilePrintResult, OrientationType, PrintOptions, Printer }; +let isPrinting = false; // @needsAudit @docsMissing /** * The orientation of the printed content. @@ -45,7 +46,16 @@ export async function printAsync(options: PrintOptions): Promise { if (options.markupFormatterIOS !== undefined) { console.warn('The markupFormatterIOS option is deprecated. Use useMarkupFormatter instead.'); } - return await ExponentPrint.print(options); + if (isPrinting) { + throw new Error('Another print request is already in progress'); + } + + isPrinting = true; + try { + return await ExponentPrint.print(options); + } finally { + isPrinting = false; + } } // @needsAudit