The app menu of a quick app is forcibly displayed as stipulated in Quick App Specification 1070 and later versions. However, on some quick app pages, some content may be blocked by the app menu. For example, the sign-in entry is blocked by the app menu in the following figure. Although the menu is configured to be movable, users do not know that they can move it. As a result, user experience is affected.
{
"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"
}
The following solutions are provided to solve this problem:
Separating the menu from any content displayed
Hiding the menu
Adding a message indicating that the menu is movable
Solution 1: Separating the Menu from Any Content Displayed
Configure a title bar for a quick app to leave a blank row for the app menu. The disadvantage of this solution is that a row of space is wasted.
Open the manifest.json file and change the value of titleBar to true.
"display": {
"fullScreen": false,
"titleBar": "true",
"menu": false,
"menuBarData": {
"draggable": true
},
"orientation": "portrait"
}
The following figure shows the modification result.
Solution 2: Hiding the Menu
Provide the package name to Huawei and Huawei will specially configure the quick app not to display the menu. The disadvantages of this solution are as follows: Functions accessed from the quick app default menu, such as adding an icon to the home screen and accessing Quick App Center are lost. These functions help improve the user retention rate and enable users to quickly access Quick App Center to experience more services. Therefore, this solution is not recommended unless otherwise specified.
Solution 3: Adding a Message Indicating that the Menu Is Movable
Display the menu and prompt users that the menu is movable by referring to the mask layer used in native apps.
This solution is implemented as follows:
In the template code as follows, code in red defines the layout of the mask, and custom sub-components are used to define tipContent and emitEvt. The advantage of using custom components is that they make code clear, concise, and readable.
<import name="menu_tip" src="./menutip.ux"></import>
<template>
<div>
<menu_tip id=“tip” if={{menuTipshow}} tip-content={{menutipContent}} onemit-evt=“emitHideTipMenuView”> //tip component
</menu_tip>
<web src="{{loadUrl}}" trustedurl="{{list}}" onpagestart="onPageStart"
onpagefinish="onPageFinish" onmessage="onMessage"
ontitlereceive="onTitleReceive" onerror="onError"
wideviewport="true" overviewmodeinload="true"
useragent="Mozilla/5.0 (Linux; Android 10; FRO-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36"
id="web"
multiwindow="true" supportzoom="true" allowthirdpartycookies="{{allowThirdPartyCookies}}">
</web>
</div>
</template>
Call the Data Storage API of the quick app and use onInit() to query the value of menutipflag from the database. If the value is false, the quick app is opened for the first time by a user. Then the mask is displayed to the user.
onInit: function () {
this.getMenuTipFlag();
},
getMenuTipFlag() {
var that = this;
storage.get({
key: 'menutipflag',
success: function (data) {
console.log(" storage.get success data=" + data);
that.menutipflag = data;
},
fail: function (data, code) {
console.log(" storage.get fail, code = " + code);
}
});
},
Save related variables to the database at a proper time based on the mask GUI design and the service logic of the quick app. In this example, the mask is designed to disappear when a user taps I got it, and the value of menutipflag is set to true and is saved to the database.
saveTipFlag() {
this.menutipflag = true;
storage.set({
key: 'menutipflag',
value: 'true',
success: function (data) {
console.log("saveTipFlag");
},
fail: function (data, code) {
console.log("saveTipFlag fail, code = " + code);
}
})
},
In conclusion, solution 3 is the optimal solution among the three options because it avoids the disadvantages of solution 1 and solution 2, and can be used to add a prompt message for a component or a function on a quick app GUI.
Related
Map Kit has various SDKs and APIs. One of them is JavaScript API which is a solution for web applications and cross platforms.
What does Map Kit JavaScript API provide?
It provides the basic map display, map interaction, route planning, place search, geocoding, and other functions to meet requirements of most developers.
Which browsers are supported?
Currently, JavaScript APIs support the following browsers:
{
"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"
}
What are the prerequisites to use Map Kit JavaScript API?
Before using the service, you need to apply for an API key on the HUAWEI Developer website.
How to integrate basic capabilities?
First thing is to copy API Key from the developer console:
Code:
AppGallery Connect > Your App > Develop > Overview > App Information > API key
We need to provide the HUAWEI Map Kit API file. The API key must be encoded. You can encode it programatically or you can try out online tools to do it manually.
Code:
<script src="https://mapapi.cloud.huawei.com/mapjs/v1/api/js?callback=initMap&key=API KEY"></script>
Create map element in the body:
Code:
<div id="map"></div>
Initialize the map. The following sample code is to create a map with Paris as the center and a zoom level of 8:
Code:
function initMap() {
const mapOptions = {};
mapOptions.center = {lat: 48.856613, lng: 2.352222};
mapOptions.zoom = 8;
mapOptions.language='ENG';
const map = new HWMapJsSDK.HWMap(document.getElementById('map'), mapOptions);
}
Add a marker:
Code:
const mMarker = new HWMapJsSDK.HWMarker({
map,
position: {lat: 48.85, lng: 2.35},
label: 'A',
icon: {
opacity: 0.5
}
});
Show information window when clicking on marker:
Code:
const infoWindow = new HWMapJsSDK.HWInfoWindow({
map,
position: 10,
content: 'This is a InfoWindow.',
offset: [0, -40],
});
mMarker.addListener('click', () => {
infoWindow.open(mMarker);
});
Sample code is available on my GitHub page: /onurkenis/ionic-hms-map-demo
Hi,
Map kit Api will support navigation.how to show shortest path.
More information like this, you can visit HUAWEI Developer Forum
Original link: https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0201314254633580183&fid=0101188387844930001
In a previous post I’ve showed you how to make the account binding process to obtain the user’s Open Id. In this article I’m going to explain you how to use the Open Id to send push events to the users of your card ability.
Previous requirements
A card Ability
A developer Enterprise account
Huawei QuickApp IDE V2.5+
Huawei Ability Test Tool V1.0+
Your own server
Preparing the card
Open your card project in the Huawei QuickApp IDE and create a new widget by going to File > New widget.
Select a template for your card and click on "Ok"
{
"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"
}
New Widget Dialog
Use the selector to choose Config and then select your card
Card Selector
Use the + button to add parameters, you can define default values for testing.
Card Setup Dialog
Receiving the parameters
When you send push events, the params will be delivered to the card. To be able to render the card dynamically with the params, define an array of properties in your exports in the “script” part of your UX file.
Code:
<script>
const locales = {
zh: require('./i18n/zh.js'),
en: require('./i18n/en.js')
}
const device = require("@system.device");
import configuration from '@system.configuration'
const localeObject = configuration.getLocale();
let local = localeObject.language;
const $i18n = new I18n({ locale: local, messages: locales, fallbackLocale: 'en' });
module.exports = {
props: [
'title',
'big_text',
'small_text'
],
Modify the onInit function to receive the parameters using the next notation: this.property=params.paramName. Where property is one of the properties from the props array and paramName is the name you’ve defined in the config dialog.
Code:
onInit: function (params) {
this.title=params.title;
this.big_text=params.big_text;
this.small_text=params.small_text;
this.margin = Math.ceil(this.dpConvert(16));
try {
var windowLogicWidth = device.getInfoSync().windowLogicWidth;
this.width = (windowLogicWidth - (this.margin * 2));
this.height = Math.ceil((this.width / 16) * 9);
} catch (error) {
this.width = (750 - (this.margin * 2));
this.height = Math.ceil((this.width / 16) * 9);
}
}
Card Rendering
You can access to your properties from the template part to display your card according to the received params using the next notation: {{property}}
Code:
<template>
<div class="maptype_box" widgetid="12e7d1f4-68ec-4dd3-ab17-dde58e6c94c6">
<card_title id='title' title="{{title}}"></card_title>
<div class="maptype_content_box">
<image src="{{$t('message.url')}}" class="maptype_img" style="width: {{width}}px ;height:{{height}}px;"></image>
<div class="maptype_one">
<text class="maptype_text_one">{{big_text}}</text>
</div>
<div class="maptype_two">
<text class="maptype_textFour">{{small_text}}</text>
</div>
</div>
<card_bottom_2 dataSource="Source"></card_bottom_2>
</div>
</template>
Card update
Go to Build > Run release to create a signed RPK package of your card. Don’t forget to update the version name and version number.
Card Build Dialog
Once the process is complete, open the AGC console go to “My apps” and select your card. If you don’t have a card in AGC, you can click on “new app” and select RPK as package type.
App Gallery Connect
From version information, scroll down to software version and then click on “Software packages”.
Package Admin Dialog
Click on upload and select your generated package
Upload Progress Dialog
That’s all for AGC, let’s make the ability configuration.
This is not the end. For full content, you can visit https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0201314254633580183&fid=0101188387844930001
What does RPK stands for ?
More information like this, you can visit HUAWEI Developer Forum
The app menu of a quick app is forcibly displayed as stipulated in Quick App Specification 1070 and later versions. However, on some quick app pages, some content may be blocked by the app menu. For example, the sign-in entry is blocked by the app menu in the following figure. Although the menu is configured to be movable, users do not know that they can move it. As a result, user experience is affected.
{
"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"
}
The following solutions are provided to solve this problem:
Separating the menu from any content displayed
Hiding the menu
Adding a message indicating that the menu is movable
Solution 1: Separating the Menu from Any Content Displayed
Configure a title bar for a quick app to leave a blank row for the app menu. The disadvantage of this solution is that a row of space is wasted.
Open the manifest.json file and change the value of titleBar to true.
Code:
"display": {
"fullScreen": false,
"titleBar": "true",
"menu": false,
"menuBarData": {
"draggable": true
},
"orientation": "portrait"
}
The following figure shows the modification result.
Solution 2: Hiding the Menu
Provide the package name to Huawei and Huawei will specially configure the quick app not to display the menu. The disadvantages of this solution are as follows: Functions accessed from the quick app default menu, such as adding an icon to the home screen and accessing Quick App Center are lost. These functions help improve the user retention rate and enable users to quickly access Quick App Center to experience more services. Therefore, this solution is not recommended unless otherwise specified.
Solution 3: Adding a Message Indicating that the Menu Is Movable
Display the menu and prompt users that the menu is movable by referring to the mask layer used in native apps.
This solution is implemented as follows:
In the template code as follows, code in red defines the layout of the mask, and custom sub-components are used to define tipContent and emitEvt. The advantage of using custom components is that they make code clear, concise, and readable.
Code:
<import name="menu_tip" src="./menutip.ux"></import>
<template>
<div>
<menu_tip id=“tip” if={{menuTipshow}} tip-content={{menutipContent}} onemit-evt=“emitHideTipMenuView”> //tip component
</menu_tip>
<web src="{{loadUrl}}" trustedurl="{{list}}" onpagestart="onPageStart"
onpagefinish="onPageFinish" onmessage="onMessage"
ontitlereceive="onTitleReceive" onerror="onError"
wideviewport="true" overviewmodeinload="true"
useragent="Mozilla/5.0 (Linux; Android 10; FRO-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36"
id="web"
multiwindow="true" supportzoom="true" allowthirdpartycookies="{{allowThirdPartyCookies}}">
</web>
</div>
</template>
Call the Data Storage API of the quick app and use onInit() to query the value of menutipflag from the database. If the value is false, the quick app is opened for the first time by a user. Then the mask is displayed to the user.
Code:
onInit: function () {
this.getMenuTipFlag();
},
getMenuTipFlag() {
var that = this;
storage.get({
key: 'menutipflag',
success: function (data) {
console.log(" storage.get success data=" + data);
that.menutipflag = data;
},
fail: function (data, code) {
console.log(" storage.get fail, code = " + code);
}
});
},
Save related variables to the database at a proper time based on the mask GUI design and the service logic of the quick app. In this example, the mask is designed to disappear when a user taps I got it, and the value of menutipflag is set to true and is saved to the database.
Code:
saveTipFlag() {
this.menutipflag = true;
storage.set({
key: 'menutipflag',
value: 'true',
success: function (data) {
console.log("saveTipFlag");
},
fail: function (data, code) {
console.log("saveTipFlag fail, code = " + code);
}
})
},
In conclusion, solution 3 is the optimal solution among the three options because it avoids the disadvantages of solution 1 and solution 2, and can be used to add a prompt message for a component or a function on a quick app GUI.
After the quick app web component is used to pack an HTML5 app into a quick app, the original web page does not provide the function of returning to the home page. In an HTML5 quick app, users want to have an entry for returning to the home page when browsing any HTML5 page.
To implement this requirement, perform the following steps:
1. Define the loadUrl variable under data in the page script. This variable is used to store the URL of the HTML5 web page. In this demo, the Huawei official website is used as the home page entry.
HTML:
export default {
props: ['websrc'],
data: {
title: "",
// TODO Replace the link to the H5 app
loadUrl: "http://www.huawei.com/en",
allowThirdPartyCookies: true,
//Attribute supportzoom, indicates whether the H5 page can be zoomed with gestures.
supportZoom: true,
wideViewport: true,
overViewModeLoad: true,
},
}
2. Modify template code.
Bind the src attribute of web in template to the variable loadUrl defined in step 1.
Listen to the pagestart event of the web component, that is, onpagestart in the code.
Add the entry layout of returning to the home page, which needs product design. This demo uses an image as an example.
The sample code is as follows. Pay attention to the text in red to see the modification points.
HTML:
<template>
<div class="doc-page">
<image src="/Common/main.png" onclick="goMain"></image>
<web class="web-page" src="{{loadUrl}}" trustedurl="{{list}}" onpagestart="onPageStart" onpagefinish="onPageFinish"
onmessage="onMessage" ontitlereceive="onTitleReceive" onerror="onError" id="web" supportzoom="{{supportZoom}}"
wideviewport="{{wideViewport}}}" overviewmodeinload="{{overViewModeLoad}}" useragent="{{userAgent}}"
Precautions:
The event callback methods goMain and onPageStart in the preceding code must be defined in the script.
The value of src in the image component must be replaced with the actual image path in the project.
3. Modify the code in the script. The following code needs to be modified:
In the callback method onPageStart of the web component, assign the value of url (indicating the URL of the current page) to loadUrl.
HTML:
onPageStart(e) {
console.info('pagestart: ' + e.url)
this.loadUrl=e.url;
},
l In the goMain method, assign the home page URL to loadUrl.
HTML:
goMain: function () {
console.log("goMain :");
this.loadUrl = "https://www.huawei.com/en";
},
Then, you can click HUAWEI on the screen to go to the Huawei official website.
{
"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"
}
Recently, I found that Remote Configuration of AppGallery Connect now supports the web platform, which I’ve long been waiting for. Previously, it has only been supported on Android, but now it can be applied to web apps. For details about the integration demo, visit GitHub.
Integration Steps1. Enable the service.
a) Sign in to AppGallery Connect and create a web app.
b) Enable Remote Configuration.
c) Click New parameter and set parameters.
{
"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"
}
2. Integrate the SDK.
a) Run the following command:
Code:
npm install –save @agconnect/remoteconfig
3. Implement the functions.
a) Obtain the local configuration parameters.
Create a local configuration map in the Vue.
Apply the local settings.
JavaScript:
export function applyDefault(map) {
return agconnect.remoteConfig().applyDefault(map);
}
b) Call the fetch API to fetch parameter values from the cloud.
JavaScript:
export async function fetch() {
return agconnect.remoteConfig().fetch().then(() => {
return Promise.resolve();
}).catch((err) => {
return Promise.reject(err);
});
}
c) Apply the parameter values to the local host immediately or upon the next launch.
1. Applying the parameter values immediately:
Call the apply API.
JavaScript:
export function apply() {
return agconnect
.remoteConfig().apply().then((res) => {
return Promise.resolve(res);
}
).catch(error => {
return Promise.reject(error);
});
}
2. Applying the parameter values upon the next launch:
Call the applyLastFetch API to apply the last fetched parameter values.
JavaScript:
// Load configurations.
export function applyLastLoad() {
return agconnect
.remoteConfig().loadLastFetched().then(async (res) => {
if (res) {
await agconnect.remoteConfig().apply(res);
}
return Promise.resolve(res);
}
).catch(error => {
return Promise.reject(error);
});
}
d) Obtain all parameter values from the local host and cloud.
Call the getMergedAll API to obtain all parameter values.
JavaScript:
export function getMergedAll() {
return agconnect.remoteConfig().getMergedAll();
}
e) Call the clearAll API to clear all parameter values.
JavaScript:
export function clearAll() {
agconnect.remoteConfig().clearAll();
}
References:
Demo:
https://github.com/AppGalleryConnect/agc-demos/tree/main/Web/agc-romoteconfig-demo-javascript
Remote Configuration Development Guide:
https://developer.huawei.com/consum...-remoteconfig-web-getstarted-0000001056501223
Well explained, Using remote config can we change UI elements.
What is the basic use of Remote Config in web?
sujith.e said:
Well explained, Using remote config can we change UI elements.
Click to expand...
Click to collapse
yes, that is convenient for developers.
ask011 said:
What is the basic use of Remote Config in web?
Click to expand...
Click to collapse
You can flexibly modify the behavior and appearance of applications by changing cloud parameter values.