Detect a bad connection in hls.js - javascript

I want to display a warning message to the user when the user’s connection is not optimal to process the current flow. But I can’t find a way to detect that information properly.
The solution I found is to calculate the loading time of each fragment to trigger or not the warning but this option impacts the performance of the application.
let localLowConnection = false;
localHlsInstance.on(Hls.Events.FRAG_LOADING, (event: any, data: any) => {
const id = setTimeout(() => {
if (!localLowConnection) {
isLowConnection(true);
localLowConnection = true;
}
}, 1000);
ids.push({ timerId: id, eventId: data.frag.sn });
});
localHlsInstance.on(Hls.Events.FRAG_LOADED, (event: any, data: any) => {
each(ids, (item, index) => {
if (item.eventId === data.frag.sn) {
clearTimeout(item.timerId);
}
});
if (localLowConnection) {
isLowConnection(false);
localLowConnection = false;
}
})
This code seems to work but it displays and removes the overlay almost instantly.
I find no post on this topic and nothing explicit in the hls.js documentation for this case. I also specify that the adapdative bitrate is not activated and I therefore have only one quality level.
Thank you for your help :)

Related

What does this getFirebaseRoot error occur on InterstitialAd?

Creating a react-native app and trying to ad ads through admob and firebase, but getting an error I couldn't find much on.
Relevant parts of my App.js:
...
import {
InterstitialAd,
TestIds,
AdEventType,
} from '#react-native-firebase/admob';
...
showAds = () => {
let interstitial = InterstitialAd.createForAdRequest(TestIds.INTERSTITIAL);
let interstitialListener = interstitial.onAdEvent(type => {
if (type === AdEventType.LOADED) {
interstitial.show();
}
});
interstitial.load();
return () => {
interstitialListener = null;
};
};
onEvent = e => {
if (e.type === 'game-over') {
this.setState({
running: false,
});
this.showAds();
};
UPDATE:
Following this guide instead but getting another error.
Yeah sorry to tell you but #react-native-firebase/admob is now deprecated The last supported version was 11.5.0. I wasted time with this too because this old website (https://rnfb-docs.netlify.app) says it exist. When really you should use this one (https://rnfirebase.io). What I did was used (https://www.applovin.com/) for ads it was really easy to setup.

webshare API multiple instances on same page

Hopefuly someone can assist/direct me here.
I'm making use of the webshare API on my site. The site contains an array of posts that will have a share link. This is built using a foreach and all have unique urls to use. I want to add a share button to each of those images. I currently have it working on a singular instance but unable to get it to loop through all the share buttons.
Here is the current script:
const shareButton = document.querySelector('.share-button');
const url = document.querySelector('.post-link a').href;
shareButton.addEventListener('click', event => {
if (navigator.share) {
navigator.share({
title: 'Check out this ad I saw on ...',
url
}).then(() => {
console.log('Shared');
})
.catch(console.error);
}
});
I'm really struggling with how to get it to loop through all share buttons and not just be usable on the first instance.
Apologeis if this is simple.
For a start, you need to add a click listener to all buttons, not just the first. You can do this exclusively when the API is supported, else, you may want to hide the buttons. Here's the modified script (note that you need to get the URL of each post individually, see the comment):
const shareButtons = document.querySelectorAll('.share-button');
if ('share' in navigator) {
shareButtons.forEach((shareButton) => {
shareButton.addEventListener('click', () => {
// Get the URL from the dataset or query the DOM.
const url = shareButton.dataset(url);
navigator.share({
title: 'Check out this ad I saw on ...',
url
}).then(() => {
console.log('Shared');
}).catch(console.error);
});
});
} else {
shareButtons.forEach((shareButton) => {
shareButton.style.display = 'none';
});
}

Stubbing of "watchPosition" in cypress

I try to inject position changes to an JS/REACT-Application. The Application registering at window.navigator.geolocation.watchPosition. My idea is to stub the "watchPosition" method to get a handle on the callback function. Then calling the callback function from the application directly.
Like:
const watchPositionFake = (successCallback, errorCallback, options) => {
console.debug("PROXY set callback watchPosition");
originalWatchPositionSuccessCallback = successCallback;
};
cy.visit("/", {
onBeforeLoad(win) {
cy.stub(win.navigator.geolocation, "watchPosition").callsFake(watchPositionFake);
}
});
This doesn't work with function registering in the Application on the watchPosition. But this does work with function in the cypress-step file. (Working as in in the console.log I see changes in position according to the values I send in via originalWatchPositionSuccessCallback ).
Any idea who to fake a position change?
There is a different way to solve the issue of getting the callbacks of the registered function to navigator.geolocation.watchPosition triggered. The code in the question tried to solve this by cy.stub(win.navigator.geolocation, "watchPosition"), but this turned to be not working reliably (too soon, too late, different browser/window context, another iframe, ...), the precise reason varied.
An alternative solution to trigger the registered watchPosition callbacks without modifying the production code is the undocumented cypress (v6.2) automation interface in cypress to CDP.
export const setFakePosition = position => {
// https://chromedevtools.github.io/devtools-protocol/tot/Emulation/#method-setGeolocationOverride
console.debug(`cypress::setGeolocationOverride with position ${JSON.stringify(position)}`);
cy.log("**setGeolocationOverride**").then(() =>
Cypress.automation("remote:debugger:protocol", {
command: "Emulation.setGeolocationOverride",
params: {
latitude: position.latitude,
longitude: position.longitude,
accuracy: 50
}
})
);
};
And verifying with:
let positionLogSpy;
When("vehicle is located in {string}", city => {
const position = cityLocationMap[city];
cy.window()
.then(win => {
const expectedLogMessage = `new position lat: ${position.latitude}, lng: ${position.longitude}`;
positionLogSpy = cy.spy(win.console, "log").withArgs(expectedLogMessage);
})
.then(() => {
setFakePosition(position);
});
});
Then("vehicle has moved to {string}", () => {
expect(positionLogSpy).to.be.called;
});

How to log in and log out user, before running tests

In Cypress I'm trying to test something in a backend. I'm really struggling to control if the user is logged in or not.
I'm trying to automate all testing that i do, when developing features. I spend so much time and effort to control if the user is logged in or not.
I'm looking for a command that does this:
Logout any user (if one is logged in), when starting any test.
A fast way to do something like: cy.loginUser( 'foo#example.org', 'password' )?
Since this will have to run before many of the tests, if would be nice to streamline it.
It's being used on a Laravel / Vue application (hence the CSRF-token).
My current attempt:
Cypress.Commands.add( "loginUser", ( email, password ) => {
cy.server();
// Source: https://github.com/cypress-io/cypress/issues/413
sessionStorage.clear();
cy.clearCookies();
cy.clearLocalStorage();
cy.window().then((win) => {
win.sessionStorage.clear()
});
cy.visit( Cypress.env( 'baseUrl' ) + "/login");
cy.location().should((loc) => {
expect(loc.pathname).to.eq('/login')
});
cy.get("head meta[name=csrf-token]")
.then((meta) => {
const csrf = meta[0].content;
cy.request({
method: 'POST',
url: '/login',
body: {
_token: csrf,
email: email,
password: password
}
});
});
cy.visit( Cypress.env( 'baseUrl' ) + "/login");
});
The problems with this:
For some wierd reason... Every second time, the user remains logged in from the previous session. But if that happens, then I simply have to run it again, - and then the user is logged out. It's driving me bananas.
It's not slow, - but it's not fast either (considering that I do it a bazillion times). So if it could be done faster (with less page loads), then it would be smashing.
Try to use another way to clear localStorage. For example, I'm using these commands to save, restore and clear storage and is working perfect. I'm using these for log in/log out things.
let LOCAL_STORAGE_MEMORY = {};
Cypress.Commands.add("saveLocalStorage", () => {
Object.keys(localStorage).forEach(key => {
LOCAL_STORAGE_MEMORY[key] = localStorage[key];
});
});
Cypress.Commands.add("restoreLocalStorage", () => {
Object.keys(LOCAL_STORAGE_MEMORY).forEach(key => {
localStorage.setItem(key, LOCAL_STORAGE_MEMORY[key]);
});
});
Cypress.Commands.add("clearLocalStorageCache", () => {
localStorage.clear();
LOCAL_STORAGE_MEMORY = {};
});

Re-subscribing in Meteor reloads all items

I have this code:
Template.messageList.onCreated(function onCreated() {
this.state = new ReactiveDict();
this.state.setDefault({
limit: 5
});
this.autorun(() => {
this.subscribe('messages', {limit: this.state.get('limit')});
});
});
Template.messageList.helpers({
messages () {
const instance = Template.instance();
return Messages.find({}, MessagesFilter.common({limit: instance.state.get('limit')}));
}
});
Template.messageList.events({
'click .ui.button.more' (event, instance) {
const limit = instance.state.get('limit');
instance.state.set('limit', limit + 5);
}
});
It's intended to be a infinite scroll, but it presents weird events. Right now, the elements on page are reloaded when the limit changes.
Looks like meteor is re-subscribing (which is expected by the documentation) but this is reloading all the documents, it deletes the messages and then reload the with the new limit value.
How can I prevent it? I want a infinite scroll, but the way it behaves right now looks impossible.
Here's a video of what's happening.
http://recordit.co/mlsGThOdHp
Here's the repository:
https://github.com/Sornii/sayito/tree/infinite-scroll
I changed
this.autorun(() => {
this.subscribe('messages', {limit: this.state.get('limit')});
});
To
Tracker.autorun(() => {
this.subscribe('messages', {limit: this.state.get('limit')});
});
And now it works the way I want to.

Categories

Resources