Get page previews in React-Native - react-native

I was trying to let users see web page previews in react-native like the link previews seen on Facebook and other apps. I've done some research.
I've seen some library that provides the function for node, but it doesn't work for react-native (because the original cheerio.js doesn't work directly with react-native)
https://github.com/cheeriojs/cheerio
I've checked the oEmbed library too, but it doesn't seem to work either.
I was wondering what might be the good ways for getting web page previews

Ended up writing a small library that does the job. Hopefully it's useful to some people
https://github.com/changey/react-native-page-previewer
Usage
import preview from 'react-native-page-previewer';
preview("http://www.google.com", function(err, data) {
if(!err) {
console.log(data);
}
});
sample return
{ url: 'https://www.google.com',
loadFailed: false,
title: 'Google',
description: 'Search the world\'s information, including webpages, images, videos and more. Google has many special features to help you find exactly what you\'re looking for.',
contentType: 'text/html',
mediaType: 'website',
images: [ 'https://www.google.com/images/branding/googlelogo/1x/googlelogo_white_background_color_272x92dp.png' ],
videos: undefined,
audios: undefined }

Related

<video> tag. DOMException: The element has no supported sources, when not utilizing require()

I am trying to play a video when developing locally with VueJS 2.
My code is the following :
<video class="back_video" :src="`../videos/Space${videoIndex}.mp4`" id="background-video"></video>
...
data :
function() {
return {
videoIndex:1
}
}
...
const vid = document.getElementById("background-video");
vid.crossOrigin = 'anonymous';
let playPromise = vid.play();
if (playPromise !== undefined) {
playPromise.then(function() {
console.log("video playing");
}).catch(function(error) {
console.error(error);
});
}
This code is causing the exception given in title. Tried in several browsers, always the same.
If I change the src by :
:src="require(`../videos/Space${videoIndex}.mp4`)"
it works.
But in that case building time is very long as I have many different videos in my videos directory, because adding require() will force to copy all videos in the running directory at build phase (vue-cli serve), and this is really annoying. In other words I want to refer videos that are outside the build directory to avoid this (but also to avoid having videos in my git).
It is interesting to note that when I deploy server side, it works perfectly with my original code
:src="`../videos/Space${videoIndex}.mp4`"
Note also that if i replace my code with simply
src="../videos/Space1.mp4"
it works too. So the video itself, or its location, are not the source of the problem.
Any clue ?
You can host your videos on a CDN to have something faster and easier to debug/work with.
Otherwise, it will need to bundle it locally and may take some time.

Share post on LinkedIn with React Native

I have an app built in react-native in which I need to share a post on LinkedIn with predefined content.
I used 'react-native-share' for sharing content on LinkedIn but It's not working. How can I achieve this?
Thanks in advance.
LinkedIn supports only one parameter being passed to it, and that is the url parameter. It will look like this...
https://www.linkedin.com/sharing/share-offsite/?url={url}
Source: Official LinkedIn Sharing Documentation.
The following parameters will not work: summary, title, source, etc.. Anything besides url.
To share to LinkedIn, just make a <a href> element that points to an above formatted-URL, and make absolutely sure to do URL-encoding on your {url}.
You probably want to share title and summary, though, based on the accepted answer. You cannot do that using GET-data, BUT you can do that using og: tags.
<meta property='og:title' content='Title of the article"/>
<meta property='og:image' content='//media.example.com/ 1234567.jpg"/>
<meta property='og:description' content='Description that will show in the preview"/>
<meta property='og:url' content='//www.example.com/URL of the article" />
Source: LinkedIn Developer Docs: Making Your Website Shareable on LinkedIn.
In case you are uncertain that you've followed the LinkedIn documentation correctly to make a share URL, you can test your page's URL to see how it will look when shared here: LinkedIn Post Inspector.
You can do it with react-native-share. I have used it in one of my application.
const shareOptions = {
title: 'Share via',
message: `Hello, ${description}`,
subject: 'Subject,
url: "data:image/png;base64," + base64Data,
showAppsToView: false,
filename: 'test',
};
Share.open(shareOptions).then(res => {
console.log(res)
}).catch(e => {
console.log(e)
});
Note: It would be greater if you can share your code.
You can use Linking from react native
import { Linking } from 'react-native';
and then you can use
Linking.openURL("https://www.linkedin.com/shareArticle?mini=true&summary=youtube&title=f1&url=https://www.youtube.com/watch?v=dQw4w9WgXcQ");
you can found more info here
https://stackoverflow.com/a/10737122/6125249

How do I use an ACS Token?

I am building a react-native app that utilizes the Google Books API. The API provides a property known as "ACSTokenLink" which downloads an .acsm file, not an .epub. A simple Google Search tells me that this .acsm file is for content protection and can only be opened with Adobe Digital Editions.
Google completely dropped the ball, failing to mention any of this in their API contract:
https://developers.google.com/books/docs/v1/using
Google API forums are a ghost-town, so I'm asking here in an attempt to learn more about these files and their use.
So, if I am developing a react-native e-reader, am I completely barred from using such a file?
Looking at the accessInfo slice sample from Google Books API :
The accessInfo section is of particular interest in determining what features are available for an eBook.
"accessInfo": {
"country": "US",
"viewability": "PARTIAL",
"embeddable": true,
"publicDomain": false,
"textToSpeechPermission": "ALLOWED_FOR_ACCESSIBILITY",
"epub": {
"isAvailable": true,
"acsTokenLink": "https://books.google.com/books/download/The_Google_story-sample-epub.acsm?id=zyTCAlFPjgYC&format=epub&output=acs4_fulfillment_token&dl_type=sample&source=gbs_api"
},
"pdf": {
"isAvailable": false
},
"accessViewStatus": "SAMPLE"
}
The epub section will have an isAvailable property indicating if this type of ebook is available.
We can use acsTokenLink as the "download epub link" and can set up our conditional:
if( book.accessInfo.epub.isAvailable ) {
axios.get(acsTokenLink).then( responseData => /* store epub in app storage here */ )
}
Looking further: I have found Epub.js as one solution to display epub files with React Native. Additionally, here's an example repo.

Not able to open PDF url using DocumentViewer ionic 4

I have a pdf URL and I want to open it using DocumentViewer. When I run code:
this._document.viewDocument(pdfUrl, 'application/pdf', options);
It is not opening PDF. I tried downloading PDF to my mobile and then open it. Please find code below:
transfer.download(downloadUrl, filename).then(entry => {
const url = entry.toURL();
if (this._plt.is('ios')) {
this._document.viewDocument(pdfUrl, 'application/pdf', options);
} else {
this._fileOpener.open(pdfUrl, 'application/pdf')
.then(() => console.log('File is opened'))
.catch(e => this.presentAlert('Error opening file', e));
}
});
I have tables and images in my PDF. When I ran above code I am not able to see HTML5 tables in the PDF.
I need help on how to open up PDF URL directly using DocumentViewer.
NOTE: I have seen a couple of post on StackOverflow suggesting to use InAppBrowser. I have a requirement where I need to display it as PDF.
I have read in https://github.com/sitewaerts/cordova-plugin-document-viewer,
that in android : Due to license restrictions in muPDF, the plugin dispatches to a separate (free) viewer app based on muPDF. If the viewer app is not yet installed, the user may be redirected to the google play app store.
https://play.google.com/store/apps/details?id=de.sitewaerts.cleverdox.viewer.
you may use other pdf plugins like
https://github.com/vadimdez/ng2-pdf-viewer/
hope this helps

Image require() in nuxt with hot reload by HRM webpack

I use the dynamic source for vue-webpack images in nuxt :src="require('path/to/image' + dynamic.variable)" in my project navbar. If the users substitute their image through a form which refetches their information and deletes their previous image I get a webpack error module (img) not found (it does not find the new one): is there a way to solve this, like wait for webpack HRM to finish?
I tried setting up a setTimeout() of one second before user re-fetch and it works, but I don't like a random waiting, I'd use a promise or a sync dynamic, the point is webpack hot reload is not controlled by my functions.. I also tried with setting the dynamic path as a computed: but it doesn't fix.
My image tag:
<img v-if="this.$auth.user.image" class="userlogo m-2 rounded-circle" :src="require('#assets/images/users/' + this.$auth.user.image)" alt="usrimg">
My Useredit page methods:
...
methods: {
userEdit() {
//uploads the image
if (this.formImageFilename.name) {
let formImageData = new FormData()
formImageData.append('file', this.formImageFilename)
axios.post('/db/userimage', formImageData, { headers: { 'Content-Type': 'multipart/form-data' } })
// once it has uploaded the new image, it deletes the old one
.then(res=>{this.deleteOldImage()})
.catch(err=>{console.log(err)})
}else{
this.userUpdate() //if no new image has to be inserted, it proceeds to update the user information
}
},
deleteOldImage(){
if(this.$auth.user.image){axios.delete('/db/userimage', {data: {delimage: this.$auth.user.image}} )}
console.log(this.$auth.user.image + ' deleted')
this.userUpdate() // it has deleted the old image so it proceeds to update the user information
},
userUpdate(){
axios.put(
'/db/user', {
id: this.id,
name: this.formName,
surname: this.formSurname,
email: this.formEmail,
password: this.formPassword,
image: this.formImageFilename.name,
})
.then(() => { console.log('User updated'); this.userReload()}) // reloads the updated user information
.catch(err => {console.log(err)} )
},
userReload(){
console.log('User reloading..')
this.$auth.fetchUser()
.then(() => { console.log('User reloaded')})
.catch(err => {console.log(err)} )
},
}
...
the problem happens after "console.log('User reloading..')" and before "console.log('User reloaded');", it is not related to the file upload nor the server response. I broke a single function in many little ones just to check the function progression and its asynchronous dynamics but the only one that is not manageable is the webpack hot reload :/
I'd like the users to upload their images and see their logo in the Navbar appear updated after submitting the form.
First of all, as somebody told you in the comments, webpack hmr shouldn't be used for production.
In Nuxt, everything that you reference from the assets folder will be optimized and bundled into the project package. So the ideal use case for this folder is all assets that can be packaged and optimized, and most likely won't change like fonts, css, background images, icons, etc.
Then, require is called only once by webpack when it is either building the site for local development or building the site for generating a production package. The problem in your case is that you delete the original file while you're in development and webpack tries to read it and fails.
In the case of these images that the user uploads, I think you should use the static folder instead and instead of using require you'll have to change the :src with
:src="'/images/users/' + this.$auth.user.image"
Let me know if this helps.
Okay, I probably solved it.
HMR: you are of course right. Thank you for pointing out, I am sorry, I am a beginner and I try to understand stuff along the way.
Aldarund, thank you, your idea of not changing the path and cache it client side.. I am too noob to understand how I could implement it ( :) ) but it gave me a good hint: the solution was to keep the image name as the user id + the '.png' extension and to manage the image with jimp so that the image name, extension and file type are always the same, and with or without webpack compiling the new path, I always have the correct require().
Jair, thank you for the help, I didn't follow that road, but I will keep it as a second chance if my way creates errors. Just to be specific: the error comes when it does not find -and asks for the name of- the NEW image, not the OLD one, as I wrote in my question: it happens because the fetchUser() functions reloads the user information including the new image name.
Do you guys see any future problems in my methodology?
Really thank you for your answers. I am learning alone and it's great to receive support.