Skip to content

Add Windows support #522

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Dec 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 71 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ So you should install react-native-pdf and rn-fetch-blob
| progress-bar-android | | | | 1.0.3+ |
| progress-view | | | | 1.0.3+ |

Currently, Windows support is partial. The rn-fetch-blob module is not yet available on Windows, only loading bundled PDFs is supported.

### Installation

```bash
Expand Down Expand Up @@ -86,6 +88,31 @@ react-native link react-native-pdf

</details>

### Windows installation
<details>
<sumary>Windows details</summary>

- Open your solution in Visual Studio 2019 (eg. `windows\yourapp.sln`)
- Right-click Solution icon in Solution Explorer > Add > Existing Project...
- Add `node_modules\@react-native-community\progress-view\windows\progress-view\progress-view.vcxproj`
- If running RNW 0.62: add `node_modules\react-native-pdf\windows\RCTPdf\RCTPdf.vcxproj`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bzoz @jaimecbernardo - Why is this a 0.62 note? It looks like this is required even in 0.63?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This action isn't needed for RNW 0.63 for RCTPdf, since auto-linking does it.
Adding the #include "winrt/RCTPdf.h" line is still needed, though, due to the existing XAML component or there'll be an error on XamlTypeInfo.g.cpp.

Manual linking is still needed for the @react-native-community/progress-view module though.

- Right-click main application project > Add > Reference...
- Select `progress-view` and in Solution Projects
- If running 0.62, also select `RCTPdf`
- In app `pch.h` add `#include "winrt/progress-view.h"` and `#include "winrt/RCTPdf.h"`
- In `App.cpp` add `PackageProviders().Append(winrt::progress-view::ReactPackageProvider());` before `InitializeComponent();`
- If running RNW 0.62, also add `PackageProviders().Append(winrt::RCTPdf::ReactPackageProvider());`

#### Bundling PDFs with the app
To add a `test.pdf` like in the example add:
```
<None Include="..\..\test.pdf">
<DeploymentContent>true</DeploymentContent>
</None>
```
in the app `.vcxproj` file, before `<None Include="packages.config" />`.
</details>

### FAQ
<details>
<summary>FAQ details</summary>
Expand Down Expand Up @@ -270,55 +297,56 @@ const styles = StyleSheet.create({

### Configuration

| Property | Type | Default | Description | iOS | Android | FirstRelease |
| ------------- |:-------------:|:----------------:| ------------------- | ------| ------- | ------------ |
| source | object | not null | PDF source like {uri:xxx, cache:false}. see the following for detail.| ✔ | ✔ | <3.0 |
| page | number | 1 | initial page index | ✔ | ✔ | <3.0 |
| scale | number | 1.0 | should minScale<=scale<=maxScale| ✔ | ✔ | <3.0 |
| minScale | number | 1.0 | min scale| ✔ | ✔ | 5.0.5 |
| maxScale | number | 3.0 | max scale| ✔ | ✔ | 5.0.5 |
| horizontal | bool | false | draw page direction, if you want to listen the orientation change, you can use [[react-native-orientation-locker]](https://github.com/wonday/react-native-orientation-locker)| ✔ | ✔ | <3.0 |
| fitWidth | bool | false | if true fit the width of view, can not use fitWidth=true together with scale| ✔ | ✔ | <3.0, abandoned from 3.0 |
| fitPolicy | number | 2 | 0:fit width, 1:fit height, 2:fit both(default)| ✔ | ✔ | 3.0 |
| spacing | number | 10 | the breaker size between pages| ✔ | ✔ | <3.0 |
| password | string | "" | pdf password, if password error, will call OnError() with message "Password required or incorrect password." | ✔ | ✔ | <3.0 |
| style | object | {backgroundColor:"#eee"} | support normal view style, you can use this to set border/spacing color... | ✔ | ✔ | <3.0 |
| activityIndicator | Component | <ProgressBar/> | when loading show it as an indicator, you can use your component| ✔ | ✔ | <3.0 |
| activityIndicatorProps | object | {color:'#009900', progressTintColor:'#009900'} | activityIndicator props | ✔ | ✔ | 3.1 |
| enableAntialiasing | bool | true | improve rendering a little bit on low-res screens, but maybe course some problem on Android 4.4, so add a switch | ✖ | ✔ | <3.0 |
| enablePaging | bool | false | only show one page in screen | ✔ | ✔ | 5.0.1 |
| enableRTL | bool | false | scroll page as "page3, page2, page1" | ✔ | ✖ | 5.0.1 |
| enableAnnotationRendering | bool | true | enable rendering annotation, notice:iOS only support initial setting,not support realtime changing | ✔ | ✔ | 5.0.3 |
| trustAllCerts | bool | true | Allow connections to servers with self-signed certification | ✔ | ✔ | 6.0.? |
| singlePage | bool | false | Only show first page, useful for thumbnail views | ✔ | ✔ | 6.1.2 |
| onLoadProgress | function(percent) | null | callback when loading, return loading progress (0-1) | ✔ | ✔ | <3.0 |
| onLoadComplete | function(numberOfPages, path, {width, height}, tableContents) | null | callback when pdf load completed, return total page count, pdf local/cache path, {width,height} and table of contents | ✔ | ✔ | <3.0 |
| onPageChanged | function(page,numberOfPages) | null | callback when page changed ,return current page and total page count | ✔ | ✔ | <3.0 |
| onError | function(error) | null | callback when error happened | ✔ | ✔ | <3.0 |
| onPageSingleTap | function(page) | null | callback when page was single tapped | ✔ | ✔ | 3.0 |
| onScaleChanged | function(scale) | null | callback when scale page | ✔ | ✔ | 3.0 |
| onPressLink | function(uri) | null | callback when link tapped | ✔ | ✔ | 6.0.0 |
| Property | Type | Default | Description | iOS | Android | Windows | FirstRelease |
| ------------- |:-------------:|:----------------:| ------------------- | ------| ------- | ------- | ------------ |
| source | object | not null | PDF source like {uri:xxx, cache:false}. see the following for detail.| ✔ | ✔ | partial | <3.0 |
| page | number | 1 | initial page index | ✔ | ✔ | ✔ | <3.0 |
| scale | number | 1.0 | should minScale<=scale<=maxScale| ✔ | ✔ | ✔ | <3.0 |
| minScale | number | 1.0 | min scale| ✔ | ✔ | ✔ | 5.0.5 |
| maxScale | number | 3.0 | max scale| ✔ | ✔ | ✔ | 5.0.5 |
| horizontal | bool | false | draw page direction, if you want to listen the orientation change, you can use [[react-native-orientation-locker]](https://github.com/wonday/react-native-orientation-locker)| ✔ | ✔ | ✔ | <3.0 |
| fitWidth | bool | false | if true fit the width of view, can not use fitWidth=true together with scale| ✔ | ✔ | ✔ | <3.0, abandoned from 3.0 |
| fitPolicy | number | 2 | 0:fit width, 1:fit height, 2:fit both(default)| ✔ | ✔ | ✔ | 3.0 |
| spacing | number | 10 | the breaker size between pages| ✔ | ✔ | ✔ | <3.0 |
| password | string | "" | pdf password, if password error, will call OnError() with message "Password required or incorrect password." | ✔ | ✔ | ✔ | <3.0 |
| style | object | {backgroundColor:"#eee"} | support normal view style, you can use this to set border/spacing color... | ✔ | ✔ | ✔ | <3.0 |
| activityIndicator | Component | <ProgressBar/> | when loading show it as an indicator, you can use your component| ✔ | ✔ | ✖ | <3.0 |
| activityIndicatorProps | object | {color:'#009900', progressTintColor:'#009900'} | activityIndicator props | ✔ | ✔ | ✖ | 3.1 |
| enableAntialiasing | bool | true | improve rendering a little bit on low-res screens, but maybe course some problem on Android 4.4, so add a switch | ✖ | ✔ | ✖ | <3.0 |
| enablePaging | bool | false | only show one page in screen | ✔ | ✔ | ✔ | 5.0.1 |
| enableRTL | bool | false | scroll page as "page3, page2, page1" | ✔ | ✖ | ✔ | 5.0.1 |
| enableAnnotationRendering | bool | true | enable rendering annotation, notice:iOS only support initial setting,not support realtime changing | ✔ | ✔ | ✖ | 5.0.3 |
| trustAllCerts | bool | true | Allow connections to servers with self-signed certification | ✔ | ✔ | ✖ | 6.0.? |
| singlePage | bool | false | Only show first page, useful for thumbnail views | ✔ | ✔ | ✔ | 6.1.2 |
| onLoadProgress | function(percent) | null | callback when loading, return loading progress (0-1) | ✔ | ✔ | ✖ | <3.0 |
| onLoadComplete | function(numberOfPages, path, {width, height}, tableContents) | null | callback when pdf load completed, return total page count, pdf local/cache path, {width,height} and table of contents | ✔ | ✔ | ✔ but without tableContents | <3.0 |
| onPageChanged | function(page,numberOfPages) | null | callback when page changed ,return current page and total page count | ✔ | ✔ | ✔ | <3.0 |
| onError | function(error) | null | callback when error happened | ✔ | ✔ | ✔ | <3.0 |
| onPageSingleTap | function(page) | null | callback when page was single tapped | ✔ | ✔ | ✔ | 3.0 |
| onScaleChanged | function(scale) | null | callback when scale page | ✔ | ✔ | ✔ | 3.0 |
| onPressLink | function(uri) | null | callback when link tapped | ✔ | ✔ | ✖ | 6.0.0 |

#### parameters of source

| parameter | Description | default | iOS | Android |
| ------------ | ----------- | ------- | --- | ------- |
| uri | pdf source, see the forllowing for detail.| required | ✔ | ✔ |
| cache | use cache or not | false | ✔ | ✔ |
| expiration | cache file expired seconds (0 is not expired) | 0 | ✔ | ✔ |
| method | request method when uri is a url | "GET" | ✔ | ✔ |
| headers | request headers when uri is a url | {} | ✔ | ✔ |
| parameter | Description | default | iOS | Android | Windows |
| ------------ | ----------- | ------- | --- | ------- | ------- |
| uri | pdf source, see the forllowing for detail.| required | ✔ | ✔ | ✔ |
| cache | use cache or not | false | ✔ | ✔ | ✖ |
| expiration | cache file expired seconds (0 is not expired) | 0 | ✔ | ✔ | ✖ |
| method | request method when uri is a url | "GET" | ✔ | ✔ | ✖ |
| headers | request headers when uri is a url | {} | ✔ | ✔ | ✖ |

#### types of source.uri

| Usage | Description | iOS | Android |
| ------------ | ----------- | --- | ------- |
| `{uri:"http://xxx/xxx.pdf"}` | load pdf from a url | ✔ | ✔ |
| `{require("./test.pdf")}` | load pdf relate to js file (do not need add by xcode) | ✔ | ✖ |
| `{uri:"bundle-assets://path/to/xxx.pdf"}` | load pdf from assets, the file should be at android/app/src/main/assets/path/to/xxx.pdf | ✖ | ✔ |
| `{uri:"bundle-assets://xxx.pdf"}` | load pdf from assets, you must add pdf to project by xcode. this does not support folder. | ✔ | ✖ |
| `{uri:"data:application/pdf;base64,JVBERi0xLjcKJc..."}` | load pdf from base64 string | ✔ | ✔ |
| `{uri:"file:///absolute/path/to/xxx.pdf"}` | load pdf from local file system | ✔ | ✔ |
| Usage | Description | iOS | Android | Windows |
| ------------ | ----------- | --- | ------- | ------- |
| `{uri:"http://xxx/xxx.pdf"}` | load pdf from a url | ✔ | ✔ | ✖ |
| `{require("./test.pdf")}` | load pdf relate to js file (do not need add by xcode) | ✔ | ✖ | ✖ |
| `{uri:"bundle-assets://path/to/xxx.pdf"}` | load pdf from assets, the file should be at android/app/src/main/assets/path/to/xxx.pdf | ✖ | ✔ | ✖ |
| `{uri:"bundle-assets://xxx.pdf"}` | load pdf from assets, you must add pdf to project by xcode. this does not support folder. | ✔ | ✖ | ✖ |
| `{uri:"data:application/pdf;base64,JVBERi0xLjcKJc..."}` | load pdf from base64 string | ✔ | ✔ | ✖ |
| `{uri:"file:///absolute/path/to/xxx.pdf"}` | load pdf from local file system | ✔ | ✔ | ✔ |
| `{uri:"ms-appx:///xxx.pdf"}}` | load pdf bundled with UWP app | ✖ | ✖ | ✔ |


### Methods
Expand Down
64 changes: 64 additions & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,67 @@ buck-out/

# CocoaPods
/ios/Pods/

# OSX
#
.DS_Store

# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate

# Android/IntelliJ
#
build/
.idea
.gradle
local.properties
*.iml

# node.js
#
node_modules/
npm-debug.log
yarn-error.log

# BUCK
buck-out/
\.buckd/
*.keystore
!debug.keystore

# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/

*/fastlane/report.xml
*/fastlane/Preview.html
*/fastlane/screenshots

# Bundle artifact
*.jsbundle

# CocoaPods
/ios/Pods/

# VS
*.binlog
*.ProjectImports.zip
1 change: 1 addition & 0 deletions example/PDFExample.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions example/metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,20 @@
*
* @format
*/
const path = require('path');
const blacklist = require('metro-config/src/defaults/blacklist');

module.exports = {
resolver: {
blacklistRE: blacklist([
// This stops "react-native run-windows" from causing the metro server to crash if its already running
new RegExp(
`${path.resolve(__dirname, 'windows').replace(/[/\\]/g, '/')}.*`,
),
// This prevents "react-native run-windows" from hitting: EBUSY: resource busy or locked, open msbuild.ProjectImports.zip
/.*\.ProjectImports\.zip/,
]),
},
transformer: {
getTransformOptions: async () => ({
transform: {
Expand Down
7 changes: 4 additions & 3 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
"url": "https://github.com/wonday/react-native-pdf/issues"
},
"dependencies": {
"react": "16.8.6",
"react-native": "0.60.4",
"react": "16.13.1",
"react-native": "0.63.2",
"react-native-orientation-locker": "^1.1.6",
"react-native-pdf": "github:wonday/react-native-pdf#master",
"react-native-pdf": "file:../",
"react-native-windows": "^0.63.11",
"rn-fetch-blob": "^0.10.16"
},
"devDependencies": {
Expand Down
92 changes: 92 additions & 0 deletions example/windows/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
*AppPackages*
*BundleArtifacts*

#OS junk files
[Tt]humbs.db
*.DS_Store

#Visual Studio files
*.[Oo]bj
*.user
*.aps
*.pch
*.vspscc
*.vssscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.[Cc]ache
*.ilk
*.log
*.lib
*.sbr
*.sdf
*.opensdf
*.opendb
*.unsuccessfulbuild
ipch/
[Oo]bj/
[Bb]in
[Dd]ebug*/
[Rr]elease*/
Ankh.NoLoad

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

#MonoDevelop
*.pidb
*.userprefs

#Tooling
_ReSharper*/
*.resharper
[Tt]est[Rr]esult*
*.sass-cache

#Project files
[Bb]uild/

#Subversion files
.svn

# Office Temp Files
~$*

# vim Temp Files
*~

#NuGet
packages/
*.nupkg

#ncrunch
*ncrunch*
*crunch*.local.xml

# visual studio database projects
*.dbmdl

#Test files
*.testsettings

#Other files
*.DotSettings
.vs/
*project.lock.json

#Files generated by the VS build
**/Generated Files/**

Loading