I got a desktop notification using HTML5 up and running. However, the look and feel of the Desktop Notification seems too simple for my requirement.
Basically, the Desktop notification, as of now is just a simple Text message with a white background on a rectangle.
Below is the code i have used for displaying the Desktop notification:
<html>
<head>
<title>Notification HTML5</title>
<script>
function notifyMe() {
// Let's check if the browser supports notifications
if (!("Notification" in window)) {
alert("This browser does not support desktop notification");
}
// Let's check if the user is okay to get some notification
else if (Notification.permission === "granted") {
// If it's okay let's create a notification
var options = {
body: "This is the body of the notification",
//icon: "icon.jpg",
dir : "ltr"
};
var notification = new Notification("Hi there",options);
notification.onclick = function () {
//console.log("this:"+this);
//window.open("https://stackoverflow.com/");
Maximize();
};
}
// Otherwise, we need to ask the user for permission
// Note, Chrome does not implement the permission static property
// So we have to check for NOT 'denied' instead of 'default'
else if (Notification.permission !== 'denied') {
Notification.requestPermission(function (permission) {
// Whatever the user answers, we make sure we store the information
if (!('permission' in Notification)) {
Notification.permission = permission;
}
// If the user is okay, let's create a notification
if (permission === "granted") {
var options = {
body: "This is the body of the notification",
//icon: "icon.jpg",
dir : "ltr"
};
var notification = new Notification("Hi there",options);
}
});
}
// At last, if the user already denied any notification, and you
// want to be respectful there is no need to bother them any more.
}
function Maximize()
{
window.innerWidth = screen.width;
window.innerHeight = screen.height;
window.screenX = 0;
window.screenY = 0;
alwaysLowered = false;
}
</script>
</head>
<body>
<button onclick="notifyMe()" style="height: 80px;width: 311px;color:white;font-size: 24px;background: cadetblue;border: none;cursor: pointer;">Show me notification</button><br><br>
</body>
</html>
Below is the image illustrating the way in which the Desktop notification is rendered:
So my query is:
Is it possible to apply some styling to the appearance of the Desktop notification? Like displaying the font in Bold and italics and in a different colour and changing the background color of the Notification and may be rounding the corners of the rectangular Notification pop-up?
What i tried:
I learnt that previously we did have a way of doing this. That is by using the API createHTMLNotification(), but now the same has been deprecated. Also, i tried finding alternatives for the same Replacement for createHTMLNotification, but it lack's clarity.
Related
How can I disable the display setting changes in the device settings?
I solved the font side of the same problem with the following code:
if (Text.defaultProps) {
Text.defaultProps.allowFontScaling = false
} else {
Text.defaultProps = {}
Text.defaultProps.allowFontScaling = false
View.defaultProps = {}
}
but I can't do the same for 'Display Settings'.
here is my ask screen on phone settings:
I hope that has been revealing
Xcode 12.3 iOS 12.4+ iPhone Application
I have a view controller which contains wkwebview which gets initialized on startup. This is on the framework side. An enclosing app adds this view onto their view controller as a subview. The app is purely HTML and javascript-based app. We render HTML pages based on user interaction. Everything works fine except for an issue with the Lock Screen
On a particular screen, there is some animation running while updating some values on the screen as well. When the app is moved to the background, the app runs fine but when I Lock the Screen and come back to the app, the animation and all processing on the screen are frozen. I would have to start the process back from the home screen.
I noticed that both moving to background and lock screen have the same state changes such as did enter the background and will enter foreground but in one case, everything is frozen. Could someone please let me know what might be the problem and what would be a solution in this scenario?
Thank you.
Edit
This is the animation called on the html page...the screen is expecting some values which is sent from framework once done processing
let showNextItemJS = """
function startNextAnimation() {
var box = document.querySelector('\(boxElement)');
if(box) {
var thisItem = box.querySelector('\(diagnosticItem)');
var statusStr = '\(statusStr)'
if (thisItem) {
thisItem.classList.add('start');
if (statusStr != 'none') {
thisItem.classList.add(statusStr);
}
}
} else {
var thisItem = document.querySelector('\(diagnosticItem)');
var statusStr = '\(statusStr)'
if (thisItem) {
thisItem.classList.add('start');
if (statusStr != 'none') {
thisItem.classList.add(statusStr);
}
}
}
};
function stopLastAnimaation() {
var box = document.querySelector('\(boxElement)');
if(box) {
var lastItem = box.querySelector('\(lastDiagnosticItem)');
if (lastItem) {
lastItem.classList.add('finish');
}
} else {
var lastItem = document.querySelector('\(lastDiagnosticItem)');
if (lastItem) {
lastItem.classList.add('finish');
}
}
};
startNextAnimation()
stopLastAnimaation()
"""
callJavaScript(showNextItemJS)
When I am on my site and I use the middle mouse button to load the page in a new tab, it renders the page as if it was on mobile but it is actually on desktop. It only recently started doing this on Chrome after an update.
As the site was done before I joined they did not use media query's like they should have, but actually used a mobile CSS file and a desktop CSS file. Depending on the size of the screen it loads the one it needs.
What I think is happening is that when the page loads in a new tab it loads it in a smaller screen, making my script believe it is on mobile but actually it is on Desktop.
jQuery:
function ResolutionSwitcher(config) {
this.cutoff = document.cutoff || 980;
this.$head = $(document.querySelector("head"));
$.extend(this, config);
}
ResolutionSwitcher.prototype.appendStyle = function(url) {
this.$head.append($("<link/>", {
type: "text/css",
rel: "stylesheet",
href: url
}));
};
ResolutionSwitcher.prototype.removeStyle = function(url) {
this.$head.find("link[href$='" + url + "']").remove();
};
ResolutionSwitcher.prototype.onDesktop = function() {
this.appendStyle("/static/public/css/desktop.v2.css");
this.removeStyle("mobile.css");
DesktopLayout.init();
};
ResolutionSwitcher.prototype.onMobile = function() {
this.appendStyle("/static/public/css/mobile.v2.css");
this.removeStyle("desktop.v2.css");
MobileLayout.init();
};
ResolutionSwitcher.prototype.checkResolution = function() {
var desktop_cutoff = 460;
// if screen is smaller than cutoff (mobile)
if(this.cutoff >= screen.width) {
this.onMobile();
window.site_version = 'strict_mobile';
}
// if screen is bigger than cutoff but window is smaller than cutoff and version is not already mobile
else if(desktop_cutoff >= window.outerWidth && window.site_version != 'mobile') {
this.onMobile();
window.site_version = 'mobile';
// navScrolling('#secondList');
// navScrolling('#thirdList');
navScrolling();
}
// if screen and window are both wider than cutoff and version is not already desktop
else if(desktop_cutoff < window.outerWidth && window.site_version != 'desktop') {
this.onDesktop();
window.site_version = 'desktop';
// navScrolling('#secondList');
// navScrolling('#thirdList');
navScrolling();
}
};
return ResolutionSwitcher;
I'm coding a web app, where user can use his camera (and choose which one to use). The problem is that I want user to be available to choose the camera before it is enabled. In the current code, when user turns on a page, he sees an empty list of cameras and when he enables the camera stream, dropdown list populates with camera names. I want the dropdown list populate when he turns on that web page.
P.S. when I stop() the camera, it disables camera and gives just a black screen. Why it is black instead of background colour?
CameraStreamView.cshtml
#using Api.Models
#{
ViewBag.Title = "Smart Vision";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="~/Content/Contact-Form-Clean.css">
</head>
<body onpageshow="Init()">
<div id="container">
<video id="video" style="display: block; margin: 0 auto; margin-top: 30px;" width="300" height="400" autoplay></video>
<button id="enableStream" style="display: block; margin: 0 auto; margin-top: 20px; height: 70px; width: 200px" onclick="start()">Enable camera</button>
<button id="disableStream" style="display: block; margin: 0 auto; margin-top: 20px; height: 70px; width: 200px" onclick="stop()">Disable camera</button>
<label for="videoSource">Video source: </label><select id="videoSource"></select>
</div>
<script src="~/Scripts/GetCameraFeed.js"></script>
</body>
</html>
GetCameraFeed.js
const videoSelect = document.querySelector('select#videoSource');
const selectors = [videoSelect];
function gotDevices(deviceInfos) {
// Handles being called several times to update labels. Preserve values.
const values = selectors.map(select => select.value);
selectors.forEach(select => {
while (select.firstChild) {
select.removeChild(select.firstChild);
}
});
for (let i = 0; i !== deviceInfos.length; ++i) {
const deviceInfo = deviceInfos[i];
const option = document.createElement('option');
option.value = deviceInfo.deviceId;
if (deviceInfo.kind === 'videoinput') {
option.text = deviceInfo.label;
videoSelect.appendChild(option);
}
}
selectors.forEach((select, selectorIndex) => {
if (Array.prototype.slice.call(select.childNodes).some(n => n.value === values[selectorIndex])) {
select.value = values[selectorIndex];
}
});
}
function Init() {
navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(handleError);
}
function gotStream(stream) {
window.stream = stream; // make stream available to console
video.srcObject = stream;
// Refresh button list in case labels have become available
return navigator.mediaDevices.enumerateDevices();
}
function handleError(error) {
console.log('navigator.getUserMedia error: ', error);
}
function start() {
const videoSource = videoSelect.value;
const constraints = {
video: { deviceId: videoSource ? { exact: videoSource } : undefined }
};
navigator.mediaDevices.getUserMedia(constraints).then(gotStream).then(gotDevices).catch(handleError);
}
function stop() {
video.pause();
video.src = "";
stream.getTracks().forEach(track => track.stop());
console.log("Stopping stream");
}
What you want is explicitly disallowed, due to fingerprinting concerns. Details about a user's setup let web sites identify them uniquely on the web, a privacy concern.
Once users trust your site with their camera and microphone, this information is considered relevant to share.
The working group determined this to be a reasonable trade-off, for several reasons:
Most desktop users have only one camera or none.
Most phone users have two, but you can use the facingMode constraint to pick.
Given 1 and 2, an up-front choice is arguably an inferior user experience for most.
I would consider changing your code to ask for the default camera the first time, and give users a choice to change it after the fact, should they need to. It's what most WebRTC sites do.
Note that this should only be a problem the first time a user visits your site. Provided they've granted camera or microphone just once in the past, you should be able to see the labels, at least in Chrome.
Unlike Chrome, Firefox does not persist permission implicitly, so you'd need a little more work to get labels on page-load on repeat visits:
enumerateDevices returns a deviceId for each device, which is persisted for your site provided the user has granted (or will grant within this session) camera or microphone at least once. You can use cookies or local storage to correlate deviceIds to device labels. This also survives people manually revoking permission in Chrome.
I'm using PowerBI REST to make an iOS App. Image below shows the result. When I click on any of the tiles I get no response, while if I click ON the red border (added in photoshop) Page respond to the click only if the tile includes a map, other tiles still no response.
Running the same page in a browser on Mac everything works, but on an iOS device it doesn't.
HTML Code:
<html>
<head>
<meta name="viewport" content="initial-scale=1.0" />
<script type="text/javascript">
// listen for message to receive tile click messages.
if (window.addEventListener) {
window.addEventListener("message", receiveMessage, false);
} else {
window.attachEvent("onmessage", receiveMessage);
}
//The embedded tile posts messages for clicks to parent window. Listen and handle as appropriate
function receiveMessage(event) {
messageData = JSON.parse(event.data);
if (messageData.event == "tileClicked"){
window.webkit.messageHandlers.callbackHandler.postMessage(messageData.navigationUrl.toString());
}
}
function updateEmbedReport() {
var w = window.innerWidth - 25;
var h = window.innerHeight;
// check if the embed url was selected
var embedUrl = "";
var iframe = document.getElementById('iframe1');
iframe.src = embedUrl;
iframe.onload = postActionLoadReport;
iframe.height = h;
iframe.width = w;
}
function postActionLoadReport() {
// get the access token.
accessToken = ;
var w = window.innerWidth - 25;
var h = window.innerHeight;
// construct the post message structure
var m = { action: "loadTile", accessToken: accessToken, height: h, width: w};
message = JSON.stringify(m);
// push the message.
iframe = document.getElementById('iframe1');
iframe.contentWindow.postMessage(message, "*");
iframe.height = h;
iframe.width = w;
}
</script>
</head>
<body onload="updateEmbedReport()">
<iframe id="iframe1" width="250px" frameBorder="0" name="iframe1" height="250px" style="cursor:pointer"/>
</body>
</html>
Swift code (which I use to make the app respond to tile click)
private var mWebView: WKWebView?
override func awakeFromNib() {
super.awakeFromNib()
let mWebViewConfig: WKWebViewConfiguration = WKWebViewConfiguration()
mWebViewConfig.userContentController.addScriptMessageHandler(self, name: "callbackHandler")
mWebViewConfig.preferences.javaScriptEnabled = true
mWebViewConfig.preferences.javaScriptCanOpenWindowsAutomatically = true
self.mWebView = WKWebView(frame: self.frame, configuration: mWebViewConfig)
//self.mWebView!.scrollView.scrollEnabled = false
self.addSubview(self.mWebView!)
}
func setData(url: String, tileClick: ITileClick){
self.mTileClick = tileClick
let page: String = (InstanceReferences.mPowerBIHandler?.GetPage(InstanceReferences.mAuthenticationToken!, EmbedURL: url, ReportPage: false))!
self.mWebView?.loadHTMLString(page, baseURL: NSURL(string: url)!)
}
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
print("iniside")
if message.name == "callbackHandler" {
self.mTileClick?.OnTilePageClick("\(message.body)")
} }
Note: Used the same HTML page in android app and everything is working without issues.
Any help would be great.
Have you been able to use any of the drill down options using the Power BI App on iphone?
There seems to be a bug in the embedded page which prevents it from detecting iOS taps. I believe you won't be able to solve this on your end due to cross-domain restrictions.
You can workaround this problem by saving the navigation URL provided to you by the tileLoaded event (fired on tile load), and detecting taps in iOS (Using a gesture recognizer on the WKWebView).