flutter_inappwebview and stripe.js blank screen - flutter

When loading a webpage that has the stripe javascript on it the InAppWebView is just a blank page, onLoadStop reports the URI: https://m.stripe.network/inner.html?url=\*\*&title=\*\*&referrer=\*\*&muid=NA&sid=NA&version=6&preview=false
The flutter app is a simple InAppWebView that mirrors a laravel website using the cashier/stripe subscription combination. The page works in a browser and when launched using url_launcher, but this requires the user to re-login and navigate back to where they were.
Is there any way to allow this page to load in flutter_inappwebview? Or, create the card-element element without the JavaScript include (https://js.stripe.com/v3)?
JavaScript code:
<script src="https://js.stripe.com/v3/"></script> -- this is the culprit
<script>
var stripe = Stripe('{{ env('STRIPE_KEY') }}');
var elements = stripe.elements();
var style = {
base: {
color: '#32325d',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '16px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
var card = elements.create('card', {
hidePostalCode: true,
style: style
});
card.mount('#card-element');
card.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});
const cardHolderName = document.getElementById('card-holder-name');
const cardButton = document.getElementById('card-button');
const clientSecret = cardButton.dataset.secret;
cardButton.addEventListener('click', async (e) => {
console.log("attempting");
const { setupIntent, error } = await stripe.confirmCardSetup(
clientSecret, {
payment_method: {
card: card,
billing_details: { name: cardHolderName.value }
}
});
if (error) {
var errorElement = document.getElementById('card-errors');
errorElement.textContent = error.message;
} else {
paymentMethodHandler(setupIntent.payment_method);
}
});
function paymentMethodHandler(payment_method) {
var form = document.getElementById('subscribe-form');
var hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'payment_method');
hiddenInput.setAttribute('value', payment_method);
form.appendChild(hiddenInput);
form.submit();
}
</script>

Solved.
Stripe doesn't like custom headers, so if you add a header to the request it will block it.

Related

Rendering a menu in vue 3 after ajax method

I've gotten this menu to work without filtering it, but now I'm doing an ajax request to filter out menu items the user isn't supposed to see, and I'm having some trouble to figure out how to set the resulting menu data, the line that is not working is commented below:
<script>
import { ref } from 'vue';
import axios from 'axios';
var currentSelected = 'device_access';
var menuData = [
{
text: 'Device Access',
id: 'device_access',
children: [
{
text: 'Interactive',
link: '/connection_center'
},{
text: 'Reservation',
link: '/reserve_probe'
}, {
text: 'Reservation Vue',
link: '/reservation.html'
}
]
}, {
text: 'Automation',
id: 'automation',
show: ['is_mxadmin', 'can_schedule_scripts'],
children: [
{
text: 'Builder',
link: '/builder',
},{
text: 'Execution Results',
link: '/test_suite_execution_results'
},
]
}
];
function hasMatch(props, list) {
var match = false;
for (var i=0; i < list.length && !match; i++) {
match = props[list[i]];
}
return match;
}
export default {
name: 'Header',
setup() {
const cursorPosition = ref('0px');
const cursorWidth = ref('0px');
const cursorVisible = ref('visible');
//the menu is zero length until I get the data:
const menu = ref([]);
return {
menu,
cursorPosition,
cursorWidth,
cursorVisible
}
},
created() {
let that = this;
axios.get('navigation_props')
.then(function(res) {
var data = res.data;
var result = [];
menuData.forEach(function(item) {
if (!item.show || hasMatch(data, item.show)) {
var children = [];
item.children.forEach(function (child) {
if (!child.show || hasMatch(data, child.show)) {
children.push({ text: child.text, link: child.link });
}
});
if (children.length > 0) {
result.push({ text: item.text,
children: children, lengthClass: "length_" + children.length });
}
}
});
//continues after comment
this is probably the only thing wrong, I've run this in the debugger and I'm getting the
correct data:
that.$refs.menu = result;
since the menu is not being rebuilt, then this fails:
//this.restoreCursor();
})
.catch(error => {
console.log(error)
// Manage errors if found any
});
},
this.$refs is for template refs, which are not the same as the refs from setup().
And the data fetching in created() should probably be moved to onMounted() in setup(), where the axios.get() callback sets menu.value with the results:
import { onMounted, ref } from 'vue'
export default {
setup() {
const menu = ref([])
onMounted(() => {
axios.get(/*...*/).then(res => {
const results = /* massage res.data */
menu.value = results
})
})
return {
menu
}
}
}
I finally figured out the problem.
This code above will probably work with:
that.menu = result;
You don't need: that.$refs.menu
You can't do it in setup because for some reason "that" is not yet defined.
In my working code I added a new method:
methods: {
setMenuData: function() {
this.menu = filterMenu();
},
}
And "this" is properly defined inside them.

html2canvas - the screenshotted canvas is always empty/blank

I have a div that i want to screenshot and save,
here is my code
function _download(uri, filename)
{
var el = $('.sf-download-button');
if (el.length)
{
var link = document.createElement('a');
if (typeof link.download === 'string')
{
link.href = uri;
link.download = filename;
document.body.appendChild(link);
//simulate click // this causes page to download an empty html file not sure why
link.click();
//remove the link when done
document.body.removeChild(link);
}
else
{
window.open(uri);
}
}
}
function _save()
{
window.takeScreenShot = function ()
{
var a =document.getElementById("my-div");
html2canvas(document.getElementById("the-div-that-i-want-to-screenshot"), {
onrendered: function (canvas)
{
document.body.appendChild(canvas);
a.append(canvas);
},
width: 220,
height: 310
});
};
$("#btnSave2").click(function ()
{
html2canvas(document.getElementById("data"), {
onrendered: function (canvas)
{
_download_card(canvas.toDataURL(), 'save.png');
}
});
});
}
This is the code i got it from web and added some of my own stuff.code was working i believe but right now, when I click on the button show me the image, it creates the image i can see it but it is just blank.
I tried every possible code combination from jsfiddle and all that and couldn't get anything different as a result.
What could be going wrong here?
I solved the problem by simply changing the browser,
It was not working with Chrome but works perfectly on Mozilla.
Also i changed the code to this,
$("#btnSave").click(function() {
html2canvas($("#card"), {
onrendered: function(canvas) {
theCanvas = canvas;
document.body.appendChild(canvas);
// Convert and download as image
$("#img-out").append(canvas);
// Clean up
//document.body.removeChild(canvas);
}
});
});
Works perfect on Mozilla only.

What does this `checkSession` function do?

I have included the firebase and angularfire libraries to my ionic framework project.
I am following the below link for my sample project.
https://www.sitepoint.com/creating-firebase-powered-end-end-ionic-application/
I am not able to understand how the 'checkSession' function in the below 'app.js' works. Could someone please explain?
How can we call the 'auth' function which is inside 'checkSession' function?
app.js
angular.module('bucketList', ['ionic', 'firebase', 'bucketList.controllers'])
.run(function($ionicPlatform, $rootScope, $firebaseAuth, $firebase, $window, $ionicLoading) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
$rootScope.userEmail = null;
$rootScope.baseUrl = 'https://bucketlist-app.firebaseio.com/';
var authRef = new Firebase($rootScope.baseUrl);
$rootScope.auth = $firebaseAuth(authRef);
$rootScope.show = function(text) {
$rootScope.loading = $ionicLoading.show({
content: text ? text : 'Loading..',
animation: 'fade-in',
showBackdrop: true,
maxWidth: 200,
showDelay: 0
});
};
$rootScope.hide = function() {
$ionicLoading.hide();
};
$rootScope.notify = function(text) {
$rootScope.show(text);
$window.setTimeout(function() {
$rootScope.hide();
}, 1999);
};
$rootScope.logout = function() {
$rootScope.auth.$logout();
$rootScope.checkSession();
};
$rootScope.checkSession = function() {
var auth = new FirebaseSimpleLogin(authRef, function(error, user) {
if (error) {
// no action yet.. redirect to default route
$rootScope.userEmail = null;
$window.location.href = '#/auth/signin';
} else if (user) {
// user authenticated with Firebase
$rootScope.userEmail = user.email;
$window.location.href = ('#/bucket/list');
} else {
// user is logged out
$rootScope.userEmail = null;
$window.location.href = '#/auth/signin';
}
});
}
});
})

youtube iframe API does not work on ipad and iphone

I was trying to recreate the multiple iframes example detailed here for a slideshow. It works flawlessly in all browsers, including desktop safari, except on iphone and ipad.
http://codepen.io/lakshminp/pen/mepIB
Js:
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var players = {}
var YT_ready = (function() {
var onReady_funcs = [],
api_isReady = false;
return function(func, b_before) {
if (func === true) {
api_isReady = true;
for (var i = 0; i < onReady_funcs.length; i++) {
// Removes the first func from the array, and execute func
onReady_funcs.shift()();
}
}
else if (typeof func == "function") {
if (api_isReady) func();
else onReady_funcs[b_before ? "unshift" : "push"](func);
}
}
})();
function onYouTubeIframeAPIReady() {
jQuery(window).bind("load", function() {
YT_ready(true);
});
}
YT_ready(function() {
var identifier = "v9d09JLBVRc";
players[identifier] = new YT.Player(identifier, {
events: {
'onReady': onPlayerReady,
"onStateChange": createYTEvent(identifier)
}
});
});
function onPlayerReady(event) {
event.target.playVideo();
}
// Returns a function to enable multiple events
function createYTEvent(identifier) {
var player = players[identifier]; // Get cached player instance
return function (event) {
console.log(event.data);
}
}
HTML:
<div id="yt-container">
<iframe width="640" height="480" id="v9d09JLBVRc" class="media-youtube-player" src="//www.youtube.com/embed/v9d09JLBVRc?enablejsapi=1&autoplay=0" frameborder="0" allowfullscreen></iframe>
</div>
According to this
functions and parameters such as autoplay, playVideo(), loadVideoById() won't work in all mobile environments
and in your YTReady function, you load dynamically a video and for the moment that's not possible on iOS.
You can also try the YouTubeDemoPage and try to load another id and you will see that it can't be done.
You should also check this.

upload base64 image facebook graph api how to use this script

Upload Base64 Image Facebook Graph API
i want to use this script that link is attached how i can use this in my wordpress post?
i want to use this for fbcover photo site.
Take a look at this code I hacked together from various examples - you can use this to post a pure base64 string to the Facebook API - no server side processing.
Here's a demo: http://rocky-plains-2911.herokuapp.com/
This javascript handles the converting of a HTML5 Canvas element to base64 and using the Facebook API to post the image string
<script type = "text/javascript">
// Post a BASE64 Encoded PNG Image to facebook
function PostImageToFacebook(authToken) {
var canvas = document.getElementById("c");
var imageData = canvas.toDataURL("image/png");
try {
blob = dataURItoBlob(imageData);
} catch (e) {
console.log(e);
}
var fd = new FormData();
fd.append("access_token", authToken);
fd.append("source", blob);
fd.append("message", "Photo Text");
try {
$.ajax({
url: "https://graph.facebook.com/me/photos?access_token=" + authToken,
type: "POST",
data: fd,
processData: false,
contentType: false,
cache: false,
success: function (data) {
console.log("success " + data);
$("#poster").html("Posted Canvas Successfully");
},
error: function (shr, status, data) {
console.log("error " + data + " Status " + shr.status);
},
complete: function () {
console.log("Posted to facebook");
}
});
} catch (e) {
console.log(e);
}
}
// Convert a data URI to blob
function dataURItoBlob(dataURI) {
var byteString = atob(dataURI.split(',')[1]);
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], {
type: 'image/png'
});
}
</script>
This handles the Facebook Authentication and shows basic HTML setup
<script type="text/javascript">
$(document).ready(function () {
$.ajaxSetup({
cache: true
});
$.getScript('//connect.facebook.net/en_UK/all.js', function () {
// Load the APP / SDK
FB.init({
appId: '288585397909199', // App ID from the App Dashboard
cookie: true, // set sessions cookies to allow your server to access the session?
xfbml: true, // parse XFBML tags on this page?
frictionlessRequests: true,
oauth: true
});
FB.login(function (response) {
if (response.authResponse) {
window.authToken = response.authResponse.accessToken;
} else {
}
}, {
scope: 'publish_actions,publish_stream'
});
});
// Populate the canvas
var c = document.getElementById("c");
var ctx = c.getContext("2d");
ctx.font = "20px Georgia";
ctx.fillText("This will be posted to Facebook as an image", 10, 50);
});
</script>
<div id="fb-root"></div>
<canvas id="c" width="500" height="500"></canvas>
<a id="poster" href="#" onclick="PostImageToFacebook(window.authToken)">Post Canvas Image To Facebook</a>
I needed this too, and was not happy with all the code around it because it is lengthy and usually needs jQuery. Here is my code for uploading from Canvas to Facebook:
const dataURItoBlob = (dataURI) => {
let byteString = atob(dataURI.split(',')[1]);
let ab = new ArrayBuffer(byteString.length);
let ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {
type: 'image/jpeg'
});
}
const upload = async (response) => {
let canvas = document.getElementById('canvas');
let dataURL = canvas.toDataURL('image/jpeg', 1.0);
let blob = dataURItoBlob(dataURL);
let formData = new FormData();
formData.append('access_token', response.authResponse.accessToken);
formData.append('source', blob);
let responseFB = await fetch(`https://graph.facebook.com/me/photos`, {
body: formData,
method: 'post'
});
responseFB = await responseFB.json();
console.log(responseFB);
};
document.getElementById('upload').addEventListener('click', () => {
FB.login((response) => {
//TODO check if user is logged in and authorized publish_actions
upload(response);
}, {scope: 'publish_actions'})
})
Source: http://www.devils-heaven.com/facebook-javascript-sdk-photo-upload-from-canvas/