diff --git a/AppGrid.qml b/AppGrid.qml index 296c8fde..131c0835 100644 --- a/AppGrid.qml +++ b/AppGrid.qml @@ -7,7 +7,7 @@ import Qt.labs.settings 1.0 import AndroidNative 1.0 as AN import FileIO 1.0 -Page { +LauncherPage { id: appLauncher anchors.fill: parent @@ -119,11 +119,6 @@ Page { property double lastAppsCheck: 0.0 - background: Rectangle { - anchors.fill: parent - color: "transparent" - } - onTextInputChanged: { console.log("AppGrid | Text input changed: " + appLauncher.textInput) for (var i = 0; i < appLauncher.appGroups.length; i++) { @@ -354,10 +349,11 @@ Page { property var app property var gridView property bool isPinnedShortcut: false + property bool canBeDeleted: false + property int menuItemHeight: 40 background: Rectangle { id: menuBackground - height: contextMenu.isPinnedShortcut ? 150 : 110 implicitWidth: contextMenu.menuWidth color: Universal.accent radius: mainView.innerSpacing @@ -401,6 +397,7 @@ Page { } leftPadding: mainView.innerSpacing rightPadding: mainView.innerSpacing + bottomPadding: removeAppItem.visible ? 0 : mainView.innerSpacing background: Rectangle { anchors.fill: parent color: "transparent" @@ -424,8 +421,30 @@ Page { } } } + MenuItem { + id: removeAppItem + height: removeAppItem.visible ? contextMenu.menuItemHeight : 0 + font.pointSize: appLauncher.labelPointSize + contentItem: Label { + width: contextMenu.menuWidth + text: qsTr("Remove App") + horizontalAlignment: Text.AlignHCenter + } + leftPadding: mainView.innerSpacing + rightPadding: mainView.innerSpacing + bottomPadding: mainView.innerSpacing + background: Rectangle { + anchors.fill: parent + color: "transparent" + } + visible: contextMenu.canBeDeleted + onClicked: { + AN.SystemDispatcher.dispatch("volla.launcher.deleteAppAction", {"appId": contextMenu.app["package"]}) + } + } MenuItem { id: removePinnedShortcutItem + height: removePinnedShortcutItem.visible ? contextMenu.menuItemHeight : 0 font.pointSize: appLauncher.labelPointSize contentItem: Label { width: contextMenu.menuWidth @@ -452,6 +471,19 @@ Page { disabledPinnedShortcuts.disableShortcut(shortcutId) } } + + onAboutToShow: { + AN.SystemDispatcher.dispatch("volla.launcher.canDeleteAppAction", {"appId": contextMenu.app["package"]}) + } + + Connections { + target: AN.SystemDispatcher + onDispatched: { + if (type === "volla.launcher.canDeleteAppResponce") { + contextMenu.canBeDeleted = message["canDeleteApp"] + } + } + } } Connections { diff --git a/Collections.qml b/Collections.qml index ff48ef2b..269ab8b3 100644 --- a/Collections.qml +++ b/Collections.qml @@ -7,7 +7,7 @@ import Qt.labs.settings 1.0 import AndroidNative 1.0 as AN import FileIO 1.0 -Page { +LauncherPage { id: collectionPage anchors.fill: parent @@ -42,11 +42,6 @@ Page { property string c_TYPE: "type" // rss or atpm feed type property string c_SIGNAL: "signal" // has a signal account - background: Rectangle { - anchors.fill: parent - color: "transparent" - } - onTextInputChanged: { console.log("Collections | text input changed") currentCollectionModel.update(textInput) @@ -134,7 +129,7 @@ Page { AN.SystemDispatcher.dispatch("volla.launcher.threadAction", filter) // load threads from further source // address (phone or contact), body (message), date, type - AN.SystemDispatcher.dispatch("volla.launcher.signalThreadsAction", filter) + if (mainView.isSignalActive) AN.SystemDispatcher.dispatch("volla.launcher.signalThreadsAction", filter) } function loadCalls(filter) { @@ -628,9 +623,9 @@ Page { var now = new Date() collectionPage.threads.forEach(function (thread, index) { - console.log("Collections | Thread: " + thread["date"]) + console.log("Collections | Thread: " + thread["address"]) if ((!thread["read"] || now.getTime() - thread["date"] < collectionPage.messageAge) && thread["address"] !== undefined) { - console.log("Collections | Thread matched: " + thread["id"]) + console.log("Collections | Thread matched: " + thread["address"]) if (thread["isSignal"]) contactThreads[thread["person"]] = thread else contactThreads[thread["address"]] = thread } @@ -798,7 +793,7 @@ Page { filteredModelItem = modelArr[i] var modelItemName = modelArr[i].c_TITLE if (text.length === 0 || modelItemName.toLowerCase().includes(text.toLowerCase())) { - //console.log("Collections | Add " + modelItemName + " to filtered items") + // console.log("Collections | Add " + modelItemName + " to filtered items") filteredModelDict[modelItemName] = filteredModelItem } } diff --git a/Conversation.qml b/Conversation.qml index 901e7052..ab3e51cf 100644 --- a/Conversation.qml +++ b/Conversation.qml @@ -6,7 +6,7 @@ import QtQuick.Controls.Universal 2.12 import QtGraphicalEffects 1.12 import AndroidNative 1.0 as AN -Page { +LauncherPage { id: conversationPage anchors.fill: parent @@ -36,11 +36,6 @@ Page { property string m_DATE: "date" // date in milliseconds of the item property string m_ERROR: "error" // error message under message - background: Rectangle { - anchors.fill: parent - color: "transparent" - } - Connections { target: Qt.inputMethod diff --git a/Details.qml b/Details.qml index aded9ebe..c82b7223 100644 --- a/Details.qml +++ b/Details.qml @@ -5,7 +5,7 @@ import QtWebView 1.12 import QtGraphicalEffects 1.12 import AndroidNative 1.0 as AN -Page { +LauncherPage { id: detailPage objectName: "detailPage" anchors.fill: parent @@ -16,11 +16,6 @@ Page { property var currentTitle property var currentDetailHasBadge: false - background: Rectangle { - anchors.fill: parent - color: "transparent" - } - header: Rectangle { id: detailPageHeader width: parent.width @@ -206,6 +201,14 @@ Page { function prepareNoteView(note, curserPosition) { console.log("Details | Process note " + currentDetailId + " with curser at " + curserPosition) + +// console.debug("================") +// var noteArr = note.split("\n") +// for (var l = 0;l < noteArr.length; l++) console.debug("LINE: " + noteArr[l]) + + detailEdit.isBlocked = true + detailEdit.textLength = note.length + var styledText = note.slice() var urlRegex = /(((https?:\/\/)|([^\s]+\.))[^\s,]+)/g; styledText = styledText.replace(urlRegex, function(url,b,c) { @@ -213,21 +216,34 @@ Page { return '' + url + ''; }) - styledText = styledText.replace(/^(### .*$)/gim, '

<$1

') // h3 tag - .replace(/^(## .*$)/gim, '

$1

') // h2 tag - .replace(/^(# .*$)/gim, '

$1

') // h1 tag - .replace(/^(.*\n)/m, '

$1

') // trailing text + styledText = styledText.replace(/^(.*$)/gim, '

$1

') + .replace(/

(### .*)<\/p>/gim, '

<$1

') // h3 tag + .replace(/

(## .*)<\/p>/gim, '

$1

') // h2 tag + .replace(/

(# .*)<\/p>/gim, '

$1

') // h1 tag + .replace(/

(.*)<\/p>/m, '

$1

') // trailing text .replace(/(\*\*.*\*\*)/gim, '$1') // bold text .replace(/(\*.*\*)/gim, '$1') // italic text - .replace(/^(\* .*)/gim, '

$1

') // unsorted list - .replace(/^(- .*)/gim, '

$1

') // unsorted list - .replace(/^([0-9]+\. .*)/gim, '

$1

') // ordered list - .replace(/^(.*$)/gim, '

$1

') - .trim() + .replace(/

(\* .*)<\/p>/gim, '

$1

') // unsorted list + .replace(/

(- .*)<\/p>/gim, '

$1

') // unsorted list + .replace(/

([0-9]+\. .*)<\/p>/gim, '

$1

') // ordered list + .replace(/(

<\/p>)/gim, '') + .replace(/\n\n/gim, '') + //.trim() + +// console.debug("----------------") +// var textArr = styledText.split("\n") +// for (l = 0;l < textArr.length; l++) console.debug("LINE: " + textArr[l]) +// console.debug("================") detailEdit.text = styledText - if (curserPosition !== undefined) detailEdit.cursorPosition = curserPosition + if (curserPosition !== undefined) { + detailEdit.cursorPosition = curserPosition + } + + detailEdit.isBlocked = false + + console.log("Details | Process note finished") } Flickable { @@ -335,30 +351,33 @@ Page { bottomPadding: mainView.innerSpacing font.pointSize: mainView.largeFontSize wrapMode: TextEdit.Wrap - textFormat: Text.RichText + textFormat: TextEdit.RichText + inputMethodHints: Qt.ImhNoPredictiveText verticalAlignment: Text.AlignTop background: Rectangle { color: "transparent" border.color: "transparent" } - property bool isBlocked: true + property bool isBlocked: false property int lastCurserPosition: 0 + property int textLength onCursorRectangleChanged: detailFlickable.ensureVisible(cursorRectangle) onCursorPositionChanged: { - console.log("Details | Curser postion changed to " + detailEdit.cursorPosition) - if (!isBlocked) { - isBlocked = true - lastCurserPosition = detailEdit.cursorPosition - console.debug("Details | Plain Text: " + detailEdit.getText(0, detailEdit.length)) - var plainText = detailEdit.getText(0, detailEdit.length) - //detailEdit.text.replace(/p, li \{ white-space: pre-wrap; \}/gim, '').replace(/<[^>]+>/g, '').trim() - detailPage.prepareNoteView(plainText, lastCurserPosition) - mainView.updateNote(detailPage.currentDetailId, plainText, detailPage.currentDetailHasBadge) + if (detailEdit.isBlocked === false) { + console.debug("Details | Curser postion changed from " + lastCurserPosition + " to " + detailEdit.cursorPosition) + + var plainText = detailEdit.getText(0, 10000) + + if (plainText.length !== detailEdit.textLength) { + mainView.updateNote(detailPage.currentDetailId, plainText, detailPage.currentDetailHasBadge) + } + + detailPage.prepareNoteView(plainText, detailEdit.cursorPosition) } - if (lastCurserPosition === detailEdit.cursorPosition) isBlocked = false + lastCurserPosition = detailEdit.cursorPosition } onActiveFocusChanged: { @@ -368,7 +387,6 @@ Page { } else { var plainText = detailEdit.text.replace(/p, li \{ white-space: pre-wrap; \}/gim, '').replace(/<[^>]+>/g, '').trim() mainView.updateNote(detailPage.currentDetailId, plainText, detailPage.currentDetailHasBadge) - isBlocked = true detailFlickable.height = mainView.height } } diff --git a/Feed.qml b/Feed.qml index 82f3ac32..cd178ab1 100644 --- a/Feed.qml +++ b/Feed.qml @@ -5,7 +5,7 @@ import QtQuick.Controls.Universal 2.12 import QtGraphicalEffects 1.12 import AndroidNative 1.0 as AN -Page { +LauncherPage { id : feedPage anchors.fill: parent diff --git a/HighlightButton.qml b/HighlightButton.qml new file mode 100644 index 00000000..87f51ba3 --- /dev/null +++ b/HighlightButton.qml @@ -0,0 +1,28 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.5 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Controls.Universal 2.12 + +Button { + id: root + + property bool boldText: false + property alias textColor: buttonText.color + property alias textOpacity: buttonText.opacity + property alias backgroundColor: buttonBackground.color + property real fontPointSize: mainView.largeFontSize + + contentItem: Text { + id: buttonText + width: parent.width - 2 * root.padding + font.pointSize: root.fontPointSize + font.weight: root.boldText ? Font.Black : Font.Normal + text: root.text + color: Universal.foreground + } + background: Rectangle { + id: buttonBackground + anchors.fill: parent + color: "transparent" + } +} \ No newline at end of file diff --git a/LauncherPage.qml b/LauncherPage.qml new file mode 100644 index 00000000..87ad9ce4 --- /dev/null +++ b/LauncherPage.qml @@ -0,0 +1,9 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.5 + +Page { + background: Rectangle { + anchors.fill: parent + color: "transparent" + } +} \ No newline at end of file diff --git a/Settings.qml b/Settings.qml index 916de9ef..196e9716 100644 --- a/Settings.qml +++ b/Settings.qml @@ -7,16 +7,11 @@ import QtGraphicalEffects 1.12 import Qt.labs.settings 1.0 import AndroidNative 1.0 as AN -Page { +LauncherPage { id: settingsPage anchors.fill: parent topPadding: mainView.innerSpacing - background: Rectangle { - anchors.fill: parent - color: "transparent" - } - Flickable { anchors.fill: parent contentWidth: parent.width @@ -109,7 +104,7 @@ Page { } } } - Button { + HighlightButton { id: darkModeOption property var theme: mainView.theme.Dark @@ -120,19 +115,13 @@ Page { width: parent.width visible: themeSettingsItem.menuState text: qsTr("Dark Mode") - contentItem: Text { - text: darkModeOption.text - font.pointSize: mainView.mediumFontSize - font.weight: themeSettingsItem.selectedMenuItem === darkModeOption ? Font.Black : Font.Normal - color: "white" - opacity: themeSettingsItem.labelOpacity - } - background: Rectangle { - anchors.fill: parent - color: themeSettingsItem.menuState ? Universal.accent : "transparent" - } + boldText: themeSettingsItem.selectedMenuItem === darkModeOption + textColor: "white" + textOpacity: themeSettingsItem.labelOpacity + backgroundColor: themeSettingsItem.menuState ? Universal.accent : "transparent" + fontPointSize: mainView.mediumFontSize } - Button { + HighlightButton { id: lightModeOption property var theme: mainView.theme.Light @@ -143,19 +132,13 @@ Page { width: parent.width visible: themeSettingsItem.menuState text: qsTr("Light Mode") - contentItem: Text { - text: lightModeOption.text - font.pointSize: mainView.mediumFontSize - font.weight: themeSettingsItem.selectedMenuItem === lightModeOption ? Font.Black : Font.Normal - color: "white" - opacity: themeSettingsItem.labelOpacity - } - background: Rectangle { - anchors.fill: parent - color: themeSettingsItem.menuState ? Universal.accent : "transparent" - } + boldText: themeSettingsItem.selectedMenuItem === lightModeOption + textColor: "white" + textOpacity: themeSettingsItem.labelOpacity + backgroundColor: themeSettingsItem.menuState ? Universal.accent : "transparent" + fontPointSize: mainView.mediumFontSize } - Button { + HighlightButton { id: translucentModeOption property var theme: mainView.theme.Translucent @@ -166,17 +149,11 @@ Page { width: parent.width visible: themeSettingsItem.menuState text: qsTr("Translucent Mode") - contentItem: Text { - text: translucentModeOption.text - font.pointSize: mainView.mediumFontSize - font.weight: themeSettingsItem.selectedMenuItem === translucentModeOption ? Font.Black : Font.Normal - color: "white" - opacity: themeSettingsItem.labelOpacity - } - background: Rectangle { - anchors.fill: parent - color: themeSettingsItem.menuState ? Universal.accent : "transparent" - } + boldText: themeSettingsItem.selectedMenuItem === translucentModeOption + textColor: "white" + textOpacity: themeSettingsItem.labelOpacity + backgroundColor: themeSettingsItem.menuState ? Universal.accent : "transparent" + fontPointSize: mainView.mediumFontSize } } @@ -456,7 +433,7 @@ Page { // Check, if password is set AN.SystemDispatcher.dispatch("volla.launcher.checkSecurityPasswordAction", {}) } else if (selectedMenuItem.text === securityModeOffOption.text) { - passwordDialog.backgroundColor = mainView.fontColor.toString() === "#ffffff" ? "#292929" : "#CCCCCC" + passwordDialog.backgroundColor = mainView.fontColor.toString() === "white" ? "#292929" : "#CCCCCC" passwordDialog.definePasswordMode = false passwordDialog.isPasswordSet = true passwordDialog.open() @@ -523,7 +500,7 @@ Page { placeholderTextColor: "darkgrey" font.pointSize: mainView.mediumFontSize background: Rectangle { - color: mainView.backgroundColor + color: mainView.fontColor.toString() === "white" ? "black" : "white" border.color: "transparent" } } @@ -551,7 +528,7 @@ Page { font.pointSize: mainView.mediumFontSize visible: passwordDialog.definePasswordMode background: Rectangle { - color: mainView.backgroundColor + color: mainView.fontColor.toString() === "white" ? "black" : "white" border.color: "transparent" } } @@ -661,7 +638,7 @@ Page { securitySettingsItem.visible = message["error"] === undefined && message["isInstalled"] } else if (type === "volla.launcher.checkSecurityPasswordResponse") { console.log("Settings | Password is set: " + message["isPasswordSet"]) - passwordDialog.backgroundColor = mainView.fontColor.toString() === "#ffffff" ? "#292929" : "#CCCCCC" + passwordDialog.backgroundColor = mainView.fontColor.toString() === "white" ? "#292929" : "#CCCCCC" passwordDialog.definePasswordMode = true passwordDialog.isPasswordSet = message["isPasswordSet"] passwordDialog.open() @@ -682,21 +659,12 @@ Page { property bool menuState: false property var newsCheckboxes: new Array - Button { + HighlightButton { id: newsSettingsItemTitle width: parent.width padding: mainView.innerSpacing - contentItem: Text { - width: parent.width - 2 * newsSettingsItemTitle.padding - text: qsTr("News Channels") - font.pointSize: mainView.largeFontSize - font.weight: newsSettingsItemColumn.menuState ? Font.Black : Font.Normal - color: Universal.foreground - } - background: Rectangle { - anchors.fill: parent - color: "transparent" - } + text: qsTr("News Channels") + boldText: newsSettingsItemColumn.menuState onClicked: { newsSettingsItemColumn.menuState = !newsSettingsItemColumn.menuState if (newsSettingsItemColumn.menuState) { @@ -773,21 +741,12 @@ Page { property bool menuState: false property var checkboxes: new Array - Button { + HighlightButton { id: shortcutSettingsItemButton width: parent.width padding: mainView.innerSpacing - contentItem: Text { - width: parent.width - 2 * shortcutSettingsItemButton.padding - text: qsTr("Shortcuts") - font.pointSize: mainView.largeFontSize - font.weight: shortcutSettingsItemColumn.menuState ? Font.Black : Font.Normal - color: Universal.foreground - } - background: Rectangle { - anchors.fill: parent - color: "transparent" - } + text: qsTr("Shortcuts") + boldText: shortcutSettingsItemColumn.menuState onClicked: { shortcutSettingsItemColumn.menuState = !shortcutSettingsItemColumn.menuState if (shortcutSettingsItemColumn.menuState) { @@ -968,21 +927,12 @@ Page { property bool menuState: false property var checkboxes: new Array - Button { + HighlightButton { id: sourceSettingsItemButton width: parent.width padding: mainView.innerSpacing - contentItem: Text { - width: parent.width - 2 * sourceSettingsItemButton.padding - text: qsTr("Source settings") - font.pointSize: mainView.largeFontSize - font.weight: sourceSettingsItemColumn.menuState ? Font.Black : Font.Normal - color: Universal.foreground - } - background: Rectangle { - anchors.fill: parent - color: "transparent" - } + boldText: sourceSettingsItemColumn.menuState + text: qsTr("Source settings") onClicked: { sourceSettingsItemColumn.menuState = !sourceSettingsItemColumn.menuState if (sourceSettingsItemColumn.menuState) { @@ -1067,21 +1017,12 @@ Page { property bool menuState: false property var checkboxes: new Array - Button { + HighlightButton { id: searchSettingsItemButton width: parent.width padding: mainView.innerSpacing - contentItem: Text { - width: parent.width - 2 * shortcutSettingsItemButton.padding - text: qsTr("Search engines") - font.pointSize: mainView.largeFontSize - font.weight: shortcutSettingsItemColumn.menuState ? Font.Black : Font.Normal - color: Universal.foreground - } - background: Rectangle { - anchors.fill: parent - color: "transparent" - } + text: qsTr("Search engines") + boldText: searchSettingsItemColumn.menuState onClicked: { searchSettingsItemColumn.menuState = !searchSettingsItemColumn.menuState if (searchSettingsItemColumn.menuState) { @@ -1171,21 +1112,12 @@ Page { property bool menuState: false property var checkboxes: new Array - Button { + HighlightButton { id: designSettingsItemButton width: parent.width padding: mainView.innerSpacing - contentItem: Text { - width: parent.width - 2 * shortcutSettingsItemButton.padding - text: qsTr("Display and menus") - font.pointSize: mainView.largeFontSize - font.weight: shortcutSettingsItemColumn.menuState ? Font.Black : Font.Normal - color: Universal.foreground - } - background: Rectangle { - anchors.fill: parent - color: "transparent" - } + text: qsTr("Display and menus") + boldText: designSettingsItemColumn.menuState onClicked: { designSettingsItemColumn.menuState = !designSettingsItemColumn.menuState if (designSettingsItemColumn.menuState) { @@ -1409,21 +1341,12 @@ Page { } } - Button { + HighlightButton { id: resetSettingsItemButton width: parent.width padding: mainView.innerSpacing - contentItem: Text { - width: parent.width - 2 * resetSettingsItemButton.padding - text: qsTr("Reset options") - font.pointSize: mainView.largeFontSize - font.weight: resetSettingsItemColumn.menuState ? Font.Black : Font.Normal - color: Universal.foreground - } - background: Rectangle { - anchors.fill: parent - color: "transparent" - } + text: qsTr("Reset options") + boldText: resetSettingsItemColumn.menuState onClicked: { resetSettingsItemColumn.menuState = !resetSettingsItemColumn.menuState settingsColumn.closeAllItemsExcept(resetSettingsItemColumn) diff --git a/Springboard.qml b/Springboard.qml index e28af1f9..14038b3e 100644 --- a/Springboard.qml +++ b/Springboard.qml @@ -7,7 +7,7 @@ import QtQuick.Window 2.2 import FileIO 1.0 import AndroidNative 1.0 as AN -Page { +LauncherPage { id: springBoard anchors.fill: parent @@ -26,11 +26,6 @@ Page { property bool dotShortcut: true property bool roundedShortcutMenu: true - background: Rectangle { - anchors.fill: parent - color: "transparent" - } - onTextInputChanged: { console.log("Springboard | text input changed") listModel.update() diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 80356187..5ef6db5d 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - +