ReactNative Expo Preloading & Caching Images - reactjs

I'm new to react-native im trying to preload 10 images at the start of the app I followed expo documentation but
I want to cache images from an external file but it gives me an error [Un Handeled Promise Rejection]
here is my entries.js
export const ENTRIES1 = [
{
title: 'Makeup Artists',
illustration: require('../assets/img/makeup.png')
},
{
title: 'Photographers',
illustration: require('../assets/img/Photographers.png')
},
{
title: 'Wedding Planners',
illustration: require('../assets/img/weddingPlanner.jpg')
},
{
title: 'Wedding Halls',
illustration: require('../assets/img/wedding-Hall.png')
},
{
title: 'Laser & Beauty Centers',
illustration: require('../assets/img/laser.png')
},
]
loadingScreen.js
async componentDidMount() { //Preload Fonts
await Asset.loadAsync(ENTRIES1.illustration),
await Font.loadAsync({
'Roboto': require('../../node_modules/native-base/Fonts/Roboto.ttf'),
'Roboto_medium': require('../../node_modules/native-base/Fonts/Roboto_medium.ttf'),
...Ionicons.font,
});
this.checkIfLoggedIn();
}
what am i doing wrong ? Thanks

Try this :)
function cacheImages(images) {
return images.map(image => {
if (typeof image.illustration === 'string') {
return Image.prefetch(image.illustration);
} else {
return Asset.fromModule(image.illustration).downloadAsync();
}
});
}
async componentDidMount() {
await Asset.cacheImages(ENTRIES1),
await Font.loadAsync({
'Roboto': require('../../node_modules/native-base/Fonts/Roboto.ttf'),
'Roboto_medium': require('../../node_modules/native-base/Fonts/Roboto_medium.ttf'),
...Ionicons.font,
});
this.checkIfLoggedIn();
}

Related

How to recover SIP js Invitation Object or Session Object in React Js on page refresh

I am implementing Audio/Video call with SIP js and Astrisk server in React JS.I was successful on creating the WebRTC Audio/Video calling. But I am facing an issue with storing the Invitation or Session Object for SIP js. Because Circular JSON data can't be stringed to store.
Assume someone has started calling and the other end got notification of calling and in that case if the page refreshed or reloaded I am unable to recover the call session to take any action(answer/ decline)
/**
* The following code is inside useState and the dependency are handled properly.
* For making it simple and sort I have just copied the required parts. */
const simpleUserDelegate = {
onCallAnswered: (session) => {
console.log(` Call answered`);
if (simpleUser) {
let remoteVideoTrack = simpleUser.getRemoteVideoTrack(session);
if (remoteVideoTrack) {
} else {
setIsAudioCall(true);
}
}
setIsCallAnswered(true);
setIsCallRecieved(false);
localStorage.setItem('isCallRecieved',null);
localStorage.setItem('callerName',null);
localStorage.setItem('callerImage',null);
setIsCallling(false);
},
onCallCreated: (session) => {
setCallSession(session);
console.log(session,` Call created`);
//console.log('session====>',JSON.stringify(session))
// localStorage.setItem('callerUserAgent',JSON.stringify(session._userAgent));
setIsCallling(true);
localStorage.getItem('callerUserAgent')
},
onCallReceived: (invitation) => {
console.log('invitation',invitation);
console.log('invitationSession',invitation.session);
setCallerActiveRoom(invitation._userAgent.options.displayRoomId);
setCallerName(invitation._userAgent.options.displayName);
setCallerImage(invitation._userAgent.options.displayImage);
localStorage.setItem('callerUserAgent',JSON.stringify(invitation.request));
console.log(` Call received`);
// dispatch(setActiveRoomId(invitation._userAgent.options.displayRoomId));
setIsCallRecieved(true);
localStorage.setItem('isCallRecieved',true);
localStorage.setItem('callerName',invitation._userAgent.options.displayName);
localStorage.setItem('callerImage',invitation._userAgent.options.displayImage);
},
onCallHangup: () => {
console.log(` Call hangup`);
setIsCallling(false);
setIsCallRecieved(false);
localStorage.setItem('isCallRecieved',null);
localStorage.setItem('callerName',null);
localStorage.setItem('callerImage',null);
setIsCallAnswered(false);
},
onCallHold: () => {
console.log(` Call hold`);
},
onRegistered: () => {
//console.log('session',session);
console.log(` Call registered`);
},
onUnregistered: () => {
console.log(` Call unregistered`);
},
onServerConnect: () => {
console.log(` server connect`);
},
onServerDisconnect: () => {
console.log(` server dis connect`);
}
};
let simpleUserOptions = {
// traceSip: false,
// logBuiltinEnabled: false,
delegate: simpleUserDelegate,
media: {
constraints: {
audio: true,
video: true
},
local: {
video: document.getElementById('localMedia')
},
remote: {
video: document.getElementById('remoteMedia'),
//audio: remoteAudioRef.current
}
},
userAgentOptions: {
logBuiltinEnabled: true,
logLevel: "debug",
authorizationPassword: password,
authorizationUsername: username,
uri: urI,
noAnswerTimeout : 30,
displayName: name,
displayImage: profileImage,
displayRoomId: `hi${displayRoomId}`
},
};
const simpleUserObj = new Web.SessionManager('wss://pbx.scinner.com:8089/ws', simpleUserOptions);
if(!simpleUserObj.isConnected()){
simpleUserObj
.connect()
.then(() => {
console.log(`${user.username} connected`);
simpleUserObj.register().then(() => {
console.log(`${user.username} registerd`);
}).catch((error) => {
alert("Failed to register.\n" + error);
});
})
.catch((error) => {
alert("Failed to connect.\n" + error);
});
setIsSARegistered(true);
setSimpleUser(simpleUserObj);
setCallerUserAgent
}else{
console.log('isconnected');
setIsSARegistered(true);
}
/**
Set calling
*/
const setCalling = (name, target) => {
simpleUser
.call(target, {
sessionDescriptionHandlerOptions: {
constraints: {
audio: true,
video: true
}
},
inviteWithoutSdp: false
}).then(() => {
console.log(`anon placed a call`);
}).catch((error) => {
console.error(`[${simpleUser.id}] failed to place call`);
console.error(error);
alert("Failed to place call.\n" + error);
});
//setIsCallling(true);
// console.log('isCallling', isCallling)
}
}
const answerCall = () => {
//callSession stored in local state
if (callSession) {
simpleUser.answer(callSession).then(() => {
console.log(`call answered`);
}).catch((error) => {
console.error(`call answered failed`);
console.error(error);
// alert("Failed to place call.\n" + error);
});
}
};

Axios Spy not being called correct number of times in Jest

I have a React context I am testing that runs a single function to check for an application update. The checkForUpdate function looks like this:
async function checkForUpdate() {
if (isPlatform('capacitor')) {
const maintanenceURL =
'https://example.com/maintenance.json';
const updateURL =
'https://example.com/update.json';
try {
const maintanenceFetch: AxiosResponse<MaintanenceDataInterface> =
await axios.get(maintanenceURL);
console.log('maintain', maintanenceFetch);
if (maintanenceFetch.data.enabled) {
setUpdateMessage(maintanenceFetch.data.msg);
return;
}
const updateFetch: AxiosResponse<UpdateDataInterface> = await axios.get(
updateURL
);
console.log('updateFetch', updateFetch);
if (updateFetch.data.enabled) {
const capApp = await App.getInfo();
const capAppVersion = capApp.version;
console.log('Thi is a thinkg', capAppVersion);
if (isPlatform('android')) {
console.log('hi');
const { currentAndroid, majorMsg, minorMsg } = updateFetch.data;
const idealVersionArr = currentAndroid.split('.');
const actualVersionArr = capAppVersion.split('.');
if (idealVersionArr[0] !== actualVersionArr[0]) {
setUpdateMessage(majorMsg);
setUpdateAvailable(true);
return;
}
if (idealVersionArr[1] !== actualVersionArr[1]) {
setUpdateMessage(minorMsg);
setUpdateAvailable(true);
return;
}
} else {
const { currentIos, majorMsg, minorMsg } = updateFetch.data;
const idealVersionArr = currentIos.split('.');
const actualVersionArr = capAppVersion.split('.');
if (idealVersionArr[0] !== actualVersionArr[0]) {
setUpdateMessage(majorMsg);
setUpdateAvailable(true);
return;
}
if (idealVersionArr[1] !== actualVersionArr[1]) {
setUpdateMessage(minorMsg);
setUpdateAvailable(true);
return;
}
}
}
} catch (err) {
console.log('Error in checkForUpdate', err);
}
}
}
For some reason, in my test I wrote to test this, my axiosSpy only shows that it has been called 1 time instead of the expected 2 times. The console logs I posted for both get requests run as well. I cannot figure out what I am doing wrong.
Here is the test:
it.only('should render the update page if the fetch call to update bucket is enabled and returns a different major version', async () => {
const isPlatformSpy = jest.spyOn(ionicReact, 'isPlatform');
isPlatformSpy.mockReturnValueOnce(true).mockReturnValueOnce(true);
const appSpy = jest.spyOn(App, 'getInfo');
appSpy.mockResolvedValueOnce({
version: '0.8.0',
name: 'test',
build: '123',
id: 'r132-132',
});
const axiosSpy = jest.spyOn(axios, 'get');
axiosSpy
.mockResolvedValueOnce({
data: {
enabled: false,
msg: {
title: 'App maintenance',
msg: 'We are currently solving an issue where users cannot open the app. This should be solved by end of day 12/31/2022! Thank you for your patience 😁',
btn: 'Ok',
type: 'maintenance',
},
},
})
.mockResolvedValueOnce({
data: {
current: '1.0.0',
currentAndroid: '1.0.0',
currentIos: '2.0.0',
enabled: true,
majorMsg: {
title: 'Important App update',
msg: 'Please update your app to the latest version to continue using it. If you are on iPhone, go to the app store and search MO Gas Tax Back to update your app. The button below does not work but will in the current update!',
btn: 'Download',
type: 'major',
},
minorMsg: {
title: 'App update available',
msg: "There's a new version available, would you like to get it now?",
btn: 'Download',
type: 'minor',
},
},
});
customRender(<UpdateChild />);
expect(axiosSpy).toHaveBeenCalledTimes(2);
});

React Native Maps

I'm busy developing a location-based app and making use of expo, is there anyone who knows how to track user location on the map and tell if they reached a specific destination on expo project similar to GPS.
<MapViewDirections
origin={userContext.userLocation}
destination={userContext.userLocation}
apikey={googleMapApi}
mode='DRIVING'
language='en's
strokeWidth={8}
strokeColor="#2A9D8F"
optimizeWaypoints={true}
resetOnChange={false}
precision={"low"}
/>
If you are using expo you should use watchPositionAsync from expo-location api
https://docs.expo.io/versions/latest/sdk/location/#locationwatchpositionasyncoptions-callback
You should track here the changes and then put the coordinates in the map.
Usage
async componentWillMount() {
const { status } = await Permissions.askAsync(Permissions.LOCATION);
if (status === 'granted') {
this._getLocationAsync();
} else {
this.setState({ error: 'Locations services needed' });
}
}
componentWillUnmount() {
this.location.remove(callback...);
}
_getLocationAsync = async () => {
this.location = await Location.watchPositionAsync(
{
enableHighAccuracy: true,
distanceInterval: 1,
timeInterval: 10000
},
newLocation => {
let coords = newLocation.coords;
// this.props.getMyLocation sets my reducer state my_location
this.props.getMyLocation({
latitude: parseFloat(coords.latitude),
longitude: parseFloat(coords.longitude)
});
},
error => console.log(error)
);
return location;
};

TypeError: this.getISO is not a function

I getting typeerror: this.getISO is not a function.
I am trying to implement mapbox API with 3 isochrones plot on it. but i am getting an error that this.getISO is not a function.
map.on("load", function() {
map.addSource("iso", {
type: "geojson",
data: {
type: "FeatureCollection",
features: []
}
});
map.addLayer(
{
id: "isoLayer",
type: "fill",
// Use "iso" as the data source for this layer
source: "iso",
layout: {},
paint: {
// The fill color for the layer is set to a light purple
"fill-color": "#5a3fc0",
"fill-opacity": 0.3
}
},
"poi-label"
);
this.getISO(data => {
map.getSource("iso").setData(data);
});
});
this.map = map;
}
getISO(callback) {
const { duration, lng, lat } = this.state;
fetch(
`https://api.mapbox.com/isochrone/v1/mapbox/driving/${lng},${lat}?
contours_minutes=${duration}&polygons=true&
access_token=pk.eyJ1Ijoiam9uYnN0b3JleSIsImEiOiJjanl5aGFyaWwxaGE3M21ycnhsNGpvYmk2In0.jfxHlg5boDqdiUgf3cco2A`
)
.then(response => response.json())
.then(data => {
callback(data);
});
}
in first-line replace function definition with arrow function and the
like this map.on("load", ()=> {
Use an arrow function () => { instead of function() {.

How to use nextjs with multiple plugins

I'm using Nextjs with a with-antd boilerplate and it comes with a preconfigured next.config.js file.
Looking like this;
/* eslint-disable */
const withCss = require('#zeit/next-css')
// fix: prevents error when .css files are required by node
if (typeof require !== 'undefined') {
require.extensions['.css'] = (file) => {}
}
module.exports = withCss()
I want to edit this configuration file and add configurations like exportPathMap.
Like this:
module.exports = {
exportPathMap: function () {
return {
'/': { page: '/' },
'/about': { page: '/about' },
'/p/hello-nextjs': { page: '/post', query: { title: 'Hello Next.js' } },
'/p/learn-nextjs': { page: '/post', query: { title: 'Learn Next.js is awesome' } },
'/p/deploy-nextjs': { page: '/post', query: { title: 'Deploy apps with Zeit' } }
}
}
}
But I have no idea how to implement that without breaking the withCss plugin, please help.
Solved this by realizing that next-plugins such as #zeit/next-css that I was using expect more next configurations that are passed as objects from the plugin.
Snippet from #zeit/next-css plugin.
module.exports = (nextConfig = {}) => {
return Object.assign({}, nextConfig, {
webpack(config, options) {
if (!options.defaultLoaders) {
throw new Error(
'This plugin is not compatible with Next.js versions below 5.0.0 https://err.sh/next-plugins/upgrade'
)
}
So with that figured out I fixed the exportPathMap as an object inside withCss.
module.exports = withCss({
exportPathMap: function() {
return {
'/': {page: '/'},
'/sevices': {page: '/services'},
'/about': {page: '/about'},
'/contacts': {page: '/contacts'},
}
}
})
That's it! 🙌🙌

Resources