I have DATECS DPP-250 POS printer and I am trying to connect it using WebUSB API and print some data. Problem that I have is that printing is not working. I can connect to device and chrome reads it fine but when I submit printing (transferOut) printer just hangs. I tried to debug error in console but I don't have any errors whatsoever. I tried on MAC OS and on Windows 10 with WinUSB driver (used Zadig to change driver on windows) and all of them have same problem.
Does someone knows where is the problem?
EDIT:
I tried with other POS printer (non bluetooth one) and my code works perfectly. Only problem is with this printer. This type of printer use micro usb so maybe that is a problem?
Here is code I am using
<html>
<body>
<textarea id="printContent"></textarea>
<input type="submit" onclick="connectAndPrint()" value="Print"/>
<P>Type text into box and click on submit button.
<script>
var device;
function setup(device) {
return device.open()
.then(() => device.selectConfiguration(1))
.then(() => device.claimInterface(device.configuration.interfaces[0].interfaceNumber))
}
function print() {
var string = document.getElementById("printContent").value + "\n";
var encoder = new TextEncoder();
var data = encoder.encode(string);
console.log(data.length);
device.transferOut(device.configuration.interfaces[0].alternate.endpoints[0].endpointNumber, data)
.catch(error => { console.warn(error); })
}
function connectAndPrint() {
console.log(device);
if (device == null) {
navigator.usb.requestDevice({ filters: [{ vendorId: 5380 }, { vendorId: 65520 }] })
.then(selectedDevice => {
device = selectedDevice;
console.log(device.configuration);
return setup(device);
})
.then(() => print())
.catch(error => { console.log(error); })
}
else
print();
}
navigator.usb.getDevices()
.then(devices => {
if (devices.length > 0) {
device = devices[0];
return setup(device);
}
})
.catch(error => { console.log(error); });
</script>
</body>
</html>
you need to run it on server for example with :xampp or node js. I was trying before with single html it doesnt work, but i put on server it will work
Related
I'm a beginner at React Native.
I am trying to access a native(built-in) camera app on Android device.
I used React-Native-Image-Picker to open the camera app but I would like to record a video somehow automatically(?) I mean not using my finger.
I need codes that make it to record and stop the video.
(I don't mean to give me a code rather, please advise if it is even possible?)
Any help would be very appreciated.
Thank you!
It is possible.
Package: https://github.com/mrousavy/react-native-vision-camera
Review the API and Guide section to see how to start and stop recording programmatically.
They also show an example app that demonstrates different types of capture including video recording, ref: https://github.com/mrousavy/react-native-vision-camera/blob/28fc6a68a5744efc85b532a338e2ab1bc8fa45fe/example/src/views/CaptureButton.tsx
...
const onStoppedRecording = useCallback(() => {
isRecording.current = false;
cancelAnimation(recordingProgress);
console.log('stopped recording video!');
}, [recordingProgress]);
const stopRecording = useCallback(async () => {
try {
if (camera.current == null) throw new Error('Camera ref is null!');
console.log('calling stopRecording()...');
await camera.current.stopRecording();
console.log('called stopRecording()!');
} catch (e) {
console.error('failed to stop recording!', e);
}
}, [camera]);
const startRecording = useCallback(() => {
try {
if (camera.current == null) throw new Error('Camera ref is null!');
console.log('calling startRecording()...');
camera.current.startRecording({
flash: flash,
onRecordingError: (error) => {
console.error('Recording failed!', error);
onStoppedRecording();
},
onRecordingFinished: (video) => {
console.log(`Recording successfully finished! ${video.path}`);
onMediaCaptured(video, 'video');
onStoppedRecording();
},
});
// TODO: wait until startRecording returns to actually find out if the recording has successfully started
console.log('called startRecording()!');
isRecording.current = true;
} catch (e) {
console.error('failed to start recording!', e, 'camera');
}
}, [camera, flash, onMediaCaptured, onStoppedRecording]);
//#endregion
...
I have a Web app built in Vuejs and has SSO authentification using microsoftTeams.authentication.getAuthToken when running in Teams, or microsoftAuthLib when running in the browser.
Inside the company's network or when connected to the VPN everything works absolutely fine.
We recently opened it outside of the VPN and we created a public certificate for it. So when I disconnect the VPN, it works:
In any browser (outside of Teams).
Teams browser version.
Teams on Android/iPhone.
But it doesn't work on Teams Windows Desktop version, it fails with the following error:
Refused to display
'https://login.microsoftonline.com/.../oauth2/authorize?...' in a
frame because it set 'X-Frame-Options' to 'deny'.
Anybody has an idea what could be the issue? And why would it work on the company's VPN but not outside?And only on specific cases? I am lost, any help would be appreciated.
Thank you
*** EDIT / ADDED SSO REDIRECT CODE ***
import * as microsoftTeams from "#microsoft/teams-js";
import * as microsoftAuthLib from "msal";
import settings from './settings.js';
var msalConfig = {
auth: {
clientId: settings.sso.id,
authority: settings.sso.authority
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true
}
};
var requestObj = {
scopes: settings.sso.scopes
};
var myMSALObj = new microsoftAuthLib.UserAgentApplication(msalConfig);
myMSALObj.handleRedirectCallback(authRedirectCallBack);
function authRedirectCallBack(error, response) {
if (error) {
console.log(error);
} else {
console.log("token type is:" + response.tokenType);
}
}
function loginRedirect(requestObj) {
let account = myMSALObj.getAccount();
if (!account) {
myMSALObj.loginRedirect(requestObj);
return false;
} else {
return true;
}
}
function acquireMsalToken() {
return new Promise(function (resolve) {
resolve(myMSALObj.acquireTokenSilent(requestObj).then(token => {
return token.accessToken;
}).catch(error => {
acquireMsalTokenRedirect(error);
}));
})
}
function acquireTeamsToken() {
return new Promise((resolve, reject) => {
microsoftTeams.authentication.getAuthToken({
successCallback: (result) => {
resolve(result);
},
failureCallback: (error) => {
reject(error);
}
});
});
}
function acquireMsalTokenRedirect(error) {
if (error.errorCode === "consent_required" ||
error.errorCode === "interaction_required" ||
error.errorCode === "login_required") {
myMSALObj.acquireTokenRedirect(requestObj);
}
}
var msal = {
autoSignIn: function () {
return loginRedirect(requestObj);
},
acquireToken: async function () {
if (settings.sso.inTeams) {
microsoftTeams.initialize();
microsoftTeams.enterFullscreen();
return acquireTeamsToken();
} else {
let signedIn = msal.autoSignIn();
if (signedIn) {
return acquireMsalToken();
}
}
}
}
export default msal
This error means that you are trying to redirect your tab's iframe to the AAD login flow which in turn is unable to silently generate an auth token for you and is attempting to show an interactive flow (e.g. sign in or consent):
Refused to display
'https://login.microsoftonline.com/.../oauth2/authorize?...' in a
frame because it set 'X-Frame-Options' to 'deny'.
To avoid this issue you need to try and acquire a token silently and if that fails use the microsoftTeams.authentication.authenticate API to open a popup window and conduct the AAD login flow there.
Replacing the acquireTeamsToken() function with the following resolved the issue.
function acquireTeamsToken() {
return new Promise((resolve, reject) => {
microsoftTeams.initialize(() => {
microsoftTeams.authentication.authenticate({
url: window.location.origin + "/ms-teams/auth-start",
width: 600,
height: 535,
successCallback: (result) => {
resolve(result);
},
failureCallback: (error) => {
reject(error);
}
});
});
});
}
I found this documentation very helpful on how to create the Authentication pop up and how to create a Callback window with the Token in it.
You might also want to cache the token and only create a popup when it expires.
This might be because you're using the auth popup option instead of the redirect option in whichever auth library you're using (hopefully MSAL 2.0). Teams is a little different because it's actually launching a popup for you when necessary, so although it sounds a bit strange, you actually want to use the redirect option, inside the popup that is launched. What might help is to look at the new SSO Sample app in the Teams PnP samples.
Go to: %APPDATA%\Microsoft\Teams
Open the file hooks.json (if it's not there, create it)
Add the following to it: {"enableSso": false, "enableSsoMac": false}
That's it, now Teams desktop has the same authentication workflow as the browser version. Have a nice day.
I would like to know how I can do to detect if during any moment of the execution of an Ionic 4 app (not only at the beginning of the app), the user manually turns off or on the GPS.
What Ionic 4 event can I hear from the GPS, to be able to alert at any time of the execution of the app if the user turned off or on the GPS?
Thank you very much and sorry for my bad English
My code on app.component.ts:
initializeApp() {
this.platform.ready().then(() => {
this.screenOrientation.lock(this.screenOrientation.ORIENTATIONS.PORTRAIT_PRIMARY);
this.platform.backButton.subscribeWithPriority(9999, () => {
document.addEventListener('backbutton', function (event) {
event.preventDefault();
event.stopPropagation();
}, false);
this.presentAlertConfirm();
});
this.geolocation.getCurrentPosition().then((resp) => {
this.global.origin = { lat: resp.coords.latitude, lng: resp.coords.longitude };
this.global.latitude = resp.coords.latitude;
this.global.longitude = resp.coords.longitude;
}).catch((error) => {
console.log('Error getting location', error);
});
let watch = this.geolocation.watchPosition();
watch.subscribe((data) => {
this.global.origin = { lat: data.coords.latitude, lng: data.coords.longitude };
this.global.latitude = data.coords.latitude;
this.global.longitude = data.coords.longitude;
}, error => {
console.log('Error getting location in WATCH', error); //error handling //
})
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
You have to watch for some GPS change. As proposed in the Ionic 4 documentation and as you have done correctly:
this.watch = this.geolocation.watchPosition();
this.watch.subscribe((data) => {
// usable data
}, (error) => {
// some error
}, { timeout: 30000 });
timeout: The maximum length of time (milliseconds) that is allowed to pass without receiving a set of coordinates.
And remeber to unsubscribe on destroy:
public ngOnDestroy(): void {
this.watch.unsubscribe();
}
I'm using cypress to test my VueJS application. The one thing I'm having trouble with is mocking an image to be displayed on the page. For my use case, I'm simply loading a user profile with the following code:
describe('Test Login', () => {
it('Can Login', () => {
cy.server();
cy.route({
method: 'GET',
url: '/api/account/',
response: 'fx:profile.json',
});
cy.route('**/media/demo1.png', 'fx:demo1.png');
});
});
fixtures/profile.json
{
"avatar": "http://localhost:8080/media/demo1.png",
"username": "cypress",
"email": "email#cypress.io",
"pk": 1,
"is_staff": true,
"is_superuser": true,
"is_active": true
}
The profile fixture data is loading correctly in the test. In my fixtures folder, I also have a demo1.png file. I am expecting this image to be loaded and displayed on the page during my test, but it is being displayed as a broken image.
In the network tab, it shows demo1.png as a broken image with a 200 response code and type of text/html.
The cypress documentation mostly discusses images in the context of uploading images, but I haven't been able to find an example of how I can mock an image that is loaded through a <img> tag. Is there an easier way of doing this?
I am not sure if this answer can help you. But at least it is a workaround for this problem ;-)
Say we have a HTML like this:
<html>
<body>
<button id="button">load</button>
<div id="profile">
</div>
<script>
function httpGetAsync(theUrl, callback)
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
callback(JSON.parse(xmlHttp.responseText));
}
xmlHttp.open("GET", theUrl, true); // true for asynchronous
xmlHttp.send(null);
}
document.getElementById("button").addEventListener("click", () => {
httpGetAsync("/api/account/", (result) => {
var div = document.querySelector("#profile");
var img = document.createElement("img");
img.src = result.avatar;
div.appendChild(img)
})
})
</script>
</body>
</html>
source: HTTP GET request in JavaScript?
And you want to load the profile after the click was done. Then you can use MutationObserver to replace the img.src.
First, write the MutationObserver:
var observeDOM = (function(){
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
return function( obj, callback ){
if( !obj || !obj.nodeType === 1 ) return; // validation
if( MutationObserver ){
// define a new observer
var obs = new MutationObserver(function(mutations, observer){
callback(mutations);
})
// have the observer observe foo for changes in children
obs.observe( obj, { childList:true, subtree:true });
}
else if( window.addEventListener ){
obj.addEventListener('DOMNodeInserted', callback, false);
obj.addEventListener('DOMNodeRemoved', callback, false);
}
}
})();
(heavily copy & pasted from Detect changes in the DOM)
Now you are able to do this:
describe('Test Login', () => {
it('Can Login', () => {
var win = null;
cy.server();
cy.route({
method: 'GET',
url: '/api/account/',
response: 'fx:profile.json'
});
cy.visit("index.html").then(w => {
cy.get("#profile").then(pro => {
var e = pro[0];
observeDOM(e, (m) => {
// add a red dot image
m[0].addedNodes[0].src = "data:image/png;base64,"+
"iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGP"+
"C/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IA"+
"AAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1J"+
"REFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jq"+
"ch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0"+
"vr4MkhoXe0rZigAAAABJRU5ErkJggg=="
})
})
cy.get("button").click()
})
});
});
(yeah at least some lines of code are written on my own ;-P)
You can read the image from the img.src attribute from the fixtures folder. For the sake of simplicity I have used a static base64 string here.
And the result:
We are not using this kind of stuff in our aurelia app but I tried similar things in a private project some time ago.
I'm building a live chat app, but I found that listenforwhisper function is not working, but .whisper() function works fine, pusher also received client typing event.
Here is my code:
For listen whisper:
Echo.private(`messages.${this.user.id}`)
.listen("NewMessage", (e) => {
this.handleIncoming(e.message);
})
.listenForWhisper("typing", (e) => {
if(e.name !='') {
this.typeStatus = 'typing .........'
}
else {
this.typeStatus = ''
}
console.log(this.typeStatus);
});
For whisper:
watch: {
message() {
Echo.private(`messages.${this.user.id}`)
.whisper("typing", {
name: this.message
});
}
}
For channel:
Broadcast::channel('messages.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
Theoretically, my console will return the typeStatus, but I got nothing in my console.
Whisper works like broadcastToOthers. You're now trying to listen for the current users whispers. You should have a room where the whisper goes to and there should be multiple clients there to recieve. Now your channel is tied to the user and no-one else can see the messages that go through that channel.
Ok, I step in same issue. I got 2 channels and 2 users. I set a interval with wisper
setInterval(() => {
channel.whisper('typing', {
message: 'hola!'
});
}, 3000);
channel.listenForWhisper('typing', (e) => {
console.log('Typing');
console.log(e);
})
The thing was that I was receving events but won't be able to see the output from listenForWhisper until I connect the second user to the channel.
Once the second user is connected, it's works just fine. So I leaved her if you got same issue.