Menu scrolls only with some devices! - C++ or Other Android Development Languages

Hi everybody,
I've developed my APP with phonegap-cordova...everythings is ok but my APP's menu scrolls only on Galaxy S3,S4, Note 10 and not on Ace and S1 ( I could test my APP only on these devices)....attached you can find the HTML page and the relative CSS code. Any helps or hints is welcome
Thanks in advance
Cheers
Claudio
HTML CODE :
HTML:
<!DOCTYPE HTML>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<title>My APP</title>
<link href="styles/style.css" rel="stylesheet" type="text/css">
<link href="styles/framework.css" rel="stylesheet" type="text/css">
<link href="styles/owl.carousel.css" rel="stylesheet" type="text/css">
<link href="styles/owl.theme.css" rel="stylesheet" type="text/css">
<link href="styles/swipebox.css" rel="stylesheet" type="text/css">
<link href="styles/colorbox.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="app" class="all-elements">
<div id="sidebar" class="page-sidebar">
<div class="page-sidebar-scroll">
<div class="sidebar-shortcuts">
</div>
<div class="sidebar-logo">
<img src="images/misc/logo.png" height="56" alt="img">
</div>
<div class="sidebar-breadcrumb">MENU</div>
<div class="navigation-item">
Home<em class="unselected-item"></em>
</div>
<div class="navigation-item">
Info & Contatti<em class="unselected-item"></em>
</div>
<div class="navigation-item">
Prenota con BUM<em class="unselected-item"></em>
</div>
<div class="sidebar-decoration"></div>
<div class="navigation-item">
Impostazioni<em class="unselected-item"></em>
</div>
<div class="sidebar-breadcrumb">SCUOLA CALCIO</div>
<div class="navigation-item">
Pulcini<em class="dropdown-item"></em>
<div class="nav-submenu">
Comunicati <em class="unselected-item"></em>
Rose <em class="unselected-item"></em>
Risultati <em class="unselected-item"></em>
</div>
</div>
<div class="sidebar-breadcrumb">APP CREATA DA -----<br>COPYRIGHT 2014. ALL RIGHTS RESERVED!</br></div>
</div>
</div>
<div id="content" class="page-content">
<div class="page-header">
<img class="header-logo" src="images/misc/logo-header.png" width="121" alt="img">
</div>
<div class="content">
<div class="decoration"></div>
<div class="container no-bottom">
<img src="img/logo_accademia.png" class="responsive-image2" alt="img">
<h3>Benvenuto Bomber!</h3>
<p>
text
</p>
</div>
</div>
</div>
</body>
</html>
AND STYLE.CSS CODE:
Code:
@charset "utf-8";
/* CSS Document */
body {
background-color: 34495e; /* for the tint */
}
.overlay{
pointer-events:none;
position:absolute;
width:100%;
height:100%;
background-color:rgba(0,0,0,0.6);
z-index:9999;
}
.all-elements{
overflow-x:hidden;
}
.page-content{
background-color:#FFFFFF;
z-index:10;
display:block;
min-height:580px;
}
.page-content-wrapper{
display:block;
margin-top:0px;
margin-bottom:0px;
padding:20px;
padding-bottom:15px;
}
.page-sidebar{
background-image:url(../images/misc/menu-bg.png);
background-repeat:repeat;
background-size:75px 75px;
width:274px;
display:block;
position:absolute;
z-index:2;
top:0px;
left:0px;
bottom:0px;
overflow:hidden;
position:fixed;
}
.page-sidebar-scroll{
z-index:2;
width:294px;
overflow: scroll;
overflow-x: hidden;
/* -webkit-overflow-scrolling: touch;*/
height:100%;
}
/*Content Controls*/
.homepage-slider{
z-index:9;
margin-top:-50px;
}
.content-controls{
z-index:15;
height:50px;
}
.sidebar-shortcuts{
background-color:#1e1e1e;
height:50px;
border-bottom:solid 1px #2a2a2a;
}
.sidebar-shortcuts a{
opacity:0.8;
}
.sidebar-shortcuts a:hover{
background-color:rgba(255,255,255,0.1);
}
.shortcut-call{
background-image:url(../images/misc/shortcut_phone.png);
background-position:16px 11px;
background-repeat:no-repeat;
background-size:25px 25px;
width:58px;
height:50px;
position:absolute;
border-right:solid 1px rgba(0,0,0,0.2);
border-bottom:solid 1px rgba(0,0,0,0.2);
}
.shortcut-facebook{
background-image:url(../images/misc/shortcut_facebook.png);
background-position:16px 11px;
background-repeat:no-repeat;
background-size:27px 27px;
left:52px;
width:58px;
height:50px;
position:absolute;
border-right:solid 1px rgba(0,0,0,0.2);
border-bottom:solid 1px rgba(0,0,0,0.2);
}
.shortcut-twitter{
background-image:url(../images/misc/shortcut_twitter.png);
background-position:17px 11px;
background-repeat:no-repeat;
background-size:0px 0px;
left:105px;
width:58px;
height:50px;
position:absolute;
border-right:solid 1px rgba(0,0,0,0.2);
border-bottom:solid 1px rgba(0,0,0,0.2);
}
.shortcut-search{
background-image:url(../images/misc/shortcut_magnifier.png);
background-position:16px 12px;
background-repeat:no-repeat;
background-size:27px 27px;
left:160px;
width:58px;
height:50px;
position:absolute;
border-right:solid 1px rgba(0,0,0,0.2);
border-bottom:solid 1px rgba(0,0,0,0.2);
}
.shortcut-close{
background-image:url(../images/misc/shortcut_close.png);
background-position:17px 12px;
background-repeat:no-repeat;
background-size:25px 25px;
left:105px;
width:58px;
height:50px;
position:absolute;
border-right:solid 1px rgba(0,0,0,0.2);
border-bottom:solid 1px rgba(0,0,0,0.2);
}
.sidebar-search{
background-color:#1e1e1e;
height:50px;
border-bottom:solid 1px #2a2a2a;
display:none;
}
.search-field{
width:190px;
background-color:#1a1a19;
height:33px;
border-radius:33px;
border:solid 1px #181819;
line-height:33px;
color:#515050;
background-image:url(../images/misc/shortcut_magnifier.png);
background-repeat:no-repeat;
background-size:22px 22px;
background-position:10px 5px;
padding-left:40px;
margin-left:10px;
margin-top:8px;
}
.search-close{
margin-right:12px;
background-position:10px 0px;
float:right;
background-image:url(../images/misc/shortcut_close.png);
background-repeat:no-repeat;
height:50px;
width:50px;
background-size:25px 25px;
margin-top:-29px;
opacity:0.8;
}
.sidebar-logo{
padding-top:10px;
padding-left:25px;
margin-bottom:10px;
}
.sidebar-breadcrumb{
border-top:solid 1px rgba(255,255,255,0.05);
border-bottom:solid 1px rgba(255,255,255,0.05);
background-color:#1a1a1a;
font-size:10px;
padding-top:5px;
padding-bottom:5px;
padding-left:20px;
}
.sidebar-decoration{
height:2px;
background-color:rgba(0,0,0,0.15);
border-bottom:solid 1px rgba(255,255,255,0.07);
}
.nav-submenu a:first-child{
margin-top:-1px;
}
.nav-submenu a:last-child{
border-bottom:solid 0px #000000!important;
}
.nav-submenu a{
border-top:solid 1px rgba(255,255,255,0.05);
border-bottom:solid 1px rgba(0,0,0,0.1);
line-height:55px;
padding-left:60px;
background-image:url(../images/misc/nav-submenu.png);
background-repeat:no-repeat;
background-size:8px 8px;
background-position:30px 24px;
color:rgba(255,255,255,0.4);
}
.nav-submenu{
display:none;
}
.navigation-item .sidebar-decoration{
display:none;
}
.active-submenu{
display:block;
}
.nav-item{
height:55px;
border-bottom:solid 1px rgba(0,0,0,0.1);
box-shadow: 0 1px 0 0px rgba(255,255,255,0.05);
}
.nav-item:hover{
background-color:rgba(255,255,255,0.05);
}
.nav-submenu a:hover{
background-color:rgba(255,255,255,0.05);
}
.nav-submenug a:hover{
background-color:rgba(255,191,0,0.05);
}
.selected-item{
position:absolute;
width:10px;
height:10px;
border-radius:10px;
background-color:#2ecc71;
right:45px;
margin-top:23px;
}
.unselected-item{
position:absolute;
width:8px;
height:8px;
border-radius:8px;
background-color:rgba(255,255,255,0.08);
right:47px;
margin-top:23px;
}
.dropdown-item{
background-image:url(../images/misc/nav-dropdown.png)!important;
background-size:14px 13px;
position:absolute;
width:14px;
height:14px;
right:45px;
margin-top:23px;
}
.submenu-deploy em{
background-image:url(../images/misc/nav-dropup.png);
background-size:14px 13px;
position:absolute;
width:14px;
height:14px;
right:45px;
margin-top:23px;
}
.link-item{
background-image:url(../images/misc/nav-link.png);
background-size:14px 13px;
position:absolute;
width:14px;
height:14px;
right:45px;
margin-top:23px;
}
.nav-item{
opacity:0.8;
background-position:20px 15px;
background-size:25px 25px;
background-repeat:no-repeat;
color:#FF0000;
font-size:12px;
padding-left:60px;
line-height:55px;
}
.nav-itemx{
opacity:0.8;
background-position:20px 15px;
background-size:25px 25px;
background-repeat:no-repeat;
color:#FFFFFF;
font-size:12px;
padding-left:60px;
line-height:55px;
}
.nav-itemg{
opacity:0.8;
background-position:20px 15px;
background-size:25px 25px;
background-repeat:no-repeat;
color:#FFA500;
font-size:14px;
padding-left:60px;
line-height:55px;
}
.nav-itemb{
opacity:0.8;
background-position:20px 15px;
background-size:25px 25px;
background-repeat:no-repeat;
color:#007FFF;
font-size:12px;
padding-left:60px;
line-height:55px;
}
.nav-itemv{
opacity:0.8;
background-position:20px 15px;
background-size:25px 25px;
background-repeat:no-repeat;
color:#03C03C;
font-size:12px;
padding-left:60px;
line-height:55px;
}
.dropdown-item{
background-image:url(../images/misc/nav-dropdown.png);
}
.home-icon{
background-image:url(../images/icons/misc/home.png);
}
.features-icon{
background-image:url(../images/icons/settings/cog2.png);
}
.features-iconx{
background-image:url(../images/icons/misc/cup.png);
}
.features-iconxx{
background-image:url(../images/icons/user/group.png);
}
.gallery-icon{
background-image:url(../images/icons/media/image2.png);
}
.info-icon{
background-image:url(../images/icons/misc/infoabout.png);
}
.appointment-icon{
background-image:url(../images/icons/time/monthcalendar.png);
}
.facebook-icon{
background-size:17px 17px;
background-position:25px 19px;
background-image:url(../images/misc/social/facebook.png);
}
.twitter-icon{
background-size:17px 17px;
background-position:25px 19px;
background-image:url(../images/misc/social/twitter.png);
}
.google-icon{
background-size:17px 17px;
background-position:25px 19px;
background-image:url(../images/misc/social/google.png);
}
.info-update{
background-image:url(../images/misc/notification-blue.png);
background-size:42px 42px;
background-position:20px 0px;
background-repeat:no-repeat;
height:50px;
padding-left:80px;
}
.notification-update{
background-image:url(../images/misc/notification-yellow.png);
background-size:42px 42px;
background-position:20px 0px;
background-repeat:no-repeat;
height:50px;
padding-left:80px;
}
.warning-update{
background-image:url(../images/misc/notification-red.png);
background-size:42px 42px;
background-position:20px 0px;
background-repeat:no-repeat;
height:50px;
padding-left:80px;
}
.tick-update{
background-image:url(../images/misc/notification-green.png);
background-size:42px 42px;
background-position:20px 0px;
background-repeat:no-repeat;
height:50px;
padding-left:80px;
}
.page-update{
margin-top:15px;
margin-bottom:10px;
}
.page-update strong{
color:rgba(255,255,255,0.6);
display:block;
}
.page-update em{
color:rgba(255,255,255,0.4);
display:block;
font-size:10px;
font-style:normal;
}
.update-icon{
background-image:url(../images/misc/nav-dropdown.png);
background-size:14px 14px;
background-repeat:no-repeat;
position:absolute;
right:45px;
margin-top:12px;
width:14px;
height:14px;
}
.active-update-icon{
background-image:url(../images/misc/nav-dropup.png)!important;
}
.page-update-text{
color:rgba(255,255,255,0.5);
font-size:12px;
width:220px;
margin-left:auto;
margin-right:auto;
}
.page-update-text{
display:none;
}
.page-header{
background-color:#1e1e1e;
height:49px;
width:100%;
position:fixed;
z-index:999999;
}
.page-header-clear{
height:49px;
}
.header-logo{
width:111px;
margin-left:auto;
margin-right:auto;
margin-top:-38px;
}
.deploy-sidebar{
background-image:url(../images/misc/deploy-nav.png);
background-size:18px 12px;
background-repeat:no-repeat;
background-position:16px 18px;
height:50px;
width:50px;
opacity:0.8;
}
.deploy-sidebar:hover{
background-color:rgba(255,255,255,0.1);
}
.deploy-contact{
background-image:url(../images/icons/settings/cog2.png);
background-size:28px 22px;
background-repeat:no-repeat;
background-position:18px 18px;
height:50px;
width:50px;
float:right;
margin-top:-53px;
opacity:0.8;
}
.deploy-contact:hover{
background-color:rgba(255,255,255,0.1);
}
/*About Faces / Quotes */
.quote-item em{
text-align:center;
display:block;
color:#e34e47;
margin-bottom:10px;
}
.quote-item h4{
text-align:center;
margin-bottom:0px;
}
.quote-item strong{
text-align:center;
font-style:normal;
font-weight:400;
display:block;
width:250px;
margin-left:auto;
margin-right:auto;
}
.quote-item img{
border-radius:100px;
width:100px;
margin-left:auto;
margin-right:auto;
margin-bottom:20px;
}
/*Thumbnails Columns*/
.thumb-clear{
height:20px;
display:block;
width:100%;
}
.thumb-left{
display:block;
padding-bottom:10px;
}
.thumb-left a{
display:block;
text-align:right;
}
.thumb-left img{
width:100px;
height:100px;
border-radius:100px;
float:left;
margin-right:20px;
}
.thumb-left strong{
color:#1a1a1a;
display:inline-block;
padding-top:5px;
padding-bottom:5px;
font-size:13px;
}
.thumb-left em{
font-style:normal;
}
.thumb-right{
display:block;
padding-bottom:10px;
}
.thumb-right img{
width:100px;
height:100px;
border-radius:100px;
float:right;
margin-left:20px;
}
.thumb-right strong{
color:#1a1a1a;
display:inline-block;
padding-top:5px;
padding-bottom:5px;
font-size:13px;
}
.thumb-right em{
font-style:normal;
}
.customer-slider div a img{
width:40px;
margin-left:auto;
margin-right:auto;
}
/*Social Boxes*/
.facebook-box{
background-image:url(../images/misc/social/facebook.png);
background-size:26px 23px;
background-repeat:no-repeat;
background-position:10px 10px;
background-color:#3b5998;
height:40px;
line-height:40px;
color:#FFFFFF;
padding-left:60px;
margin-bottom:20px;
}
.social-box em{
position:absolute;
height:40px;
width:1px;
background-color:#FFFFFF;
margin-left:-15px;
}
.social-box:hover{
opacity:0.9;
}
.twitter-box{
background-image:url(../images/misc/shortcut_phone.png);
background-size:20px 17px;
background-repeat:no-repeat;
background-position:12px 13px;
background-color:#4099ff;
height:40px;
line-height:40px;
color:#FFFFFF;
padding-left:60px;
margin-bottom:20px;
}
.google-box{
background-image:url(../images/icons/time/monthcalendar.png);
background-size:20px 17px;
background-repeat:no-repeat;
background-position:12px 13px;
background-color:#d34836;
height:40px;
line-height:40px;
color:#FFFFFF;
padding-left:60px;
margin-bottom:20px;
}
/*Footer Socials*/
.copyright{
font-size:10px;
}
.footer-socials{
width:110px;
margin-left:auto;
margin-right:auto;
margin-bottom:10px;
}
.footer-socials a{
float:left;
margin-left:5px;
margin-right:5px;
}
.facebook-footer{
background-image:url(../images/misc/facebook.png);
background-repeat:no-repeat;
background-size:25px 26px;
height:25px;
width:25px;
}
.goup-footer{
background-image:url(../images/misc/goup.png);
background-repeat:no-repeat;
background-size:25px 25px;
height:25px;
width:25px;
}
.twitter-footer{
background-image:url(../images/misc/twitter.png);
background-repeat:no-repeat;
background-size:25px 25px;
height:25px;
width:25px;
}
/*Wide Portfolio*/
.wide-active{
margin-top:20px;
display:none;
}
.wide-item-wrapper{
background-color:#FFFFFF;
padding-bottom:1px;
margin-top:3px;
}
.wide-folio{
margin-top:-17px;
margin-bottom:20px;
}
.wide-item{
margin-bottom:3px;
}
.wide-item .responsive-image{
margin-bottom:0px;
}
.responsive-image2{
margin-bottom:0px;
margin-top:15px;
max-width:100%;
max-height:100%;
}
.wide-image{
max-height:100px;
overflow:hidden;
}
.wide-item-titles{
position:relative;
z-index:99999;
top:30px;
margin-bottom:-45px;
pointer-events:none;
}
.wide-item-titles h4{
font-family:'Open Sans', sans-serif;
font-weight:200;
font-size:16px;
text-transform:uppercase;
color:#FFFFFF;
position:relative;
z-index:999999;
text-align:center;
margin-bottom:5px;
}
.wide-item-titles p{
color:#FFFFFF;
margin-bottom:0px;
color:rgba(255,255,255,0.5);
text-align:center;
position:relative;
z-index:999999;
}
.wide-item-content{
display:none;
margin-top:20px;
margin-left:20px;
margin-right:20px;
}
@media (min-width:760px) {
.wide-image{
max-height:150px;
}
.wide-item-titles{
top:55px;
margin-bottom:-45px;
}
}
.contact-call{
padding-top:5px;
color:#666;
padding-left:30px;
background-image:url(../images/misc/contact_phone.png);
background-position:0px 5px;
background-repeat:no-repeat;
background-size:18px 18px;
height:30px;
display:block;
}
.contact-text{
color:#666;
margin-bottom:5px;
padding-left:30px;
background-image:url(../images/misc/contact_message.png);
background-position:0px 2px;
background-repeat:no-repeat;
background-size:18px 18px;
height:20px;
display:block;
margin-bottom:2px;
}
.contact-mail{
color:#666;
margin-bottom:5px;
padding-left:30px;
background-image:url(../images/misc/contact_mail.png);
background-position:3px 3px;
background-repeat:no-repeat;
background-size:14px 14px;
height:20px;
display:block;
margin-top:5px;
margin-bottom:2px;
}
.contact-facebook{
color:#666;
margin-bottom:5px;
padding-left:30px;
background-image:url(../images/misc/contact_facebook.png);
background-position:0px 0px;
background-repeat:no-repeat;
background-size:20px 20px;
height:20px;
display:block;
margin-top:5px;
margin-bottom:2px;
}
.contact-twitter{
color:#666;
margin-bottom:5px;
padding-left:30px;
background-image:url(../images/misc/contact_twitter.png);
background-position:0px 0px;
background-repeat:no-repeat;
background-size:20px 20px;
height:20px;
display:block;
margin-top:5px;
margin-bottom:2px;
}

Related

Upgrade to WM 6.0 for Hermes, Dopod...

xxxxxxxxxxxxxxxx
[deleted]
@mods: Please close or even better delete!
.wysiwyg { background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%; background-color: #ffffcc; background-image: none; color: #000000; font-family: Verdana, Arial, Arial; font-style: normal; font-variant: normal; font-weight: 400; font-size: 10pt; line-height: normal } p { margin: 0px; }
yep, sorry, deleted my post.

In addition to using the promt.showDialog API, how can I implement custom pop-up windows?

You can run the if/show command to control the display of a pop-up window based on the stack component and the position:fixed CSS file. The following code implements two custom pop-up windows:
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
1. Initialize data models.
data() {
return {
list: [1, 2, 3],
isShow: false,
ifShow1: false,
ifShow2: false
}
},
2. Set the page layout.
<text onclick="showToast1">Custom pop-up window 1</text>
<text onclick="showToast2">Custom pop-up window 2</text>
<!-- Pop-up window -->
<div if="{{isShow}}" class="modal center-modal">
<div class="toast-box password-box">
<block>
<stack>
<div style="flex-direction: column;width: 100%;" if="{{ifShow1}}">
<div style="width: 100%;">
<text style="font-size: 32px;font-weight: 500;">Traffic violation</text>
<text style="font-size: 25px;text-align: right;padding-left: 400px" onclick="hide">Hide</text>
</div>
<list style="height: 550px">
<list-item type="list" for="list" style="height: 160px;margin-top: 20px">
<div style="padding-top: 1px;">
<image src="/Common/icon.png" style="border-radius: 100%;width: 100px;height: 100px;"></image>
<div style="flex-direction: column; margin-left: 20px">
<text style="font-size: 28px;font-weight: 600;">Level-2 title</text>
<text style="font-size: 26px;margin-top: 10px">Displaying product attributes, prices, release dates, and more.</text>
<div style="height: 2px;background-color:#808080;bottom: 0;margin-top: 25px" if="{{$idx<2}}">
</div>
</div>
</div>
</list-item>
</list>
</div>
<div style="flex-direction: column;width: 100%;" if="{{ifShow2}}">
<text style="font-size: 31px;font-weight: 700;">City services</text>
<text style="font-weight: 400;"><span>By tapping Agree, you agree to the above terms as well as the </span><a style="color: #0000ff;" onclick="toast">XX User Agreement</a>
<span> and </span><a style="color: #0000ff;" onclick="toast">Privacy Statement About XX.</a></text>
<div style="width: 100%;">
<text style="width: 50%; text-align: center; color: #0000ff;" onclick="hide">OK</text>
<text style="width: 50%; text-align: center; color: #0000ff;" onclick="hide">Cancel</text>
</div>
</div>
</stack>
</block>
</div>
</div>
3. Set the page style.
.container {
flex-direction: column;
justify-content: center;
align-items: center;
.body {
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
.img {
margin-top: 500px;
}
.txt {
margin-top: 570px;
}
}
// Pop-up window style.
.modal {
position: fixed;
flex-direction: column;
justify-content: flex-end;
width: 100%;
height: 100%;
padding: 0 34px 34px;
background-color: rgba(0, 0, 0, 0.18);
animation-name: Modal;
animation-duration: 130ms;
animation-timing-function: ease-in;
.toast-box {
width: 100%;
padding: 25px 50px 20.8px;
border-radius: 34px;
background-color: white;
flex-direction: column;
.toast-title {
font-size: 41.6px;
line-height: 56px;
font-weight: 500;
font-family: HWtext-65ST;
color: #000000;
}
.toast-tip {
font-family: HWtext-55ST;
font-size: 29px;
color: rgba(0, 0, 0, 0.6);
line-height: 40px;
margin-top: 3.6px;
margin-bottom: 25px;
}
.label-box {
height: 100px;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
.label {
color: #000000;
width: 100%;
font-family: HWtext-55ST;
font-size: 34px;
}
input {
margin-right: -11px;
}
}
.manage {
height: 100px;
font-family: HWtext-65ST;
font-size: 29.12px;
color: #007dff;
font-weight: 500;
}
.cancel {
width: 100%;
height: 75px;
margin-top: 37.44px;
text-align: center;
font-family: HWtext-65ST;
font-size: 33.28px;
color: #007dff;
font-weight: 500;
}
.btn-box {
justify-content: space-between;
align-items: center;
.bind {
width: 47%;
height: 60px;
border-radius: 10px;
font-family: HWtext-65ST;
text-align: center;
font-size: 33.28px;
color: #007dff;
margin: 16px 0;
font-weight: 500;
}
.line {
height: 50px;
width: 1px;
background-color: rgba(0, 0, 0, 0.2);
}
.quit {
width: 47%;
height: 60px;
border-radius: 10px;
text-align: center;
font-family: HWtext-65ST;
font-size: 33.28px;
color: #007dff;
margin: 16px 0;
font-weight: 500;
}
.bind:active {
background-color: rgba(0, 0, 0, 0.1);
}
.quit:active {
background-color: rgba(0, 0, 0, 0.1);
}
}
.nocar-tip {
height: 99.84px;
font-size: 33.28px;
font-family: HWtext-55ST;
color: #000000;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
}
.password-box {
margin-top: -110px;
padding: 30.63px 50px 20.8px;
.toast-title {
height: 55.64px;
margin-bottom: 30.12px;
}
.password-tip {
flex-direction: column;
margin-top: 3.6px;
margin-bottom: 25px;
.control-tip {
font-family: HWtext-55ST;
font-size: 24.96px;
color: rgba(0, 0, 0, 0.6);
}
}
.error-password-tip {
font-family: HWtext-55ST;
font-size: 24.96px;
color: #fa2a2d;
height: 32.76px;
margin-bottom: 37.4px;
margin-top: 0;
}
.btn-box {
.bind {
margin-top: 8px;
margin-bottom: 8px;
}
.quit {
margin-top: 8px;
margin-bottom: 8px;
}
}
.eyes-input-box {
width: 100%;
flex-direction: row;
justify-content: flex-end;
.input-password {
width: 100%;
height: 94.64px;
border: 1px solid #ffffff;
border-bottom-color: #000000;
padding: 11.44px 0;
margin-bottom: 20.8px;
}
.password-text {
width: 100%;
height: 94.64px;
padding: 11.44px 0;
border-bottom: 1px solid #000000;
margin-bottom: 20.8px;bind:active {
color: #000000;
font-size: 36px;
}
.eyes-img {
width: 49.92px;
height: 49.92px;
margin-top: 23px;
}
}
.password-loading-box {
flex-direction: row;
align-items: center;
justify-content: space-between;
height: 150px;
.loading-text {
font-family: HWtext-55ST;
font-size: 33.28px;
color: rgba(0, 0, 0, 0.96);
}
.loading-circular {
width: 102px;
height: 102px;
color: #666666;
}
}
}
}
}
4. Bind an event.
showToast1() {
this.isShow = true;
this.ifShow1 = true
this.ifShow2 = false
},
showToast2() {
this.isShow = true;
this.ifShow1 = false
this.ifShow2 = true
},
hide(){
this.isShow = false;
},
toast() {
prompt.showToast({
message: 'View privacy agreement'
})
}
How can I read the global variables defined in app.ux from a JavaScript file?
For example, You can define the variable AppData in app.ux.
data: {
AppData: '123456',
}
The code in the JavaScript file is as follows:
export default {
getAppData() {
return getApp().$def.data.AppData
}
}
For more information, please refer to the Common methods section in Script.

Obtaining Device Information in Harmony OS Lite wearable

Introduction
Harmony OS is a future-proof distributed operating system open to you as part of the initiatives for the all-scenario strategy, adaptable to mobile office, fitness and health, social communication, and media entertainment, to name a few. Unlike a legacy operating system that runs on a standalone device, Harmony OS is built on a distributed architecture designed based on a set of system capabilities. It can run on a wide range of device forms, including smartphones, tablets, wearables, smart TVs and head units.
In this article, we will create simple lite wearable JS application to obtain device information.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Requirements
1) DevEco IDE
2) Lite wearable simulator
Implementation
First page, index.hml contains <swiper> container that enables the switch of child components.
Code:
<swiper class="container" index="{{index}}">
<div class="swiper-item item1">
<text class="title">BRAND</text>
<text class="subtitle">{{brand}}</text>
<div class="seperator" ></div>
<text class="title">MANUFACTURER</text>
<text class="subtitle">{{manufacturer}}</text>
<div class="seperator" ></div>
<text class="title">MODEL</text>
<text class="subtitle">{{model}}</text>
</div>
<div class="swiper-item item2">
<text class="title">PRODUCT</text>
<text class="subtitle">{{product}}</text>
<div class="seperator" ></div>
<text class="title">LANGUAGE</text>
<text class="subtitle">{{language}}</text>
<div class="seperator" ></div>
<text class="title">REGION</text>
<text class="subtitle">{{region}}</text>
</div>
<div class="swiper-item item3">
<text class="title">SCREEN SHAPE</text>
<text class="subtitle">{{shape}}</text>
<div class="seperator" ></div>
<text class="title">SCREEN DENSITY</text>
<text class="subtitle">{{screendensity}}</text>
<div class="seperator" ></div>
<text class="title">DIMENSION</text>
<text class="subtitle">{{dimension}}</text>
</div>
</swiper>
index.css has style defined for the page.
Code:
.container {
left: 0px;
top: 0px;
width: 454px;
height: 454px;
}
.swiper-item {
width: 454px;
height: 454px;
flex-direction: column;
justify-content: center;
align-items: center;
}
.item1 {
background-color: #007dff;
}
.item2 {
background-color: #cc0000;
}
.item3 {
background-color: #41ba41;
}
.title {
font-size:30px;
justify-content: center;
}
.subtitle {
font-size:30px;
color: lightgrey;
margin: 15px;
justify-content: center;
}
.seperator {
height: 1px;
width: 454px;
margin-bottom: 5px;
margin-top: 5px;
background-color: white;
}
To obtain the device information, we will call device.info()
Code:
device.getInfo({
success: function(data) {
console.log('success get device info brand:' + data.brand);
_this.brand = data.brand;
_this.manufacturer = data.manufacturer;
_this.model = data.model;
_this.language = data.language;
_this.product = data.product;
_this.region = data.region;
_this.screendensity = data.screenDensity;
_this.shape = data.screenShape;
_this.dimension = data.windowWidth + ' X ' + data.windowHeight;
},
fail: function(data, code) {
console.log('fail get device info code:'+ code + ', data: ' + data);
},
});
Code Snippet of index.js
Code:
import device from '@system.device';
export default {
data: {
brand: '--',
manufacturer: '--',
language: '--',
model: '--',
product: '--',
region: '--',
dimension: '--',
screendensity: 0,
shape : '--'
}
,
onInit(){
let _this = this;
device.getInfo({
success: function(data) {
console.log('success get device info brand:' + data.brand);
_this.brand = data.brand;
_this.manufacturer = data.manufacturer;
_this.model = data.model;
_this.language = data.language;
_this.product = data.product;
_this.region = data.region;
_this.screendensity = data.screenDensity;
_this.shape = data.screenShape;
_this.dimension = data.windowWidth + ' X ' + data.windowHeight;
},
fail: function(data, code) {
console.log('fail get device info code:'+ code + ', data: ' + data);
},
});
}
}
Tips and Tricks
Not all the information can be obtained on simulator. Hence it is recommended to use physical Harmony OS wearable watch.
Conclusion
In this article, we learnt how easily we can obtain wearable device information such as brand, product, device dimension, density, etc.
References
Harmony OS JS API :
Document
developer.harmonyos.com
Harmony Official document -
Document
developer.harmonyos.com
Very useful

Super Easy Way to Implement a Custom Pop-up

The promt.showDialog API of Quick App can be used to implement simple pop-up elements such as text and buttons, but cannot achieve complex display effects. UI designers will often design complex effects, so how do we actually achieve them as engineers?
For example, the design of a pop-up includes a list, in which images are displayed on the left and descriptions need to be shown on the right, as shown in Figure 1 below. Another pop-up instructs users to check the app’s privacy statement via a link, as shown in Figure 2.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Figure 1 Pop-up with a list Figure 2 Pop-up with a link
Proper arrangement of quick app elements and style attributes can help achieve such complex effects.
Solution​You can use the stack element with the position: fixed CSS style to implement a custom pop-up. Whether to display the pop-up can be determined using the if/show command. Sample code is as follows:
1.Initialize data models:
HTML:
data() {
return {
list: [1, 2, 3],
isShow: false,
ifShow1: false,
ifShow2: false
}
},
2.Page layout:
HTML:
<text onclick="showToast1">Custom pop-up window 1</text>
<text onclick="showToast2">Custom pop-up window 2</text>
<!-- Pop-up window -->
<div if="{{isShow}}" class="modal center-modal">
<div class="toast-box password-box">
<block>
<stack>
<div style="flex-direction: column;width: 100%;" if="{{ifShow1}}">
<div style="width: 100%;">
<text style="font-size: 32px;font-weight: 500;">Traffic violation</text>
<text style="font-size: 25px;text-align: right;padding-left: 400px" onclick="hide">Hide</text>
</div>
<list style="height: 550px">
<list-item type="list" for="list" style="height: 160px;margin-top: 20px">
<div style="padding-top: 1px;">
<image src="/Common/icon.png" style="border-radius: 100%;width: 100px;height: 100px;"></image>
<div style="flex-direction: column; margin-left: 20px">
<text style="font-size: 28px;font-weight: 600;">Level-2 title</text>
<text style="font-size: 26px;margin-top: 10px">Displaying product attributes, prices, release dates, and more.</text>
<div style="height: 2px;background-color:#808080;bottom: 0;margin-top: 25px" if="{{$idx<2}}">
</div>
</div>
</div>
</list-item>
</list>
</div>
<div style="flex-direction: column;width: 100%;" if="{{ifShow2}}">
<text style="font-size: 31px;font-weight: 700;">City services</text>
<text style="font-weight: 400;"><span>By tapping Agree, you agree to the above terms as well as the </span><a style="color: #0000ff;" onclick="toast">XX User Agreement</a>
<span> and </span><a style="color: #0000ff;" onclick="toast">Privacy Statement About XX.</a></text>
<div style="width: 100%;">
<text style="width: 50%; text-align: center; color: #0000ff;" onclick="hide">OK</text>
<text style="width: 50%; text-align: center; color: #0000ff;" onclick="hide">Cancel</text>
</div>
</div>
</stack>
</block>
</div>
</div>
Page style:
CSS:
.container {
flex-direction: column;
justify-content: center;
align-items: center;
.body {
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
.img {
margin-top: 500px;
}
.txt {
margin-top: 570px;
}
}
// Pop-up style
.modal {
position: fixed;
flex-direction: column;
justify-content: flex-end;
width: 100%;
height: 100%;
padding: 0 34px 34px;
background-color: rgba(0, 0, 0, 0.18);
animation-name: Modal;
animation-duration: 130ms;
animation-timing-function: ease-in;
.toast-box {
width: 100%;
padding: 25px 50px 20.8px;
border-radius: 34px;
background-color: white;
flex-direction: column;
.toast-title {
font-size: 41.6px;
line-height: 56px;
font-weight: 500;
font-family: HWtext-65ST;
color: #000000;
}
.toast-tip {
font-family: HWtext-55ST;
font-size: 29px;
color: rgba(0, 0, 0, 0.6);
line-height: 40px;
margin-top: 3.6px;
margin-bottom: 25px;
}
.label-box {
height: 100px;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
.label {
color: #000000;
width: 100%;
font-family: HWtext-55ST;
font-size: 34px;
}
input {
margin-right: -11px;
}
}
.manage {
height: 100px;
font-family: HWtext-65ST;
font-size: 29.12px;
color: #007dff;
font-weight: 500;
}
.cancel {
width: 100%;
height: 75px;
margin-top: 37.44px;
text-align: center;
font-family: HWtext-65ST;
font-size: 33.28px;
color: #007dff;
font-weight: 500;
}
.btn-box {
justify-content: space-between;
align-items: center;
.bind {
width: 47%;
height: 60px;
border-radius: 10px;
font-family: HWtext-65ST;
text-align: center;
font-size: 33.28px;
color: #007dff;
margin: 16px 0;
font-weight: 500;
}
.line {
height: 50px;
width: 1px;
background-color: rgba(0, 0, 0, 0.2);
}
.quit {
width: 47%;
height: 60px;
border-radius: 10px;
text-align: center;
font-family: HWtext-65ST;
font-size: 33.28px;
color: #007dff;
margin: 16px 0;
font-weight: 500;
}
.bind:active {
background-color: rgba(0, 0, 0, 0.1); // To be modified in the high-fidelity design.
}
.quit:active {
background-color: rgba(0, 0, 0, 0.1); // To be modified in the high-fidelity design.
}
}
.nocar-tip {
height: 99.84px;
font-size: 33.28px;
font-family: HWtext-55ST;
color: #000000;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
}
.password-box {
margin-top: -110px;
padding: 30.63px 50px 20.8px;
.toast-title {
height: 55.64px;
margin-bottom: 30.12px;
}
.password-tip {
flex-direction: column;
margin-top: 3.6px;
margin-bottom: 25px;
.control-tip {
font-family: HWtext-55ST;
font-size: 24.96px;
color: rgba(0, 0, 0, 0.6);
}
}
.error-password-tip {
font-family: HWtext-55ST;
font-size: 24.96px;
color: #fa2a2d;
height: 32.76px;
margin-bottom: 37.4px;
margin-top: 0;
}
.btn-box {
.bind {
margin-top: 8px;
margin-bottom: 8px;
}
.quit {
margin-top: 8px;
margin-bottom: 8px;
}
}
.eyes-input-box {
width: 100%;
flex-direction: row;
justify-content: flex-end;
.input-password {
width: 100%;
height: 94.64px;
border: 1px solid #ffffff;
border-bottom-color: #000000;
padding: 11.44px 0;
margin-bottom: 20.8px;
}
.password-text {
width: 100%;
height: 94.64px;
padding: 11.44px 0;
border-bottom: 1px solid #000000;
margin-bottom: 20.8px;
color: #000000;
font-size: 36px;
}
.eyes-img {
width: 49.92px;
height: 49.92px;
margin-top: 23px;
}
}
.password-loading-box {
flex-direction: row;
align-items: center;
justify-content: space-between;
height: 150px;
.loading-text {
font-family: HWtext-55ST;
font-size: 33.28px;
color: rgba(0, 0, 0, 0.96);
}
.loading-circular {
width: 102px;
height: 102px;
color: #666666;
}
}
}
}
}
For more information,please refer to the following:
Style of Quick App
Quick App materials
Common settings of Quick App
Is it supports in Xamarin?
ask011 said:
Is it supports in Xamarin?
Click to expand...
Click to collapse
Sorry. It supported in quick app. It is different from Xamarin. If you want to implement custom pop up in xamarin, you can try to study other tutorials perhaps.
Hope it works for Hormony os as well.
shikkerimath said:
Hope it works for Hormony os as well.
Click to expand...
Click to collapse
The JS UI framework supports custom components for you to extend existing components based on your application services. you can implement by following the document.

Huawei Smart Watch – Fetch Location to make Prayer times calculation Application Development using JS on HUAWEI DevEco Studio (HarmonyOS)

{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Article Introduction
In this article we will develop Prayer Times application for Huawei Smart Watch device using Huawei DevEco Studio (HarmonyOS). We will fetch Location using HarmonyOS JS language API’s and use some of the npm libraries (adhan, moment, moment-timezone, tz-lookup) to develop complete Real world Prayer Times Calculation Application.
1. Create New Project
Let’s create Smart Watch Project and choosing ability template, Empty Ability (JS)
Define project name, package name and relevant directory where you want to save your project. Choose the Device type “wearable” for which we are developing the application.
2. Preparing Files and Permission
Let’s first add images and permissions which we will use for project.
All project images will be under common/images folder, check below screenshot.
Next we need to add Location and Internet permissions under config.json file.
Code:
"reqPermissions": [
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.LOCATION",
"reason": "get user location to show prayer time",
"usedScene": {
"ability": [
"default"
],
"when": "always"
}
}
]
3. NPM libraries installation
We need to install following NPM libraries in the application:
adhan
moment
moment-timezone
tz-lookup
First we need to open the terminal under our DevEco studio project.
We need to change directory to entry folder.
Code:
cd entry
Now we need to install all the required libraries for our project.
Code:
npm i adhan moment moment-timezone tz-lookup -s
After installation our package.json file look like below:
Code:
{
"dependencies": {
"adhan": "^4.1.0",
"moment": "^2.29.1",
"moment-timezone": "^0.5.33",
"tz-lookup": "^6.1.25"
}
}
4. Prayer Time App Development
In Prayer time screen development we will cover Location permission, Location fetching, location error layout, prayer timer screen and today all prayers dialog screen.
Let’s start development without wasting more time.
Styling:
index.css: (Common screen styling)
Code:
/* common styling */
.container {
background-color: black;
justify-content: center;
}
.container-sub {
display: flex;
width: 100%;
justify-content: center;
align-items: center;
flex-direction: column;
padding-top: 24px;
}
.container-location-loading {
flex-direction: column;
padding-top: 0px;
padding-bottom: 0px;
height: 456px;
width: 456px;
}
.column {
display: flex;
flex-direction: column;
justify-content: center;
width: 100%;
background-color: transparent;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
width: 80%;
height: 25px;
background-color: transparent;
}
.title {
text-align: center;
display: flex;
font-size: 16px;
}
.center {
text-align: center;
}
.location_loading {
object-fit: contain;
height: 456px;
width: 240px;
text-align: center;
align-items: center;
}
.current_time {
font-size: 18px;
text-align: center;
}
.mosque {
margin-top: 5px;
text-align: center;
fit-original-size: true;
}
.prayer_name {
text-align: center;
font-size: 16px;
margin-top: 2px;
margin-bottom: 5px;
}
.remaining_timer {
text-align: center;
font-size: 14px;
}
.button-circle {
background-color: transparent;
}
index.css: (Prayer BG & Color styling)
Code:
/* prayer BG & Color */
.prayer_bg {
background-position: top center;
background-size: 100% 280px;
}
.fajr_bg {
background-image: url('/common/images/prayer_bg/fajr.jpg');
}
.fajr_color {
background-color: #30170d;
}
.dhuhr_bg {
background-image: url('/common/images/prayer_bg/dhuhr.jpg');
}
.dhuhr_color {
background-color: #021823;
}
.asr_bg {
background-image: url('/common/images/prayer_bg/asr.jpg');
}
.asr_color {
background-color: #172B34;
}
.maghrib_bg {
background-image: url('/common/images/prayer_bg/maghrib.jpg');
}
.maghrib_color {
background-color: #010101;
}
.isha_bg {
background-image: url('/common/images/prayer_bg/isha.jpg');
}
.isha_color {
background-color: #082C44;
}
.night_bg {
background-image: url('/common/images/prayer_bg/night.jpg');
}
.night_color {
background-color: #131C39;
}
index.css: (Dialog styling)
Code:
/*Dialog styling*/
.dialog-main {
width: 100%;
}
.dialog-div {
display: flex;
flex-direction: column;
align-items: center;
}
.inner-txt {
width: 100%;
height: 300px;
flex-direction: column;
align-items: center;
}
.inner-btn {
width: 100%;
height: 154px;
align-items: center;
}
index.css: (List styling)
Code:
/*list styling*/
.list-wrapper {
width: 100%;
flex-direction: column;
}
.list-items {
width: 100%;
flex-direction: column;
padding: 0 24px;
}
.item-wrapper {
flex-direction: row;
justify-content: space-between;
align-items: center;
width: 100%;
height: 34px;
margin: 8px 0;
}
.item-icon-wrapper {
width: 24px;
}
.item-icon {
width: 24px;
height: 24px;
object-fit: contain;
}
.item-name-description-wrapper {
flex-direction: column;
justify-content: center;
align-items: center;
flex-grow: 1;
flex-shrink: 1;
width: 50%;
margin-right: 24px;
margin-left: 24px;
}
.item-name {
text-align: left;
color: #DBFFFFFF;
font-size: 16px;
}
.item-description {
text-align: left;
opacity: 0.75;
color: #99FFFFFF;
font-size: 14px;
}
.item-right-part-wrapper {
flex-direction: row;
justify-content: flex-end;
align-items: center;
}
.item-right-text {
margin-right: 4px;
margin-left: 8px;
font-size: 14px;
opacity: 0.75;
}
.item-right-arrow {
width: 12px;
height: 24px;
object-fit: contain;
}
.line {
stroke-width: 1px;
width: 100%;
background-color: #33FFFFFF;
margin-left: 40px;
}
index.css: (Birds animation styling)
Code:
/* Birds animation */
.birds_animation {
object-fit: scale-down;
position: absolute;
top: 0px;
left: -200px;
animation-name: Fly;
animation-duration: 15s;
animation-timing-function: ease;
animation-iteration-count: infinite;
}
@keyframes Fly {
from {
transform: translateX(-200px);
}
to {
transform: translateX(1000px);
}
}
Layout:
Index.hml: (Location Loading Animation)
Code:
<div if="{{ isLocationLoading === true }}" class="container-location-loading">
<image src="common/images/location_animation.gif" class="location_loading"/>
</div>
Index.hml: (Location Loading Output):
Index.hml: (Location Error & Retry)
Code:
<div class="column" if="{{ isLocationLoading === false && isLocationError === true }}">
<text class="title">Location not fetch, please try again later.</text>
</div>
Index.hml: (Prayer timer UI)
Code:
<div class="container-sub prayer_bg {{ prayer_bg }}" if="{{ isLocationLoading === false && isLocationError === false }}">
<image src="common/images/birds.gif" class="birds_animation"></image>
<text class="current_time">{{ currentTime }}</text>
<image class="mosque" src="common/images/mosque.png"></image>
<text class="prayer_name">{{nextPrayer}} {{nextPrayerTime}}</text>
<text if="{{isShowTargetTime}}" class="remaining_timer">{{nextPrayerRemaining}}</text>
<button type="circle" class="button-circle"
ontouchend="showPrayer" icon="common/images/down-arrow.png"></button>
</div>
Index.hml: (Prayer timer UI Output)
Index.hml: (Dialog all Prayer times)
Code:
<dialog id="simpledialog" class="dialog-main">
<div class="dialog-div {{ dialog_bg }}">
<button type="circle" class="button-circle"
ontouchend="closePrayer" icon="common/images/close.png"></button>
<div class="inner-txt">
<div class="prayers-list">
<div class="list-items-left">
<list class="list-wrapper" initialindex="{{ initial_index_value }}">
<block for="{{ prayer_data }}">
<list-item class="list-items" @click="changeList($idx)" id="{{ $idx }}">
<div class="item-wrapper">
<div class="item-icon-wrapper">
<image class="item-icon" src="{{ $item.item_icon }}"></image>
</div>
<div class="item-name-description-wrapper">
<text class="item-name">{{ $item.item_name }}</text>
<text class="item-description">{{ $item.item_description }}</text>
</div>
<div class="item-right-part-wrapper">
<image class="item-right-arrow" src="common/images/right_arrow_dark_mode.png"></image>
</div>
</div>
<div class="divider-line">
<divider class="line"></divider>
</div>
</list-item>
</block>
</list>
</div>
</div>
</div>
</div>
</dialog>
Index.hml: (Dialog all Prayer times Ouput)
Index.hml: (Complete code)
Code:
<div class="container {{ (isLocationLoading === false) ? 'column' : '' }}">
<div if="{{ isLocationLoading === true }}" class="container-location-loading">
<image src="common/images/location_animation.gif" class="location_loading"/>
</div>
<div class="column" if="{{ isLocationLoading === false && isLocationError === true }}">
<text class="title">Location not fetch, please try again later.</text>
</div>
<div class="container-sub prayer_bg {{ prayer_bg }}" if="{{ isLocationLoading === false && isLocationError === false }}">
<image src="common/images/birds.gif" class="birds_animation"></image>
<text class="current_time">{{ currentTime }}</text>
<image class="mosque" src="common/images/mosque.png"></image>
<text class="prayer_name">{{nextPrayer}} {{nextPrayerTime}}</text>
<text if="{{isShowTargetTime}}" class="remaining_timer">{{nextPrayerRemaining}}</text>
<button type="circle" class="button-circle"
ontouchend="showPrayer" icon="common/images/down-arrow.png"></button>
</div>
<dialog id="simpledialog" class="dialog-main">
<div class="dialog-div {{ dialog_bg }}">
<button type="circle" class="button-circle"
ontouchend="closePrayer" icon="common/images/close.png"></button>
<div class="inner-txt">
<div class="prayers-list">
<div class="list-items-left">
<list class="list-wrapper" initialindex="{{ initial_index_value }}">
<block for="{{ prayer_data }}">
<list-item class="list-items" @click="changeList($idx)" id="{{ $idx }}">
<div class="item-wrapper">
<div class="item-icon-wrapper">
<image class="item-icon" src="{{ $item.item_icon }}"></image>
</div>
<div class="item-name-description-wrapper">
<text class="item-name">{{ $item.item_name }}</text>
<text class="item-description">{{ $item.item_description }}</text>
</div>
<div class="item-right-part-wrapper">
<image class="item-right-arrow" src="common/images/right_arrow_dark_mode.png"></image>
</div>
</div>
<div class="divider-line">
<divider class="line"></divider>
</div>
</list-item>
</block>
</list>
</div>
</div>
</div>
</div>
</dialog>
</div>
JS code:
index.js: (Structural - Code)
Code:
import geolocation from '@system.geolocation';
import adhan from 'adhan';
import moment from 'moment';
import tz from 'moment-timezone';
var tzlookup = require("tz-lookup");
const TAG = 'app_log [index]';
export default {}
index.js: (Data - Code)
Code:
data: {
config: {
isTesting: true,
locationCoordinates: {
"latitude": 24.65382908421087,
"longitude": 46.73552629355017
},
timeZone: "Asia/Riyadh",
fakeDateTime: "2021-06-12 18:13:01"
},
prayer_data: [
{
item_id: "fajr",
item_icon: "common/images/prayer_icon/fajr.png",
item_name: 'Fajr',
item_description: ''
},
{
item_id: "dhuhr",
item_icon: "common/images/prayer_icon/dhuhr.png",
item_name: 'Dhuhr',
item_description: ''
},
{
item_id: "asr",
item_icon: "common/images/prayer_icon/asr.png",
item_name: 'Asr',
item_description: ''
},
{
item_id: "maghrib",
item_icon: "common/images/prayer_icon/maghrib.png",
item_name: 'Maghrib',
item_description: ''
},
{
item_id: "isha",
item_icon: "common/images/prayer_icon/isha.png",
item_name: 'Isha',
item_description: ''
},
],
defaultPrayerSetting: {
allowNotification: false,
prayerSetting: {
Madhab: 'Shafi',
calculationMethod: 'UmmAlQura',
adjustments: {
fajr: "0",
sunrise: "0",
dhuhr: "0",
asr: "0",
maghrib: "0",
isha: "0"
}
}
},
initial_index_value: 2,
isLocationError: false,
isLocationLoading: true,
locationCoordinates: null,
currentTime: null,
timeUpdateTimer: null,
nextPrayer: 'Night',
nextPrayerTime: '',
nextPrayerRemaining: '',
isShowTargetTime: true,
date: moment().toDate(),
prayer_bg: "night_bg",
dialog_bg: "night_color"
},
index.js: (Common - Code)
Code:
onInit() {
console.log(TAG + 'onInit');
if(this.config.isTesting === true){
this.locationCoordinates = this.config.locationCoordinates
moment.tz.setDefault(this.config.timeZone);
this.date = moment(this.config.fakeDateTime).toDate();
}
this.currentTime = moment(this.date).format('ddd LT');
this.timeUpdateTimer = setInterval(this.updateTimer, 2000);
},
onReady() {
console.log(TAG + 'onReady');
var _this = this;
if (this.locationCoordinates !== null) {
setTimeout(() => {
_this.calculatePrayerTime();
_this.isLocationLoading = false;
_this.isLocationError = false;
}, 4000);
} else {
this.locationLoading().then(result => {
_this.locationCoordinates = result;
console.info(TAG + "Location: " + result);
_this.calculatePrayerTime();
_this.isLocationLoading = false;
_this.isLocationError = false;
}, error => {
console.info(TAG + "Location: error ->" + error);
_this.isLocationLoading = false;
_this.isLocationError = true;
});
}
},
onShow() {
console.log(TAG + 'onShow');
},
onDestroy() {
console.log(TAG + 'onDestroy');
clearInterval(this.timeUpdateTimer);
this.timeUpdateTimer = null;
clearInterval(this.countDownTimer);
this.countDownTimer = null;
},
updateTimer() {
this.currentTime = moment().format('ddd LT');
if(this.config.isTesting === true){
this.currentTime = moment(this.config.fakeDateTime).format('ddd LT');
}
},
index.js: (Dialog - Code)
Code:
showPrayer(e) {
this.$element('simpledialog').show();
},
closePrayer(e) {
this.$element('simpledialog').close();
},
index.js: (Location Fetching - Code)
Code:
locationLoading() {
return new Promise(function (resolve, reject) {
return geolocation.getLocation({
success: function (data) {
console.log('success get location data. latitude:' + data.latitude + 'long:' + data.longitude);
return resolve({
latitude: data.latitude,
longitude: data.longitude
});
},
fail: function (data, code) {
console.log('fail to get location. code:' + code + ', data:' + data);
return reject({
error: 'fail to get location. code:' + code + ', data:' + data
});
},
});
});
},
index.js: (Prayer times - Code)
Code:
calculatePrayerTime() {
var _this = this;
var prayerSettings = this.defaultPrayerSetting;
console.log(TAG + 'prayer_setting: getPrayerSetting() ' + JSON.stringify(prayerSettings));
if (prayerSettings !== null) {
this.prayerSettings = prayerSettings;
var params = this.getPrayerParameter(this.prayerSettings);
var coordinates = new adhan.Coordinates(_this.locationCoordinates.latitude, _this.locationCoordinates.longitude);
var date = this.date;
var prayerTimes = new adhan.PrayerTimes(coordinates, date, params);
console.info(TAG + 'locationCoordinates ' + JSON.stringify(_this.locationCoordinates));
var timezone = tzlookup(_this.locationCoordinates.latitude, _this.locationCoordinates.longitude)
if(this.config.isTesting === true){
timezone = this.config.timeZone
}
console.log(TAG + "timezone: " + timezone);
var nextPrayer = prayerTimes.nextPrayer(date);
var currentPrayer = prayerTimes.currentPrayer(date);
console.info(TAG + 'nextPrayer ' + nextPrayer);
console.info(TAG + 'currentPrayer ' + currentPrayer);
if (nextPrayer.toString() === "none") {
_this.isShowTargetTime = false
_this.nextPrayer = "Night";
_this.managePrayerTime(prayerTimes, timezone, nextPrayer, currentPrayer)
} else {
_this.isShowTargetTime = true
_this.nextPrayer = nextPrayer;
var nextPrayerTime = prayerTimes.timeForPrayer(nextPrayer);
_this.nextPrayerTime = moment(nextPrayerTime).tz(timezone).format('h:mm A');
_this.setTimeInfo(nextPrayerTime.getTime());
_this.managePrayerTime(prayerTimes, timezone, nextPrayer, currentPrayer)
}
}
},
managePrayerTime(prayerTimes, timezone, nextPrayer, currentPrayer) {
var _this = this;
var fajrTime = moment(prayerTimes.fajr).tz(timezone).format('h:mm A');
var sunriseTime = moment(prayerTimes.sunrise).tz(timezone).format('h:mm A');
var dhuhrTime = moment(prayerTimes.dhuhr).tz(timezone).format('h:mm A');
var asrTime = moment(prayerTimes.asr).tz(timezone).format('h:mm A');
var maghribTime = moment(prayerTimes.maghrib).tz(timezone).format('h:mm A');
var ishaTime = moment(prayerTimes.isha).tz(timezone).format('h:mm A');
_this.prayer_data.map(item => {
if (item.item_id === "fajr") {
item.item_description = fajrTime;
}
if (item.item_id === "dhuhr") {
item.item_description = dhuhrTime;
}
if (item.item_id === "asr") {
item.item_description = asrTime;
}
if (item.item_id === "maghrib") {
item.item_description = maghribTime;
}
if (item.item_id === "isha") {
item.item_description = ishaTime;
}
if (nextPrayer.toString().toLowerCase() === item.item_id) {
_this.prayer_bg = item.item_id + "_bg";
_this.dialog_bg = item.item_id + "_color";
}
});
},
getPrayerParameter(prayerSettings) {
var params = adhan.CalculationMethod.UmmAlQura();
var prayerSetting = prayerSettings.prayerSetting;
if (prayerSetting.calculationMethod === 'MuslimWorldLeagueMuslimWorldLeague') {
params = adhan.CalculationMethod.MuslimWorldLeague();
} else if (prayerSetting.calculationMethod === 'Egyptian') {
params = adhan.CalculationMethod.Egyptian();
} else if (prayerSetting.calculationMethod === 'Karachi') {
params = adhan.CalculationMethod.Karachi();
} else if (prayerSetting.calculationMethod === 'Dubai') {
params = adhan.CalculationMethod.Dubai();
} else if (prayerSetting.calculationMethod === 'MoonsightingCommittee') {
params = adhan.CalculationMethod.MoonsightingCommittee();
} else if (prayerSetting.calculationMethod === 'NorthAmerica') {
params = adhan.CalculationMethod.NorthAmerica();
} else if (prayerSetting.calculationMethod === 'Kuwait') {
params = adhan.CalculationMethod.Kuwait();
} else if (prayerSetting.calculationMethod === 'Qatar') {
params = adhan.CalculationMethod.Qatar();
} else if (prayerSetting.calculationMethod === 'Singapore') {
params = adhan.CalculationMethod.Singapore();
} else if (prayerSetting.calculationMethod === 'Other') {
params = adhan.CalculationMethod.Other();
}
if (prayerSetting.Madhab === 'Shafi') {
params.madhab = adhan.Madhab.Shafi;
} else {
params.madhab = adhan.Madhab.Hanafi;
}
params.adjustments.fajr = parseInt(prayerSetting.adjustments.fajr) || 0;
params.adjustments.sunrise = parseInt(prayerSetting.adjustments.sunrise) || 0;
params.adjustments.dhuhr = parseInt(prayerSetting.adjustments.dhuhr) || 0;
params.adjustments.asr = parseInt(prayerSetting.adjustments.asr) || 0;
params.adjustments.maghrib = parseInt(prayerSetting.adjustments.maghrib) || 0;
params.adjustments.isha = parseInt(prayerSetting.adjustments.isha) || 0;
return params;
},
index.js: (Count down timer - Code)
Code:
setTimeInfo(next_time) {
console.log(TAG + "next_time: " + next_time);
this.CaculateTime(next_time);
this.countDownTimer = setInterval(() => {
this.CaculateTime(next_time);
}, 1000);
},
CaculateTime(timeObj) {
var myDate = new Date();
if (this.config.isTesting === true) {
this.date = moment(this.date).add(500, 'milliseconds').toDate();
myDate = this.date;
}
let currentTime = myDate.getTime();
var targetTime = parseInt(timeObj);
var remainTime = parseInt(targetTime - currentTime);
if (remainTime > 0) {
this.isShowTargetTime = true;
this.setRemainTime(remainTime);
//this.setTargetTime(targetTime);
}
},
setRemainTime(remainTime) {
let days = this.addZero(Math.floor(remainTime / (24 * 3600 * 1000))); // Calculate the number of days
let leavel = remainTime % (24 * 3600 * 1000); // Time remaining after counting days
let hours = this.addZero(Math.floor(leavel / (3600 * 1000))); // Calculate the number of hours remaining
let leavel2 = leavel % (3600 * 1000); // Number of milliseconds remaining after calculating the remaining hours
let minutes = this.addZero(Math.floor(leavel2 / (60 * 1000))); // Calculate the number of minutes remaining
// Calculate the difference seconds.
let leavel3 = leavel2 % (60 * 1000); // Number of milliseconds remaining after minutes are calculated
let seconds = this.addZero(Math.round(leavel3 / 1000));
this.nextPrayerRemaining = hours + ':' + minutes + ':' + seconds;
},
setTargetTime(targetTime) {
var _this = this
var times = new Date(targetTime);
let date = times.toLocaleDateString(); //Gets the current date
var tempSetHours = times.getHours(); //Gets the current number of hours (0 - 23)
let hours = this.addZero(tempSetHours)
var tempSetMinutes = times.getMinutes(); //Gets the current number of minutes (0 - 59)
let minutes = this.addZero(tempSetMinutes)
var tempSetSeconds = times.getSeconds(); //Gets the current number of seconds (0 - 59)
let seconds = this.addZero(tempSetSeconds)
this.targetTime = `${hours}:${minutes}:${seconds}`;
},
addZero: function (i) {
return i < 10 ? "0" + i : i + "";
},
Prayer time Screen Notes:
To manage different state of application on single screen, we can able to use logic layouts using if=”true/false” or show=”true/false” conditions on containers.
For testing of custom date and time developer need to modify config data variable (isTesting: true).
For production we need to apply isTesting: false and relay on real date and time.
For prayer time parameter we implement adhan npm libraries, developer can have access on prayer time adjustment (plus/minus) in minutes.
For better management of prayer time parameters always use local storage (key/value), to save user preferences in storage and adjust prayer time.
5. Result
Tips & Tricks:
HarmonyOS JS project while installing any NPM libraries, in terminal must be on entry folder of your project module.
For testing of any date and time, developer need to modify config data variable (isTesting: true)
For production or realtime device, developer need to modify config data variable (isTesting: false)
For prayer time adjustment developer can modify defaultPrayerSetting data variable and could store user preference in storage.
Requesting some data from internet, you must need to add Internet permission in config.json file.
Fetching Location data, you must need to add Internet Permission in config.json file.
Use Dev Eco Studio Previewer to check the screen layout and design. Previewer is developer friendly to Hot release changes on fly.
For better management of big application it’s a good practice to centralize you common scripts and common style in common folder. Add images folder for complete application images.
In JS script when you make some variable, in callback functions you can store the reference of this to some variable and then call reference variable. Like var _this = this.
References:
HarmonyOS JS API Official Documentation: https://developer.harmonyos.com/en/docs/documentation/doc-references/js-apis-overview-0000001056361791
Geographic Location Documentation: https://developer.harmonyos.com/en/docs/documentation/doc-references/js-apis-system-location-0000000000626089
Conclusion:
Developers can able to develop real world Prayer time calculation application, while fetch user location data and using npm ready-made libraries. While developing application for HarmonyOS developer can get benefit for both JS and JAVA language. Benefit for developing JS based HarmonyOS application developer can able to use npm based libraries and can reduce development time.
Original Source
Useful sharing, thanks!!
Very useful. Thanks for sharing

Categories

Resources