aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEgor Nemtsev <enemtsev@luxoft.com>2020-02-21 19:21:45 +0300
committerEgor Nemtsev <enemtsev@luxoft.com>2020-04-06 13:11:34 +0000
commitec183828f827220527266cf64d2d73b46cdb4d24 (patch)
treeda781a393262163116720180c6eb4b35ed2defa0
parent35f65a9ff013d51f057f458ceb5467ca5dafdd4b (diff)
[downloads] move to state observer/controller
Task-number: AUTOSUITE-1486 Change-Id: I9ac110f93691e9345f31ac791f21581293169e8b Reviewed-by: Grigorii Zimin <gzimin@luxoft.com>
-rw-r--r--apps/com.pelagicore.downloads/controls/DownloadAppList.qml58
-rw-r--r--apps/com.pelagicore.downloads/controls/DownloadsToolsColumn.qml9
-rw-r--r--apps/com.pelagicore.downloads/stores/DownloadsStates.qml311
-rw-r--r--apps/com.pelagicore.downloads/stores/DownloadsStore.qml82
-rw-r--r--apps/com.pelagicore.downloads/stores/JSONBackend.js29
-rw-r--r--apps/com.pelagicore.downloads/stores/JSONModel.qml6
-rw-r--r--apps/com.pelagicore.downloads/stores/ServerConfig.qml70
-rw-r--r--apps/com.pelagicore.downloads/views/DownloadsView.qml331
-rw-r--r--imports_shared/assets/translations/ar_MA.ts33
-rw-r--r--imports_shared/assets/translations/cs_CZ.ts33
-rw-r--r--imports_shared/assets/translations/de_DE.ts33
-rw-r--r--imports_shared/assets/translations/en_GB.ts35
-rw-r--r--imports_shared/assets/translations/en_US.ts35
-rw-r--r--imports_shared/assets/translations/ja_JP.ts33
-rw-r--r--imports_shared/assets/translations/ko_KR.ts33
-rw-r--r--imports_shared/assets/translations/zh_CN.ts33
16 files changed, 960 insertions, 204 deletions
diff --git a/apps/com.pelagicore.downloads/controls/DownloadAppList.qml b/apps/com.pelagicore.downloads/controls/DownloadAppList.qml
index 59ea9742..f082f3e5 100644
--- a/apps/com.pelagicore.downloads/controls/DownloadAppList.qml
+++ b/apps/com.pelagicore.downloads/controls/DownloadAppList.qml
@@ -41,49 +41,75 @@ import shared.Sizes 1.0
ListView {
id: root
- property var store
+ property string appServerUrl
+ property string cpuArch
+ property var applicationModel
+ property real currentInstallationProgress
signal toolClicked(string appId, string appName)
+ signal appClicked(string appId)
- model: root.store.applicationModel
+ function refreshAppsInfo(isPackageInstalledByPackageControllerFunc,
+ isPackageBuiltInFunc, getInstalledPackageSizeTextFunc) {
+ d.installedPackagesChanged(isPackageInstalledByPackageControllerFunc,
+ isPackageBuiltInFunc, getInstalledPackageSizeTextFunc);
+ }
+
+ QtObject {
+ id: d
+
+ signal installedPackagesChanged(var isPackageInstalledByPackageControllerFunc,
+ var isPackageBuiltInFunc,
+ var getInstalledPackageSizeTextFunc)
+ }
+
+ model: root.applicationModel
currentIndex: -1
delegate: ListItemProgress {
id: delegatedItem
objectName: "itemDownloadApp_" + model.id
- property bool isInstalled: root.store.isPackageInstalledByPackageController(model.id)
- width: Sizes.dp(720)
- height: Sizes.dp(100)
- icon.source: root.store.appServerUrl
- + "/app/icon?id=" + model.id
- + "&architecture=" + store.cpuArch
+ property bool isInstalled: model.isInstalled
+ property string packageSizeText: model.packageSizeText
+ property bool packageBuiltIn: model.packageBuiltIn
+
+ width: Sizes.dp(720); height: Sizes.dp(100)
+ icon.source: root.appServerUrl + "/app/icon?id=" + model.id
+ + "&architecture=" + root.cpuArch
text: model.name
subText: model.id
- secondaryText: delegatedItem.isInstalled ? root.store.getInstalledPackageSizeText(model.id)
- : ( root.store.isPackageBuiltIn(model.id) ?
+ secondaryText: delegatedItem.isInstalled ? delegatedItem.packageSizeText
+ : ( delegatedItem.packageBuiltIn ?
qsTr("update") : "" )
cancelSymbol: delegatedItem.isInstalled ? "ic-close" : "ic-download_OFF"
- value: root.store.currentInstallationProgress
+ value: root.currentInstallationProgress
onValueChanged: {
if (value === 1.0) {
root.currentIndex = -1;
}
}
- progressVisible: root.currentIndex === index && root.store.currentInstallationProgress < 1.0
+ progressVisible: root.currentIndex === index && root.currentInstallationProgress < 1.0
onProgressCanceled: {
if (!delegatedItem.isInstalled) {
root.currentIndex = index;
}
root.toolClicked(model.id, model.name);
}
- onClicked: root.store.tryStartApp(model.id)
+ onClicked: root.appClicked(model.id)
Connections {
- target: root.store
+ target: d
onInstalledPackagesChanged: {
- isInstalled = root.store.isPackageInstalledByPackageController(model.id)
+ // functions are passed as parameters to signal
+ model.isInstalled = isPackageInstalledByPackageControllerFunc(model.id);
+ if (isInstalled) {
+ model.packageBuiltIn = isPackageBuiltInFunc(model.id);
+ model.packageSizeText = getInstalledPackageSizeTextFunc(model.id);
+ } else {
+ model.packageBuiltIn = false;
+ model.packageSizeText = "";
+ }
}
}
-
}
}
diff --git a/apps/com.pelagicore.downloads/controls/DownloadsToolsColumn.qml b/apps/com.pelagicore.downloads/controls/DownloadsToolsColumn.qml
index 6795797b..95dea832 100644
--- a/apps/com.pelagicore.downloads/controls/DownloadsToolsColumn.qml
+++ b/apps/com.pelagicore.downloads/controls/DownloadsToolsColumn.qml
@@ -34,9 +34,6 @@ import QtQuick 2.10
import QtQuick.Controls 2.3
import shared.utils 1.0
import shared.Sizes 1.0
-import QtQuick.Controls 2.2
-import QtQuick.Layouts 1.2
-import QtQml.Models 2.2
import shared.controls 1.0
@@ -44,8 +41,8 @@ Item {
id: root
property alias model: toolsColumn.model
- property int currentIndex: 0
property string serverUrl
+
signal toolClicked(int index)
ToolsColumn {
@@ -55,8 +52,6 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: Sizes.dp(53)
- onCurrentIndexChanged: {
- root.toolClicked(currentIndex)
- }
+ onClicked: root.toolClicked(currentIndex)
}
}
diff --git a/apps/com.pelagicore.downloads/stores/DownloadsStates.qml b/apps/com.pelagicore.downloads/stores/DownloadsStates.qml
new file mode 100644
index 00000000..69db4c7c
--- /dev/null
+++ b/apps/com.pelagicore.downloads/stores/DownloadsStates.qml
@@ -0,0 +1,311 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Luxoft Sweden AB
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune 3 UI.
+**
+** $QT_BEGIN_LICENSE:GPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import QtQml.StateMachine 1.0 as DSM
+
+import "JSONBackend.js" as JSONBackend
+import shared.com.pelagicore.systeminfo 1.0
+import shared.utils 1.0
+
+DSM.StateMachine {
+ running: true
+ initialState: networkConnectedState
+
+ property alias noNetwork: noNetworkState
+ property alias networkConnected: networkConnectedState
+ property alias connectingToServer: connectingToServerState
+ property alias connectedError: connectedErrorState
+ property alias connectedToServer: connectedToServerState
+ property alias fetchingApps: fetchingAppsState
+ property alias fetchingCategories: fetchingCategoriesState
+ property alias appsLoaded: appsLoadedState
+ property alias serverOnMaintance: serverOnMaintanceState
+ property alias serverNA: serverNAState
+ property alias loggingIn: loggingInState
+ property alias categoriesLoaded: categoriesLoadedState
+ property alias checkServerError: checkServerErrorState
+
+ property SystemInfo sysinfo
+ property ServerConfig appStoreConfig
+ property JSONModel jsonCategoryModel
+ property JSONModel jsonAppModel
+
+ DSM.State {
+ id: noNetworkState
+
+ DSM.SignalTransition {
+ targetState: networkConnectedState
+ signal: sysinfo.onInternetAccessChanged
+ guard: sysinfo.internetAccess
+ }
+
+ DSM.SignalTransition {
+ targetState: networkConnectedState
+ signal: sysinfo.onConnectedChanged
+ guard: sysinfo.connected
+ }
+ }
+
+ DSM.State {
+ id: networkConnectedState
+
+ initialState: connectingToServerState
+ onEntered: { appStoreConfig.reconnectionAttempt = 0; }
+
+ DSM.SignalTransition {
+ targetState: noNetworkState
+ signal: sysinfo.onConnectedChanged
+ guard: !sysinfo.connected
+ }
+
+ DSM.SignalTransition {
+ targetState: noNetworkState
+ signal: sysinfo.onInternetAccessChanged
+ guard: !sysinfo.internetAccess
+ }
+
+ DSM.State {
+ id: connectingToServerState
+
+ DSM.SignalTransition {
+ targetState: connectedToServerState
+ signal: appStoreConfig.connectionSuccessful
+ }
+ DSM.SignalTransition {
+ targetState: checkServerErrorState
+ signal: appStoreConfig.connectionFailed
+ }
+ DSM.SignalTransition {
+ targetState: serverOnMaintanceState
+ signal: appStoreConfig.serverOnMaintanceState
+ }
+ }
+
+ DSM.State {
+ id: serverOnMaintanceState
+
+ DSM.SignalTransition {
+ targetState: connectingToServerState
+ signal: appStoreConfig.tryConnectToServer
+ }
+ }
+
+ DSM.State {
+ id: checkServerErrorState
+
+ signal noMoreAttempts()
+
+ onEntered: {
+ if (appStoreConfig.reconnectionAttempt < appStoreConfig.maxReconnectCount) {
+ appStoreConfig.reconnectionAttempt += 1;
+ retryTimer.start();
+ } else {
+ noMoreAttempts();
+ }
+ }
+
+ Timer {
+ id: retryTimer
+ interval: 2000
+ onTriggered: {
+ console.warn(Logging.apps, "Neptune 3 UI::DownloadsStates - Retry Connection",
+ appStoreConfig.reconnectionAttempt, "of",
+ appStoreConfig.maxReconnectCount);
+ appStoreConfig.checkServer();
+ }
+ }
+
+ DSM.SignalTransition {
+ targetState: connectingToServerState
+ signal: appStoreConfig.tryConnectToServer
+ }
+
+ DSM.SignalTransition {
+ targetState: serverNAState
+ signal: checkServerErrorState.noMoreAttempts
+ }
+ }
+
+ DSM.State {
+ id: serverNAState
+
+ onEntered: { appStoreConfig.reconnectionAttempt = 0; }
+
+ DSM.SignalTransition {
+ targetState: connectingToServerState
+ signal: appStoreConfig.tryConnectToServer
+ }
+ }
+
+ DSM.State {
+ id: connectedToServerState
+
+ initialState: loggingInState
+ onEntered: { appStoreConfig.reconnectionAttempt = 0; }
+
+ DSM.SignalTransition {
+ targetState: checkServerErrorState
+ signal: appStoreConfig.connectionFailed
+ }
+
+ DSM.State {
+ id: loggingInState
+
+ onEntered: { appStoreConfig.login(); }
+
+ Connections {
+ target: appStoreConfig
+ onLoginFailed: {
+ connectedErrorState.errorText = qsTr("Login Failed");
+ }
+ }
+
+ DSM.SignalTransition {
+ targetState: connectedErrorState
+ signal: appStoreConfig.loginFailed
+ }
+
+ DSM.SignalTransition {
+ targetState: loggedInState
+ signal: appStoreConfig.loginSuccessful
+ }
+ }
+
+ DSM.State {
+ id: connectedErrorState
+
+ property string errorText: ""
+
+ DSM.SignalTransition {
+ targetState: connectingToServerState
+ signal: appStoreConfig.tryConnectToServer
+ }
+ }
+
+ DSM.State {
+ id: loggedInState
+
+ initialState: fetchingCategoriesState
+
+ DSM.State {
+ id: fetchingCategoriesState
+
+ onEntered: { jsonCategoryModel.refresh(); }
+
+ Connections {
+ target: jsonCategoryModel
+ onStatusChanged: {
+ if (jsonCategoryModel.status === "error")
+ connectedErrorState.errorText = qsTr("Fetching categories error");
+ }
+ }
+
+ DSM.SignalTransition {
+ targetState: categoriesLoadedState
+ signal: jsonCategoryModel.onStatusChanged
+ guard: jsonCategoryModel.status === "ready"
+ }
+
+ DSM.SignalTransition {
+ targetState: connectedErrorState
+ signal: jsonCategoryModel.onStatusChanged
+ guard: jsonCategoryModel.status === "error"
+ }
+ }
+
+ DSM.State {
+ id: categoriesLoadedState
+
+ onEntered: {
+ if (jsonCategoryModel.count > 0) {
+ jsonAppModel.categoryId = jsonCategoryModel.get(0).id;
+ jsonAppModel.refresh()
+ } else {
+ jsonCategoryModel.emptyCategoriesList()
+ }
+ }
+
+ DSM.SignalTransition {
+ targetState: fetchingAppsState
+ signal: jsonAppModel.onStatusChanged
+ guard: jsonAppModel.status === "loading"
+ }
+
+ DSM.SignalTransition {
+ targetState: appsLoadedState
+ signal: jsonAppModel.onStatusChanged
+ guard: jsonAppModel.status === "ready"
+ }
+
+ DSM.SignalTransition {
+ targetState: appsLoadedState
+ signal: jsonCategoryModel.onEmptyCategoriesList
+ }
+ }
+
+ DSM.State {
+ id: fetchingAppsState
+
+ Connections {
+ target: jsonAppModel
+ onStatusChanged: {
+ if (jsonAppModel.status === "error")
+ connectedErrorState.errorText = qsTr("Fetching apps error");
+ }
+ }
+
+ DSM.SignalTransition {
+ targetState: appsLoadedState
+ signal: jsonAppModel.onStatusChanged
+ guard: jsonAppModel.status === "ready"
+ }
+
+ DSM.SignalTransition {
+ targetState: connectedErrorState
+ signal: jsonAppModel.onStatusChanged
+ guard: jsonAppModel.status === "error"
+ }
+ }
+
+ DSM.State {
+ id: appsLoadedState
+
+ DSM.SignalTransition {
+ targetState: fetchingAppsState
+ signal: jsonAppModel.onStatusChanged
+ guard: jsonAppModel.status === "loading"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/apps/com.pelagicore.downloads/stores/DownloadsStore.qml b/apps/com.pelagicore.downloads/stores/DownloadsStore.qml
index af76482b..98728495 100644
--- a/apps/com.pelagicore.downloads/stores/DownloadsStore.qml
+++ b/apps/com.pelagicore.downloads/stores/DownloadsStore.qml
@@ -46,13 +46,9 @@ Item {
property alias appStoreConfig: appStoreConfig
property string appServerUrl: appStoreConfig.serverUrl
property alias cpuArch: appStoreConfig.cpuArch
- property int categoryid: 0
property string filter: ""
property real currentInstallationProgress: 0.0
readonly property var installedPackages: PackageManager.packageIds()
- readonly property bool isOnline: appStoreConfig.serverOnline
- readonly property bool isReconnecting: appStoreConfig.isReconnecting
- property bool isBusy: false// appModel.count == 0 && isOnline
readonly property IntentHandler intentHandler: IntentHandler {
intentIds: "activate-app"
onRequestReceived: {
@@ -60,9 +56,14 @@ Item {
request.sendReply({ "done": true })
}
}
+ property DownloadsStates downloadsStates: DownloadsStates {
+ sysinfo: sysinfo
+ appStoreConfig: appStoreConfig
+ jsonCategoryModel: jsonCategoryModel
+ jsonAppModel: jsonAppModel
+ }
signal requestRaiseAppReceived()
- signal categoryListReady()
function formatBytes(bytes) {
if (bytes < 1024) return qsTr("%1 Bytes").arg(bytes);
@@ -78,23 +79,26 @@ Item {
var url = appStoreConfig.serverUrl + "/app/purchase";
var data = {"id": packageId, "device_id" : "00-11-22-33-44-55" };
+ var icon = root.appServerUrl
+ + "/app/icon?id=" + packageId
+ + "&architecture=" + root.cpuArch;
JSONBackend.serverCall(url, data, function(data) {
if (data !== 0) {
if (data.status === "ok") {
console.log(Logging.apps, "start downloading");
- var icon = root.appServerUrl
- + "/app/icon?id=" + packageId
- + "&architecture=" + root.cpuArch;
var installID = PackageManager.startPackageInstallation(data.url);
PackageManager.acknowledgePackageInstallation(installID);
} else if (data.status === "fail" && data.error === "not-logged-in"){
- console.log(Logging.apps, ":::AppStoreServer::: not logged in");
+ console.warn(Logging.apps, ":::AppStoreServer::: not logged in");
showNotification(qsTr("System is not logged in"), qsTr("System is not logged in"), icon);
} else {
- console.log(Logging.apps, ":::AppStoreServer::: download failed: " + data.error);
+ console.warn(Logging.apps, ":::AppStoreServer::: download failed: " + data.error);
showNotification(qsTr("%1 Download Failed").arg(name), qsTr("%1 download failed").arg(name), icon);
}
+ } else {
+ console.warn(Logging.apps, ":::AppStoreServer::: download failed");
+ showNotification(qsTr("%1 Download Failed").arg(name), qsTr("%1 download failed").arg(name), icon);
}
})
}
@@ -106,7 +110,7 @@ Item {
function isPackageBuiltIn(packageId) {
var pkg = PackageManager.package(packageId);
- return pkg && pkg.builtIn;
+ return !!pkg && pkg.builtIn;
}
function isPackageBusy(packageId) {
@@ -140,12 +144,12 @@ Item {
function selectCategory(index) {
var category = categoryListModel.get(index);
if (category) {
- root.categoryid = category.id;
+ jsonAppModel.categoryId = category.id;
} else {
- root.categoryid = 1;
+ jsonAppModel.categoryId = 1;
}
- appModel.refresh();
+ jsonAppModel.refresh();
}
function showNotification(summary, body, icon) {
@@ -162,7 +166,7 @@ Item {
if (isPackageBuiltIn(packageId)) {
return qsTr("built-in");
} else {
- console.warn("Uknown app package size: -1", id);
+ console.warn("Uknown app package size: -1", packageId);
return qsTr("Unknown size");
}
}
@@ -290,21 +294,10 @@ Item {
ServerConfig {
id: appStoreConfig
cpuArch: sysinfo.cpu + "-" + sysinfo.kernel
- property bool initialized: false
- onLoginSuccessful: {
- if (!initialized) {
- categoryListModel.refresh();
- initialized = true;
- }
- }
}
ListModel {
id: categoryListModel
-
- function refresh() {
- jsonCategoryModel.refresh();
- }
}
JSONModel {
@@ -312,6 +305,11 @@ Item {
url: appStoreConfig.serverUrl + "/category/list"
onStatusChanged: {
+ if (status === "loading" && categoryListModel.count > 0) {
+ categoryListModel.clear();
+ jsonAppModel.categoryId = 0;
+ }
+
if (status === "ready") {
categoryListModel.clear();
for (let i = 0; i < jsonCategoryModel.count; ++i) {
@@ -322,14 +320,40 @@ Item {
"sourceOff": root.appServerUrl + "/category/icon?id=" + cat.id,
});
}
- root.categoryListReady();
}
}
}
- JSONModel {
+ ListModel {
id: appModel
+ }
+
+ JSONModel {
+ id: jsonAppModel
+
+ property int categoryId: 0
url: appStoreConfig.serverUrl + "/app/list"
- data: root.categoryid >= 0 ? ({ "filter" : root.filter , "category_id" : root.categoryid}) : ({ "filter" : root.filter})
+ data: jsonAppModel.categoryId >= 0 ? ({ "filter" : root.filter ,
+ "category_id" : jsonAppModel.categoryId})
+ : ({ "filter" : root.filter})
+ onStatusChanged: {
+ appModel.clear();
+
+ if (status === "ready") {
+ let appList = [];
+ for (let i = 0; i < jsonAppModel.count; ++i) {
+ let app = jsonAppModel.get(i);
+ let isInstalled = isPackageInstalledByPackageController(app.id)
+ appList.push({
+ "id": app.id,
+ "name": app.name,
+ "isInstalled": isInstalled,
+ "packageSizeText": isInstalled ? getInstalledPackageSizeText(app.id) : "",
+ "packageBuiltIn": isInstalled ? isPackageBuiltIn(app.id) : false
+ });
+ }
+ appModel.append(appList)
+ }
+ }
}
}
diff --git a/apps/com.pelagicore.downloads/stores/JSONBackend.js b/apps/com.pelagicore.downloads/stores/JSONBackend.js
index bd08c54c..1aa58ee3 100644
--- a/apps/com.pelagicore.downloads/stores/JSONBackend.js
+++ b/apps/com.pelagicore.downloads/stores/JSONBackend.js
@@ -42,7 +42,7 @@ function setErrorFunction(func) {
}
function serverCall(url, data, dataReadyFunction) {
- var i = 0
+ var i = 0;
for (var key in data)
{
if (i === 0) {
@@ -50,26 +50,35 @@ function serverCall(url, data, dataReadyFunction) {
} else {
url += "&" + key+ "=" + data[key];
}
- i++
+ i++;
}
var xhr = new XMLHttpRequest();
- console.log(Utils.Logging.sysui, "HTTP GET to " + url);
+ console.log(Utils.Logging.apps, "HTTP GET to " + url);
xhr.open("GET", url);
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.responseText !== "") {
- errorCounter = 0
- var data = JSON.parse(xhr.responseText);
- return dataReadyFunction(data)
+ errorCounter = 0;
+ var data = 0;
+
+ try {
+ data = JSON.parse(xhr.responseText);
+ } catch(e) {
+ console.warn(Utils.Logging.apps, "JSONBackend error parsing answer:",
+ xhr.responseText);
+ }
+
+ return dataReadyFunction(data);
} else {
- console.log(Utils.Logging.sysui, "JSONBackend: " + xhr.status + xhr.statusText)
- errorCounter++
+ console.warn(Utils.Logging.apps, "JSONBackend: status:", xhr.status,
+ xhr.statusText);
+ errorCounter++;
if (errorCounter >= 3 && errorFunc) {
- errorFunc()
+ errorFunc();
}
- return dataReadyFunction(0)
+ return dataReadyFunction(0);
}
}
}
diff --git a/apps/com.pelagicore.downloads/stores/JSONModel.qml b/apps/com.pelagicore.downloads/stores/JSONModel.qml
index 2b3cb842..e18cf4ef 100644
--- a/apps/com.pelagicore.downloads/stores/JSONModel.qml
+++ b/apps/com.pelagicore.downloads/stores/JSONModel.qml
@@ -45,6 +45,12 @@ ListModel {
status = "loading"
clear();
JSONBackend.serverCall(url, data, function(data) {
+ if (data === 0) {
+ status = "error";
+
+ return;
+ }
+
for (var i = 0; i < data.length; i++) {
var entry = data[i];
append(entry);
diff --git a/apps/com.pelagicore.downloads/stores/ServerConfig.qml b/apps/com.pelagicore.downloads/stores/ServerConfig.qml
index 46c527f4..666b215b 100644
--- a/apps/com.pelagicore.downloads/stores/ServerConfig.qml
+++ b/apps/com.pelagicore.downloads/stores/ServerConfig.qml
@@ -39,88 +39,72 @@ import shared.utils 1.0
QtObject {
id: root
- property bool serverOnline: false
- property string serverReason
property string cpuArch
property string serverUrl: ApplicationManager.systemProperties.appStoreServerUrl
property string userName: ApplicationManager.systemProperties.userName
property string userPassword: ApplicationManager.systemProperties.userPassword
readonly property string imei: ApplicationManager.systemProperties.imei
- property bool isReconnecting: false
+
+ readonly property int maxReconnectCount: 5
+ property int reconnectionAttempt: 0
signal loginSuccessful()
+ signal connectionSuccessful()
+ signal connectionFailed()
+ signal tryConnectToServer()
+ signal loginFailed()
+ signal serverOnMaintance()
property var d: QtObject {
-
- property int attempt: 0
- property Timer retryTimer: Timer {
- interval: 2000
- onTriggered: {
- d.checkServerPrivate()
- }
- }
-
- function retry() {
- console.log(Logging.apps, "Neptune-UI::Application Store - Retry Connection");
- if (attempt < 5) {
- attempt += 1;
- retryTimer.start();
- } else {
- root.isReconnecting = false;
- }
- }
-
function checkServerPrivate() {
- root.isReconnecting = true;
console.log(Logging.apps, "Neptune-UI::Application Store - Check Server");
+ root.tryConnectToServer();
var url = root.serverUrl + "/hello";
var data = {"platform" : "NEPTUNE3", "version" : "1", "architecture": root.cpuArch};
- JSONBackend.setErrorFunction(function () {
- root.serverOnline = false;
- root.serverReason = "unknown";
- root.d.retry()
- })
+ JSONBackend.setErrorFunction(0);
JSONBackend.serverCall(url, data, function(data) {
if (data !== 0) {
if (data.status === "ok") {
- root.d.attempt = 0
- root.serverOnline = true;
- root.isReconnecting = false;
- root.login();
+ root.reconnectionAttempt = 0
+ root.connectionSuccessful();
} else if (data.status === "maintenance") {
- console.log(Logging.apps, "Server Call: maintenance");
- root.serverOnline = false;
- root.serverReason = "maintenance";
+ console.warn(Logging.apps, "Server Call: maintenance");
+ root.serverOnMaintance();
} else {
- console.log(Logging.apps, "Server Call Err: " + data.error);
- root.serverOnline = false;
- root.d.retry()
+ console.warn(Logging.apps, "Server Call Err: " + data.error,
+ "Status: " + data.status);
+ root.connectionFailed();
}
} else {
- root.serverOnline = false;
- root.serverReason = "unknown";
- root.d.retry();
+ console.warn(Logging.apps, "Server Check Error: zero data error")
+ root.connectionFailed();
}
})
}
}
function checkServer() {
- root.d.attempt = 0
root.d.checkServerPrivate()
}
function login() {
var url = serverUrl + "/login"
var data = { "username" : userName, "password" : userPassword, "imei" : imei }
+
+ JSONBackend.setErrorFunction(0);
JSONBackend.serverCall(url, data, function(data) {
if (data !== 0) {
if (data.status === "ok") {
console.log(Logging.apps, "Login Succeeded");
loginSuccessful();
} else {
- console.log(Logging.apps, "Login Err: " + data.error);
+ console.warn(Logging.apps, "Login Error: " + data.error,
+ "Status: " + data.status);
+ root.loginFailed();
}
+ } else {
+ console.warn(Logging.apps, "Login Error: zero data error");
+ root.loginFailed();
}
})
}
diff --git a/apps/com.pelagicore.downloads/views/DownloadsView.qml b/apps/com.pelagicore.downloads/views/DownloadsView.qml
index 29424f11..ca7fa916 100644
--- a/apps/com.pelagicore.downloads/views/DownloadsView.qml
+++ b/apps/com.pelagicore.downloads/views/DownloadsView.qml
@@ -46,109 +46,137 @@ Item {
property DownloadsStore store
- Connections {
- target: store
- onCategoryListReady: {
- if (toolsColumn.model && toolsColumn.model.count > 0) {
- toolsColumn.toolClicked(0);
+ states: [
+ State {
+ when: store.downloadsStates.noNetwork.active
+ PropertyChanges { target: busyMessage; opacity: 1.0 }
+ PropertyChanges { target: downloadsContent; opacity: 0.0 }
+ PropertyChanges {
+ target: busyIndicator
+ opacity: store.downloadsStates.connectingToServer.active ? 1.0 : 0.0
}
- }
- }
-
- BusyIndicator {
- id: busyIndicator
-
- width: Sizes.dp(225)
- height: Sizes.dp(440)
- anchors.centerIn: parent
- running: visible
- opacity: root.store.isBusy ? 1.0 : 0.0
- visible: opacity > 0.0
- Behavior on opacity {
- PauseAnimation { duration: 1000 }
- DefaultNumberAnimation { }
- }
- }
-
- Loader {
- anchors.top: root.store.isBusy ? busyIndicator.bottom : undefined
- anchors.centerIn: busyIndicator.visible ? undefined : root
- anchors.topMargin: Sizes.dp(8)
- anchors.horizontalCenter: parent.horizontalCenter
- sourceComponent: root.store.isOnline ? fetchingLabel : noInternetLabel
- visible: opacity > 0
- opacity: root.store.isOnline ? busyIndicator.opacity : 1.0
- Behavior on opacity { DefaultNumberAnimation { } }
- }
-
- Component {
- id: fetchingLabel
-
- Label {
- color: Style.contrastColor
- font.pixelSize: Sizes.fontSizeM
- text: qsTr("Fetching data from Neptune Server")
- }
- }
-
- Component {
- id: noInternetLabel
-
- Column {
- id: column
- anchors.centerIn: parent
- spacing: Sizes.dp(50)
- Label {
- color: Style.contrastColor
- font.pixelSize: Sizes.fontSizeM
- horizontalAlignment: Text.AlignHCenter
+ PropertyChanges {
+ target: topMessageText
text: qsTr("Cannot Connect to the Server") + "\n" +
qsTr("A Network connection is required")
}
- Label {
- color: Style.contrastColor
- font.pixelSize: Sizes.fontSizeM
- horizontalAlignment: Text.AlignHCenter
+ PropertyChanges {
+ target: bottomMessageText
text: qsTr("Reconnecting...")
- visible: store.isReconnecting
- anchors.horizontalCenter: parent.horizontalCenter
+ opacity: store.downloadsStates.connectingToServer.active ? 1.0 : 0.0
}
- Button {
- text: qsTr("Retry")
- implicitHeight: Sizes.dp(70)
- implicitWidth: Sizes.dp(315)
- font.pixelSize: Sizes.fontSizeS
- anchors.horizontalCenter: column.horizontalCenter
- visible: !store.isReconnecting
- onClicked: {
- store.appStoreConfig.checkServer()
- }
+ PropertyChanges {
+ target: retryButton
+ visible: !store.downloadsStates.connectingToServer.active
+ }
+ },
+ State {
+ when: store.downloadsStates.networkConnected.active
+ && store.downloadsStates.connectingToServer.active
+ PropertyChanges { target: busyMessage; opacity: 1.0 }
+ PropertyChanges { target: downloadsContent; opacity: 0.0 }
+ PropertyChanges { target: busyIndicator; opacity: 1.0 }
+ PropertyChanges {
+ target: topMessageText
+ text: qsTr("Connecting to server...")
+ }
+ PropertyChanges { target: bottomMessageText; opacity: 0.0 }
+ PropertyChanges { target: retryButton; visible: false }
+ },
+ State {
+ when: store.downloadsStates.networkConnected.active
+ && store.downloadsStates.checkServerError.active
+ PropertyChanges { target: busyMessage; opacity: 1.0 }
+ PropertyChanges { target: downloadsContent; opacity: 0.0 }
+ PropertyChanges { target: busyIndicator; opacity: 1.0 }
+ PropertyChanges {
+ target: topMessageText
+ text: qsTr("Connecting to server...")
+ }
+ PropertyChanges { target: bottomMessageText; opacity: 0.0 }
+ PropertyChanges { target: retryButton; visible: false }
+ },
+ State {
+ when: store.downloadsStates.serverNA.active
+ PropertyChanges { target: busyMessage; opacity: 1.0 }
+ PropertyChanges { target: downloadsContent; opacity: 0.0 }
+ PropertyChanges { target: busyIndicator; opacity: 0.0 }
+ PropertyChanges {
+ target: topMessageText
+ text: qsTr("Server is not available")
+ }
+ PropertyChanges { target: retryButton; visible: true }
+ },
+ State {
+ when: store.downloadsStates.serverOnMaintance.active
+ PropertyChanges { target: busyMessage; opacity: 1.0 }
+ PropertyChanges { target: downloadsContent; opacity: 0.0 }
+ PropertyChanges { target: busyIndicator; opacity: 0.0 }
+ PropertyChanges {
+ target: topMessageText
+ text: qsTr("Server is on Maintance")
+ }
+ PropertyChanges { target: retryButton; visible: true }
+ },
+ State {
+ when: store.downloadsStates.connectedError.active
+ PropertyChanges { target: busyMessage; opacity: 1.0 }
+ PropertyChanges { target: downloadsContent; opacity: 0.0 }
+ PropertyChanges { target: busyIndicator; opacity: 0.0 }
+ PropertyChanges {
+ target: topMessageText
+ text: store.downloadsStates.connectedError.errorText
+ }
+ PropertyChanges { target: retryButton; visible: true }
+ },
+ State {
+ when: store.downloadsStates.fetchingApps.active
+ || store.downloadsStates.fetchingCategories.active
+ PropertyChanges { target: busyMessage; opacity: 1.0 }
+ PropertyChanges { target: downloadsContent; opacity: 1.0 }
+ PropertyChanges { target: appList; opacity: 0.0 }
+ PropertyChanges { target: busyIndicator; opacity: 1.0 }
+ PropertyChanges {
+ target: topMessageText
+ text: qsTr("Fetching data from Neptune Server")
+ }
+ PropertyChanges { target: bottomMessageText; text: "" }
+ PropertyChanges { target: retryButton; visible: false }
+ },
+ State {
+ when: store.downloadsStates.appsLoaded.active && appList.count === 0
+ PropertyChanges { target: busyMessage; opacity: 1.0 }
+ PropertyChanges { target: downloadsContent; opacity: 1.0 }
+ PropertyChanges { target: busyIndicator; opacity: 0.0 }
+ PropertyChanges {
+ target: topMessageText
+ text: qsTr("No apps")
}
+ PropertyChanges { target: bottomMessageText; text: "" }
+ PropertyChanges { target: retryButton; visible: false }
+ },
+ State {
+ when: store.downloadsStates.appsLoaded.active && appList.count > 0
+ PropertyChanges { target: busyMessage; opacity: 0.0 }
+ PropertyChanges { target: downloadsContent; opacity: 1.0 }
+ PropertyChanges { target: appList; opacity: 1.0 }
}
- }
-
- Label {
- anchors.centerIn: parent
- color: Style.contrastColor
- font.pixelSize: Sizes.fontSizeM
- text: qsTr("No apps found!")
- opacity: 1.0 - busyIndicator.opacity
- visible: root.store.isBusy
- }
+ ]
RowLayout {
id: downloadsContent
+
anchors.left: parent.left
anchors.top: parent.top
anchors.topMargin: Sizes.dp(500)
anchors.bottom: parent.bottom
anchors.bottomMargin: Sizes.dp(20)
+ opacity: 0.0
visible: opacity > 0
- opacity: root.store.isOnline ? 1.0 : 0.0
- Behavior on opacity { DefaultNumberAnimation { } }
DownloadsToolsColumn {
id: toolsColumn
+
objectName: "downloadsAppColumn"
Layout.preferredWidth: Sizes.dp(264)
Layout.fillHeight: true
@@ -159,13 +187,16 @@ Item {
DownloadAppList {
id: appList
+
objectName: "downloadAppList"
Layout.preferredHeight: Sizes.dp(800)
Layout.preferredWidth: Sizes.dp(675)
Layout.alignment: Qt.AlignTop
Layout.topMargin: Sizes.dp(16)
- store: root.store
-
+ appServerUrl: root.store.appServerUrl
+ cpuArch: root.store.cpuArch
+ applicationModel: root.store.applicationModel
+ currentInstallationProgress: root.store.currentInstallationProgress
onToolClicked: {
if (root.store.isPackageBusy(appId)) {
console.warn("Package busy... Aborting", appId)
@@ -177,6 +208,136 @@ Item {
root.store.download(appId, appName);
}
}
+ onAppClicked: { root.store.tryStartApp(appId); }
+
+ Behavior on opacity { DefaultNumberAnimation { duration: 200 } }
+
+ Connections {
+ target: root.store
+ onInstalledPackagesChanged: {
+ // update states of app items, pass functions to update function
+ appList.refreshAppsInfo(root.store.isPackageInstalledByPackageController,
+ root.store.isPackageBuiltIn,
+ root.store.getInstalledPackageSizeText)
+ }
+ }
+ }
+ }
+
+ Item {
+ id: busyMessage
+
+ anchors.fill: parent
+ Behavior on opacity {
+ SequentialAnimation{
+ // keep invisible and only show if nothing happens not to blink
+ PauseAnimation { duration: 400 }
+ DefaultNumberAnimation { }
+ }
+ }
+
+ ColumnLayout {
+ anchors.top: parent.top
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.topMargin: Sizes.dp(400)
+
+ BusyIndicator {
+ id: busyIndicator
+
+ implicitWidth: Sizes.dp(225)
+ implicitHeight: Sizes.dp(440)
+ opacity: 0.0
+ Layout.alignment: Qt.AlignHCenter
+ Behavior on opacity {
+ SequentialAnimation{
+ PauseAnimation { duration: 1000 }
+ DefaultNumberAnimation { }
+ }
+ }
+ }
+
+ Label {
+ id: topMessageText
+
+ color: Style.contrastColor
+ font.pixelSize: Sizes.fontSizeM
+ horizontalAlignment: Text.AlignHCenter
+ Layout.alignment: Qt.AlignHCenter
+ }
+
+ Label {
+ id: bottomMessageText
+
+ color: Style.contrastColor
+ font.pixelSize: Sizes.fontSizeM
+ horizontalAlignment: Text.AlignHCenter
+ Layout.alignment: Qt.AlignHCenter
+ }
+
+ Button {
+ id: retryButton
+
+ text: qsTr("Retry")
+ implicitHeight: Sizes.dp(70)
+ implicitWidth: Sizes.dp(315)
+ font.pixelSize: Sizes.fontSizeS
+ visible: false
+ Layout.alignment: Qt.AlignHCenter
+ onClicked: { store.appStoreConfig.checkServer() }
+ }
+ }
+ }
+
+ /*
+
+ // Debug visual output for states changes
+
+ Loader {
+ active: true
+ sourceComponent: Component {
+ id: debugStatesComponent
+
+ ListView {
+ width: parent.width; height: Sizes.dp(600)
+ model: statesModel
+ delegate: Row {
+ Rectangle {
+ width: Sizes.dp(20); height: Sizes.dp(30);
+ color: model.stateValue ? "green" : "red"
+ }
+ Label { text: model.stateName }
+ }
+
+ function updateStatesList() {
+ statesModel.clear();
+ statesModel.append({"stateName": "noNetwork", "stateValue": store.downloadsStates.noNetwork.active });
+ statesModel.append({"stateName": "networkConnected", "stateValue": store.downloadsStates.networkConnected.active });
+ statesModel.append({"stateName": "connectingToServer", "stateValue": store.downloadsStates.connectingToServer.active });
+ statesModel.append({"stateName": "connectedError", "stateValue": store.downloadsStates.connectedError.active });
+ statesModel.append({"stateName": "connectedToServer", "stateValue": store.downloadsStates.connectedToServer.active });
+ statesModel.append({"stateName": "fetchingApps", "stateValue": store.downloadsStates.fetchingApps.active });
+ statesModel.append({"stateName": "fetchingCategories", "stateValue": store.downloadsStates.fetchingCategories.active });
+ statesModel.append({"stateName": "appsLoaded", "stateValue": store.downloadsStates.appsLoaded.active });
+ statesModel.append({"stateName": "serverOnMaintance", "stateValue": store.downloadsStates.serverOnMaintance.active });
+ statesModel.append({"stateName": "serverNA", "stateValue": store.downloadsStates.serverNA.active });
+ statesModel.append({"stateName": "loggingIn", "stateValue": store.downloadsStates.loggingIn.active });
+ statesModel.append({"stateName": "categoriesLoaded", "stateValue": store.downloadsStates.categoriesLoaded.active });
+ statesModel.append({"stateName": "checkServerError", "stateValue": store.downloadsStates.checkServerError.active });
+ }
+
+ ListModel {
+ id: statesModel
+ Component.onCompleted: { updateStatesList(); }
+ }
+
+ Connections {
+ target: root
+ onStateChanged: { updateStatesList(); }
+ }
+ }
+
}
}
+
+ */
}
diff --git a/imports_shared/assets/translations/ar_MA.ts b/imports_shared/assets/translations/ar_MA.ts
index 869fd934..1d573ccc 100644
--- a/imports_shared/assets/translations/ar_MA.ts
+++ b/imports_shared/assets/translations/ar_MA.ts
@@ -301,6 +301,21 @@ temperatures between 14° and 18°.</source>
</message>
</context>
<context>
+ <name>DownloadsStates</name>
+ <message>
+ <source>Login Failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fetching categories error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fetching apps error</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>DownloadsStore</name>
<message>
<source>%1 Bytes</source>
@@ -399,7 +414,7 @@ temperatures between 14° and 18°.</source>
</message>
<message>
<source>No apps found!</source>
- <translation>لا وجود لتطبيقات!</translation>
+ <translation type="vanished">لا وجود لتطبيقات!</translation>
</message>
<message>
<source>A Network connection is required</source>
@@ -413,6 +428,22 @@ temperatures between 14° and 18°.</source>
<source>Retry</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Connecting to server...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server is not available</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server is on Maintance</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No apps</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>DrivingModeRange</name>
diff --git a/imports_shared/assets/translations/cs_CZ.ts b/imports_shared/assets/translations/cs_CZ.ts
index db2abfaf..a58ebb29 100644
--- a/imports_shared/assets/translations/cs_CZ.ts
+++ b/imports_shared/assets/translations/cs_CZ.ts
@@ -613,6 +613,21 @@ temperatures between 14° and 18°.</source>
</message>
</context>
<context>
+ <name>DownloadsStates</name>
+ <message>
+ <source>Login Failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fetching categories error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fetching apps error</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>DownloadsStore</name>
<message>
<source>%1 Successfully Installed</source>
@@ -711,7 +726,7 @@ temperatures between 14° and 18°.</source>
</message>
<message>
<source>No apps found!</source>
- <translation type="unfinished">Žádné aplikace nenalezeny!</translation>
+ <translation type="obsolete">Žádné aplikace nenalezeny!</translation>
</message>
<message>
<source>A Network connection is required</source>
@@ -725,6 +740,22 @@ temperatures between 14° and 18°.</source>
<source>Retry</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Connecting to server...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server is not available</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server is on Maintance</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No apps</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>DrivingModeRange</name>
diff --git a/imports_shared/assets/translations/de_DE.ts b/imports_shared/assets/translations/de_DE.ts
index 9d790ae4..bbe6cbd7 100644
--- a/imports_shared/assets/translations/de_DE.ts
+++ b/imports_shared/assets/translations/de_DE.ts
@@ -454,6 +454,21 @@ temperatures between 14° and 18°.</source>
</message>
</context>
<context>
+ <name>DownloadsStates</name>
+ <message>
+ <source>Login Failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fetching categories error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fetching apps error</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>DownloadsStore</name>
<message>
<source>%1 Successfully Installed</source>
@@ -548,7 +563,7 @@ temperatures between 14° and 18°.</source>
</message>
<message>
<source>No apps found!</source>
- <translation>Keine Apps gefunden!</translation>
+ <translation type="vanished">Keine Apps gefunden!</translation>
</message>
<message>
<source>A Network connection is required</source>
@@ -562,6 +577,22 @@ temperatures between 14° and 18°.</source>
<source>Retry</source>
<translation>Wiederholung</translation>
</message>
+ <message>
+ <source>Connecting to server...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server is not available</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server is on Maintance</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No apps</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>DrivingModeRange</name>
diff --git a/imports_shared/assets/translations/en_GB.ts b/imports_shared/assets/translations/en_GB.ts
index 0b4d0391..b24b4b62 100644
--- a/imports_shared/assets/translations/en_GB.ts
+++ b/imports_shared/assets/translations/en_GB.ts
@@ -278,6 +278,21 @@ temperatures between 14° and 18°.</source>
</message>
</context>
<context>
+ <name>DownloadsStates</name>
+ <message>
+ <source>Login Failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fetching categories error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fetching apps error</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>DownloadsStore</name>
<message>
<source>%1 Successfully Installed</source>
@@ -371,10 +386,6 @@ temperatures between 14° and 18°.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No apps found!</source>
- <translation></translation>
- </message>
- <message>
<source>A Network connection is required</source>
<translation type="unfinished"></translation>
</message>
@@ -386,6 +397,22 @@ temperatures between 14° and 18°.</source>
<source>Retry</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Connecting to server...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server is not available</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server is on Maintance</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No apps</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>DrivingModeRange</name>
diff --git a/imports_shared/assets/translations/en_US.ts b/imports_shared/assets/translations/en_US.ts
index 4390cd37..b0c7b4a1 100644
--- a/imports_shared/assets/translations/en_US.ts
+++ b/imports_shared/assets/translations/en_US.ts
@@ -278,6 +278,21 @@ temperatures between 14° and 18°.</source>
</message>
</context>
<context>
+ <name>DownloadsStates</name>
+ <message>
+ <source>Login Failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fetching categories error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fetching apps error</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>DownloadsStore</name>
<message>
<source>%1 Successfully Installed</source>
@@ -371,10 +386,6 @@ temperatures between 14° and 18°.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No apps found!</source>
- <translation></translation>
- </message>
- <message>
<source>A Network connection is required</source>
<translation type="unfinished"></translation>
</message>
@@ -386,6 +397,22 @@ temperatures between 14° and 18°.</source>
<source>Retry</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Connecting to server...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server is not available</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server is on Maintance</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No apps</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>DrivingModeRange</name>
diff --git a/imports_shared/assets/translations/ja_JP.ts b/imports_shared/assets/translations/ja_JP.ts
index 852ce7d2..cf03eb90 100644
--- a/imports_shared/assets/translations/ja_JP.ts
+++ b/imports_shared/assets/translations/ja_JP.ts
@@ -440,6 +440,21 @@ temperatures between 14° and 18°.</source>
</message>
</context>
<context>
+ <name>DownloadsStates</name>
+ <message>
+ <source>Login Failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fetching categories error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fetching apps error</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>DownloadsStore</name>
<message>
<source>%1 Successfully Installed</source>
@@ -534,7 +549,7 @@ temperatures between 14° and 18°.</source>
</message>
<message>
<source>No apps found!</source>
- <translation type="unfinished">アプリが見つかりません!</translation>
+ <translation type="obsolete">アプリが見つかりません!</translation>
</message>
<message>
<source>A Network connection is required</source>
@@ -548,6 +563,22 @@ temperatures between 14° and 18°.</source>
<source>Retry</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Connecting to server...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server is not available</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server is on Maintance</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No apps</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>DrivingModeRange</name>
diff --git a/imports_shared/assets/translations/ko_KR.ts b/imports_shared/assets/translations/ko_KR.ts
index f46cb8fe..e714754d 100644
--- a/imports_shared/assets/translations/ko_KR.ts
+++ b/imports_shared/assets/translations/ko_KR.ts
@@ -447,6 +447,21 @@ temperatures between 14° and 18°.</source>
</message>
</context>
<context>
+ <name>DownloadsStates</name>
+ <message>
+ <source>Login Failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fetching categories error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fetching apps error</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>DownloadsStore</name>
<message>
<source>%1 Successfully Installed</source>
@@ -541,7 +556,7 @@ temperatures between 14° and 18°.</source>
</message>
<message>
<source>No apps found!</source>
- <translation type="unfinished">앱을 찾을 수 없습니다!</translation>
+ <translation type="obsolete">앱을 찾을 수 없습니다!</translation>
</message>
<message>
<source>A Network connection is required</source>
@@ -555,6 +570,22 @@ temperatures between 14° and 18°.</source>
<source>Retry</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Connecting to server...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server is not available</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server is on Maintance</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No apps</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>DrivingModeRange</name>
diff --git a/imports_shared/assets/translations/zh_CN.ts b/imports_shared/assets/translations/zh_CN.ts
index 42b48cad..28c835e7 100644
--- a/imports_shared/assets/translations/zh_CN.ts
+++ b/imports_shared/assets/translations/zh_CN.ts
@@ -447,6 +447,21 @@ temperatures between 14° and 18°.</source>
</message>
</context>
<context>
+ <name>DownloadsStates</name>
+ <message>
+ <source>Login Failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fetching categories error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fetching apps error</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>DownloadsStore</name>
<message>
<source>%1 Successfully Installed</source>
@@ -541,7 +556,7 @@ temperatures between 14° and 18°.</source>
</message>
<message>
<source>No apps found!</source>
- <translation type="unfinished">未找到app!</translation>
+ <translation type="obsolete">未找到app!</translation>
</message>
<message>
<source>A Network connection is required</source>
@@ -555,6 +570,22 @@ temperatures between 14° and 18°.</source>
<source>Retry</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Connecting to server...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server is not available</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server is on Maintance</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No apps</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>DrivingModeRange</name>