Audio Tracks are not playing when phone is on vibrate/silent - angularjs

I'm using ngAudio to control audio tracks (spotify 30 seconds previews) on an ionic app. It all works swell in the browser. However, in both ionic view and the actual demo app, the tracks will only stream when I have the phone vibrate toggle turned to not silent/ring mode. If it's in vibrate mode, the user hears nothing. I've dug all over and can't seem to solve this riddle.
Here's my service:
.factory('PlayerService', function(ngAudio) {
var _play = function(show) {
if (typeof audioObject === "undefined") {
audioObject = ngAudio.load(show.track1_preview);
console.log(audioObject);
audioObject.play();
audioObject.playing = show.id;
return audioObject;
} else if (audioObject.paused) {
audioObject = ngAudio.load(show.track1_preview);
audioObject.play();
audioObject.playing = show.id;
return audioObject;
} else {
audioObject.stop();
audioObject = ngAudio.load(show.track1_preview);
audioObject.play();
audioObject.playing = show.id;
return audioObject;
}
}
var _pause = function(show) {
audioObject.stop();
audioObject.playing = '';
}
return {
play: _play,
pause: _pause
};
Here's the controller:
$scope.playStream = function(show) {
PlayerService.play(show);
$scope.audioObject = audioObject; // this allow for styling the play/pause icons
}
$scope.pauseStream = function(show) {
PlayerService.pause(show);
$scope.audioObject = audioObject; // this allow for styling the play/pause icons
//console.log($scope.audioObject);
}
$scope.togglePlayPause = function(show) {
if (!$scope.audioObject || $scope.audioObject.paused) {
$scope.playStream(show);
} else if (show.track1_preview !== $scope.audioObject.id) {
$scope.playStream(show);
} else {
$scope.pauseStream(show);
}
}
Obviously, it's a bit of a crap user experience if someone has to put the phone off vibrate to hear the tracks.
I'm wondering if this is related to asyncronous stuff and mobile. I just don't know. Giving up after 4 hours of messing with it.

Related

How do a add prefers-color-scheme media query

Hello I have this code:
<script>
function storageAvailable(type) {
try {
var storage = window[type],
x = '__storage_test__';
storage.setItem(x, x);
storage.removeItem(x);
return true;
}
catch(e) {
return e instanceof DOMException && (
// everything except Firefox
e.code === 22 ||
// Firefox
e.code === 1014 ||
// test name field too, because code might not be present
// everything except Firefox
e.name === 'QuotaExceededError' ||
// Firefox
e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
// acknowledge QuotaExceededError only if there's something already stored
storage.length !== 0;
}
}
jQuery(document).ready(function($) {
var storageAvailable = window.storageAvailable('sessionStorage');
$(".et-dark-toggle").click(function() {
$(".et-dark-mode-capable,body").toggleClass("et-dark-mode");
if ( storageAvailable ) {
$("body").hasClass("et-dark-mode") ?
sessionStorage.setItem('etDarkModeEnabled','1'):
sessionStorage.removeItem('etDarkModeEnabled');
}
});
if (storageAvailable) {
'1' == sessionStorage.getItem('etDarkModeEnabled') ?
$(".et-dark-mode-capable,body").addClass("et-dark-mode"):
$(".et-dark-mode-capable,body").removeClass("et-dark-mode");
}
});
</script>
How can i add prefers-color-scheme media query to autoenable the created dark mode when user has dark mode enabled in browser ?
Can you please help me
Sorry for the late response. A quick code to integrate (p.s. not tested):
jQuery(document).ready(function($) {
var storageAvailable = window.storageAvailable('sessionStorage');
if(window.matchMedia)
{
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event =>
{
if (event.matches && !$("body").hasClass("et-dark-mode"))
{
$(".et-dark-mode-capable,body").addClass("et-dark-mode");
if ( storageAvailable )
{
sessionStorage.setItem('etDarkModeEnabled','1'):
}
}
else
{
$(".et-dark-mode-capable,body").removeClass("et-dark-mode");
if ( storageAvailable )
{
sessionStorage.removeItem('etDarkModeEnabled');
}
}
}
);
}
$(".et-dark-toggle").click(function() {
$(".et-dark-mode-capable,body").toggleClass("et-dark-mode");
if ( storageAvailable ) {
$("body").hasClass("et-dark-mode") ?
sessionStorage.setItem('etDarkModeEnabled','1'):
sessionStorage.removeItem('etDarkModeEnabled');
}
});
if (storageAvailable) {
'1' == sessionStorage.getItem('etDarkModeEnabled') ?
$(".et-dark-mode-capable,body").addClass("et-dark-mode"):
$(".et-dark-mode-capable,body").removeClass("et-dark-mode");
}
});
In short it checks if the browser supports window.matchMedia and then it reads it and sets the theme based on that preference. In the end it is the same as your code to allow the user to toggle the dark and light mode (maybe a button, or a checkbox).
For more info you can search some dev blogs on the subject and after a quick search I would say that this one might closely match your needs (p.s. not my blog :) )

Intermittent "element is not found" in protractor

In Protractor, I am trying to write a function to simulate clicking a responsive navigation menu item (i.e. menu is either a bar of dropdowns across the top or a hamburger link if mobile). The structure of the bar is defined by MEANJS with a few id="" attributes mixed in.
It seems to work exactly as I want when I run it one spec at a time, like so:
protractor app/tests/e2e/conf.js --suite mySuite
but when I run with the full test (that only has 4 tests in it), like so:
protractor app/tests/e2e/conf.js
I start to get this error intermittently (source of error is in 2 places below):
Failed: element not visible
Here's my function
commonPOs.clickNavBar = function(mainTab, linkUrl) {
var deferred = protractor.promise.defer();
var hamburger = element(by.id('nav-hamburger'));
var linkCssExpression = 'a[href*="' + linkUrl + '"]';
hamburger.isDisplayed().then(function(result) {
if ( result ) {
hamburger.click().then(function() {
var navBar = hamburger
.element(by.xpath('../..'))
.element(by.id('myapp-navbar'));
return clickItNow(mainTab, linkUrl, navBar);
});
} else {
return clickItNow(mainTab, linkUrl, element(by.id('myapp-navbar')));
}
});
return deferred.promise;
function clickItNow(mainTab, linkUrl, navBar) {
var link;
if(mainTab) {
// if mainTab was passed, need to
// click the parent first to expose the link
var parentLink;
if (mainTab == 'ACCTADMIN') {
parentLink = navBar.element(by.id('account-admin-menu'));
}
else {
parentLink = navBar.element(by.linkText(mainTab));
}
expect(parentLink.isPresent()).toBeTruthy();
parentLink.click(); // FIRST PLACE ERROR HAPPENS
link = parentLink.element(by.xpath('..')).element(by.css(linkCssExpression));
}
else {
link = navBar.element(by.css(linkCssExpression));
}
expect(link.isPresent()).toBeTruthy();
link.click(); // SECOND PLACE ERROR HAPPENS
return deferred.fulfill();
}
};
I have tried to use both of these but neither work:
browser.sleep(500);
browser.driver.wait(protractor.until.elementIsVisible(parentLink));
What NOOB async error am I making?
Self answer... but any better answer will win the green check mark!!!
EDITED - After more problems, found a nice 'waitReady()' contribution from elgalu.
There were a few obvious problems with my original code, but fixing them did not solve the problem. After working through what I could, the solution seemed to be the expect(navBar.waitReady()).toBeTruthy(); lines I added. I also had to split the nested function out. Anyway, here is the new code that seems to be working now. A better (comprehensive) answer will get the green checkmark! I'm pretty sure there's a flaw or 2 here.
commonPOs.clickNavBar = function(mainTab, linkUrl) {
var deferred = protractor.promise.defer();
var hamburger = element(by.id('nav-hamburger'));
hamburger.isDisplayed().then(function(result) {
if ( result ) {
hamburger.click().then(function() {
var navBar = hamburger
.element(by.xpath('../..'))
.element(by.id('myapp-navbar'));
return clickItNow(mainTab, linkUrl, navBar, deferred);
});
} else {
return clickItNow(mainTab, linkUrl, element(by.id('myapp-navbar')), deferred);
}
});
return deferred.promise;
};
function clickItNow(mainTab, linkUrl, navBar, deferred) {
var targetLink;
var linkCssExpression = 'a[href*="' + linkUrl + '"]';
expect(navBar.waitReady()).toBeTruthy();
if(mainTab) {
// if mainTab was passed, neet to
// click the parent first to expose the link
var parentTabLink;
if (mainTab == 'ACCTADMIN') {
parentTabLink = navBar.element(by.id('account-admin-menu'));
}
else {
parentTabLink = navBar.element(by.id('main-menu-' + mainTab));
}
// expect(parentTabLink.isDisplayed()).toBeTruthy();
expect(parentTabLink.waitReady()).toBeTruthy();
parentTabLink.click();
targetLink = parentTabLink.element(by.xpath('..')).element(by.css(linkCssExpression));
}
else {
targetLink = navBar.element(by.css(linkCssExpression));
}
expect(targetLink.isDisplayed()).toBeTruthy();
targetLink.click().then(function() {
return deferred.fulfill();
});
}

Cordova backbutton preventDefault is not working

I have application which is done using ionicframework and cordova. In my app i have requirement that if user pressed back button then i need to ignore it. But only after user pressed it third time it should close app.
Previously project was done using phonegap and jquery and same code works. I did small workaround when i am throwing an exception then it app was not closed when it should not.
document.addEventListener("backbutton", function (e) {
if (new Date() - firstDateClick > 1000) {
firstDateClick = new Date();
totalClicks = 1;
} else {
totalClicks++;
if (totalClicks >= 3) {
var answer = confirm('Are You Sure You Want Exit');
if (answer) {
var service = angular.injector(['ng', 'starter.services']).get('DanceService');
service.logEvent("exit")
.then(function () {
alert('exit1')
if (navigator.app) {
navigator.app.exitApp();
}
else if (navigator.device) {
navigator.device.exitApp();
}
})
} else {
totalClicks = 1;
}
}
}
throw "ignore"
});
But i dont like idea to throw exception.
i made two times control before log out from the app. So the user can press one time and a toast will appear with the text "press again to exit" and the second press -> log out.
This is my service:
var deregisterFunction = null;
return {
disableBack: disableBack,
registerAction: registerAction,
goHome: goHome,
goBack: goBack,
deregisterAction: deregisterAction,
closeApp: closeApp
};
function disableBack() {
deregisterFunction = angular.copy($ionicPlatform.registerBackButtonAction(null, 101));
}
function registerAction(cb, priority) {
deregisterFunction = angular.copy($ionicPlatform.registerBackButtonAction(cb, priority));
}
function deregisterAction() {
if (deregisterFunction) {
deregisterFunction();
}
goBack();//default behaviour
}
function goHome() {
deregisterFunction = angular.copy($ionicPlatform.registerBackButtonAction(function() {
$state.go('app.home');
}, 101));
}
function goBack() {
deregisterFunction = angular.copy($ionicPlatform.registerBackButtonAction(function() {
$ionicHistory.goBack();
}, 101));
}
function closeApp() {
deregisterFunction = angular.copy($ionicPlatform.registerBackButtonAction(function() {
ionic.Platform.exitApp();
}, 101));
}
And this my utils service:
var service = {
logoutToast: logoutToast,
resetToastCount: resetToastCount
};
var toastCount = 0;
return service;
function resetToastCount() {
toastCount = 0;
}
function logoutToast() {
switch (toastCount) {
case 0:
$cordovaToast.show('Press again to log out', 'short', 'bottom');
toastCount++;
break;
case 1:
toastCount = 0;
//logout
break;
default:
$cordovaToast.show('Error', 'short', 'bottom');
}
}
}
}());
So in my controller i have this for register the action of my service:
$scope.$on('$ionicView.afterEnter', backButtonService.registerAction(utils.logoutToast, 101));
This for reset the count where i want:
$scope.$on('$ionicView.afterEnter', utils.resetToastCount());
And this for deregister my action when i navigate:
$scope.$on('$stateChangeStart', backButtonService.deregisterAction);
Hope this will helps you :)
Disable back button on Ionic/Cordova
$ionicPlatform.registerBackButtonAction(null, 101);

ad timer focus required

hi i want to show a timer that will stop if the window/tab is not in focus and when the user will back to the window/tab it will again start to countdown. i have following code and i tried some methods but not getting the desired result!hope one of you will able to solve my problem
function adTimer() {
timer++;
if(timer == fulltimer) {
var show="Click <img src=\"clickimages/"+key+".png\">";
$("#buttons").fadeIn();
$("#timer").html(show);
}
else {
setTimeout(adTimer, 1000);
}
$("#bar").width((timer/fulltimer)*200);
}
$(document).ready(function() {
if(id != -1) adTimer();
else $("#timer").html("Cheat Check");
});
Check for focus with a timer:
var focus;
function mytimer() {
if (focus) {
// Do stuff.
alert("test");
}
}
$(window).blur(function () {
focus = false;
});
$(window).focus(function () {
focus = true;
});
setInterval(mytimer, 1000);
Fiddle

in sencha touch in navigation view after back button shows an old value

I am creating an application in sencha touch 2.0
i m using navigation view
i m creating an arrangement of numbers in ascending order math quiz
my problem is when i run the application it works fine for first time but when i click on back button and aging enters on the same view its shows me the old number
strenge thing is that on the button text new numbers appears but when i click on the button and get the text it shows me the old number
my code
sequence_user_answer="";
sequence_answer="";
sequence_number1=this.getRandomNumber(99,10);
sequence_number2=this.getRandomNumber(99,10);
sequence_number3=this.getRandomNumber(99,10);
if(sequence_number1==sequence_number2)
{
while(sequence_number1==sequence_number2)
{
sequence_number2=this.getRandomNumber(99,10);
}
}
else if(sequence_number3==sequence_number1 || sequence_number3==sequence_number1)
{
while(sequence_number3==sequence_number2 || sequence_number3==sequence_number1)
{
sequence_number3= this.getRandomNumber(99,10);
}
}
var sequencenumber1=Ext.getCmp('NumberSequence1');
sequencenumber1.setHtml(sequence_number1);
var sequencenumber2=Ext.getCmp('NumberSequence2');
sequencenumber2.setHtml(sequence_number2);
// alert("two");
var sequencenumber3=Ext.getCmp('NumberSequence3');
sequencenumber3.setHtml(sequence_number3);
var label1=Ext.getCmp('lblsequencenumber1');
label1.setHtml("");
var label2=Ext.getCmp('lblsequencenumber2');
label2.setHtml("");
var label3=Ext.getCmp('lblsequencenumber3');
label3.setHtml("");
if(sequence_number1>sequence_number2)
{
if(sequence_number1>sequence_number3)
{
if(sequence_number2>sequence_number3)
{
sequence_answer=sequence_answer+sequence_number3;
sequence_answer=sequence_answer+sequence_number2;
}
else
{
sequence_answer=sequence_answer+sequence_number2;
sequence_answer=sequence_answer+sequence_number3;
}
sequence_answer=sequence_answer+sequence_number1;
}
else
{
sequence_answer=sequence_answer+sequence_number2;
sequence_answer=sequence_answer+sequence_number1;
sequence_answer=sequence_answer+sequence_number3;
}
}
else
{
if(sequence_number2>sequence_number3)
{
if(sequence_number1>sequence_number3)
{
sequence_answer=sequence_answer+sequence_number3;
sequence_answer=sequence_answer+sequence_number1;
}
else
{
sequence_answer=sequence_answer+sequence_number1;
sequence_answer=sequence_answer+sequence_number3;
}
sequence_answer=sequence_answer+sequence_number2;
}
else
{
sequence_answer=sequence_answer+sequence_number2;
sequence_answer=sequence_answer+sequence_number1;
sequence_answer=sequence_answer+sequence_number3;
}
}
on button tap
getSequenceAnswer:function(selected_button_id)
{
//alert(selected_button_id);
alert(selected_button_id.getHtml()); // here it shows me an old value when i go back and enter again to this view
var ans_audio=Ext.getCmp('answeraudio');
var que_audio=Ext.getCmp('questionaudio');
var result=Ext.getCmp('statuslbl');
if(sequence_count==0)
{
var sequence_label1=Ext.getCmp('lblsequencenumber1');
sequence_label1.setHtml(selected_button_id.getHtml());
sequence_count++;
sequence_user_answer=sequence_user_answer+selected_button_id.getHtml();
}
else if(sequence_count==1)
{
var sequence_label2=Ext.getCmp('lblsequencenumber2');
sequence_label2.setHtml(selected_button_id.getHtml());
sequence_count++;
sequence_user_answer=sequence_user_answer+selected_button_id.getHtml();
}
else if(sequence_count==2)
{
var sequence_label3=Ext.getCmp('lblsequencenumber3');
sequence_label3.setHtml(selected_button_id.getHtml());
sequence_count++;
sequence_user_answer=sequence_user_answer+selected_button_id.getHtml();
if(sequence_answer==sequence_user_answer)
{
que_audio.setUrl("");
ans_audio.setUrl('audio/true.mp3');
ans_audio.play();
this.getTrue(result);
var marks=Ext.getCmp('lblMarks');
sequence_marks = sequence_marks+2;
marks.setHtml(sequence_marks);
var total=Ext.getCmp('lbltotal');
sequence_total_marks= sequence_total_marks+2;
total.setHtml(sequence_total_marks);
}
else
{
que_audio.setUrl("");
ans_audio.setUrl('audio/false.mp3');
ans_audio.play();
this.getFalse(result);
var total=Ext.getCmp('lbltotal');
sequence_total_marks= sequence_total_marks+2;
total.setHtml(sequence_total_marks);
}
}
}
Most likely you can use show listener, which invokes while a container displays. Write your logic to create components dynamically here. Or, as another alternative you can reset your label or other component data inside it.
listeners: {
show: function(list, opts){
// code to reset your comp
}
}

Resources