The new .HEIC files on IOS 11 is causing problems because image hosting services to not support it.
The camera roll api is returning.HEIC files. How can we get .JPG/.PNG instead. Or convert .HEIC to .JPG/.PNG
ImagePicker.showImagePicker(options, imgResponse => {
this.setState({ imageLoading: true, avatarMediaId: null });
if ((imgResponse.didCancel) || (imgResponse.error)) {
this.setState({ imageLoading: false });
} else {
let source = {};
let fileName = imgResponse.fileName;
if (Platform.OS === 'ios' && (fileName.endsWith('.heic') || fileName.endsWith('.HEIC'))) {
fileName = `${fileName.split(".")[0]}.JPG`;
}
source = { uri: imgResponse.uri, fileName };
this.uploadImage(source);
}});
Related
I am trying to download an Excel Sheet given a Base64 string using RNFetchBlob, I'm able to download for android, SDK version 29, but when I try to download from android 11 it showing Error: Operation not permitted.
My code is:
downloading = (data, arrayBuffer) => {
var date = moment()
.utcOffset('+05:30')
.format('YYYY-MM-DD hh:mm:ss');
let docName = `Excel_${date}.xlsx`
let pathToWrite = ''
if (Platform.OS == 'ios') {
const DownloadDir = RNFetchBlob.fs.dirs['MainBundleDir']
const pathToDownload = `${DownloadDir}/${docName}`;
pathToWrite = pathToDownload
} else {
pathToWrite = `${RNFetchBlob.fs.dirs.DownloadDir}/${docName}`;
}
let split = data.split('base64,')
var mimeType = 'application/xlsx';
RNFetchBlob.fs
.writeFile(pathToWrite, split[1], 'base64')
.then(() => {
// alert(`${docName} Downloaded Successfully`)
RNFetchBlob.android.addCompleteDownload({
title: 'ChitNote' + date,
description: 'Downloading FILE.',
mime: mimeType,
path: pathToWrite,
showNotification: true,
notification: true
})
alert(`Downloaded Successfully ${docName}`)
})
.catch((error) => {
alert(error)
console.log(error)
});
}
Please help me to solve this issue.
I'm trying to upload a multipart form in nativescript and I'm using http-background. I keep getting the error Class constructor Observable cannot be invoked without 'new'. I've tried changing the compilerOptions target to es5 and es2017, but nothing changed.
Here's all my code from the component.
onSave(){
console.log("clicked")
this.proccessImageUpload(this.file);
}
public onSelectSingleTap() {
this.isSingleMode = true;
let context = imagepicker.create({
mode: "single"
});
this.startSelection(context);
}
private startSelection(context) {
let that = this;
context
.authorize()
.then(() => {
that.imageAssets = [];
that.imageSrc = null;
return context.present();
})
.then((selection) => {
console.log("Selection done: " + JSON.stringify(selection));
this.file = selection[0]._android;
that.imageSrc = that.isSingleMode && selection.length > 0 ? selection[0] : null;
// set the images to be loaded from the assets with optimal sizes (optimize memory usage)
selection.forEach(function (element) {
element.options.width = that.isSingleMode ? that.previewSize : that.thumbSize;
element.options.height = that.isSingleMode ? that.previewSize : that.thumbSize;
});
that.imageAssets = selection;
}).catch(function (e) {
console.log(e);
});
}
// proccess image function
proccessImageUpload(fileUri) {
var backgroundHttp = require("nativescript-background-http");
return new Promise((resolve, reject) => {
// body...
var request = {
url: 'http://192.168.0.2:4000/api/posts',
method: "POST",
headers: {
"Content-Type": "application/octet-stream",
"user_id": "<user_id>"
},
description: 'Uploading profile image..',
androidAutoDeleteAfterUpload: false,
androidNotificationTitle: 'Profile image'
}
var params = [
{ name: "title", value: "test" },
{ name: "content", value: "test" },
{ name: "fileToUpload", filename: fileUri, mimeType: "image/jpeg" }
];
var backgroundSession = backgroundHttp.session('image-upload');
var task = backgroundSession.uploadFile(fileUri, request);
task.on("progress", (e) => {
// console log data
console.log(`uploading... ${e.currentBytes} / ${e.totalBytes}`);
});
task.on("error", (e) => {
// console log data
console.log(`Error processing upload ${e.responseCode} code.`);
reject(`Error uploading image!`);
});
task.on("responded", (e) => {
// console log data
console.log(`received ${e.responseCode} code. Server sent: ${e.data}`);
// var uploaded_response = JSON.parse(e.data);
});
task.on("complete", (e) => {
// console log data
console.log(`upload complete!`);
console.log(`received ${e.responseCode} code`);
// console.log(e.data);
})
resolve(task);
});
}
I know the issue is coming from this line.
var task = backgroundSession.uploadFile(fileUri, request);
Any help would be greatly appreciated!
You use old version if nativescript-background-http plugin
You have to install latest version
tns plugin add #nativescript/background-http
I was able to get this working by installing tns version 6.
I had exactly the same problem. I got this from slack.com, compliments Chris Vietor
"tns plugin add nativescript-background-http" works with nativescript 6.
"tns plugin add #nativescript/background-http" works with nativescript 7.
I am trying to implement a camera functionality in Desktop and Tablet. I need to detect the device first and then add camera functionality.
I have detected Device using navigator-user-agent but when I try it in windows or tablet, It is detecting as windows only:
enter const webcam_Result = (sync () => {
try {
var has_webcam = await detecting_Webcam();
if (has_webcam === true) {
var detect_Device = navigator.userAgent;
if (detect_Device.includes("Windows")) {
this.setState({
webcam_access: true
});
} else {
this.setState({ webcam_access: false });
}
}
if (has_webcam === false) {
this.setState({ webcam_access: false });
}
} catch (e) {
alert("entered into catch block");
console.log(e);
}
})();
};
Expected Results : need to differentiate desktop and tablet using navigator.useragent
I have a react-google-maps instance in my application which draws multiple location icons on google map. When there are more than one icons, sometimes, one icon, which have different location, gets stuck on another icon. The new icon is not clickable and gets removed automatically after giving a little nudge to the map (see image below)
IMO, the issue is with the google map's drawing multiple location icons.
Any idea, how can I fix this?
Here's how I am setting state when the component mounts
this.state = this.convertEntityStructureToComponentState(props.entities, props.hideInfoInitially, props.showDirections);
convertEntityStructureToComponentState() function looks like this:
convertEntityStructureToComponentState(entities, hideInfoInitially, showDirections=false) {
if (!entities || entities.length === 0) {
// send seattle longitude and latitude and set markers as null
const center = {
lat: 47.602743,
lng: -122.330626
};
return {
center: center,
markers: []
};
}
const markers = [];
let firstEntityReadings = null;
let destinationPosition = null;
let selectedEntityPosition = null;
let showPathLine = true;
for (let i = 0; i < entities.length; i++) {
if (entities[i].location) {
if (!firstEntityReadings) {
firstEntityReadings = {
lat: entities[i].location.lat,
lng: entities[i].location.lng
};
}
let showLocation = true;
if (entities[i].type === 'customer') {
destinationPosition = i;
} else {
if (this.isTimeInOnlineRange(entities[i].time)) {
selectedEntityPosition = i;
} else if (this.props.customerView) {
showLocation = false;
showPathLine = false;
}
}
if (showLocation) {
markers.push({
position: new google.maps.LatLng(entities[i].location.lat, entities[i].location.lng),
showInfo: false,
data: {
name: entities[i].name,
address: entities[i].address,
id: entities[i].id,
time: entities[i].time,
color: entities[i].type === 'customer' ? entities[i].color : '#ccc',
type: entities[i].type,
image_path: entities[i].image_path
}
});
}
}
}
//Optimize where we get previous location and don't call direction if it's the same
if (showDirections && destinationPosition != null && selectedEntityPosition != null && showPathLine) {
const DirectionsService = new google.maps.DirectionsService();
DirectionsService.route({
origin: new google.maps.LatLng(entities[selectedEntityPosition].location.lat, entities[selectedEntityPosition].location.lng),
destination: new google.maps.LatLng(entities[destinationPosition].location.lat, entities[destinationPosition].location.lng),
travelMode: google.maps.TravelMode.DRIVING,
}, (result, status) => {
if (status === google.maps.DirectionsStatus.OK) {
this.setState({
directions: result
});
}
});
} else {
this.setState({
directions: null
});
}
return {
center: firstEntityReadings,
markers: markers
};
}
Link to Github issue: https://github.com/tomchentw/react-google-maps/issues/805
Link to the gist of location map component: https://gist.github.com/arximughal/f91b7a922a4711e25ef82ed9ac6427b5
The issue was with the key and ref of the markers that I was drawing on the map. Generating a random ID for key fixed the issue properly.
Other than workaround of calling fetch multiple times for multiple image files upload (looping through the files), on Frontend, How to upload multiple of image files by just calling fetch/Upload once? Could someone provide a simple example? Just like we do on Facebook.
Thanks in advance!
Update: I am done with looping logic in front end, now as there is loader on every image getting uploaded, Percent uploaded is getting calculated for all images in single value, how to split this value for all images separately?
Looping Logic
for (let i = 0; i <= e.target.files.length; i++){
let reader = new FileReader();
let file = e.target.files[i];
var self = this
reader.onloadstart = () => {
self.setState({ImageUploader: true})
}
reader.onloadend = () => {
var data = reader.result;
if (!file.type.includes('image')) {
alert('PLEASE CHOSE A IMAGE BRAH!')
} else if (file.size / (1024 * 1024) > 5) {
alert('PLEASE CHOSESmaller Image')
} else {
var url = 'https://api......'
var ifd = new FormData();
ifd.append('file', file)
axios({url: url,method: 'put',
onUploadProgress: function(progressEvent) {
var percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
self.setState({Completed: percentCompleted})
}, withCredentials: true, data: ifd}).then((res) => {
this.setState({ImageUploader: false})
this.setState({
image_id: this.state.image_id.concat(res.data.reason.image_id)
})
})
this.setState({
file: file,
imagePreviewUrl: this.state.imagePreviewUrl.concat(reader.result),
noImage: false,
ImageChoosen: true
});
}
}
reader.readAsDataURL(file)
}