I am trying to use the cordova social sharing plugin for sharing video on social sites. So far what I have achieved is, I have successfully captured video using following code -
var options = {
limit: 1,
duration: 15
};
$cordovaCapture.captureVideo(options).then(function (videoData) {
$scope.videoUrl = videoData[0].fullPath;
}, function (err) {
// An error occurred. Show a message to the user
//alert("video error : "+err);
});
I can successfully find the captured video files url but unfortunately I can not share them to the social media sites. I have tried both of the following methods -
$cordovaSocialSharing
.share(message, subject, file, link)
and
$cordovaSocialSharing
.shareViaTwitter(message, image, link)
Now my question is -
Is there any way to share video through this approach?
If not, please let me know if there is any possible way for this.
N.B. : I have already bothered the Google a lot.
Thanks in advance.
my problem was passing a bad filePath, so i found a solution like below :
import {CaptureError, MediaFile, MediaCapture, CaptureImageOptions, Transfer} from "ionic-native";`
declare let cordova: any;
private static options = {
message: '', // not supported on some apps (Facebook, Instagram)
subject: '', // for email
files: [''], // an array of filenames either locally or remotely
url: ''
};
videoOptions: CaptureImageOptions = {limit: 1};
videoData: any;
captureVideo() {
MediaCapture.captureVideo(this.videoOptions)
.then(
(data: MediaFile[]) => {
this.videoData = data[0];
const fileTransfer = new Transfer();
fileTransfer.download(this.videoData.fullPath, cordova.file.applicationStorageDirectory + 'fileDir/filename.mp4').then((entry) => {
this.options.message = " Your message";
this.options.subject = "Your Subject";
this.options.files = [entry.toURL()];
this.options.url = "https://www.google.com.tr/";
SocialSharing.shareWithOptions(this.options);
}, (error) => {
});
},
(err: CaptureError) => {
}
);
}
As you see above, i just copy my video file to applicationStorageDirectory
Related
I am trying to run a WebApp which allows files sharing.
After few google search, I found Web Share API like the standard to do so.
According to the documentation it should works like this using plain JS
This is the code for html page
<p><button>Share MDN!</button></p>
<p class="result"></p>
The code to share all sort "textbased" metadata:
let shareData = {
title: 'MDN',
text: 'Learn web development on MDN!',
url: 'https://developer.mozilla.org',
}
const resultPara = document.querySelector('.result');
if (!navigator.canShare) {
resultPara.textContent = 'navigator.canShare() not supported.';
}
else if (navigator.canShare(shareData)) {
resultPara.textContent = 'navigator.canShare() supported. We can use navigator.share() to send the data.';
} else {
resultPara.textContent = 'Specified data cannot be shared.';
}
The code above works fine, the trouble happens when I try to share files.
According to the documentation it should works like this:
// filesArray is an array of files we want to share (audios, images, videos, pdf)
if (navigator.canShare && navigator.canShare({ files: filesArray })) {
navigator.share({
files: filesArray,
title: 'Pictures',
text: 'Our Pictures.',
})
.then(() => console.log('Share was successful.'))
.catch((error) => console.log('Sharing failed', error));
} else {
console.log(`Your system doesn't support sharing files.`);
}
I started my code from this example and I never success to share a file.
My actual code using React and Typescript looks like this:
//some react code here
const shareNow = async () => {
let imageResponse = await window.fetch('https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png', {mode: "no-cors"});
let imageBuffer = await imageResponse.arrayBuffer();
let fileArray = [new File([imageBuffer], "File Name", {
type: "image/png",
lastModified: Date.now()
})];
if (navigator.canShare && navigator.canShare({ files: filesArray })) {
navigator.share({
files: filesArray
}).then(() => {
console.log('Thanks for sharing!');
})
.catch(console.error);
}
}
//some react code here too
At this point, my typescript compiler yell at me.
Apparently, the navigator object has no method canShare()
I am new to typescript, but I don't understand how and why the navigator could have less attribute since TypeScript is JavaScript superset.
Anyone has an idea on how to solve that except running normal JS ?
Thank you for your time reading this, and I hope to thank you for your answers.
P.S: I also tried a react-component based solution, but all the component I found in open source which wraps Web Share API does not allow file sharing.
Edit
Hey, #DenverCoder9
There is the same use case but using vanilla JS, could anyone try it and tell me what I am doing wrong please ?
<html>
<head>
<title>Sharing Image</title>
<meta charset="UTF-8" />
</head>
<body>
<div className="App">
<img src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"/>
<button id="button">Share</button>
</div>
</body>
<script>
async function shareImage(title, imageUrl) {
const image = await fetch(imageUrl, {mode: "no-cors"});
const blob = await image.blob();
const file = new File([blob], title, { type: 'image/png' });
const filesArray = [file];
const shareData = {
files : filesArray
}
// add it to the shareData
const navigator = window.navigator
const canShare = navigator.canShare && navigator.canShare(shareData) //navigator.canShare()navigator.share //navigator.canShare()
if(canShare){
navigator.share(shareData)
.then(() => console.log('Successful share'))
.catch((error) => console.log('Error sharing', error));
}
else {
console.log("cannot share this file in this context")
}
}
document.getElementById('button').onclick = function() {
shareImage("Title", "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png")
};
</script>
</html>
I am running this on safari for mac
This is more of a TypeScript issue than a coding issue. Support for the Web Share API (Level 2) was added in this PR, so you can either update to a version of TypeScript that includes this, or alternatively teach your current TypeScript version the relevant types as follows:
type ShareData = {
title? : string;
text? : string;
url? : string;
files?: ReadonlyArray<File>;
};
interface Navigator
{
share? : (data? : ShareData) => Promise<void>;
canShare?: (data?: ShareData) => boolean;
}
So, basically I'm trying to receive a call from provider to my app. For that purpose Quickblox gives us a listener to receive the upcoming calls onCallListener. So here is my code snippet that should work but doesn't.
const calleesIds = [4104]
const sessionType = QB.webrtc.CallType.VIDEO
const additionalOptions = {}
let callSession = QB.webrtc.createNewSession(calleesIds, sessionType, null, additionalOptions)
console.log(callSession, "SESSION")
const mediaParams = {
audio: true,
video: true,
options: {
muted: true,
mirror: true,
},
elemId: "myVideoStream"
}
QB.webrtc.onCallListener = function(session: any, extension: object) {
callSession = session
console.log('asdasd')
// if you are going to take a call
session.getUserMedia(mediaParams, function (error: object, stream: object) {
if (error) {
console.error(error)
} else {
session.accept(extension)
session.attachMediaStream("videoStream", stream)
}
})
}
P.S. I also integrated chat which works perfect!
Found the solution by myself! Whenever you create a user and dialog id, search that user in the quickblox dashboard by the dialogId and change its settings: you will see that userId and providerId is the same which is wrong. So put your userId in the userId field and save that. After that you video calling listeners will work fine!)
P. S. also in the backend replace provider token with user token.
I'm using Google Drive Picker UI to select a folder and create or update spreadsheet into that folder on a schedule
Sometimes it works as expected but recently it is showing a message called "In order to select an item, please sign in". On clicking "sign in" button it shows "The feature you requested is currently unavailable. Please try again later."
Previously, this used to occur when reauthorizing immediately after revoking access but now I'm requesting with extra params like whom the folder is shared with, created date, folder name to display in front-end. It worked fine for some days but now, the issue above mentioned is occurring frequently.
createPicker(oauthToken, authCode, authUser) {
const googleViewId = window.google.picker.ViewId.FOLDERS;
const docsView = new window.google.picker.DocsView(googleViewId)
.setIncludeFolders(true)
.setMimeTypes('application/vnd.google-apps.folder')
.setSelectFolderEnabled(true);
const picker = new window.google.picker.PickerBuilder()
.addView(docsView)
.setOAuthToken(oauthToken)
.setDeveloperKey(this.props.developerKey)
.setCallback(data => {
if (data.action === window.google.picker.Action.PICKED) {
this.fetchFolderDetails(data, authCode, authUser);
}
});
if (this.props.multiSelect) {
picker.enableFeature(window.google.picker.Feature.MULTISELECT_ENABLED);
}
picker.build().setVisible(true);
}
fetchFolderDetails(data, authCode, authUser) {
window.gapi.client
.init({
apiKey: this.props.developerKey
})
.then(() =>
window.gapi.client.request({
path: 'https://www.googleapis.com/drive/v2/files/' + data.docs[0].id,
params: {
fields: 'permissions, title, createdDate, shared'
}
})
)
.then(response => {
let googleDriveData = {
folderId: data.docs[0].id,
mimeType: data.docs[0].mimeType,
authCode,
authUser,
folderName: response.result.title,
permissions: response.result.permissions,
shared: response.result.shared,
createdTime: response.result.createdDate
};
this.props.onChange(googleDriveData);
});
}
I expect to see the list of folders after authorizing.
Update
Adding a google drive scope somewhat fixed the issue but still the immediate reauthorizing issue persists.
I am trying to save the base64 string to the gallery. When I invoke this plugin my code get's crashed. Here is the link I used to check.
code I use
let options:Base64ToGalleryOptions = { prefix: '_img',mediaScanner: true }
//after the below line my gets close automatically any idea
this.base64ToGallery.base64ToGallery(base64Image[1],options)
.then(
res => {
debugger
console.log('Saved image to gallery ', res)
},
err => {
debugger
console.log('Error saving image to gallery ', err)
});
I am not able to debug
I am not able to understand why my app closes automatically after hitting this code
Update:
After installing this particular version of the plugin
ionic cordova plugin add cordova-base64-to-gallery#2.0.2
and moving my code to platform
this.platform.ready().then(() => {
this.base64ToGallery.base64ToGallery(base64Image,options)
.then(
res => {
console.log('Saved image to gallery ', res);
this.navCtrl.pop();
},
err => { //For ios i am getting as `plugin_not_installed`
console.log('Error saving image to gallery ', err);
this.navCtrl.pop()
});
})
But this same code is not working for ios according to the doc i have installed the same version which supports ios also (2.0.2) but it looks something is missing if any please let me know
Since you are unable to debug here are three problems I ran across until I got it to work, most likely the second problem if on Android or the third problem if on iOS.
1) Error saving image to gallery cordova_not_available
Fix for this was to create a project that had cordova baked in with the command ionic start blank --cordova
2) Error saving image to gallary Error while saving image I got this error message on an Android device. I looked at their code implementation here https://github.com/Nexxa/cordova-base64-to-gallery/blob/2f531aaa0bf17b900cf6bd9704082e72f183d325/src/android/Base64ToGallery.java
Saw that they have not done anything regarding WRITE_EXTERNAL_STORAGE permissions.
My solution was to add AndroidPermissions and check for WRITE_EXTERNAL_STORAGE permissions at runtime.
hasWriteAccess: boolean = false;
constructor(private base64ToGallery: Base64ToGallery,
private androidPermissions: AndroidPermissions) {
}
ionViewWillEnter() {
this.checkPermissions();
}
checkPermissions() {
this.androidPermissions
.checkPermission(this.androidPermissions
.PERMISSION.WRITE_EXTERNAL_STORAGE)
.then((result) => {
console.log('Has permission?',result.hasPermission);
this.hasWriteAccess = result.hasPermission;
},(err) => {
this.androidPermissions
.requestPermission(this.androidPermissions
.PERMISSION.WRITE_EXTERNAL_STORAGE);
});
if (!this.hasWriteAccess) {
this.androidPermissions
.requestPermissions([this.androidPermissions
.PERMISSION.WRITE_EXTERNAL_STORAGE]);
}
}
saveImage() {
if (!this.hasWriteAccess) {
this.checkPermissions();
}
let options: Base64ToGalleryOptions = {
prefix: '_img',
mediaScanner: true
};
this.base64ToGallery
.base64ToGallery(this.base64Data, options).then(
res => console.log('Saved image to gallery:', res),
err => console.log('Error saving image to gallery:', err)
);
}
3) This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryAddUsageDescription key with a string value explaining to the user how the app uses this data.
Solution is to add NSPhotoLibraryAddUsageDescription to project_name/config.xml nested between <platform name="ios"> and </platform>
<config-file parent="NSPhotoLibraryAddUsageDescription" target="*-Info.plist">
<string>Saves images from base64 to your Photo Library</string>
</config-file>
I hope there is few among you who have experience with Jaspersoft Reports and their new visualise.js api
I have a problem with visualise.js not producing report export file. What happens is:
I am able to succsefully load the report through the visualise.js API, it loads and displays on my web page
Export controls load up successfully too, so I have dropdown with export file formats and a button to export the file.
When I click the export button though, the whole page reloads as if the export button was really a submit button and nothing happens.
Occasionally, the export will work and it will produce file. Though there is no pattern to when it will produce the file and when it will fail.
Below is the code I am using for this (I am using plain text auth for testing purposes):
visualize({
auth: {
name: "mylogin",
password: "mypass",
organization: "organization_1"
}
}, function (v) {
var $select = buildControl("Export to: ", v.report.exportFormats),
$button = $("#button"),
report = v.report({
resource: "/FPSReports/journal",
container: "#export",
params: {
"journal_ref": [ "<?php echo $reference; ?>" ],
},
success: function () {
button.removeAttribute("disabled");
},
error : function (error) {
console.log(error);
}
});
$button.click(function () {
console.log($select.val());
report.export({
// export options here
outputFormat: $select.val(),
// exports all pages if not specified
// pages: "1-2"
}, function (link) {
var url = link.href ? link.href : link;
window.location.href = url;
}, function (error) {
console.log(error);
});
});
function buildControl(name, options){
function buildOptions(options) {
var template = "<option>{value}</option>";
return options.reduce(function (memo, option) {
return memo + template.replace("{value}", option);
}, "")
}
var template = "<label>{label}</label><select>{options}</select><br />",
content = template.replace("{label}", name)
.replace("{options}", buildOptions(options));
var $control = $(content);
$control.insertBefore($("#button"));
//return select
return $($control[1]);
}
});
HTML:
<div class="grid">
<div class="grid-8"></div>
<div class="grid-8 center">Export</div>
<div class="grid-8"></div>
</div>
<div class="grid">
<div class="grid-24" id="export"></div>
</div>
The only parameter comes from URI segment (I am using codeigniter framework):
$reference = $this->uri->segment(3, 0);
I have found an answer that seems to work, and has resolved the issue. Posting it here in case anyone else has this specific problem like I did.
In brief:
After spending hours looking at console debug output I have realised that each time I tried to send a request for export a new session would be opened. Without logging out of the previous one. And apparently that is a no-no. I do not know JS very well but from what I understood there was session id mismatch in request. Please feel free to correct me here :)
The solution to this problem (or for example if you are having authentication issues with visualize.js) is very simple. Set the authentication in global config:
visualize.config({
auth: {
name: "superuser",
password: "superuser"
}
});
No matter if you are using tokens or plain text or whatever else auth is available through the api.
Then do your stuff wherever else on your website:
visualize(function (v) {
v("#container1").report({
resource: "/public/Samples/Reports/06g.ProfitDetailReport",
error: function (err) {
alert(err.message);
}
});
});
visualize(function (v) {
v("#container2").report({
resource: "/public/Samples/Reports/State_Performance",
error: function (err) {
alert(err.message);
}
});
});
Everything should work for you as it did for me. This works in version 5.6 and 6.1 of visualize.js.
Further reading and links from my research:
Token based authentication to Jasper reports failing when used with visualize.js
Visualize.js authentication error after second login
http://community.jaspersoft.com/questions/842695/visualizejs-authentication-error
http://community.jaspersoft.com/questions/845886/authentication-error-refresh-credentials-visualizejs
Code example (5.6):
http://jsfiddle.net/TIBCO_JS_Community/sozzq0sL/embedded/
Api samples (6.1):
http://community.jaspersoft.com/wiki/visualizejs-api-samples-v61
Api samples (5.6):
http://community.jaspersoft.com/wiki/visualizejs-api-notes-and-samples-v56
Really hope this will help someone new to Jaspersoft & visualize.js like me.