Get Stream IO React Native UnFollowing option not available - reactjs

I am using Get Stream Io react native in my project https://github.com/GetStream/react-native-activity-feed
I see there is a functionality in the library of following a particular user, whereas the opposite is not available i.e. how to unfollow a user.
Please point me in the right direction on how to achieve this in react native

Our library doesn't include the logic for following/unfollowing. It has a button that allows you to set it up yourself though. Which is the FollowButton you're talking about. You could do something like this:
<FollowButton
followed={async () => {
// check if you're following the user
const following = await your_timeline_feed.following({filter: ['user:user_42'] })
if (following) {
return true;
}
return false;
}} // renders the button as "following"
clicked={async () => {
// your logic for following/unfollowing
await your_timeline_feed.follow('user', 'user_42');
}}
/>
Read more here:
https://getstream.github.io/react-native-activity-feed/#!/FollowButton
https://getstream.io/docs/following/?language=js

Related

React native, get value from url browser

How do i get the value of url from the browser? using the react native
If you can make callbacks from the gateway website, then I recommend to use deep linking to handle flow between app and browser. Basically, your app will open the gateway website for payment, and depending on payment result, the website will make a callback to the app using its deep link. App then will listen to the link, take out necessary information and continue to proceed.
What you need to do is:
Set up deep linking in your app. You should follow the guide from official website (here) to enable it. Let pick a random URL here for linking, e.g. gatewaylistener
Set the necessary callbacks from gateway to your app. In your case, since you need to handle successful payment and failed payment, you can add 2 callbacks, e.g. gatewaylistener://success?id={paymentId} and gatewaylistener://error?id={paymentId}
Finally, you need to listen to web browser from the app. One way to do that is add listener right inside the component opening the gateway.
// setup
componentDidMount() {
Linking.getInitialURL().then((url) => {
if (url) {
this.handleOpenURL(url)
}
}).catch(err => {})
Linking.addEventListener('url', this.handleOpenURL)
}
componentWillUnmount() {
Linking.removeEventListener('url', this.handleOpenURL)
}
// open your gateway
async openGateWay = () => {
const { addNewOrderGatewayToken } = this.props
const url = `${BASEURL}${addNewOrderGatewayToken}`
const canOpen = await Linking.canOpenURL(url)
if (canOpen) {
this.props.dispatch(setPaymentStatus('checked'))
Linking.openURL(url)
}
}
// handle gateway callbacks
handleOpenURL = (url) => {
if (isSucceedPayment(url)) { // your condition
// handle success payment
} else {
// handle failure
}
}

How can I test all this logic inside setState callback parameter

I'm trying to test the following code. I'm using jest and react testing library. This is the firs time I've used setState like this. I solved my initial which was to avoid passing in the dependency of current state but I'm not sure how can I test this. Can someone please advise.
useEffect(() => {
setUsers(currentUsers => {
if(currentUsers === undefined) {
return userDataFromApi;
} else {
//Users already exist in state
const mergedUserData = currentUsers.map(existingUser => {
const matchedUser = userDataFromApi.find(user => user.name === existingUser.name);
if (matchedUser) {
existingUser.stats = user.stats;
}
return existingUser;
});
return mergedUserData;
}
});
}, [setUsers, userDataFromApi]);
This piece of code is implementation detail. React testing library enforces UI testing. You can read this article from Kent Dodds.
In your tests you can do the same thing as the user would do (fill a form, click etc.), and then check what the user should see or not see (maybe his name, his stats etc.).
And if you get data from your backend and you would like to test only the frontend, you can mock the answer of the backend.

Google One Tap SignIn Popup not showing

I was trying to implement Google One Tap SignIn in my project. At the first time after building the project the google one tap prompt will display. But next time onwards if we refresh the page also the prompt is not displaying.
Here is my code snippet.
import { addScript } from 'Util/DOM';
/**
* Loads One Tap Client Library
*/
const loadOneTapClientLibrary = async() => {
await addScript('https://accounts.google.com/gsi/client');
}
/**
* Loads One Tap Javascript API
* #param {*} resolve
*/
const loadOneTapJsAPI = (resolve) => {
window.onload = () => {
google.accounts.id.initialize({
client_id: "My client Id",
callback: data => resolve(data)
});
google.accounts.id.prompt();
}
}
export const loadOneTap = async() => {
return new Promise( (resolve, reject) => {
loadOneTapClientLibrary();
loadOneTapJsAPI(resolve);
})
}
After page loads i am calling loadOneTap();
To avoid One Tap UI prompting too frequently to end users, if users close the UI by the 'X' button, the One Tap will be disabled for a while. This is the so-called "Exponental Cool Down" feature. More detail at: https://developers.google.com/identity/one-tap/web/guides/features#exponential_cool_down
I believe you triggered this feature during development. To avoid this, use Chrome incognito mode (and restart the browser when necessary).
As noted by Guibin this is the OneTap exponential cool down feature, it can be easily triggered during development when testing auth flow, but also legitimately when the end user clicks the close icon by mistake. On sites where Google login is optional this might seem pragmatic (i.e. the user genuinely wants to dismiss the popup prompt in favor of alternative login methods), however on a site where Google is the sole login identity provider and you are using the Javascript API instead of HTML api then this can manifest as broken functionality - i.e. no login prompt - and you want to avoid telling your users to use incognito or clear cache/cookies at all costs..
You can potentially handle this with some fallback logic..
window.google.accounts.id.prompt((notification) => {
if(notification.isNotDisplayed() || !notification.isDisplayed()) {
// #ts-ignore
const buttonDiv = window.document.createElement("div")
buttonDiv.setAttribute("id", "googleLoginBtn")
document.getElementsByTagName('body')[0].appendChild(buttonDiv);
// #ts-ignore
window.google.accounts.id.renderButton(
document.getElementById("googleLoginBtn"),
{ theme: "outline", size: "large" } // customization attributes
);
}
This renders a button to login that isn't subject the one-tap cool down feature. We're early days into playing with this so there may be other invariants with regards to state you need to consider (e.g. can isNotDisplayed return true when already logged in) - we already observed some oddities where isDisplayed and isNotDisplayed can both be false on the same invocation of the callback.
Extra note: I recall reading the user can disable all one tap features too, so if you're using the javascript API instead HTML api you will need the fallback to SignIn with Google button.

Uploading an image to Azure Blob Storage using React

I want to upload an image to Azure Blob Storage using React.
I've tried a lot of examples and none of them work.
The one that seemed the best was this one but still didn't manage to get it working on React.
What I'm trying right now is to use the createContainerIfNotExists method just to test and the error is Cannot read property createBlobServiceWithSas of undefined
My code is the following:
import AzureStorage from 'azure-storage';
const account = {
name: 'x',
sas: 'x',
};
const blobUri = `https://${account.name}.blob.core.windows.net`;
const blobService = AzureStorage.Blob.createBlobServiceWithSas(blobUri, account.sas);
export const createContainer = () => {
blobService.createContainerIfNotExists('test', (error, container) => {
if (error) {
// Handle create container error
} else {
console.log(container.name);
}
});
};
export default createContainer;
According to my research, because you develop A React application, we can not use the createBlockBlobFromBrowserFile method. We just can use the method in the browser. For more details, please refer to the document.
According to the situation, I suggest you use the other method(such as uploadStreamToBlockBlob) to upload image with V10 sdk. For more details, please refer to https://learn.microsoft.com/en-us/javascript/api/#azure/storage-blob/?view=azure-node-latest

html2canvas dynamically rendered div

I am trying to use html2canvas (http://html2canvas.hertzen.com) to take a screenshot of my page that contains a google maps view, but I am running into an issue where the resulting screenshot is white, except for the marker. What (possibly) complicates the issue is that I am (trying to) creating a React application.
I use this code to take the screenshot:
takeScreenshot = () => {
let googleMapsView = document.querySelector('.google-map');
html2canvas(googleMapsView).then((canvas) => {
let imgData = canvas.toDataURL('image/png');
console.log(imgData);
});
}
This is the page I'm trying to take a screenshot of:
The code above generates the following image:
As you can see, it generates the screenshot and captures the marker and the bottom "Map Data ©2018 Google" however, the resulting screenshot is still blank.
In the documentation on their Github, I see an option to preload here: https://github.com/niklasvh/html2canvas/wiki/Documentation#preload-content
However, this seems to have been removed from the library since the 0.5.0 beta version - they're now in 1.0.0 alpha, so going back that far to such an outdated library is not really an option.
How can I tell html2canvas to wait for the GMaps component to be rendered, before taking the screenshot?
You need to add param useCORS to use it with google maps, in your case:
takeScreenshot = () => {
let googleMapsView = document.querySelector('.google-map');
html2canvas(googleMapsView, {useCORS: true}).then((canvas) => {
let imgData = canvas.toDataURL('image/png');
console.log(imgData);
});
}
Have you tried to put your code inside the google map listener
google.maps.event.addListenerOnce(map, 'idle', function(){
// do something only the first time the map is loaded
takeScreenshot = () => {
let googleMapsView = document.querySelector('.google-map');
html2canvas(googleMapsView).then((canvas) => {
let imgData = canvas.toDataURL('image/png');
console.log(imgData);
});
}
});
See also the events section in the Google Maps Reference.

Resources